Torus 的纹理应用不正确
Texture for Torus is not applying properly
我正在创建一个带有 6 Torus 的开放式 GL 程序。当我应用纹理时,它以一种颜色显示。尽管它不是单一的颜色。
我正在从数组中获取图像。除 Torus 纹理外,其他纹理(天空盒、行星、HUD)应用正确。我也尝试使用光源,但没有成功。有人可以帮我实现这个目标吗?
下面是我的代码。
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glTranslatef(xpos, ypos, zpos);
glRotatef(fPlanetRot, 0.0f, -1.0f, 0.0f);
glColor3f(0.0, 0.0, 0.0);
// Select the texture object
glBindTexture(GL_TEXTURE_2D, textures[3]);
glutSolidTorus(0.1, 1.0, 30, 30);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
//This is where I load the texture
void SetupRC()
{
//textures
GLuint texture;
// allocate a texture name
glGenTextures( 1, &texture );
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
//there are quite a few ways of loading images
// Load textures in a for loop
glGenTextures(TEXTURE_COUNT, textures);
//this puts the texture into OpenGL texture memory
// glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - not defined so probably need to update GLEW - not needed here so ignore
for(int iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)
{
// Bind to next texture object
glBindTexture(GL_TEXTURE_2D, textures[iLoop]);
// Load texture data, set filter and wrap modes
//note that gltLoadTGA is in the glm.cpp file and not a built-in openGL function
pBytes0 = gltLoadTGA(textureFiles[iLoop],&iWidth, &iHeight,
&iComponents, &eFormat);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes0);
//set up texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//try these too
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
free(pBytes0);
}
//enable textures
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW);// Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside
// glCullFace(GL_FRONT_AND_BACK);
// Enable lighting
glEnable(GL_LIGHTING);
glEnable(GL_POINT_SMOOTH);
// Setup and enable light 0
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLightLessBright);
glLightfv(GL_LIGHT0,GL_DIFFUSE,redLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
// Enable colour tracking
glEnable(GL_COLOR_MATERIAL);
// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// Black blue background
glClearColor(0.0f, 0.0f, 0.03f, 1.0f );
}
简而言之:
glutSolidTorus()
只是不发出环面的纹理坐标,而只发出坐标和每个顶点的法线。
长话短说:
出于好奇,我谷歌了一下,我相信我找到了对 OP 观察的解释
Other textures (skybox, planet, HUD) are applying properly except Torus textures.
首先我看了一下文档。 11.4 glutSolidTorus, glutWireTorus 但我找不到任何提示是否支持或不支持纹理坐标。我尝试了其他一些文档,但大多数都是此文档的副本,或者也没有提到纹理。
接下来我试图找到“glutSolidTorus 纹理”的示例图像,但我找不到。
非常可疑……
所以,我终于在github上看到了glutSolidTorus()的源代码:
void APIENTRY
glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
doughnut(innerRadius, outerRadius, nsides, rings);
}
doughnut()函数定义在同一个源文件中:
static void
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
glBegin(GL_QUAD_STRIP);
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
glEnd();
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
}
答案简单明了——glutSolidTorus()
只是不发出环面的纹理坐标,而只发出坐标和每个顶点的法线。因此,所有像素从一开始就将具有相同且唯一的纹理坐标。这将导致颜色均匀的环面(如 OP 所观察到的那样)。
所以,当 glutSolidTorus()
不支持纹理时,为什么glutSolidSphere()?同源文件中给出了答案:
void APIENTRY
glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluSphere(quadObj, radius, slices, stacks);
}
即glutSolidSphere()
只是 gluSphere()
的包装。医生。 gluSphere() 的人明确提到纹理:
If texturing is turned on (with gluQuadricTexture), then texture coordinates are generated so that t ranges from 0.0 at z = - radius to 1.0 at z = radius (t increases linearly along longitudinal lines), and s ranges from 0.0 at the +y axis, to 0.25 at the +x axis, to 0.5 at the -y axis, to 0.75 at the -x axis, and back to 1.0 at the +y axis.
如果 OP 打算拥有带纹理的环面,则 glutSolidTorus()
必须替换为发出纹理坐标的自定义版本。
使用给定的源代码,扩展函数应该不会太难。
(请不要忘记给它一个新名称,以防止 link 符号重复定义错误 glutSolidTorus()
…)
我后来找到的有用链接:
(可能重复但 [closed]
)
- 3D Opengl Graphics: Texture mapping on Torus
我正在创建一个带有 6 Torus 的开放式 GL 程序。当我应用纹理时,它以一种颜色显示。尽管它不是单一的颜色。
我正在从数组中获取图像。除 Torus 纹理外,其他纹理(天空盒、行星、HUD)应用正确。我也尝试使用光源,但没有成功。有人可以帮我实现这个目标吗?
下面是我的代码。
glPushMatrix();
glEnable(GL_TEXTURE_2D);
glTranslatef(xpos, ypos, zpos);
glRotatef(fPlanetRot, 0.0f, -1.0f, 0.0f);
glColor3f(0.0, 0.0, 0.0);
// Select the texture object
glBindTexture(GL_TEXTURE_2D, textures[3]);
glutSolidTorus(0.1, 1.0, 30, 30);
glDisable(GL_TEXTURE_2D);
glPopMatrix();
//This is where I load the texture
void SetupRC()
{
//textures
GLuint texture;
// allocate a texture name
glGenTextures( 1, &texture );
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
//there are quite a few ways of loading images
// Load textures in a for loop
glGenTextures(TEXTURE_COUNT, textures);
//this puts the texture into OpenGL texture memory
// glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - not defined so probably need to update GLEW - not needed here so ignore
for(int iLoop = 0; iLoop < TEXTURE_COUNT; iLoop++)
{
// Bind to next texture object
glBindTexture(GL_TEXTURE_2D, textures[iLoop]);
// Load texture data, set filter and wrap modes
//note that gltLoadTGA is in the glm.cpp file and not a built-in openGL function
pBytes0 = gltLoadTGA(textureFiles[iLoop],&iWidth, &iHeight,
&iComponents, &eFormat);
glTexImage2D(GL_TEXTURE_2D, 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes0);
//set up texture parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
//try these too
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
free(pBytes0);
}
//enable textures
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH_TEST); // Hidden surface removal
glFrontFace(GL_CCW);// Counter clock-wise polygons face out
glEnable(GL_CULL_FACE); // Do not calculate inside
// glCullFace(GL_FRONT_AND_BACK);
// Enable lighting
glEnable(GL_LIGHTING);
glEnable(GL_POINT_SMOOTH);
// Setup and enable light 0
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLightLessBright);
glLightfv(GL_LIGHT0,GL_DIFFUSE,redLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
// Enable colour tracking
glEnable(GL_COLOR_MATERIAL);
// Set Material properties to follow glColor values
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
// Black blue background
glClearColor(0.0f, 0.0f, 0.03f, 1.0f );
}
简而言之:
glutSolidTorus()
只是不发出环面的纹理坐标,而只发出坐标和每个顶点的法线。
长话短说:
出于好奇,我谷歌了一下,我相信我找到了对 OP 观察的解释
Other textures (skybox, planet, HUD) are applying properly except Torus textures.
首先我看了一下文档。 11.4 glutSolidTorus, glutWireTorus 但我找不到任何提示是否支持或不支持纹理坐标。我尝试了其他一些文档,但大多数都是此文档的副本,或者也没有提到纹理。
接下来我试图找到“glutSolidTorus 纹理”的示例图像,但我找不到。
非常可疑……
所以,我终于在github上看到了glutSolidTorus()的源代码:
void APIENTRY
glutSolidTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings)
{
doughnut(innerRadius, outerRadius, nsides, rings);
}
doughnut()函数定义在同一个源文件中:
static void
doughnut(GLfloat r, GLfloat R, GLint nsides, GLint rings)
{
int i, j;
GLfloat theta, phi, theta1;
GLfloat cosTheta, sinTheta;
GLfloat cosTheta1, sinTheta1;
GLfloat ringDelta, sideDelta;
ringDelta = 2.0 * M_PI / rings;
sideDelta = 2.0 * M_PI / nsides;
theta = 0.0;
cosTheta = 1.0;
sinTheta = 0.0;
for (i = rings - 1; i >= 0; i--) {
theta1 = theta + ringDelta;
cosTheta1 = cos(theta1);
sinTheta1 = sin(theta1);
glBegin(GL_QUAD_STRIP);
phi = 0.0;
for (j = nsides; j >= 0; j--) {
GLfloat cosPhi, sinPhi, dist;
phi += sideDelta;
cosPhi = cos(phi);
sinPhi = sin(phi);
dist = R + r * cosPhi;
glNormal3f(cosTheta1 * cosPhi, -sinTheta1 * cosPhi, sinPhi);
glVertex3f(cosTheta1 * dist, -sinTheta1 * dist, r * sinPhi);
glNormal3f(cosTheta * cosPhi, -sinTheta * cosPhi, sinPhi);
glVertex3f(cosTheta * dist, -sinTheta * dist, r * sinPhi);
}
glEnd();
theta = theta1;
cosTheta = cosTheta1;
sinTheta = sinTheta1;
}
}
答案简单明了——glutSolidTorus()
只是不发出环面的纹理坐标,而只发出坐标和每个顶点的法线。因此,所有像素从一开始就将具有相同且唯一的纹理坐标。这将导致颜色均匀的环面(如 OP 所观察到的那样)。
所以,当 glutSolidTorus()
不支持纹理时,为什么glutSolidSphere()?同源文件中给出了答案:
void APIENTRY
glutSolidSphere(GLdouble radius, GLint slices, GLint stacks)
{
QUAD_OBJ_INIT();
gluQuadricDrawStyle(quadObj, GLU_FILL);
gluQuadricNormals(quadObj, GLU_SMOOTH);
/* If we ever changed/used the texture or orientation state
of quadObj, we'd need to change it to the defaults here
with gluQuadricTexture and/or gluQuadricOrientation. */
gluSphere(quadObj, radius, slices, stacks);
}
即glutSolidSphere()
只是 gluSphere()
的包装。医生。 gluSphere() 的人明确提到纹理:
If texturing is turned on (with gluQuadricTexture), then texture coordinates are generated so that t ranges from 0.0 at z = - radius to 1.0 at z = radius (t increases linearly along longitudinal lines), and s ranges from 0.0 at the +y axis, to 0.25 at the +x axis, to 0.5 at the -y axis, to 0.75 at the -x axis, and back to 1.0 at the +y axis.
如果 OP 打算拥有带纹理的环面,则 glutSolidTorus()
必须替换为发出纹理坐标的自定义版本。
使用给定的源代码,扩展函数应该不会太难。
(请不要忘记给它一个新名称,以防止 link 符号重复定义错误 glutSolidTorus()
…)
我后来找到的有用链接:
(可能重复但[closed]
)- 3D Opengl Graphics: Texture mapping on Torus