首页 > 解决方案 > 添加纹理时分离 3D 模型

问题描述

在为背景添加纹理后,我的 3D 模型没有连接起来。我尝试更改 z 值,glTransated但 3D 模型仍然存在问题。在添加纹理之前,我的 3D 模型完美地相互连接,但在我为其背景添加纹理之后,3D 节点变得如下图所示。

有或没有纹理

#include <stdlib.h>
#include <stdio.h>
#include <GL/glut.h>
#include "SOIL2.h"

GLuint myTexture;
GLuint mybody;
const GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
const GLfloat mat_diffuse[] = { 0.8f, 0.8f, 0.8f, 1.0f };

static int head = 0, a = 0, s = 0, rear = -90, lear = -90, body = 0, lleg = -90, rleg = -90, ball = 0, stage = 0;
GLfloat ballRadius = 0.1f;
static int slices = 50;
static int stacks = 50;

float angle = 0.0f;
float handAngle[2] = { 0.0f, 0.0f };
float legAngle[2] = { 0.0f,0.0f };
float baseAngle[2] = { 0.0f,0.0f };

int refreshMills = 30;

void hand() {
    const double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
    const double a = t * 90.0;
    const double s = t * 90.0;

    glColor3d(0.5, 0.85, 0.9);
    glPushMatrix();         //hand
    glTranslated(0.2, 0.12, 0);
    glRotated(50, 0, 1, 0);
    glRotated((GLfloat)a, 0, 0, 1);
    glutSolidCone(0.1, 0.4, 16, 16);
    glPopMatrix();

    glPushMatrix();         //hand
    glTranslated(-0.2, 0.12, 0);
    glRotated(50, 0, -1, 0);
    glRotated((GLfloat)s, 0, 0, 1);
    glutSolidCone(0.1, 0.4, 16, 16);
    glPopMatrix();
}

void leg() {
    glColor3d(1.0, 0.7, 0.3);
    glPushMatrix();         //leg
    glTranslated(0.15, -0.27, 0.15);
    glRotated((GLfloat)rleg, 0.5, 0, 0);
    glutSolidTorus(0.026, 0.08, 16, 16);
    glPopMatrix();

    glPushMatrix();         //leg
    glTranslated(-0.15, -0.27, 0.15);
    glRotated((GLfloat)lleg, 0.5, 0, 0);
    glutSolidTorus(0.026, 0.08, 16, 16);
    glPopMatrix();

    glColor3d(0.4, 0.3, 0.1);
    glPushMatrix();         //leg
    glTranslated(0.15, -0.27, 0.15);
    glRotated((GLfloat)rleg, 0.5, 0, 0);
    glutSolidTorus(0.026, 0.03, 16, 16);
    glPopMatrix();

    glPushMatrix();         //leg
    glTranslated(-0.15, -0.27, 0.15);
    glRotated((GLfloat)lleg, 0.5, 0, 0);
    glutSolidTorus(0.026, 0.03, 16, 16);
    glPopMatrix();
}

void mainpart() {
    glColor3d(0.5, 0.85, 0.9);  // head
    glPushMatrix();
    glTranslated(0, 0.25, 0.18);
    glRotated((GLfloat)head, 0, 1, 0);
    glutSolidSphere(0.2, 40, 50);
    glPopMatrix();

    glPushMatrix();         //ear
    glTranslated(0.11, 0.34, 0.18);
    glRotated((GLfloat)rear, 1, 0, 0);
    glutSolidCone(0.08, 0.2, 16, 16);
    glPopMatrix();

    glPushMatrix();         //ear
    glTranslated(-0.11, 0.34, 0.18);
    glRotated((GLfloat)lear, 1, 0, 0);
    glutSolidCone(0.08, 0.2, 16, 16);
    glPopMatrix();

    glColor3d(0.0, 0.0, 0.0);  //eyes
    glPushMatrix();
    glTranslated(0.07, 0.3, 0.33);
    glRotated(0, 0, 0, 0);
    glScalef(0.5, 0.1, 0.1);
    glutSolidCube(0.1);
    glPopMatrix();

    glPushMatrix();      //eyes
    glTranslated(-0.07, 0.3, 0.33);
    glRotated(0, 0, 0, 0);
    glScalef(0.5, 0.1, 0.1);
    glutSolidCube(0.1);
    glPopMatrix();

    glPushMatrix();      //mouth
    glTranslated(0.03, 0.25, 0.35);
    glRotated(10, 0, 0, 1);
    glScalef(0.6, 0.1, 0.1);
    glutSolidCube(0.1);
    glPopMatrix();

    glPushMatrix();      //mouth
    glTranslated(-0.03, 0.25, 0.35);
    glRotated(-10, 0, 0, 1);
    glScalef(0.6, 0.1, 0.1);
    glutSolidCube(0.1);
    glPopMatrix();

    glColor3d(1.0, 1.0, 1.0);
    glPushMatrix();   // teeth
    glTranslated(-0.045, 0.255, 0.34);
    glRotated(-90, 1, 0, 0);
    glutSolidCone(0.01, 0.03, 16, 16);
    glPopMatrix();

    glPushMatrix();   // teeth
    glTranslated(0.045, 0.255, 0.34);
    glRotated(-90, 1, 0, 0);
    glutSolidCone(0.01, 0.03, 16, 16);
    glPopMatrix();


    glColor3d(0.5, 0.85, 0.88);  // body
    //glColor3d(1.0, 1.0, 1.0);
    glTranslatef(0, -0.05, 1.1);
    glPushMatrix();
    glRotated((GLfloat)body, 1, 0, 0);
    glutSolidSphere(0.3, 40, 50);
    glPopMatrix();

    glEnd();

    // prepare for drawing the geometry
    glDisable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);
}

void pokeball() {
    glColor3d(1.0, 0, 0);  // pokeball(red)
    glPushMatrix();
    glTranslated(0, -0.7, 1);
    glRotated((GLfloat)ball, 0, 0, 0);
    glutSolidSphere(0.1, slices, stacks);
    glPopMatrix();

    glColor3d(0.0, 0.0, 0.0);  // pokeball(black)
    glPushMatrix();
    glTranslated(0, -0.7, 1.04);
    glRotated(0, 0, 0, 0);
    glutSolidSphere(0.07, slices, stacks);
    glPopMatrix();


    glColor3d(1.0, 1.0, 1.0);  // pokeball(small white)
    glPushMatrix();
    glTranslated(0, -0.7, 1.09);
    glRotated(0, 0, 0, 0);
    glutSolidSphere(0.03, slices, stacks);
    glPopMatrix();

    glColor3d(1.0, 1.0, 1.0);  // pokeball(big white)
    glPushMatrix();
    glTranslated(0, -0.71, 1);
    glRotated(0, 0, 0, 0);
    glutSolidSphere(0.1, slices, stacks);
    glPopMatrix();

    glColor3d(0.0, 0.0, 0.0);  // pokeball TORUS
    glPushMatrix();
    glTranslated(0, -0.7, 1);
    glRotated(90, 1, 0, 0);
    glutSolidTorus(0.01, 0.1, slices, stacks);
    glPopMatrix();
}


void display(void)
{
    // clear color buffer and depth buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // prepare for drawing the back ground
    glDisable(GL_DEPTH_TEST);
    glDisable(GL_LIGHTING);
    glColor3d(1.0, 1.0, 1.0);

    // projection and model view for the background
    glLoadIdentity();
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // draw the background
    glBindTexture(GL_TEXTURE_2D, myTexture);

    glEnable(GL_TEXTURE_2D);
    glBegin(GL_QUADS);

    glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(1.0f, -1.0f, 1.0f);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); 

    glEnd();

    // prepare for drawing the geometry
    glDisable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, 0);

    glDisable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);

    // projection and model view for the geoemtry
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    //glFrustum(-ar + 1, ar - 1, -1.0, 1.0, 2.0, 90.0);
    //gluOrtho2D(0, width, 0, height);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    // draw geometry
    pokeball();
    leg();
    hand();
    mainpart();

    glFlush();
    glutSwapBuffers();
    glutPostRedisplay();
}

void reshape(int w, int h)
{
    glViewport(0, 0, (GLsizei)w, (GLsizei)h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    if (w <= h)
        glOrtho(-1.5, 1.5, -1.5 * (GLfloat)h / (GLfloat)w,
            1.5* (GLfloat)h / (GLfloat)w, -10.0, 10.0);
    else
        glOrtho(-1.5 * (GLfloat)w / (GLfloat)h, 1.5 * (GLfloat)
            w / (GLfloat)h, -1.5, 1.5, -10.0, 10.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void keyboard(unsigned char key, int x, int y)
{
    switch (key) {

    case 27:
    case 'q':
        exit(0);
        break;

        /* case '-':
             head++;
             glutPostRedisplay();
             break;

         case 'w':
             lleg++;
             rleg--;
             break;

         case 'W':
             lleg--;
             rleg++;
             break;

         case 'E':
             a--;
             s++;
             break;

         case 'e':
             s--;
             a++;
             break;

         case '+':
             if (slices>3 && stacks>3)
             {
                 slices--;
                 stacks--;
             }
             break;*/
    default:
        break;
    }
}

void TimerFunc(int value) {
    glutPostRedisplay();
    glutTimerFunc(50, TimerFunc, 1);
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowSize(600, 600);
    glutInitWindowPosition(100, 100);
    //glutCreateWindow("Snorlex");
    glutCreateWindow(argv[0]);
    glutDisplayFunc(display);
    glutReshapeFunc(reshape);   
    glutKeyboardFunc(keyboard);
    glutTimerFunc(0, TimerFunc, 0);

    myTexture = SOIL_load_OGL_texture("background.png", 0, 1, SOIL_FLAG_POWER_OF_TWO | SOIL_FLAG_INVERT_Y);
    if (!myTexture)
    {
        printf("soil failed to load texture\n");
    }
    glEnable(GL_TEXTURE_2D);


    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHT0);
    glEnable(GL_NORMALIZE);
    glEnable(GL_COLOR_MATERIAL);
    glEnable(GL_LIGHTING);

    glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);

    glutMainLoop();
    return 0;
}



标签: openglopengl-compat

解决方案


在这里您禁用深度测试:

// prepare for drawing the back ground
glDisable(GL_DEPTH_TEST);

但是,您不再重新启用它,而是再次禁用它:

// prepare for drawing the geometry
// ...
glDisable(GL_DEPTH_TEST);

结果,几何图形被绘制在另一个之上,从而产生您看到的伪影。

要修复它,第二个glDisable应替换为glEnable

// prepare for drawing the geometry
// ...
glEnable(GL_DEPTH_TEST);

推荐阅读