LINUX.ORG.RU

[openGL] Не пойму, как закинуть нормали в массив

 


0

1

Сначала делал так:

glm::vec3 modelData[28];
    float size = 3.0f;
    modelData[0] = glm::vec3(0.0f,size,0.0f);
    modelData[1] = glm::vec3(-size,0.0f,+size);
    modelData[2] = glm::vec3(size,0.0f,+size);
    modelData[3] = glm::vec3(size,0.0f,+-size);
    modelData[4] = glm::vec3(-size,0.0f,+-size);
    modelData[5] = glm::vec3(0.0f,0.0f,0.0f);
    modelData[6] = glm::vec3(0.3f,0.3f,0.0f);
    modelData[7] = glm::vec3(0.6f,0.6f,0.0f);
    modelData[8] = glm::vec3(1.0f,0.0f,0.0f);
    modelData[9] = glm::vec3(1.0f,1.0f,0.0f);
    modelData[10] = glm::triangleNormal(modelData[0],modelData[2],modelData[1]);
    modelData[11] = modelData[10];
    modelData[12] = modelData[10];
    modelData[13] = glm::triangleNormal(modelData[0],modelData[3],modelData[2]);
    modelData[14] = modelData[13];
    modelData[15] = modelData[13];
    modelData[16] = glm::triangleNormal(modelData[0],modelData[4],modelData[3]);
    modelData[17] = modelData[16];
    modelData[18] = modelData[16];
    modelData[19] = glm::triangleNormal(modelData[0],modelData[1],modelData[4]);
    modelData[20] = modelData[19];
    modelData[21] = modelData[19];
    modelData[22] = glm::triangleNormal(modelData[1],modelData[3],modelData[4]);
    modelData[23] = modelData[22];
    modelData[24] = modelData[22];
    modelData[25] = glm::triangleNormal(modelData[3],modelData[2],modelData[1]);
    modelData[26] = modelData[25];
    modelData[27] = modelData[25];
    int indexes[18] = {0,2,1,0,3,2,0,4,3,0,1,4,1,3,4,2,3,1};
Рисовалось так:
glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glEnableVertexAttribArray(2);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,IBO);
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(glm::vec3),0);
    GLubyte ss =5*sizeof(glm::vec3);
    glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,sizeof(float),(const GLvoid*)ss);
    ss =10*sizeof(glm::vec3);
    glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,sizeof(glm::vec3),(const GLvoid*)ss);
    glDrawElements(GL_TRIANGLES,18,GL_UNSIGNED_INT,0);
    glDisableVertexAttribArray(0);
    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(2);
Шейдеры:
#version 330
in layout (location = 0) vec3 Position;
in layout (location = 1) vec2 TexCoord;
in layout (location = 2) vec3 Normal;
uniform mat4 mvp;
uniform mat4 world;
out vec2 finalCoord;
out vec3 normal0;
void main(void)
{
    gl_Position = mvp * vec4(Position,1.0);
    normal0 = (world * vec4(Normal,0.0)).xyz;
    finalCoord = TexCoord;
}
#version 330
in vec2 finalCoord;
in vec3 normal0;
out vec4 fragColor;
uniform sampler2D samp;
struct dirlight
{
    vec3 color;
    float ambInt;
    float diffInt;
    vec3 dir;
};
uniform dirlight light;
void main(void)
{
    vec4 AmbientColor = vec4(light.color, 1.0f) * light.ambInt;
    float DiffuseFactor = dot(normalize(normal0), -light.dir);
    vec4 DiffuseColor;
    if (DiffuseFactor > 0) {
        DiffuseColor = vec4(light.color, 1.0f) * light.diffInt * DiffuseFactor;
    }
    else {
        DiffuseColor = vec4(0, 0, 0, 0);
    }
    fragColor = texture2D(samp,finalCoord.st) * (AmbientColor + DiffuseColor);
}
Но диффузное освещение не получалось - хз, почему, но в результате получался тот же самый ambient. На gamedev.ru посоветовали убрать «магические числа» «5» и «10» из glVertexAttribPointer и сделать структуру вершины с текстурными координатами и нормалями.
struct vertex
{
    glm::vec3 pos;
    glm::vec2 tex;
    glm::vec3 norm;
};
Рисуется иначе:
vertex *offset = NULL;
    glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,sizeof(vertex),&offset->pos);
    glVertexAttribPointer(1,2,GL_FLOAT,GL_FALSE,sizeof(vertex),&offset->tex);
    glVertexAttribPointer(2,3,GL_FLOAT,GL_FALSE,sizeof(vertex),&offset->norm);
    glDrawElements(GL_TRIANGLES,18,GL_UNSIGNED_INT,0);
В принципе, заработало, но, из-за неправильно расставленных нормалей пропали все тени. И это понятно: ведь нормаль должна привязываться не к вершине, а к треугольнику. Есть выход - сделать структуру triangle и рисовать через glDrawArrays, но это неоптимально. Можно ли оставить индексы, но сделать нормали?

★★★★
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.