我一直试图将我的游戏原型渲染器从其即时模式测试实现转换为实际的VAO / VBO实现。 VBO在屏幕上呈现,但拒绝纹理。下面是显示问题的最简单的测试类:
public static void main(String[] args) throws Exception {
// VertX,VertY TexX, TexY
float[] data = new float[] {0.0f, 0.0f, 0.25f, 0.75f,
0.0f, 64.0f, 0.25f, 1.0f,
64.0f, 64.0f, 0.5f, 1.0f,
0.0f, 0.0f, 0.25f, 0.75f,
64.0f, 64.0f, 0.5f, 1.0f,
64.0f, 0.0f, 0.5f, 0.75f};
glfwSetErrorCallback(GLFWErrorCallback.createPrint(System.err));
if (!glfwInit())
throw new IllegalStateException("Unable to initialize GLFW");
long window = GLFW.glfwCreateWindow(1600, 900, "TEST", 0, 0);
GLFW.glfwMakeContextCurrent(window);
GL.createCapabilities();
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1600, 900, 0, 0.000001, 100);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
int vboId = glGenBuffers();
int vaoId = glGenVertexArrays();
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindVertexArray(vaoId);
glBindBuffer(GL_ARRAY_BUFFER, vboId);
glBufferData(GL_ARRAY_BUFFER, data, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, false, 4*Float.BYTES, 0);
glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 4*Float.BYTES);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glTranslatef(50, 50, 0);
Texture t = new Texture(TEST.class.getClassLoader().getResourceAsStream("test/WallFloor.png"));
while (!GLFW.glfwWindowShouldClose(window)) {
GLFW.glfwPollEvents();
GLFW.glfwSwapBuffers(window);
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
glClientActiveTexture(GL_TEXTURE0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindVertexArray(vaoId);
glEnableVertexAttribArray(0);
t.bind();
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(0);
glBindVertexArray(0);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
/* Equivelent immediate mode code - that works
t.bind();
glBegin(GL_TRIANGLES);
glTexCoord2f(0.25f, 0.75f);
glVertex2f(0, 0);
glTexCoord2f(0.25f, 1f);
glVertex2f(0, 64);
glTexCoord2f(0.5f, 0.75f);
glVertex2f(64, 0);
glTexCoord2f(0.5f, 1f);
glVertex2f(64, 64);
glTexCoord2f(0.25f, 1f);
glVertex2f(0, 64);
glTexCoord2f(0.5f, 0.75f);
glVertex2f(64, 0);
glEnd();
*/
}
}
纹理绑定调用如下(其中wrap = GL_REPEAT和filter = GL_NEAREST):
public void bind()
{
glActiveTexture(GL_TEXTURE0);
glClientActiveTexture(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(target, id);
glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter);
glTexParameteri(target, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(target, GL_TEXTURE_WRAP_T, wrap);
}
周末用谷歌搜索它没有找到答案,我做了一件非常糟糕的事吗?我还测试了使用立即模式,它仍然使用纹理渲染。
答案 0 :(得分:4)
此外,您将核心配置文件代码(glVertexAttribPointer
)与非核心配置文件(glTexCoordPointer
)混合
但真正的问题来自于错误的步幅和偏移。 Stride定义一个顶点的数据有多大,而偏移量指定实际数据从每个顶点的起点开始的距离。在您的情况下,每个顶点由4个浮点组成,因此步幅必须为4 * Float.BYTES
。位置是每个顶点中的前两个浮点数(偏移0),而纹理坐标是第3和第4个浮点数,这意味着offset = 2 * Float.BYTES
。正确的代码可能看起来像这样(注意glVertexPointer
而不是glVertexAttribPointer
的用法):
glVertexPointer(2, GL_FLOAT, false, 4*Float.BYTES, 0);
glTexCoordPointer(2, GL_FLOAT, 4*Float.BYTES, 2*Float.BYTES);
修改强>
您的VAO的使用也是错误的。在初始化中,将glVertexPointer / glTexCoordPointer存储到VAO vaoId
。但是在渲染代码中,您将绑定VAO 0。绘图时,很可能不存在属性设置。另外,我不完全确定VAO是否与固定函数调用一起工作。在这种情况下,您可以删除所有VAO呼叫。