纹理未显示在屏幕上的问题。 OpenGL ES

Problem with texture not showing in screen. OpenGL ES

我是 opengl es 2 编程的新手,我试图在我的测试应用程序中加载 png 格式的纹理。我使用 PNGDecoder 来执行此操作,但屏幕上只显示黑色矩形和线条。怎么了?

渲染器:

@file:Suppress("NAME_SHADOWING")

package vga
import de.matthiasmann.twl.utils.PNGDecoder
import org.lwjgl.opengles.GLES20.*
import java.io.File
import org.lwjgl.BufferUtils
import org.lwjgl.opengl.GLUtil
import java.io.BufferedInputStream
import java.io.FileInputStream
import java.io.InputStream
import java.nio.Buffer
import java.nio.ByteBuffer
import kotlin.math.cos
import kotlin.math.sin


object RendererGLES {

    val vertexShader: Int
    val fragmentShader: Int
    val program: Int

    lateinit var vbosSquareIndices: IntArray
    lateinit var vbosSquareVertices: IntArray

    lateinit var vbosLine: IntArray

    val a_Position: Int

    val square: Square2D

    val textureId: Int

    val u_SamplerLocation: Int
    val a_TextCoordLocation: Int

    init
    {
        val vertexCode = File("C:\Users\cassio\Desktop\tutorial_learnopengles\seila\src\main\resources\vertex_shader.glsl").run{
            readText()
        }
        val fragmentCode = File("C:\Users\cassio\Desktop\tutorial_learnopengles\seila\src\main\resources\fragment_shader.glsl").run{
            readText()
        }

        vertexShader = compileShader(vertexCode, GL_VERTEX_SHADER)
        fragmentShader = compileShader(fragmentCode, GL_FRAGMENT_SHADER)

        program = createProgram(fragmentShader, vertexShader)

        a_Position = glGetAttribLocation(program, "a_Position")
        u_SamplerLocation = glGetUniformLocation(program, "u_Sampler")
        a_TextCoordLocation = glGetAttribLocation(program, "a_TextureCoord")
        glEnableVertexAttribArray(a_Position)

        square = Square2D(0.1f)
        glClearColor(0.8f, 0.8f, 0.8f, 1f)

        createVBOS()
        textureId = loadTexture("C:\Users\cassio\Desktop\tutorial_learnopengles\seila\src\main\resources\sla.png")

    }

    fun compileShader(code: String, type: Int): Int
    {
        val shader = glCreateShader(type)

        glShaderSource(shader, code)
        glCompileShader(shader)

        println(glGetShaderInfoLog(shader))

        return shader

    }

    fun createProgram(frag: Int, vert: Int): Int
    {
        val prog = glCreateProgram()

        glAttachShader(prog, vert)
        glAttachShader(prog, frag)

        glLinkProgram(prog)

        println(glGetProgramInfoLog(program))

        return prog
    }

    fun createVBOS()
    {

        vbosSquareVertices = IntArray(1)
        vbosSquareIndices = IntArray(1)
        vbosLine = IntArray(1)

        glGenBuffers(vbosSquareVertices)
        glBindBuffer(GL_ARRAY_BUFFER, vbosSquareVertices[0])
        glBufferData(GL_ARRAY_BUFFER, square.vertexArray, GL_STATIC_DRAW)

        glGenBuffers(vbosSquareIndices)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbosSquareIndices[0])
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, square.vertexIndices, GL_STATIC_DRAW)

        glGenBuffers(vbosLine)
        glBindBuffer(GL_ARRAY_BUFFER, vbosLine[0])
        glBufferData(GL_ARRAY_BUFFER, square.line, GL_STATIC_DRAW)

    }

    fun loadTexture(fileName: String): Int {

        // Load PNG file
        val decoder = PNGDecoder(
            BufferedInputStream(FileInputStream(fileName))
        )

        // Create a big buffer to store the png data
        val buffer = ByteBuffer.allocateDirect( 4 * decoder.width * decoder.height)
        decoder.decode(buffer, decoder.width * 4, PNGDecoder.Format.RGBA)
        buffer.flip()
        val id = glGenTextures()
        glBindTexture(GL_TEXTURE_2D, id)

        // Say to opengl how unpack bytes
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, decoder.width,
            decoder.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, buffer)

        return id
    }

    fun renderer()
    {
        glClear(GL_COLOR_BUFFER_BIT)
        glUseProgram(program)

        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, textureId)

        glUniform1i(u_SamplerLocation, 0)
        square.bufferTexture.position(0)
        glBindBuffer(GL_ARRAY_BUFFER, 0)
        glVertexAttribPointer(a_TextCoordLocation, 2, GL_FLOAT, false,
                0, square.bufferTexture)

        glEnableVertexAttribArray(a_TextCoordLocation)

        glBindBuffer(GL_ARRAY_BUFFER, vbosSquareVertices[0])
        glVertexAttribPointer(a_Position, 2, GL_FLOAT, false, 0, 0)

        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbosSquareIndices[0])
        nglDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0)
    }    
}

片段着色器:

precision mediump float;

varying vec2 v_TextureCoord;
uniform sampler2D u_Sampler;

void main(){
    gl_FragColor = texture2D(u_Sampler, v_TextureCoord);
}

顶点着色器:

attribute vec4 a_Position;
attribute vec2 a_TextureCoord;

uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;

varying vec2 v_TextureCoord;

void main() {
    v_TextureCoord = a_TextureCoord;

    gl_Position = a_Position;
    gl_PointSize = 1.0;

}

Square2D(用于存储顶点位置):

package vga

import java.nio.*
import org.lwjgl.opengles.GLES20.*

class Square2D(val size: Float) {
    val vertexArray: FloatArray
    val vertexIndices: ShortArray
    val line: FloatArray

    val textureCoordinate: FloatArray
    val bufferTexture: FloatBuffer
    init {
        line = floatArrayOf(
                -0.5f, -0.5f,
                0.5f, 0.5f
        )

        vertexArray = floatArrayOf(
                 -1f,  1f,
                 -1f, -1f,
                  1f, -1f,
                  1f,  1f,

        )

        for (i in vertexArray.indices) {
            vertexArray[i] *= size

        }

        vertexIndices = shortArrayOf(
                0, 1, 2, 2, 3, 0
        )

        textureCoordinate = floatArrayOf(
                1f,0f,
                0f,0f,
                1f,1f,
                0f,1f
        )

        for (i in textureCoordinate.indices) {
            textureCoordinate[i] *= size

        }
        bufferTexture = ByteBuffer.allocateDirect(textureCoordinate.size * 4)
                .order(ByteOrder.nativeOrder())
                .asFloatBuffer()
        bufferTexture.put(textureCoordinate)
        bufferTexture.flip()
    }


}

glVertexAttribPointer 有两种使用方式。如果绑定了命名缓冲区对象,则最后一个参数将被视为缓冲区对象数据存储中的字节偏移量。如果没有绑定缓冲区 (0),则最后一个参数是指向数组数据的指针。
因此,在指定纹理坐标属性之前,您必须不将缓冲区 (0) 绑定到 GL_ARRAY_BUFFER 目标:

glBindBuffer(GL_ARRAY_BUFFER, 0)
glVertexAttribPointer(
    a_TextCoordLocation, 2, GL_FLOAT, false, 0, square.bufferTexture)