Skip to content

Commit

Permalink
fix frames renderer bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
mi-sts committed Nov 3, 2023
1 parent 427da08 commit d4cff26
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 86 deletions.
51 changes: 10 additions & 41 deletions src/main/kotlin/solve/rendering/canvas/OpenGLCanvas.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,21 @@ import org.lwjgl.opengl.GL30.glDisableVertexAttribArray
import org.lwjgl.opengl.GL30.glEnableVertexAttribArray
import solve.constants.ShadersDefaultFragmentPath
import solve.constants.ShadersDefaultVertexPath
import solve.project.model.ProjectFrame
import solve.rendering.engine.Window
import solve.rendering.engine.camera.Camera
import solve.rendering.engine.components.SpriteRenderer
import solve.rendering.engine.rendering.renderers.DefaultRenderer
import solve.rendering.engine.rendering.renderers.FramesRenderer
import solve.rendering.engine.rendering.texture.Texture
import solve.rendering.engine.scene.GameObject
import solve.rendering.engine.scene.Scene
import solve.rendering.engine.scene.Transform
import solve.rendering.engine.shader.ShaderProgram
import solve.rendering.engine.shader.ShaderType
import solve.rendering.engine.structures.Color
import solve.utils.getResourceAbsolutePath
import java.nio.file.Path
import kotlin.math.sin
import com.huskerdev.openglfx.OpenGLCanvas as OpenGLFXCanvas

Expand All @@ -72,9 +76,7 @@ class OpenGLCanvas {
}

private lateinit var window: Window
private lateinit var renderer: DefaultRenderer
private lateinit var gameObject: GameObject
private var gs = mutableListOf<GameObject>()
private lateinit var renderer: FramesRenderer

var time = 0f

Expand All @@ -91,7 +93,6 @@ class OpenGLCanvas {
println(1/deltaTime)
renderer.render()
time += deltaTime
gameObject.transform.position.x = sin(time) * 100

/*shaderProgram.use()
shaderProgram.uploadTexture("uTex", 0)
Expand Down Expand Up @@ -170,44 +171,12 @@ class OpenGLCanvas {
texture = Texture("icons/img.png")*/

window = Window(1920, 600, Camera(Vector2f(), 1f))
val scene = Scene(Camera())
val texture1 = Texture("icons/img.png")
gameObject = GameObject(
"gameObject1",
Transform(Vector2f(), 0f, Vector2f(1000f, 1000f)),
listOf(SpriteRenderer(texture1))
)

/*val gameObject2 = GameObject(
"gameObject2",
Transform(Vector2f(1f, 0f)),
listOf(SpriteRenderer(texture1).also { it.setColor(Color.black) })
)
val gameObject3 = GameObject(
"gameObject3",
Transform(Vector2f(300f, 300f)),
listOf(SpriteRenderer(texture1))
)*/
scene.addGameObject(gameObject)
//scene.addGameObject(gameObject2)
//scene.addGameObject(gameObject3)
window = Window(1920, 600, Camera(Vector2f(0f, 0f), 5f))
val scene = Scene()
window.changeScene(scene)

renderer = DefaultRenderer(window)
renderer.addGameObject(gameObject)
//renderer.addGameObject(gameObject2)
//renderer.addGameObject(gameObject3)


for (i in -20 until 20)
for (j in -20 until 20) {
renderer.addGameObject( GameObject(
"gameObject1",
Transform(Vector2f(i * 10f, j * 10f), 0f, Vector2f(100f, 100f)),
listOf(SpriteRenderer(texture1))
))
}
val frames = List<ProjectFrame>(100000) { ProjectFrame(0L, Path.of(getResourceAbsolutePath("icons/img.png")!!), emptyList()) }
renderer = FramesRenderer(window)
renderer.setSceneFrames(frames)
}

@Suppress("UNUSED_PARAMETER")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package solve.rendering.engine.rendering.batch
import org.joml.Vector2f
import org.joml.Vector3f
import org.joml.Vector4f
import org.lwjgl.BufferUtils
import org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER
import org.lwjgl.opengl.GL15.GL_DYNAMIC_DRAW
import org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER
Expand Down Expand Up @@ -187,6 +188,10 @@ open class RenderBatch(
pushFloat(value.toFloat())
}

fun pushNone() {
++verticesDataBufferIndexPointer
}

companion object {
private const val MaxTexturesNumber = 8
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package solve.rendering.engine.rendering.renderers

import org.joml.Matrix4f
import org.joml.Vector2f
import org.joml.Vector2i
import org.lwjgl.opengl.GL11
import org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE
import org.lwjgl.opengl.GL11.glBindTexture
import org.lwjgl.opengl.GL11.glGenTextures
import org.lwjgl.opengl.GL13
import org.lwjgl.opengl.GL30.GL_TEXTURE_2D_ARRAY
import org.lwjgl.opengl.GL45.glTextureStorage3D
import org.lwjgl.opengl.GL45.glTextureSubImage3D
Expand Down Expand Up @@ -44,12 +47,19 @@ class FramesRenderer(

private var cameraLastGridCellPosition = Vector2i(0)

val texture = Texture("icons/img.png")

fun changeModelsCommonMatrix(newMatrix: Matrix4f) {
modelsCommonMatrix = newMatrix
}

fun setSceneFrames(frames: List<ProjectFrame>) {
if (frames.isEmpty())
return

this.frames = frames
initializeTexturesBuffers(frames)

needToRebuffer = true
}

Expand All @@ -68,19 +78,24 @@ class FramesRenderer(
shaderProgram.uploadMatrix4f(ModelUniformName, modelsCommonMatrix)
shaderProgram.uploadInt(GridWidthUniformName, gridWidth)
shaderProgram.uploadVector2i(BuffersSizeUniformName, buffersSize)
shaderProgram.uploadInt(TexturesArrayUniformName, buffersTexturesArrayID)
}

override fun createNewBatch(zIndex: Int) =
RenderBatch(maxBatchSize, zIndex, PrimitiveType.Point, listOf(ShaderAttributeType.FLOAT2))
RenderBatch(maxBatchSize, zIndex, PrimitiveType.Point, listOf(ShaderAttributeType.FLOAT))


override fun updateBatchesData() {
frames.forEach {
// val
frames.forEachIndexed { index, _ ->
val batch = getAvailableBatch(null, 0)
//val frameGridCellPosition = Vector2f((1..5).random().toFloat(), (1..5).random().toFloat())
batch.pushInt(index % 1000);
}
}

override fun beforeRender() {
texture.bindToSlot(1)

val cameraGridCellPosition = getCameraGridCellPosition()
if (cameraGridCellPosition != cameraLastGridCellPosition) {
updateBuffersTextures(cameraGridCellPosition)
Expand All @@ -106,7 +121,7 @@ class FramesRenderer(
private fun getFramesAtRect(rect: IntRect): List<List<ProjectFrame>> {
val framesRect = mutableListOf<List<ProjectFrame>>()
for (y in rect.y0 until rect.y0 + rect.height) {
framesRect.add(frames.subList(rect.x0, rect.x0 + rect.width - 1))
framesRect.add(frames.subList(rect.x0, rect.x0 + rect.width))
}

return framesRect
Expand All @@ -117,15 +132,13 @@ class FramesRenderer(
return

val buffersOffset = Vector2i(framesRect.x0 % buffersSize.x, framesRect.y0 % buffersSize.y)
val framesWidth = rectFrames.first().count()
val framesHeight = rectFrames.count()
if (framesWidth + buffersOffset.x > buffersSize.x || framesHeight + buffersOffset.y > buffersSize.y) {
if (framesRect.width + buffersOffset.x > buffersSize.x || framesRect.height + buffersOffset.y > buffersSize.y) {
println("The size of the loading frames is out of buffers bounds!")
return
}

for (y in 0 until framesHeight) {
for (x in 0 until framesWidth) {
for (y in 0 until framesRect.height) {
for (x in 0 until framesRect.width) {
val textureBuffersIndex = (y + buffersOffset.y) * buffersSize.x + x + buffersOffset.x
uploadFrameToBuffer(rectFrames[y][x], textureBuffersIndex)
}
Expand All @@ -149,20 +162,16 @@ class FramesRenderer(
}
}

private fun initializeTexturesBuffers(
framesWidth: Int,
framesHeight: Int,
framesChannelsType: TextureChannelsType
) {
private fun initializeTexturesBuffers(frames: List<ProjectFrame>) {
val firstTextureData = Texture.loadData(frames.first().imagePath.toString())
if (firstTextureData == null) {
println("The read texture is null!")
return
}

this.framesWidth = framesWidth
this.framesHeight = framesHeight
this.framesChannelsType = framesChannelsType
framesWidth = firstTextureData.width
framesHeight = firstTextureData.height
framesChannelsType = firstTextureData.channelsType

buffersTexturesArrayID = glGenTextures()
glBindTexture(GL_TEXTURE_2D_ARRAY, buffersTexturesArrayID)
Expand Down Expand Up @@ -196,17 +205,19 @@ class FramesRenderer(
GL_UNSIGNED_BYTE,
textureData.data
)

Texture.freeData(textureData)
}

companion object {
private const val ProjectionUniformName = "uProjection"
private const val ModelUniformName = "uModel"
private const val GridWidthUniformName = "uGridWidth"
private const val BuffersSizeUniformName = "uBuffersSize"
private const val TexturesUniformName = "uTextures"
private const val TexturesArrayUniformName = "uTextures"

private const val DefaultGridWidth = 5
private const val DefaultGridWidth = 50

private val defaultBuffersSize = Vector2i(10, 10)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ class Texture(private val resourcesPath: String) {
GL_UNSIGNED_BYTE,
textureData.data
)

freeData(textureData)
}

override fun equals(other: Any?): Boolean {
Expand Down Expand Up @@ -134,9 +136,12 @@ class Texture(private val resourcesPath: String) {
println("Wrong type of the texture image channels!")
return null
}
stbi_image_free(data)

return TextureData(data, width, height, imageChannelsType)
}

fun freeData(textureData: TextureData) {
stbi_image_free(textureData.data)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package solve.rendering.engine.shader

import org.lwjgl.opengl.GL11.GL_BYTE
import org.lwjgl.opengl.GL11.GL_FLOAT
import org.lwjgl.opengl.GL11.GL_INT

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,6 @@ operator fun Vector3f.times(value: Float): Vector3f = Vector3f(this).mul(value)

operator fun Vector4f.times(value: Float): Vector4f = Vector4f(this).mul(value)

operator fun Vector2f.div(value: Float): Vector2f = this * (1 / value)

operator fun Vector3f.div(value: Float): Vector3f = this * (1 / value)

operator fun Vector4f.div(value: Float): Vector4f = this * (1 / value)

fun Vector2f.toIntVector(): Vector2i = Vector2i(x.toInt(), y.toInt())

fun Vector3f.toIntVector(): Vector3i = Vector3i(x.toInt(), y.toInt(), z.toInt())
Expand Down
5 changes: 2 additions & 3 deletions src/main/resources/engine/shaders/frame/frame.frag
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
#version 330 core

in vec2 fTexCoords;
in int fTexID;

uniform sampler2DArray uTextures;
uniform sampler2D uTextures[2];

out vec4 color;

void main()
{
color = texture(uTextures, vec3(fTexCoords, fTexID));
color = texture(uTextures[1], fTexCoords);
}
21 changes: 9 additions & 12 deletions src/main/resources/engine/shaders/frame/frame.geom
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,36 @@ uniform int uGridWidth;
uniform ivec2 uBuffersSize;

in VS_OUT {
uint frameID;
} gs_in[0];
int frameID;
} gs_in[];

out vec2 fTexCoords;
out int fTexID;

layout (points) in;
layout (triangle_strip, max_vertices = 4) out;

void main() {
uint frameID = gs_in[0].frameID;
int frameID = gs_in[0].frameID;
int frameX = frameID / uGridWidth;
int frameY = mod(frameID, uGridWidth);
int frameY = int(mod(frameID, uGridWidth));

int bufferX = mod(frameID, uBuffersSize.x);
int bufferY = mod(frameID, uBuffersSize.y);

fTexID = bufferY * uBuffersSize.x + bufferX;
int bufferX = int(mod(frameID, uBuffersSize.x));
int bufferY = int(mod(frameID, uBuffersSize.y));

gl_Position = uProjection * uModel * gl_in[0].gl_Position;
fTexCoords = vec2(-1.0, 1.0);
fTexCoords = vec2(0.0, 1.0);
EmitVertex();

gl_Position = uProjection * uModel * (gl_in[0].gl_Position + vec4(1.0, 0.0, 0.0, 0.0));
fTexCoords = vec2(1.0, 1.0);
EmitVertex();

gl_Position = uProjection * uModel * (gl_in[0].gl_Position + vec4(0.0, 1.0, 0.0, 0.0));
fTexCoords = vec2(-1.0, -1.0);
fTexCoords = vec2(0.0, 0.0);
EmitVertex();

gl_Position = uProjection * uModel * (gl_in[0].gl_Position + vec4(1.0, 1.0, 0.0, 0.0));
fTexCoords = vec2(1.0, -1.0);
fTexCoords = vec2(1.0, 0.0);
EmitVertex();

EndPrimitive();
Expand Down
10 changes: 7 additions & 3 deletions src/main/resources/engine/shaders/frame/frame.vert
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
#version 330 core

layout (location=0) in vec2 aGridPos;
layout (location=0) in float aIndex;

uniform mat4 uProjection;
uniform mat4 uModel;
uniform int uGridWidth;

out VS_OUT {
uint frameID;
int frameID;
} vs_out;

void main()
{
int i = gl_VertexID;

gl_Position = uProjection * uModel * vec4(aGridPos, 1.0);
int index = int(aIndex);
int xPos = index % uGridWidth;
int yPos = index / uGridWidth;
gl_Position = vec4(xPos, yPos, 0.0, 1.0);
vs_out.frameID = i;
}

0 comments on commit d4cff26

Please sign in to comment.