2

我开始学习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");
    }
}

结果是只会绘制最后创建的实体对象。不管抽奖顺序。

4

1 回答 1

0

好吧,我通过放置这个块来修复它 // 指定顶点数据的布局 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 构造函数中的感觉,但正如我所说,它在任何地方都不起作用。

于 2013-01-21T09:10:34.237 回答