рисование нескольких объектов в OpenGL

Я начал изучать OpenGL. Я могу загрузить модель .obj и нарисовать ее с помощью elementBuffer. Но я застрял, пытаясь использовать две разные модели одновременно. Модель, которую я хочу нарисовать, находится в классе Entity. Большинство руководств, которые я могу найти, показывают только то, как загружать и рисовать одну модель. Никто не объясняет (по крайней мере, я могу найти/понять), как обращаться с несколькими моделями.

Вот весь мой код:

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. Независимо от порядка розыгрыша.


person René Jensen    schedule 20.01.2013    source источник
comment
vao, vbo и ebo — глобальные целые числа — вы имеете в виду переменные static? Тогда это проблема.   -  person kerim    schedule 21.01.2013
comment
@kerim, они не статичны. Я обновил вопрос, чтобы точно показать, как выглядит класс.   -  person René Jensen    schedule 21.01.2013
comment
Еще одно замечание: вам не нужно вызывать glBindBuffer после glBindVertexArray в draw. Вы уже связали эти буферы с VAO в конструкторе.   -  person kerim    schedule 21.01.2013
comment
На самом деле я могу ошибаться, так как уверен в этом только при использовании glVertexAttribPointer. Я не знаю, как VAO работает без вершинных атрибутов...   -  person kerim    schedule 21.01.2013
comment
Где остальная часть кода? Часть, которая вызывает какую-то функцию вида gl*Pointer и glEnableClientState или glEnableVertexAttribArray? А как насчет ваших шейдеров?   -  person Nicol Bolas    schedule 21.01.2013
comment
@NicolBolas Я добавил остальную часть кода, который использую. Тем не менее, класс текстур и сами шейдеры не опубликованы, так как рисование одной модели — это хорошо, поэтому я сомневаюсь, почему? Я надеюсь, что то, что я опубликовал, достаточно хорошо, чтобы продолжить.   -  person René Jensen    schedule 21.01.2013
comment
@RenéJensen: Укажите расположение данных вершин Нет; это не так работает. Я бы дал подробный ответ, но у меня уже есть хорошая статья OpenGL Wiki, которая все объясняет в мельчайших подробностях. Короче говоря, все это входит в настройку VAO в вашей организации; это не часть объекта шейдера.   -  person Nicol Bolas    schedule 21.01.2013


Ответы (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. Размещение фрагмента в любом другом месте приведет к сбою программы:

«Невозможно использовать смещения, когда объект буфера массива отключен»

В противном случае он бы просто вообще ничего не рисовал. У меня было ощущение от НиколБоласа, что я должен поместить это в конструктор Entity, но, как я уже сказал, это нигде не сработало.

person René Jensen    schedule 21.01.2013