我正在尝试在 OpenGL 中绘制一个框(顶部打开)。我给了它纹理,但它们似乎渲染得很奇怪。当我旋转盒子时,侧面纹理有时会出现在底部,什么不是。
这是前视图:
稍微旋转一下后:
显然,这里出了点问题。蓝色的是侧面板的纹理,但是当它旋转时,它似乎在地板上。灰色的是前面板的纹理。因此,在前视图中,后面板根本不可见。但是,可以看到。
代码片段:
绘制容器的方法(不包括盖子):
void box::drawContainer() {
GLuint tex = loadTexture("wood.bmp");
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, tex);
drawBlock(vertex(0, 0, 0), length + 0.2, length + 0.2, thickness); // bottom
tex = loadTexture("tiles.bmp");
glBindTexture(GL_TEXTURE_2D, tex);
drawBlock(
vertex((length - thickness) / 2.0,
(containerHeight + thickness) / 2.0, 0), thickness, breadth,
containerHeight); // right
tex = loadTexture("ocean.bmp");
glBindTexture(GL_TEXTURE_2D, tex);
drawBlock(
vertex((thickness - length) / 2.0,
(containerHeight + thickness) / 2.0, 0), thickness, breadth,
containerHeight); // left
tex = loadTexture("smoke.bmp");
glBindTexture(GL_TEXTURE_2D, tex);
drawBlock(
vertex(0, (containerHeight + thickness) / 2.0,
(breadth - thickness) / 2.0), (length - 2.0 * thickness),
thickness, containerHeight); // front
tex = loadTexture("lightning.bmp");
glBindTexture(GL_TEXTURE_2D, tex);
drawBlock(
vertex(0, (containerHeight + thickness) / 2.0,
(thickness - breadth) / 2.0), (length - 2.0 * thickness),
thickness, containerHeight); // back
glPopMatrix();
}
drawBlock 方法:
void object::drawBlock(vertex center, float length, float breadth,
float height) {
glPushMatrix();
glTranslatef(center.x, center.y, center.z);
glScalef(length, height, breadth);
glBegin(GL_QUADS);
drawPrimitive(vertex(-0.5, 0.5, 0.5), vertex(-0.5, -0.5, 0.5),
vertex(0.5, -0.5, 0.5), vertex(0.5, 0.5, 0.5),
vertex(-0.5, 0.5, -0.5), vertex(-0.5, -0.5, -0.5),
vertex(0.5, -0.5, -0.5), vertex(0.5, 0.5, -0.5));
glEnd();
glPopMatrix();
}
drawPrimitive 方法:
void object::drawPrimitive(vertex v1, vertex v2, vertex v3, vertex v4,
vertex v5, vertex v6, vertex v7, vertex v8) {
drawFace(v1, v2, v3, v4);
drawFace(v5, v6, v7, v8);
drawFace(v1, v5, v6, v2);
drawFace(v4, v3, v7, v8);
drawFace(v1, v4, v8, v5);
drawFace(v2, v6, v7, v3);
}
并且,drawFace 方法:
void object::drawFace(vertex v1, vertex v2, vertex v3, vertex v4) {
glTexCoord2f(0, 1);
glVertex3f(v1.x, v1.y, v1.z);
glTexCoord2f(0, 0);
glVertex3f(v2.x, v2.y, v2.z);
glTexCoord2f(1, 0);
glVertex3f(v3.x, v3.y, v3.z);
glTexCoord2f(1, 1);
glVertex3f(v4.x, v4.y, v4.z);
}
主要功能:
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowSize(640, 480);
glutInitWindowPosition(50, 50);
glutCreateWindow(title);
glutDisplayFunc(display);
glutKeyboardFunc(processKey);
glutReshapeFunc(reshape);
initGL();
glutMainLoop();
return 0;
}
initGL 方法:
void initGL() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Set background color to black and opaque
glClearDepth(1.0f); // Set background depth to farthest
glEnable(GL_DEPTH_TEST); // Enable depth testing for z-culling
glDepthFunc(GL_LEQUAL); // Set the type of depth-test
glShadeModel(GL_FLAT);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Nice perspective corrections
}
加载纹理方法:
GLuint inline loadTexture(const char* fName) {
// Data read from the header of the BMP file
unsigned char header[54]; // Each BMP file begins by a 54-bytes header
unsigned int dataPos; // Position in the file where the actual data begins
unsigned char * data;
unsigned int imageSize;
unsigned int width, height;
// Actual RGB data
// Open the file
FILE * file = fopen(fName, "rb");
if (!file) {
printf("Image could not be opened\n");
}
if (fread(header, 1, 54, file) != 54) { // If not 54 bytes read : problem
printf("Not a correct BMP file\n");
return 0;
}
if (header[0] != 'B' || header[1] != 'M') {
printf("Not a correct BMP file\n");
return 0;
}
// Read ints from the byte array
dataPos = *(int*) &(header[0x0A]);
imageSize = *(int*) &(header[0x22]);
width = *(int*) &(header[0x12]);
height = *(int*) &(header[0x16]);
// Some BMP files are misformatted, guess missing information
if (imageSize == 0)
imageSize = width * height * 3; // 3 : one byte for each Red, Green and Blue component
if (dataPos == 0)
dataPos = 54;
// Create a buffer
data = new unsigned char[imageSize];
// Read the actual data from the file into the buffer
fread(data, 1, imageSize, file);
//Everything is in memory now, the file can be closed
fclose(file);
// Create one OpenGL texture
GLuint textureID;
glGenTextures(1, &textureID);
// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_2D, textureID);
// Give the image to OpenGL
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_BGR,
GL_UNSIGNED_BYTE, data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
return textureID;
}
调用drawContainer的draw方法:
void box::draw()
{
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
drawContainer();
glDisable(GL_TEXTURE_2D);
}
请告诉我是否需要插入更多代码或需要删除任何内容。