glDrawArraysInstanced не работает должным образом

Я новичок в opengl

Я создаю два куба

когда я использую glDrawArraysInstanced . Согласно моей матричной трансформации я не получаю ожидаемый результат

Вот мой код, который я использую с различными данными

float fovy=tanf(GLKMathDegreesToRadians(30));
float nearplane=0.1f;
float farplane=10.0f;
float aspectratio=self.view.frame.size.width/self.view.frame.size.height;

float height=fovy*nearplane;
float width=height*aspectratio;

GLKMatrix4 frustum=GLKMatrix4MakeFrustum(-width, +width, -height, height, nearplane, farplane);
GLKMatrix4 translate=GLKMatrix4Translate(frustum, 0, 0.9, -3);

GLKMatrix4 rotatey= GLKMatrix4Rotate(translate, GLKMathDegreesToRadians(54), 0, 1, 0);

GLKMatrix4 translate1=GLKMatrix4Translate(frustum, 0, -0.5, -3);

GLKMatrix4 rotatey1= GLKMatrix4Rotate(translate1, GLKMathDegreesToRadians(54), 1, 1, 0);


GLKMatrix4 matarray[]=
{
    rotatey,rotatey1
};

glGenBuffers(1, &matbuffer);
glBindBuffer(GL_ARRAY_BUFFER, matbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(matarray), matarray, GL_STATIC_DRAW);

glVertexAttribPointer(fulltransform,4, GL_FLOAT, GL_FALSE,sizeof(float)*4, (GLvoid*)(sizeof(float)*0));
glVertexAttribPointer(fulltransform+1, 4, GL_FLOAT, GL_FALSE,sizeof(float)*4, (GLvoid*)(sizeof(float)*4));
glVertexAttribPointer(fulltransform+2, 4, GL_FLOAT, GL_FALSE,sizeof(float)*4, (GLvoid*)(sizeof(float)*8));
glVertexAttribPointer(fulltransform+3, 4, GL_FLOAT, GL_FALSE,sizeof(float)*4, (GLvoid*)(sizeof(float)*12));

glVertexAttribDivisor(fulltransform, 1);
glVertexAttribDivisor(fulltransform+1, 1);
glVertexAttribDivisor(fulltransform+2, 1);
glVertexAttribDivisor(fulltransform+3, 1);

glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDrawArraysInstanced(GL_TRIANGLES, 0, numvertex,2);

Вот мой результат

если я использую единую переменную и использую gldrawarray два раза, тогда я получаю идеальный результат. Вот мой код и результат

  glClearColor(0.65f, 0.65f, 0.65f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

float fovy=tanf(GLKMathDegreesToRadians(30));
float nearplane=0.1f;
float farplane=10.0f;
float aspectratio=self.view.frame.size.width/self.view.frame.size.height;
float height=fovy*nearplane;
float width=height*aspectratio;

GLKMatrix4 frustum=GLKMatrix4MakeFrustum(-width, +width, -height, height, nearplane, farplane);
GLKMatrix4 translate=GLKMatrix4Translate(frustum, 0, 0.9, -3);
GLKMatrix4 rotatey= GLKMatrix4Rotate(translate, GLKMathDegreesToRadians(54), 0, 1, 0);
glUniformMatrix4fv(uniformmatrix, 1, GL_FALSE, rotatey.m);
glDrawArrays(GL_TRIANGLES, 0, numvertex);

GLKMatrix4 translatey=GLKMatrix4Translate(frustum, 0,-0.5, -3);
GLKMatrix4 rotatex= GLKMatrix4Rotate(translatey,     GLKMathDegreesToRadians(54), 1, 0, 0);
glUniformMatrix4fv(uniformmatrix, 1, GL_FALSE, rotatex.m);
glDrawArrays(GL_TRIANGLES, 0, numvertex);

Вот мой код GLSL

# версия 300 es

in vec4 position;
in vec4 color;
in mat4 fulltransform;
uniform  mat4 matrix;
out vec4 fragcolor;

void main()
{
// in mat4 fulltransform

fragcolor=color;
gl_Position=fulltransform*position;

// uniform  mat4 matrix
fragcolor=color;
gl_Position=matrix*position;
}

Также я хочу знать, какой из этих двух методов будет работать лучше в случае fps

Вся помощь будет оценена.

GLuint programhandle=glCreateProgram();
glAttachShader(programhandle, vertex);
glAttachShader(programhandle, fragment);
glLinkProgram(programhandle);
GLint status;
position=glGetAttribLocation(programhandle,"position");
color=glGetAttribLocation(programhandle, "color");
uniformmatrix=glGetUniformLocation(programhandle, "matrix");
fulltransform=glGetAttribLocation(programhandle, "fulltransform");
glEnableVertexAttribArray(position);
glEnableVertexAttribArray(color);
glEnableVertexAttribArray(fulltransform);
glEnableVertexAttribArray(fulltransform+1);
glEnableVertexAttribArray(fulltransform+2);
glEnableVertexAttribArray(fulltransform+3);
glGetProgramiv(programhandle , GL_LINK_STATUS, &status);
if (status==GL_FALSE)
{
    NSLog(@"program");
}
glDeleteShader(vertex);
glDeleteShader(fragment);
glUseProgram(programhandle);

2 ответа

Решение

Значения шага в вашем glVertexAttribPointer() звонки смотри

glVertexAttribPointer(fulltransform,4, GL_FLOAT, GL_FALSE,
    sizeof(float)*4, (GLvoid*)(sizeof(float)*0));
glVertexAttribPointer(fulltransform+1, 4, GL_FLOAT, GL_FALSE,
    sizeof(float)*4, (GLvoid*)(sizeof(float)*4));
glVertexAttribPointer(fulltransform+2, 4, GL_FLOAT, GL_FALSE,
    sizeof(float)*4, (GLvoid*)(sizeof(float)*8));
glVertexAttribPointer(fulltransform+3, 4, GL_FLOAT, GL_FALSE,
    sizeof(float)*4, (GLvoid*)(sizeof(float)*12));

Шаг (второй, но последний аргумент) - это разница в байтах между последующими значениями атрибута. Поскольку ваши атрибуты являются строками матрицы, а вся матрица содержит 16 значений с плавающей запятой, разница между, например, первой строкой (которая является вашим первым атрибутом) одной матрицы и первой строкой следующей матрицы составляет 16 значений с плавающей запятой. Так что эти звонки должны быть:

glVertexAttribPointer(fulltransform,4, GL_FLOAT, GL_FALSE,
    sizeof(float)*16, (GLvoid*)(sizeof(float)*0));
glVertexAttribPointer(fulltransform+1, 4, GL_FLOAT, GL_FALSE,
    sizeof(float)*16, (GLvoid*)(sizeof(float)*4));
glVertexAttribPointer(fulltransform+2, 4, GL_FLOAT, GL_FALSE,
    sizeof(float)*16, (GLvoid*)(sizeof(float)*8));
glVertexAttribPointer(fulltransform+3, 4, GL_FLOAT, GL_FALSE,
    sizeof(float)*16, (GLvoid*)(sizeof(float)*12));

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

Является ли "fulltransform" возвращенным из glGetAttribLocation() в вызове "glVertexAttribPointer(fulltransform,...)", и я не видел, чтобы вы вызывали "glEnableVertexAttribArray(fulltransform + 0/1/2/3)" перед отрисовкой.

Другие вопросы по тегам