英文:
Problem with texture not showing in screen. OpenGL ES
问题
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")
}
// Other methods...
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)
}
}
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,
)
// Other initialization...
bufferTexture = ByteBuffer.allocateDirect(textureCoordinate.size * 4)
.order(ByteOrder.nativeOrder())
.asFloatBuffer()
bufferTexture.put(textureCoordinate)
bufferTexture.flip()
}
}
// Fragment Shader
precision mediump float;
varying vec2 v_TextureCoord;
uniform sampler2D u_Sampler;
void main() {
gl_FragColor = texture2D(u_Sampler, v_TextureCoord);
}
// Vertex Shader
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;
}
英文:
I am newbie in opengl es 2 programming, I was trying to load a texture in png format in my test application. I used PNGDecoder to do this, but just the black rectangle and the line are show in the screen. What is wrong?
Renderer:
@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)
}
}
Fragment Shader:
precision mediump float;
varying vec2 v_TextureCoord;
uniform sampler2D u_Sampler;
void main(){
gl_FragColor = texture2D(u_Sampler, v_TextureCoord);
}
Vertex Shader:
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 (is used to store vertex positions):
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()
}
}
答案1
得分: 0
glVertexAttribPointer
有两种使用方式。如果绑定了命名的缓冲对象,那么最后一个参数被视为缓冲对象数据存储中的字节偏移量。如果没有绑定缓冲(0),那么最后一个参数是指向数组数据的指针。
因此,在指定纹理坐标属性之前,您必须将缓冲目标绑定到无缓冲(0):
glBindBuffer(GL_ARRAY_BUFFER, 0);
glVertexAttribPointer(
a_TextCoordLocation, 2, GL_FLOAT, false, 0, square.bufferTexture);
英文:
glVertexAttribPointer
can be use in 2 ways. If a named buffer object is bound, then the last argument is treated as byte offset in the buffer objects data store. If no buffer is bound (0), then the last argument is a pointer to the array data.
Hence you have to bind no buffer (0), to the GL_ARRAY_BUFFER
target, before you can specify the texture coordinate attribute:
glBindBuffer(GL_ARRAY_BUFFER, 0)
glVertexAttribPointer(
a_TextCoordLocation, 2, GL_FLOAT, false, 0, square.bufferTexture)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论