c++ - OpenGL 4,GL_ARRAY_BUFFER 没有正确发送法线数据
问题描述
我有一个使用这种方法创建的平原:这是一张显示我的思维方式的图像
我将这些三角形条纹分开,这样每个条纹都可以有唯一的颜色,而且我仍然可以使用顶点索引。
我的问题是法线缓冲区。我像这样创建法线(这是在计算顶点的算法中):
//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) 一切正常,但这不是我想要的方式。
所以我以同样的方式发送颜色数据,它很好,但发送法线数据似乎不起作用。
解决方案
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
因此,您为颜色(1)启用 VertexAttribArray,您应该为法线(2)激活 VertexAttribArray,并且(void*)0
如果您使用结构,请确保您得到正确的确保使用 offsetof 它更可靠,特别是如果您使用编译器有优化
推荐阅读
- dc.js - 在 dc.js 中使用 lineChart 的 x 轴上的年份字段
- python - 无法从某些 html 元素中提取某些地址
- c++ - 处理重构、模板 SFINAE 测试和 lambda
- c# - 如果在结果表中引用了子类别,如何获得类别的平均值?
- javascript - 如何根据数字的值更改数字的颜色。(开放使用任何标签)
- javascript - 字符串流类型中缺少属性映射
- outlook - 使用 Web 插件启动 Outlook 时如何执行 JS 代码?
- fonts - GothamBold 字体未在 Safari 上呈现
- javascript - NativeScript Sidekick 是否会在构建应用程序时删除 XML 和 JavaScript 中的注释并缩小源代码?
- tcp - 我如何发送带有 Ip 标志和 Tcp 控制标志的 TCP 原始套接字