2012-04-14 1 views
3

Я работаю над личным проектом Java OpenGL (JOGL), и я использую некоторые пользовательские объекты с отдельными функциями рисования и вершинами.Должен ли я использовать несколько glDrawArrays() или собрать все вершины в один большой вызов glDrawArrays?

public class Cube extends PhysicalObject { 

public void draw(GL gl) { 

     gl.glColor3f(1.0f, 1.0f, 0.0f); 

     gl.glEnableClientState(GL.GL_VERTEX_ARRAY); // Enable Vertex Arrays 

      gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY); 

      gl.glVertexPointer(3, GL.GL_FLOAT, 0, vertices); 

      gl.glTexCoordPointer(2, GL.GL_FLOAT, 0, texCoords); 

      gl.glDrawArrays(GL.GL_QUADS, 0, 4*6); 


      gl.glDisableClientState(GL.GL_VERTEX_ARRAY); 

      gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY); 

} 

Затем я прохожу через целую кучу этих кубов, называя их функции рисования. Мой вопрос: Должен ли я собрать все вершины в один большой вызов glDrawArrays, т. Е. Собрать все вершины в один большой массив и нарисовать это? Много ли это для производительности и fps?

ответ

6

Общее правило заключается в минимизации числа OpenGL вызовов, особенно в таких языках, как Java или C#, где есть накладные расходы на взаимодействие с машинным кодом. Однако вы не должны группировать разные объекты, если какое-либо из их свойств будет когда-либо изменяться (применяя другую матрицу модели, имеющую другой цвет и т. Д.), Потому что невозможно применить две отдельные матричные модели к различным частям одного и того же чертежа вызов. Таким образом, в принципе, если все ваши кубы никогда не будут меняться, лучше объединить их все вместе, иначе сохранить их отдельно.

Еще одна вещь, которая будет полезна при работе, - это минимизировать количество изменений состояния. Если вы рисуете 10 000 кубов, переместите glEnableClientState и glDisableClientState вызовы из метода куба draw и вызовите их только до/после того, как все кубы будут нарисованы. Если они все используют одну и ту же текстуру, свяжите текстуру один раз в начале и отвяжите ее один раз в конце.

О, и если вы действительно беспокоитесь о производительности, большинство компьютеров (даже двухлетних нетбуков) поддерживают OpenGL 1.5, поэтому перемещение ваших данных на VBOs даст вам значительное преимущество в производительности. И если вы делаете что-то вроде Minecraft, то лучшим методом оптимизации является просмотр всех ваших кубов и только рисование поверхностей.

1

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

Из моего прошлого опыта, одна вещь, которая может сделать увеличение производительности было бы использовать List (более высокая производительность памяти).

Это хороший Opengl bottleneck Pdf

+0

Я не уверен, что вы имеете в виду под «списком». ArrayList или VertexBufferObject, или я пропущу здесь пункт? – JulenissensHjelper

+1

Мои приличия, если это было непонятно ... Их называют «CallList» или «DisplayList». http://www.swiftless.com/tutorials/opengl/displaylists.html – Erwald

+0

Хорошо, спасибо. Я посмотрю на это. – JulenissensHjelper

Смежные вопросы