Skip to content

Commit

Permalink
finish initial batch rendering logic
Browse files Browse the repository at this point in the history
  • Loading branch information
mi-sts committed Oct 22, 2023
1 parent 613fbc7 commit 4f4ca70
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ class SpriteRenderer(gameObject: GameObject) : Component(gameObject) {
var sprite: Sprite? = null
private set

val texture: Texture?
get() = sprite?.texture

fun setColor(color: Color) {
this.color = color
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package solve.rendering.engine.rendering.batch

import org.joml.Matrix2f
import org.joml.Vector2f
import org.joml.Vector3f
import org.joml.Vector4f
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 All @@ -16,6 +20,8 @@ import org.lwjgl.opengl.GL30.glDeleteVertexArrays
import org.lwjgl.opengl.GL30.glGenVertexArrays
import solve.rendering.engine.rendering.texture.Texture
import solve.rendering.engine.shader.ShaderAttributeType
import solve.rendering.engine.utils.toList
import java.nio.ByteBuffer

open class RenderBatch(
private val maxBatchSize: Int,
Expand All @@ -25,12 +31,13 @@ open class RenderBatch(
) {
var isFull = false
private set
var isTexturesFull = false
private set

private var vboID = 0
private var vaoID = 0
private var eboID = 0

private val textureIDs = mutableListOf<Int>()
private val textures = mutableListOf<Texture>()

private val attributesNumber = attributes.sumOf { it.number }
Expand Down Expand Up @@ -73,13 +80,15 @@ open class RenderBatch(
textures.add(texture)
textureID = textures.lastIndex + 1

if (textures.count() >= maxBatchSize)
isFull = true
if (textures.count() >= MaxTexturesNumber)
isTexturesFull = true
}

return textureID
}

fun getTextureLocalID(texture: Texture) = textures.indexOf(texture) + 1

fun removeTexture(texture: Texture): Boolean = textures.remove(texture)

fun containsTexture(texture: Texture) = textures.contains(texture)
Expand Down Expand Up @@ -133,4 +142,32 @@ open class RenderBatch(

return elementsBuffer
}

fun pushFloat(value: Float) {
verticesDataBuffer[verticesDataBufferIndexPointer++] = value
}

fun pushVector2f(vector: Vector2f) {
vector.toList().forEach { pushFloat(it) }
}

fun pushVector3f(vector: Vector3f) {
vector.toList().forEach { pushFloat(it) }
}

fun pushVector4f(vector: Vector4f) {
vector.toList().forEach { pushFloat(it) }
}

fun pushInt(value: Int) {
val byteArray = ByteBuffer.allocate(Int.SIZE_BYTES).putInt(value).array()
val buffer = ByteBuffer.wrap(byteArray)
val floatValue = buffer.float

pushFloat(floatValue)
}

companion object {
private const val MaxTexturesNumber = 8
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@ import org.lwjgl.opengl.GL11.GL_UNSIGNED_INT
import org.lwjgl.opengl.GL11.glDrawElements
import solve.rendering.engine.Window
import solve.rendering.engine.rendering.batch.RenderBatch
import solve.rendering.engine.shader.ShaderProgram
import solve.rendering.engine.rendering.texture.Texture
import solve.rendering.engine.scene.GameObject
import solve.rendering.engine.scene.Scene
import solve.rendering.engine.shader.ShaderProgram


abstract class Renderer(protected val window: Window) {
protected abstract val maxBatchSize: Int

protected var needToRebuffer = true
private lateinit var shaderProgram: ShaderProgram
private val batches = mutableListOf<RenderBatch>()
Expand Down Expand Up @@ -39,6 +42,24 @@ abstract class Renderer(protected val window: Window) {
batches.forEach { it.deleteBuffers() }
}

protected fun getAvailableBatch(texture: Texture, requiredZIndex: Int): RenderBatch {
batches.forEach { batch ->
if (!batch.isFull && !batch.isTexturesFull && batch.zIndex == requiredZIndex) {
batch.addTexture(texture)
return batch
}

if (batch.isTexturesFull && batch.containsTexture(texture) && batch.zIndex == requiredZIndex)
return batch
}

val batch = createNewBatch(requiredZIndex)
batch.addTexture(texture)
batches.add(batch)

return batch
}

protected open fun beforeRender() { }

protected abstract fun createShaderProgram(): ShaderProgram
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package solve.rendering.engine.rendering.renderers

import org.joml.Matrix4f
import org.joml.Vector2f
import solve.constants.ShadersDefaultFragmentPath
import solve.constants.ShadersDefaultVertexPath
import solve.rendering.engine.Window
Expand All @@ -12,7 +13,11 @@ import solve.rendering.engine.shader.ShaderProgram
import solve.rendering.engine.shader.ShaderType
import solve.rendering.engine.scene.GameObject

class SpriteRenderer(window: Window) : Renderer(window) {
class SpriteRenderer(
window: Window
) : Renderer(window) {
override val maxBatchSize = 1000

private var modelsCommonMatrix: Matrix4f = Matrix4f().identity()
private val spriteRenderers = mutableListOf<SpriteRenderer>()

Expand All @@ -38,7 +43,7 @@ class SpriteRenderer(window: Window) : Renderer(window) {
)

return RenderBatch(
MaxBatchSize,
maxBatchSize,
zIndex,
PrimitiveType.Quad,
shaderAttributesTypes
Expand All @@ -51,7 +56,27 @@ class SpriteRenderer(window: Window) : Renderer(window) {
}

override fun updateBatchesData() {

spriteRenderers.forEach { spriteRenderer ->
val sprite = spriteRenderer.sprite ?: return@forEach

val texture = sprite.texture
val batch = getAvailableBatch(texture, spriteRenderer.gameObject.transform.zIndex)
val textureID = batch.getTextureLocalID(texture)
val scale = spriteRenderer.gameObject.transform.scale
val position = spriteRenderer.gameObject.transform.position
val color = spriteRenderer.color
val uvCoordinates = sprite.uvCoordinates

spriteLocalVerticesPositions.forEachIndexed { index, vertexPosition ->
val scaledX = vertexPosition.x * scale.x
val scaleY = vertexPosition.y * scale.y

batch.pushVector2f(position)
batch.pushVector4f(color.toVector4f())
batch.pushVector2f(uvCoordinates[index])
batch.pushInt(textureID)
}
}
}

override fun addGameObject(gameObject: GameObject) {
Expand All @@ -70,9 +95,14 @@ class SpriteRenderer(window: Window) : Renderer(window) {
}

companion object {
private const val MaxBatchSize = 1000

private const val projectionUniformName = "uProjection"
private const val modelUniformName = "uModel"

private val spriteLocalVerticesPositions = listOf(
Vector2f(1f, 1f),
Vector2f(1f, 0f),
Vector2f(0f, 0f),
Vector2f(0f, 1f)
)
}
}
2 changes: 1 addition & 1 deletion src/main/kotlin/solve/rendering/engine/scene/GameObject.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import solve.rendering.engine.components.Component
import kotlin.reflect.KClass

class GameObject(private val name: String) {
private val transform = Transform()
val transform = Transform()
private val _components = mutableListOf<Component>()
val components: List<Component>
get() = _components
Expand Down
8 changes: 4 additions & 4 deletions src/main/kotlin/solve/rendering/engine/scene/Transform.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package solve.rendering.engine.scene
import org.joml.Vector2f

data class Transform(
private val position: Vector2f = Vector2f(),
private val rotation: Float = 0f,
private val scale: Vector2f = Vector2f(),
private val zIndex: Float = 0f
val position: Vector2f = Vector2f(),
val rotation: Float = 0f,
val scale: Vector2f = Vector2f(),
val zIndex: Int = 0
)
11 changes: 11 additions & 0 deletions src/main/kotlin/solve/rendering/engine/utils/StructuresUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package solve.rendering.engine.utils

import org.joml.Vector2f
import org.joml.Vector3f
import org.joml.Vector4f

fun Vector2f.toList() = listOf(x, y)

fun Vector3f.toList() = listOf(x, y, z)

fun Vector4f.toList() = listOf(x, y, z, w)

0 comments on commit 4f4ca70

Please sign in to comment.