我开始使用OpenGL ES 1.0并遇到一些(初学者)问题:我试图将方形纹理映射到三角形描述的立方体。
// Turn necessary features on
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_SRC_COLOR);
glEnable(GL_CULL_FACE);
//glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
// Bind the number of textures we need, in this case one.
glGenTextures(1, &texture[0]);
glBindTexture(GL_TEXTURE_2D, texture[0]);
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);
//Drawing code
static GLfloat rot = 0.0;
static const Vertex3D vertices[] = {
-1.0f,-1.0f,-1.0f, //0 00
1.0f,-1.0f,-1.0f, //1 10
1.0f, 1.0f,-1.0f, //2 11
-1.0f, 1.0f,-1.0f, //3 01
};
static const int vertexCnt = 3 * 2;
static const GLubyte cube[] = {
3,0,2,
1,2,0,
};
static const GLfloat texCoords[] = {
0,1,
0,0,
1,1,
1,0,
1,1,
0,0,
};
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -3.0f);
glBindTexture(GL_TEXTURE_2D, texture[0]);
glEnableClientState(GL_VERTEX_ARRAY);
//glEnableClientState(GL_COLOR_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnable(GL_COLOR_MATERIAL);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);
//glColorPointer(4, GL_FLOAT, 0, colors);
glNormalPointer(GL_FLOAT, 0, normals);
glDrawElements(GL_TRIANGLES, vertexCnt, GL_UNSIGNED_BYTE, cube);
glDisableClientState(GL_VERTEX_ARRAY);
//glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
现在,经过无数次尝试,我无法让其他方面的工作...... 将方形纹理映射到三角形时是否有一些经验法则?
编辑:我想我弄清楚应该如何完成映射。但它不适用于这个例子(一个面)。有人可以请验证我是否正确映射(假设其余代码正常工作)?非常感谢
答案 0 :(得分:1)
我没有尝试过你的顶点列表,但我的猜测是你的坐标完全混乱并且映射错误,你已经错误地指定了你的索引缓冲区格式,或者你有背面剔除打开,你的一些顶点顺序错误。
对于纹理坐标本身,与四边形相比,应该没有与三角形映射的技巧。你只需要有6个纹理坐标,之前你有4个,因为有6个顶点(每个面有两个重复)。您可以使用索引缓冲区避免重复,就像使用多维数据集一样。
对于潜在的背面剔除问题,您必须每次都以相同的顺序定义顶点。所有顺时针方向,相对于纹理将面向的方向,或全部逆时针方向。
您使用什么命令来设置OpenGL管道,以及您使用哪些命令来绘制这些顶点?请在问题中添加相应的代码。
答案 1 :(得分:1)
就像其他人一样,我认为将四边形纹理映射到三角形上并不存在诀窍。
您遇到的主要问题是每个角落的纹理坐标不连续。如果一个角作为一个面的一些UV坐标{u,v},则并不意味着它将与共享顶点的其他两个面具有相同的值。可以找到一个映射,以便UV在立方体的每个角上是唯一的(由3个面共享),因此所有4个UV值({0,0},{1,0},{1,1}和{0,1})存在于每个面上,但是一些纹理将完全扭曲。尝试在一张纸上验证这一点:{1,1}并不总是与{0,0}相反。
最简单的方法是明确声明6个四边形,每个四边形由2个三角形组成。这给你总共24个顶点(24个位置和24个tex coords,交错或不交错)和36个索引(6个四边形由两个三角形组成,6 * 2 * 3 = 36)。
以下是您更新的代码以显示多维数据集(可能存在一些缠绕问题,因此我禁用了面部剔除以确保):
glEnable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_CULL_FACE);
static const float vertices[] = {
0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
0.0f, 1.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f,
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f,
1.0f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 1.0f, 1.0f,
0.0f, 0.0f, 1.0f
};
static const int vertexCnt = 6 * 4;
static const GLubyte cube[] = {
0, 1, 2, 1, 2, 3,
4, 5, 6, 5, 6, 7,
8, 9, 10, 9, 10, 11,
12, 13, 14, 13, 14, 15,
16, 17, 18, 17, 18, 19,
20, 21, 22, 21, 22, 23
};
static const GLfloat texCoords[] = {
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
0.0f, 1.0f,
0.0f, 0.0f,
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 0.0f,
1.0f, 0.0f,
0.0f, 1.0f,
1.0f, 1.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 0.0f,
0.0f, 1.0f
};
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//glLoadIdentity();
//glTranslatef(0.0f, 0.0f, -3.0f);
glRotatef(3.1415927f, 1.0f, 1.0f, 0.0f);
glBindTexture(GL_TEXTURE_2D, spriteTexture);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glVertexPointer(3, GL_FLOAT, 0, vertices);
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, cube);