纹理未显示在屏幕上的问题。 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)
我是 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)