【问题标题】:Simple Texturing with LWJGL and VBOs does not work使用 LWJGL 和 VBO 的简单纹理不起作用
【发布时间】:2013-09-14 11:24:25
【问题描述】:

我用 VBO 编写了一个小 3D 程序,但在纹理方面失败了。加载它们很好,但它们只是不显示。因此,我为 VBO 纹理编写了一个小型纹理渲染器,并采用了本主题中的内容:VBO with texture in LWJGL。 但是仍然没有渲染任何内容。 帮我让这段代码显示一个纹理;)

import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;

import java.io.IOException;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;
import org.newdawn.slick.util.ResourceLoader;

public class VBOTextureDemo {

private static Texture texture;

public static void main(String[] args) {
    try {
        Display.setDisplayMode(new DisplayMode(500, 500));
        Display.setTitle("Texture");
        Display.create();
    } catch (LWJGLException e) {
        e.printStackTrace();
        Display.destroy();
        System.exit(1);
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(1, -1, 1, -1, 1, 1);
    glMatrixMode(GL_MODELVIEW);
    glEnable(GL_TEXTURE_2D);
    glLoadIdentity();


    try {
        texture = TextureLoader.getTexture("PNG",
                ResourceLoader.getResourceAsStream("res/images/grass.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }

    final int amountOfVertices = 6;
    final int vertexSize = 3;
    final int texSize = 2;

    FloatBuffer vertexData = BufferUtils.createFloatBuffer(amountOfVertices
            * vertexSize);
    vertexData.put(new float[] { -10f, 10f, 0f, }); // Vertex
    vertexData.put(new float[] { 10f, 10f, 0f, }); // Vertex
    vertexData.put(new float[] { -10f, -10f, 0f, }); // Vertex

    vertexData.put(new float[] { 10f, -10f, 0f, }); // Vertex
    vertexData.put(new float[] { -10f, -10f, 0f, }); // Vertex
    vertexData.put(new float[] { 10f, 10f, 0f, }); // Vertex;
    vertexData.flip();

    FloatBuffer textureData = BufferUtils
            .createFloatBuffer(amountOfVertices * texSize);
    textureData.put(new float[] { 0f, 1f, }); // Texture Coordinate
    textureData.put(new float[] { 1f, 1f, }); // Texture Coordinate
    textureData.put(new float[] { 0f, 0f, }); // Texture Coordinate

    textureData.put(new float[] { 1f, 0f, }); // Texture Coordinate
    textureData.put(new float[] { 0f, 0f, }); // Texture Coordinate
    textureData.put(new float[] { 1f, 1f, }); // Texture Coordinate
    textureData.flip();

    glBindTexture(GL_TEXTURE_2D, texture.getTextureID());

    texture.bind();

    int vboVertexHandle = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
    glBufferData(GL_ARRAY_BUFFER, vertexData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);


    int vboTexCoordHandle = texture.getTextureID();
    glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
    glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glClearColor(0.5f, 0.1f, 0f, 1f);



    while (!Display.isCloseRequested()) {
        glClear(GL_COLOR_BUFFER_BIT);

        glBindBuffer(GL_ARRAY_BUFFER, vboVertexHandle);
        glVertexPointer(vertexSize, GL_FLOAT, 0, 0L);

        glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
        glTexCoordPointer(2, GL_FLOAT, 0, 0);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
        glDrawArrays(GL_TRIANGLES, 0, amountOfVertices);
        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);

        Display.update();
        Display.sync(60);
    }

    glDeleteBuffers(vboVertexHandle);
    glDeleteBuffers(vboTexCoordHandle);
    texture.release();


    Display.destroy();
    System.exit(0);
}

}

【问题讨论】:

  • 我在您的代码中没有看到任何绑定纹理的调用。由于这似乎是固定功能管道,因此您还需要为绑定的纹理单元启用GL_TEXTURE_2D
  • 谢谢,我通常在里面放这些东西....不知道它去了哪里;)#修复了它,但它仍然不起作用):

标签: java opengl textures lwjgl vbo


【解决方案1】:

我没有测试你的代码,但我猜有两件事可能是错误的!

  1. 顶点顺序错误!
  2. 纹理没有被加载,因此在调用绑定时,没有任何东西被绑定!

简单的纹理测试

仅用于测试尝试使用已弃用的方法

  • glBegin(GL_TRIANGLES);
  • glVertex3f(x, y, z);
  • glTexCoord2f(u, v);

当然记得绑定纹理,但是如果使用不推荐使用的方法渲染三角形有效,那么它肯定不是纹理问题。虽然如果什么都没有出现,它可能是一个纹理程序(或者顶点的顺序错误)。

简单的纹理测试渲染 |代码

texture.bind();

glBegin(GL_TRIANGLES);

    glTexCoord2f(0f, 1f);
    glVertex3f(-1f, 1f, 0f);
    glTexCoord2f(1f, 1f);
    glVertex3f(1f, 1f, 0f);
    glTexCoord2f(0f, 0f);
    glVertex3f(-1f, -1f, 0f);

    glTexCoord2f(1f, 0f);
    glVertex3f(1f, -1f, 0f);
    glTexCoord2f(0f, 0f);
    glVertex3f(-1f, -1f, 0f);
    glTexCoord2f(1f, 1f);
    glVertex3f(1f, 1f, 0f);

glEnd();

texture.unbind();

VBO 测试

因此,如果它没有显示的原因是因为顶点的顺序错误,那么请尝试使用以下代码来创建和渲染纹理 VBO。

创建 VBO |代码

int vertices = 6;

int vertex_size = 3; // X, Y, Z,
int texture_size = 2; // U, V,

FloatBuffer vertex_data = BufferUtils.createFloatBuffer(vertices * vertex_size);
vertex_data.put(new float[] { -1f, 1f, 0f, }); // Vertex
vertex_data.put(new float[] { 1f, 1f, 0f, }); // Vertex
vertex_data.put(new float[] { -1f, -1f, 0f, }); // Vertex

vertex_data.put(new float[] { 1f, -1f, 0f, }); // Vertex
vertex_data.put(new float[] { -1f, -1f, 0f, }); // Vertex
vertex_data.put(new float[] { 1f, 1f, 0f, }); // Vertex

FloatBuffer texture_data = BufferUtils.createFloatBuffer(vertices * texture_size);
texture_data.put(new float[] { 0f, 1f, }); // Texture Coordinate
texture_data.put(new float[] { 1f, 1f, }); // Texture Coordinate
texture_data.put(new float[] { 0f, 0f, }); // Texture Coordinate

texture_data.put(new float[] { 1f, 0f, }); // Texture Coordinate
texture_data.put(new float[] { 0f, 0f, }); // Texture Coordinate
texture_data.put(new float[] { 1f, 1f, }); // Texture Coordinate

vertex_data.flip();
texture_data.flip();

int vbo_vertex_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glBufferData(GL_ARRAY_BUFFER, vertex_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

int vbo_texture_handle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vbo_texture_handle);
glBufferData(GL_ARRAY_BUFFER, texture_data, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

渲染 VBO |代码

还可以尝试实际绑定和取消绑定纹理!这实际上也可能以某种奇怪的方式成为问题。

texture.bind();

glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
glVertexPointer(vertex_size, GL_FLOAT, 0, 0l);

glBindBuffer(GL_ARRAY_BUFFER, vbo_texture_handle);
glTexCoordPointer(texture_size, GL_FLOAT, 0, 0l);

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glDrawArrays(GL_TRIANGLES, 0, vertices); // The vertices is of course the max vertices count, in this case 6

glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);

glBindBuffer(GL_ARRAY_BUFFER, 0);

texture.unbind();

当然,在处理纹理时,记得致电glEnable(GL_TEXTURE_2D);

编辑

我发现代码中的错误,你居然说。

int vboTexCoordHandle = texture.getTextureID();
glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

但你需要说。

int vboTexCoordHandle = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vboTexCoordHandle);
glBufferData(GL_ARRAY_BUFFER, textureData, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);

【讨论】:

  • 谢谢,我做了所有这些,但无论如何它都不起作用,wtf?
  • 你确定实际的纹理被加载了吗?
  • 我从不完全确定,但我认为,它被加载了。我在示例中添加了导入,以便您可以按原样运行它.....
  • 我无法按原样运行它,因为您使用像 slick 这样的库,而我没有!我已经创建了自己的Texture 类等。但是请尝试检查纹理的句柄/id 值,如果该值类似于 0 或 -1,那么纹理肯定不会被加载!
  • @TimVisée 是的,您只需添加另一个缓冲区,但我不建议这样做,因为必须为每个元素创建一个缓冲区会很烦人。拥有一个缓冲区要容易得多,然后存储 x、y、z、r、g、b、nx、ny、nz(然后是下一个顶点)。这不是我在答案中描述的。但是请查看this,以获取示例。
猜你喜欢
  • 1970-01-01
  • 2014-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多