【发布时间】:2021-08-07 08:10:51
【问题描述】:
我正在尝试使用基本着色器绘制一个球体。但我无法绘制完整的球体。
球体计算
const float pi = 3.1414927f;
GLint layers = 100;
GLint circumferenceTiles = 100;
std::vector<float> va;
std::vector<int> ia;
// create the vertex attributes
va.reserve((layers + 1)* (circumferenceTiles + 1) * 5); // 5 floats: x, y, z, u, v
for (int il = 0; il <= layers; ++il)
{
float layer_rel = (float)il / (float)layers;
float layer_ang = (1.0f - 2.0f * layer_rel) * pi / 2.0f;
float layer_sin = std::sin(layer_ang);
float layer_cos = std::cos(layer_ang);
for (int ic = 0; ic <= circumferenceTiles; ic++)
{
float circum_rel = (float)ic / (float)circumferenceTiles;
float cricum_ang = circum_rel * 2.0f * pi - pi;
float circum_sin = std::sin(cricum_ang);
float circum_cos = std::cos(cricum_ang);
va.push_back(layer_cos * circum_cos); // x
va.push_back(layer_cos * circum_sin); // y
va.push_back(layer_sin); // z
va.push_back(circum_rel); // u
va.push_back(1.0f - layer_rel); // v
}
}
// create the face indices
ia.reserve(layers * circumferenceTiles * 6);
for (int il = 0; il < layers; ++il)
{
for (int ic = 0; ic < circumferenceTiles; ic++)
{
int i0 = il * (circumferenceTiles + 1) + ic;
int i1 = i0 + 1;
int i3 = i0 + circumferenceTiles + 1;
int i2 = i3 + 1;
int faces[]{ i0, i1, i2, i0, i2, i3 };
ia.insert(ia.end(), faces + (il == 0 ? 3 : 0), faces + (il == layers - 1 ? 3 : 6));
}
}
绑定
// Vertex Array
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Vertex Buffer
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, va.size() * sizeof(*va.data()), va.data(), GL_STATIC_DRAW);
// Index Buffer
GLuint ibo;
glGenBuffers(1, &ibo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, ia.size() * sizeof(*ia.data()), ia.data(), GL_STATIC_DRAW);
GLuint v_attr_inx = 0;
glVertexAttribPointer(v_attr_inx, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableVertexAttribArray(v_attr_inx);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
绘图
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, (GLsizei)ia.size(), GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
片段着色器
#version 330 core
// Interpolated values from the vertex shaders
in vec3 fragmentColor;
// Ouput data
layout(location = 0) out vec4 color;
uniform vec4 u_Color;
void main(){
// Output color = color specified in the vertex shader,
// interpolated between all 3 surrounding vertices
color = u_Color;
}
顶点着色器
#version 330 core
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexColor;
// Output data ; will be interpolated for each fragment.
out vec3 fragmentColor;
// Values that stay constant for the whole mesh.
uniform mat4 MVP;
void main(){
// Output position of the vertex, in clip space : MVP * position
gl_Position = MVP * vec4(vertexPosition_modelspace,1);
// The color of each vertex will be interpolated
// to produce the color of each fragment
fragmentColor = vertexColor;
}
我在这里做错了什么。是顶点的计算还是它的顺序。还是我的着色器有问题?会给予任何帮助。 提前谢谢你。
球体的种类:
【问题讨论】:
-
@Spektre 注释掉这两行效果很好。谢谢但我不明白如何解决这个问题。你能写出第二个 glVertexAttribPointer 函数吗?提前致谢
-
我把 cmets 移到了答案中