【问题标题】:drawing multiple objects in OpenGL在OpenGL中绘制多个对象
【发布时间】:2013-01-20 20:46:50
【问题描述】:

我开始学习 OpenGL。我可以加载一个 .obj 模型并用 elementBuffer 绘制它。但我坚持一次尝试两种不同的模型。我要绘制的模型在实体类中。 我能找到的大多数关于这个的教程只显示了如何加载和绘制一个单一的模型。没有人解释(至少在某种程度上我可以找到/理解)如何处理多个模型。

这是我所有的代码:

public static void main(String[] args) throws LWJGLException, IOException
{
    PixelFormat pixelFormat = new PixelFormat();
    ContextAttribs contextAtrributes = new ContextAttribs(3, 2);
    contextAtrributes.withForwardCompatible(true);
    contextAtrributes.withProfileCore(true);

    Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
    Display.setTitle("Textured quad!");
    Display.create(pixelFormat, contextAtrributes);

    Mouse.create();
    Mouse.setGrabbed(true);
    Keyboard.create();

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    entity = new Entity("planeTex.obj");
    entity2 = new Entity("modelTex2.obj");

    Shaders.load();
    Textures.load();
    Camera.create(new Vector3f(0, 1, -0.75f), new Vector3f(-50, 0, 20), HEIGHT, WIDTH);

    while (!Display.isCloseRequested())
    {

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        entity.draw();
        entity2.draw();

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

}

public class Entity
{
    private int vao, vbo, ebo;
    private int elementSize;

    public Entity(String name)
    {
        vao = glGenVertexArrays();
        glBindVertexArray(vao);
        vbo = glGenBuffers();
        *Load vertex data into buffer*
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
        ebo = glGenBuffers();
        *load data into elementBuffer*
        *Set elementSize to the element count*
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, elementBuffer, GL_STATIC_DRAW);
    }

    public void draw()
    {
        glBindVertexArray(vao);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);

        glDrawElements(GL_TRIANGLES, elementSize, GL_UNSIGNED_INT, 0);
    }
}

public class Shaders
{

public static int vertexShader, fragmentShader;
public static int shaderProgram;
public static int uniTrans;

    public static void load()
    {
        vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, loadFile("vertex.shader"));
        glCompileShader(vertexShader);

        fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, loadFile("fragment.shader"));
        glCompileShader(fragmentShader);


        shaderProgram = glCreateProgram();
        glAttachShader(shaderProgram, vertexShader);
        glAttachShader(shaderProgram, fragmentShader);
        glBindFragDataLocation(shaderProgram, 0, "outColor");
        glLinkProgram(shaderProgram);
        glUseProgram(shaderProgram);


        // Specify the layout of the vertex data
        int posAttrib = glGetAttribLocation(shaderProgram, "position");
        glEnableVertexAttribArray(posAttrib);
        glVertexAttribPointer(posAttrib, 3, GL_FLOAT, false, (Float.SIZE / 8) * 8, 0);

        int colAttrib = glGetAttribLocation(shaderProgram, "color");
        glEnableVertexAttribArray(colAttrib);
        glVertexAttribPointer(colAttrib, 3, GL_FLOAT, false, (Float.SIZE / 8) * 8, (Float.SIZE / 8) * 3);

        int texAttrib = glGetAttribLocation(shaderProgram, "texcoord");
        glEnableVertexAttribArray(texAttrib);
        glVertexAttribPointer(texAttrib, 2, GL_FLOAT, false, (Float.SIZE / 8) * 8, (Float.SIZE / 8) * 6);

        uniTrans = glGetUniformLocation(Shaders.shaderProgram, "model");
    }
}

结果是只会绘制最后创建的Entity对象。无论抽奖顺序如何。

【问题讨论】:

  • "vao、vbo 和 ebo 都是全局整数" - 你的意思是 static 变量?那么这就是问题所在。
  • @kerim,它们不是静态的。我更新了问题以准确显示课程的外观。
  • 另一个注意事项 - 您无需在 draw 中的 glBindVertexArray 之后调用 glBindBuffer。您已经将这些缓冲区与构造函数中的 VAO 相关联。
  • 实际上我可能是错的,因为只有当您使用glVertexAttribPointer 时我才确定这一点。我不知道没有顶点属性的 VAO 是如何工作的......
  • 其余代码在哪里?调用gl*PointerglEnableClientStateglEnableVertexAttribArray 形式的某些函数的部分?你的着色器呢?

标签: java opengl lwjgl


【解决方案1】:

好吧,我通过放置这个块来修复它 // 指定顶点数据的布局 int posAttrib = glGetAttribLocation(Shaders.shaderProgram, "position"); glEnableVertexAttribArray(posAttrib); glVertexAttribPointer(posAttrib, 3, GL_FLOAT, false, (Float.SIZE / 8) * 8, 0);

    int colAttrib = glGetAttribLocation(Shaders.shaderProgram, "color");
    glEnableVertexAttribArray(colAttrib);
    glVertexAttribPointer(colAttrib, 3, GL_FLOAT, false, (Float.SIZE / 8) * 8, (Float.SIZE / 8) * 3);

    int texAttrib = glGetAttribLocation(Shaders.shaderProgram, "texcoord");
    glEnableVertexAttribArray(texAttrib);
    glVertexAttribPointer(texAttrib, 2, GL_FLOAT, false, (Float.SIZE / 8) * 8, (Float.SIZE / 8) * 6);

在 glDrawElements 方法之前的实体类绘制循环中。将块放在其他任何地方都会导致程序崩溃:

“数组缓冲区对象被禁用时不能使用偏移量”

否则它根本不会画任何东西。我从 NicolBolas 那里得到了我应该把它放在 Entity 构造函数中的感觉,但正如我所说,它在任何地方都不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-04
    相关资源
    最近更新 更多