4

我在使用 VBO 的 OpenGL 中工作,并且我有一组三条线(沿着 X、Y 和 Z 轴——想想捷克刺猬)。这些线条默认是灰色的,但我希望它们是鲜红色的,这样我可以更好地看到它们。不幸的是,虽然我将颜色信息添加为顶点数据,但线条仍然显示为灰色。我可能缺少一些基本的东西,但我看不到它。这是我创建 VBO 的方法:

//Position data
sf::Vector3<float> Top    = sf::Vector3<float>(0.0, 1.0, 0.0);
sf::Vector3<float> Front  = sf::Vector3<float>(0.0, 0.0, -1.0);
sf::Vector3<float> Right  = sf::Vector3<float>(1.0, 0.0, 0.0);
sf::Vector3<float> Back   = sf::Vector3<float>(0.0, 0.0, 1.0);
sf::Vector3<float> Left   = sf::Vector3<float>(-1.0, 0.0, 0.0);
sf::Vector3<float> Bottom = sf::Vector3<float>(0.0, -1.0, 0.0);

//Color data
//Just to be clear, I also tried with 255.0, although I'm rather certain OpenGL 
//does its colors on a 0-1 scale.
sf::Vector3<float> Color = sf::Vector3<float>(1.0, 0.0, 0.0);

//Create vector
std::vector<float> LineArray;

//Top
LineArray.push_back(Top.x);
LineArray.push_back(Top.y);
LineArray.push_back(Top.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Bottom
LineArray.push_back(Bottom.x);
LineArray.push_back(Bottom.y);
LineArray.push_back(Bottom.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);

//Front
LineArray.push_back(Front.x);
LineArray.push_back(Front.y);
LineArray.push_back(Front.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Back
LineArray.push_back(Back.x);
LineArray.push_back(Back.y);
LineArray.push_back(Back.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);

//Right
LineArray.push_back(Right.x);
LineArray.push_back(Right.y);
LineArray.push_back(Right.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);
//Left
LineArray.push_back(Left.x);
LineArray.push_back(Left.y);
LineArray.push_back(Left.z);
LineArray.push_back(Color.x);
LineArray.push_back(Color.y);
LineArray.push_back(Color.z);

//Create buffer
glGenBuffers(1, &m_Buffer);
glBindBuffer(GL_ARRAY_BUFFER, m_Buffer);
int SizeInBytes = LineArray.size() * 6 * sizeof(float);
glBufferData(GL_ARRAY_BUFFER, SizeInBytes, NULL, GL_STATIC_DRAW);

//Upload buffer data
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(float) * LineArray.size(), &LineArray[0]);

这就是我每次显示它的方式:

glPushMatrix();

//Translate
glTranslatef(m_Position.x, m_Position.y, m_Position.z);
//Rotate
glMultMatrixf(m_RotationMatrix);

//Bind buffers for vertex and color arrays
glBindBuffer(GL_ARRAY_BUFFER, m_Buffer);

glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 6 * sizeof(float), 0);
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(3, GL_FLOAT, 6 * sizeof(float), (void*)12);

//Draw
glDrawArrays(GL_LINES, 0, 36);

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

//Unbind the buffers
glBindBuffer(GL_ARRAY_BUFFER, 0);

glPopMatrix();

我以前从未使用过 GL_COLOR_ARRAY,但我基于成功使用 GL_NORMAL_ARRAY 的代码。有人可以指出什么问题吗?

编辑:如果我设置我的基本 OpenGL 参数错误(特别是照明),这里是那些:

m_AmbientLight = {0.5f, 0.5f, 0.5f, 1.0f};
m_DiffuseLight = {1.0f, 1.0f, 1.0f, 1.0f};
m_LightPos = {8.0f, -16.0f, 8.0f, 0.0f};

//Smooth Shading
glShadeModel(GL_SMOOTH);

// Set color and depth clear value
glClearDepth(1.f);
//Color here is in RGB, converted to a 0-1 scale.
glClearColor(0.3f, 0.3f, 0.3f, 1.f);

// Enable Z-buffer read and write
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

///
///LIGHTING
///
//Set up lighting.
//This activates the ambient light.
glLightfv(GL_LIGHT0, GL_AMBIENT, m_AmbientLight);
//This activates the diffuse light.
glLightfv(GL_LIGHT1, GL_DIFFUSE, m_DiffuseLight);
//This sets the position of the diffuse light.
glLightfv(GL_LIGHT1, GL_POSITION, m_LightPos);
//This enables the light.
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
//Enables all lighting...?
glEnable(GL_LIGHTING);
glEnable(GL_COLOR_MATERIAL);
//glEnable(GL_NORMALIZE);

// Setup a perspective projection
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.f, 1.33f, 0.1f, 512.f);

编辑2:确定 glColor3f() 也没有任何效果,我想知道我的着色器是否是问题所在:

垂直着色器:

void main()
{
vec3 normal, lightDir;
vec4 diffuse;
float NdotL;

normal = normalize(gl_NormalMatrix * gl_Normal);

lightDir = normalize(vec3(gl_LightSource[0].position));

NdotL = max(dot(normal, lightDir), 0.0);

diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
gl_FrontColor =  NdotL * diffuse;

gl_Position = ftransform();
}

片段着色器:

void main()
{
gl_FragColor = gl_Color;
}
4

2 回答 2

5

不是 100% 肯定的,但我不认为你应该在画线时启用 GL_COLOR_MATERIAL。尝试禁用它。

编辑(从评论复制):

你的着色器对我没有意义。您应该只传递一种颜色,然后将该颜色直接传递给片段着色器。为什么要使用光照着色器来绘制线条?您应该创建一个不使用任何材料的不同着色器。除非您使用固定功能管道,否则启用/禁用照明无效。我认为您将固定功能命令与着色器混合在一起并感到困惑。

于 2012-06-19T06:05:08.717 回答
1

在我看来,您在绘制线条时启用了照明,因此顶点数据的颜色被照明计算的颜色覆盖。在. glDisable(GL_LIGHTING)_glDrawArrays

于 2012-06-18T16:45:44.823 回答