All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.ru.casperix.opengl.renderer.DeviceGeometryData.kt Maven / Gradle / Ivy

package ru.casperix.opengl.renderer

import ru.casperix.misc.Disposable
import ru.casperix.opengl.core.*
import ru.casperix.opengl.renderer.impl.VertexAttributeLayout
import ru.casperix.renderer.vector.vertex.ColorFormat
import ru.casperix.renderer.vector.vertex.VertexAttributes

class DeviceGeometryData(val attributes: VertexAttributes) :
    Disposable {
    private val vertexBufferId = glGenBuffer()
    private val indexBufferId = glGenBuffer()
    private val vaoId = glGenVertexArray()

    val vertexSize = attributes.calculateVertexSize()

    var isDisposed = false; private set

    private var useIndices = false
    var verticesAmount = 0; private set
    var indicesAmount = 0; private set

    init {
        glBindVertexArray(vaoId)
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId)

        var offset = 0
        if (attributes.hasPosition2) offset += appendAttribute(VertexAttributeLayout.POSITION2, offset)
        if (attributes.hasTextureCoord) offset += appendAttribute(VertexAttributeLayout.TEXTURE_COORD, offset)
        if (attributes.hasTangent) offset += appendAttribute(VertexAttributeLayout.TANGENT, offset)
        if (attributes.hasPosition3) offset += appendAttribute(VertexAttributeLayout.POSITION3, offset)
        if (attributes.color == ColorFormat.BGR || attributes.color == ColorFormat.RGB) offset += appendAttribute(VertexAttributeLayout.COLOR3, offset)
        if (attributes.color == ColorFormat.BGRA || attributes.color == ColorFormat.RGBA) offset += appendAttribute(VertexAttributeLayout.COLOR4, offset)
    }

    private fun appendAttribute(vertexAttribute: VertexAttributeLayout, offset: Int): Int {
        val size = vertexAttribute.size
        val layoutIndex = vertexAttribute.layout

        glEnableVertexAttribArray(layoutIndex)
        glVertexAttribPointer(layoutIndex, size, GL_FLOAT, false, vertexSize * 4, offset * 4)

        return size
    }

    override fun dispose() {
        glDeleteVertexArrays(intArrayOf(vaoId))
        glDeleteBuffers(intArrayOf(vertexBufferId, indexBufferId))
        isDisposed = true
    }

    fun bind() {
        glBindVertexArray(vaoId)
        glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId)
        if (useIndices) {
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId)
        }
    }

    fun reset() {
        verticesAmount = 0
        indicesAmount = 0
    }

    fun uploadData(stateController: StateController, vertices: FloatArray, indices: UIntArray?, isStatic: Boolean) {
        useIndices = indices != null
        stateController.setGeometry(this)

        val glUsageFlag = if (isStatic) {
            GL_STATIC_DRAW
        } else {
            GL_DYNAMIC_DRAW
        }

        glBufferData(GL_ARRAY_BUFFER, vertices, glUsageFlag)

        if (indices != null) {
            glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.asIntArray(), glUsageFlag)
            indicesAmount = indices.size
        } else {
            indicesAmount = 0
        }
        verticesAmount = vertices.size / vertexSize
    }

    fun draw() {
        if (useIndices && indicesAmount > 0) {
            glDrawElements(GL_TRIANGLES, indicesAmount, GL_UNSIGNED_INT, 0)
        } else if (verticesAmount > 0){
            glDrawArrays(GL_TRIANGLES, 0, verticesAmount)
        }
    }

    companion object {
        fun unbind() {
            glBindVertexArray(0)
            glBindBuffer(GL_ARRAY_BUFFER, 0)
            glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
        }
    }
}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy