При попытке нарисовать куб, загруженный из файла .obj, все треугольники имеют общую точку. Кроме того, не все треугольники отображаются.
Я заметил, что изменение количества вершин для glDrawElements позволяет рисовать другие треугольники, но я не уверен, почему количество точек будет больше, чем количество используемых индексов.
Я проверил, что файл (кажется) правильно загружен отладчиком как: В классе ModelObject 'vCoords' содержится:
{
1.0, 1.0, 1.0,
-1.0, -1.0, 1.0,
1.0, -1.0, 1.0,
-1.0, 1.0, 1.0,
-1.0, -1.0, -1.0,
1.0, -1.0, -1.0,
1.0, 1.0, -1.0,
-1.0, 1.0, -1.0
}
и каждая MaterialGroup имеет 6 индексов, которые смещены на -1 из файла obj. (индексы .obj начинаются с 1 вместо 0)
Индексы каждой MaterialGroup находятся в отдельной строке (также извлекаются из отладчика во время вызовов отрисовки).
{ 3, 6, 7, 3, 0, 6 } //yellow
{ 0, 5, 6, 0, 2, 5 } //blue
{ 5, 7, 6, 5, 4, 7 } //purple
{ 2, 4, 5, 2, 1, 4 } //red
{ 1, 7, 4, 1, 3, 7 } //white
{ 0, 1, 2, 0, 3, 1 } //light green
В классе ModelObject:
public void draw(float[] mvpm, GLProgram program){
int mvpmH = program.getUniformLocation("mvpm");
GLES20.glEnableVertexAttribArray(posH);
GLES20.glVertexAttribPointer(
posH,
COORDS_PER_VERTEX,
GLES20.GL_FLOAT,
false,
COORDS_PER_VERTEX*Float.BYTES,
vCoords);
GLES20.glUniformMatrix4fv(mvpmH, 1, false, mvpm,0 );
GLErrorLogger.check();
for(MaterialGroup materialGroup : groups){
materialGroup.draw(program);
}
GLES20.glDisableVertexAttribArray(posH);
GLErrorLogger.check();
}
В классе MaterialGroup:
public void draw(GLProgram program){
GLErrorLogger.check();
int colorH = program.getUniformAttribLocation("vColor");
GLErrorLogger.check();
GLES20.glUniform4fv(colorH, 1, material.diffuse, 0);
GLErrorLogger.check();
//GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, points);
GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(),
GLES20.GL_UNSIGNED_SHORT, iv);
GLErrorLogger.check();
}
iv - индексный буфер vCoords — это буфер, содержащий все вершины
Полный исходник можно найти по адресу: https://github.com/TheIncgi/GLES_GAME_fixed/blob/master/app/src/main/java/com/theincgi/gles_game_fixed/geometry/ModelLoader2.java
Текущий результат: Текущая проблема рендеринга
Цель: Как должен выглядеть куб
Редактировать 1: исправлена проблема с форматированием
Третий параметр glDrawElements
указывает тип значений в списке индексов.
Буфер (iv
) — это буфер int
, в котором каждый элемент имеет 4 байта.
IntBuffer iv, it, in;
Но константа перечислителя OpenGL GL_UNSIGNED_SHORT
указывала, что буфер — это буфер short
значений, где размер каждого значения равен 2 байтам:
GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(), GLES20.GL_UNSIGNED_SHORT, iv);
Если версия OpenGL ES поддерживает GL_UNSIGNED_INT
, то для решения проблемы достаточно заменить GL_UNSIGNED_SHORT
на GL_UNSIGNED_INT
:
GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(), GLES20.GL_UNSIGNED_INT, iv);
Если GL_UNSIGNED_INT
не поддерживается, то вместо ShortBuffer
необходимо создать IntBuffer
:
ShortBuffer iv;
GLES20.glDrawElements(GLES20.GL_TRIANGLES, iv.limit(), GLS20.GL_UNSIGNED_SHORT, iv);
Однако спецификация говорит, что в ES 2.0 он принимает только GL_UNSIGNED_BYTE
и GL_UNSIGNED_SHORT
. Тем не менее, я протестировал его на некоторых устройствах, которые работают с GL_UNSIGNED_INT
, но вам, вероятно, не следует слишком полагаться на это.
@Reaper Спасибо. Я был небрежен и не рассматривал версию OpenGL ES.
Это сработало отлично. Было ощущение, что это было что-то простое, что я упустил из виду. Благодаря тонну!