C++ 未在平面上显示纹理
所以我想写一个折射着色器,平面上有一个玻璃球。我的问题是纹理没有在平面上显示 平面代码:C++ 未在平面上显示纹理,c++,opengl,glsl,C++,Opengl,Glsl,所以我想写一个折射着色器,平面上有一个玻璃球。我的问题是纹理没有在平面上显示 平面代码: GLfloat plane[4][5] = // s, t, x, y, z { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 100.0f, 1.0f, 1.0f, 80.0f, 0.0f, 100.0f, 1.0f, 0
GLfloat plane[4][5] = // s, t, x, y, z
{
0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 100.0f,
1.0f, 1.0f, 80.0f, 0.0f, 100.0f,
1.0f, 0.0f, 80.0f, 0.0f, 0.0f,
};
void DrawPlane()
{
glBegin(GL_QUADS);
glVertex3fv(plane[0]+2);
glVertex3fv(plane[1]+2);
glVertex3fv(plane[2]+2);
glVertex3fv(plane[3]+2);
glEnd();
}
我的片段着色器如下所示:
varying vec3 varPosition;
varying vec2 varTexCoords;
uniform vec3 sphere_center;
uniform float sphere_radius;
uniform float sphere_refractive_index;
uniform vec3 eyePosition;
uniform sampler2D texture;
out vec3 fragColor;
void main()
{
vec3 ray_direction = normalize(varPosition - eyePosition);
float a = dot(ray_direction, ray_direction);
float b = 2.0 * dot(ray_direction, eyePosition - sphere_center);
float c = dot(sphere_center, sphere_center) + dot(eyePosition, eyePosition) - 2.0 * dot(sphere_center, eyePosition) - sphere_radius*sphere_radius;
float test = b*b - 4.0*a*c;
if (test >= 0.0) {
//there is an intersection with the sphere
//here I refract the ray
} else {
//no intersection with the sphere
//we test for shadow
if (test >= 0.0) {
//the point is in shadow
vec3 black = vec3(0.0);
fragColor = mix(texture2D(texture, varTexCoords).rgb,black,shadowIntensity).rgb;
} else {
//the point is not in shadow
fragColor = texture2D(texture, varTexCoords).rgb;
}
}
}
情况是球体被绘制,但平面仍为灰色。问题可能出在我的texCoords上,因为如果我在texture2D函数中更改varTexCoords参数(类似于position.xz),它会绘制平面(当然是错误的)。但在我看来,我在那里拥有一切必要的东西
属性数组:
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 5 * sizeof(GLfloat), (GLvoid*)(plane[0]+2));
glVertexAttribPointer(ATTRIB_TEX_COORDS, 2, GL_FLOAT, 0, 5 * sizeof(GLfloat), (GLvoid*)(plane[0]));
glBindAttribLocation(program->id(), ATTRIB_VERTEX, "position");
glBindAttribLocation(program->id(), ATTRIB_TEX_COORDS, "texCoords");
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_TEX_COORDS);
我绑定属性位置并启用顶点属性数组:
glVertexAttribPointer(ATTRIB_VERTEX, 3, GL_FLOAT, 0, 5 * sizeof(GLfloat), (GLvoid*)(plane[0]+2));
glVertexAttribPointer(ATTRIB_TEX_COORDS, 2, GL_FLOAT, 0, 5 * sizeof(GLfloat), (GLvoid*)(plane[0]));
glBindAttribLocation(program->id(), ATTRIB_VERTEX, "position");
glBindAttribLocation(program->id(), ATTRIB_TEX_COORDS, "texCoords");
glEnableVertexAttribArray(ATTRIB_VERTEX);
glEnableVertexAttribArray(ATTRIB_TEX_COORDS);
我什么都试过了。也许这个错误是微不足道的,我不能再直接思考了,因为我快要失去理智了
任何提示都非常感谢。您没有使用纹理坐标。您确实设置了一些属性指针,但这些指针从未使用过,因为您正在使用立即模式
glBegin()
/glEnd()
绘制平面,而从未指定任何tex坐标(因此着色器将看到该属性的常量值)。仅当您实际发出基于顶点数组的绘制调用时,才会使用您设置的属性指针,如glDrawArrays()
或glDrawElements()
glEnable(纹理2D);OpenGL是基于状态的。我在initGL()函数中有它。@Krythic:glEnable(TEXTURE_2D)
与着色器完全无关,它只影响固定的函数管道。@derhass我会修复你的管道。好的,如果我在每个glVertex3fv(平面[0]+2)
之前写glTexCoord2f(x.0f,y.0f)
它应该正常工作(其中x和y是对应的一和零)?不幸的是,它没有。不,它不应该。使用glVertex
、glColor
、glTexCoord
等将为固定功能管道设置不推荐使用的内置属性。您正在使用具有常规属性的着色器,因此必须将glVertexAttrib
与各种属性索引一起使用。OpenGL仅保证glVertex
等同于设置通用属性0,因此您至少获得正确顶点坐标的原因很可能是ATTRIB\u vertex
恰好是0
。但是,您最好完全放弃立即模式。