2013-11-16 2 views
1

Я пытаюсь создать проект OpenGL с Qt (v5.1.1) на OS X 10.9 в соответствии с современной реализацией трубопровода. Предполагается, что программа представляет собой систему с несколькими агентами или систему частиц. Однако мне не хватает понимания того, как сделать что-то из другого класса.Рисунок с OpenGL в OOP

В шламе была некоторая простая команда drawThisAndThat(), которую вы могли бы назвать. Я прочитал 6-е издание «OpenGL Superbible». Из этого и нескольких руководств все примеры, похоже, охватывают только программы, в которых все модификации сделаны из класса, который инициализирует OpenGL.

Я хотел бы создать несколько объектов, перемещающихся по сетке, и нарисовать пиксель, чтобы отобразить их положение. Я знаю, что мне нужно позвонить void glVertexAttrib4fv(GLuint index, const GLfloat * vi);, но этого недостаточно.

  • Мне нужно позвонить glEnableVertexAttribArray(1); и glDrawArrays(GL_POINTS, 0, 3);, а также и то, что еще делать?
  • Я прав, чтобы создать экземпляр класса, контролирующего частицы, после создания OpenGL и bevor основного цикла?
  • Как я могу управлять тем, что частица рисует себя, стирая позицию, которую он рисовал бектором?

Программа основана на этом code.

ответ

1

Чтобы полностью ответить на ваши вопросы, мне пришлось бы написать стену с текстом, я попытаюсь указать только на наиболее важные аспекты. Надеюсь, это поможет вам справиться с вашими знаниями и, возможно, продолжить чтение, чтобы заставить его работать.

все модификации сделаны из класса, который инициализирует OpenGL

Вы можете инкапсулировать update(time) и draw() методы для объектов, которые вы затем вызвать в главном цикле.

Нужно ли мне звонить glEnableVertexAttribArray(1); и glDrawArrays(GL_POINTS, 0, 3);, а также что еще?

Я бы поместил все частицы в один массив вершин, чтобы избежать повторного связывания различных массивов вершин после каждой частицы. Затем вам нужно будет использовать glBindVertexArray(vaid); и glDrawArrays(GL_POINTS, 0, vertexCount); в призыве draw(). Будьте осторожны с vertexCount, это не число поплавков (как следует из вашего вопроса), а количество вершин, которое должно быть 1 в вашем примере или количество частиц в моем предлагаемом подходе (если я правильно понял, что 3 означает «x, y и z моей вершины»).

И так как у вас есть только частицы glDrawElements(...);, вероятно, уже соответствует вашим потребностям.

Я прав, чтобы создать экземпляр класса, контролирующего частицы, после создания OpenGL и bevor основного цикла?

Возможно, ваш заказ на создание экземпляра выглядит правильно. Вы обязательно должны делать все экземпляры, прежде чем вызывать основной цикл в вашем случае.

Как я могу управлять тем, что частица рисует себя, стирая положение, которое он рисовал бевором?

Если вы правильно поняли свой последний вопрос: просто изменив элементы в ваших буферных объектах (glBufferData(...);). Так как вы очистите экран и замените буферы после каждого цикла, это заставит их двигаться. Просто обновите свою позицию вызовом update(time), например. pos = pos + dir * time;, поместите новые позиции в буфер и нажмите этот буфер с glBufferData(...) в массив вершин. Не забудьте привязать массив вершин до нажатия буфера.


Некоторые дополнительные вещи, которые я хотел бы указать.

glEnableVertexAttribArray(1); - включить атрибут вершины в вашей шейдерной программе, чтобы передавать данные этому атрибуту. Вы должны создать шейдер программу

id = glCreateProgram() 
    // ... create and attach shaders here 
    // then bind attribute locations, e.g. positionMC 
    glBindAttribLocation(id, 0, "positionMC"); 
    glLinkProgram(id); 

И после инициализации массива вершин с glGenVertexArrays(); вы должны включить все атрибуты вашего массив вершин нуждается в вашей шейдерной программе. В этом примере positionMC бы на месте 0, так что вы могли бы назвать что-то вроде

glUseProgram(pid); 
    glBindVertexArray(vaid); 
    glEnableVertexAttribArray(1); 
    glVertexAttribPointer(...); 

Это только предстоит сделать один раз, поскольку OpenGL хранит состояние для каждого конкретного массива вершин. Перевернув массив вершин, вы восстановите это состояние.

В главном цикле все, что вам нужно сделать сейчас звонит обновление и сделать методы, например .:

handleInputs(); 
    update(deltaTime); 
    glClear(...); 
    draw(); 
    swapBuffers(); 
Смежные вопросы