OpenGl 4, GL_ARRAY_BUFFER неправильно отправляет данные нормалей - PullRequest
1 голос
/ 13 октября 2019

У меня есть равнина, созданная с использованием этого метода: Вот изображение, показывающее мой образ мышления

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

Моя проблема с обычным буфером. Я создаю нормали, как это (это в алгоритме, который вычисляет вершины):

//Calculating Vertices
    for (unsigned int z = 0; z < m_size; z++)
    {
        for (unsigned int x = 0; x <= m_size; x++)
        {
            Vertices.push_back(glm::vec3(m_startingPos.x + x * m_sqrWidth, m_startingPos.y, m_startingPos.z + z * m_sqrWidth));
            Vertices.push_back(glm::vec3(m_startingPos.x + x * m_sqrWidth, m_startingPos.y, m_startingPos.z + (z + 1) * m_sqrWidth));


            glm::vec3 TL = glm::vec3(m_startingPos.x + x * m_sqrWidth, m_startingPos.y, m_startingPos.z + z * m_sqrWidth);
            glm::vec3 TR = glm::vec3(m_startingPos.x + (x + 1) * m_sqrWidth, m_startingPos.y, m_startingPos.z + z * m_sqrWidth);
            glm::vec3 BL = glm::vec3(m_startingPos.x + x * m_sqrWidth, m_startingPos.y, m_startingPos.z + (z + 1) * m_sqrWidth);
            glm::vec3 BR = glm::vec3(m_startingPos.x + (x + 1) * m_sqrWidth, m_startingPos.y, m_startingPos.z + (z + 1) * m_sqrWidth);

            //Normals:
            Normals.push_back(glm::normalize(glm::cross(TL - BR, BL - BR)));
            Normals.push_back(glm::normalize(glm::cross(TR - BR, TL - BR))); 

            //Color:
            colors.push_back(0.0f); colors.push_back(0.0f); colors.push_back(0.5f);
            colors.push_back(0.0f); colors.push_back(0.5f); colors.push_back(0.0f);
        }
    }

Так что каждая нормаль равна 0 1 0, я знаю это.

Здесь я создаю буфер и attribPointerдля нормалей (все в классе, так что unsigned int normalsBuffer объявлен в файле .h и инициализирован как NULL):

glGenBuffers(1, &normalsBuffer);
    glBindBuffer(GL_ARRAY_BUFFER, normalsBuffer);
    glBufferData(GL_ARRAY_BUFFER, Normals.size() * sizeof(float) * 3, &Normals[0].x, GL_STATIC_DRAW);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0); 

В glVertexAttribPointer inedex установлен в 2, потому что вершины принимают 0, а цвета принимают 1.

Итак, вот мой шейдер:

#shader vertex
#version 330 core

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 color_in;
layout(location = 2) in vec3 normals_in;

uniform mat4 u_MVP;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

out vec3 FragPos;
out vec3 Normal;
out vec3 color_f;

void main()
{
    color_f = color_in;
    FragPos = vec3(model * vec4(position, 1.0));
    Normal = normals_in;
    Normal = mat3(transpose(inverse(model))) * normals_in;

    gl_Position = projection * view * vec4(FragPos, 1.0);
};

#shader fragment
#version 330 core
out vec4 color;

in flat vec3 Normal;
in vec3 FragPos;

in flat vec3 color_f;

uniform vec4 u_Color;

uniform vec3 lightPos;
uniform vec3 viewPos;
uniform vec3 lightColor;


void main()
{
    vec3 objectColor = color_f;

    // ambient
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;

    // diffuse 
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    // specular
    float specularStrength = 0.5;
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor;

    vec3 result = (ambient + diffuse + specular) * objectColor;
    color = vec4(result, 1.0);
}

Вот пример того, как работает объект с таким же шейдером и как ведет себя моя равнина. В ней полностью отсутствует рассеянное освещение

Если я перейду к фрагментному шейдеру и установлю vec3 norm = vec3 (0.0, 1.0, 0.0), все будет работать нормально, но я не хочу этого делать.

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

Вот как это выглядит, когда я получил фрагмент шейдера и установил norm в 0 1 0

1 Ответ

1 голос
/ 13 октября 2019
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

, чтобы вы включили VertexAttribArray для цвета (1), вам следует активировать VertexAttribArray для нормалей (2), а также убедиться, что вы получили правильный (void*)0, если вы используете структуру, убедитесь, что вы используете offsetofэто более надежно, особенно если вы используете компилятор с оптимизацией

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...