zoukankan      html  css  js  c++  java
  • 【求助】在OPENGL中实现三维纹理映射,自动生成坐标未完全成功

    首先,从网上和红宝书书上找了些代码。凭自己的那点小经验改了改,希望能做一个颜色的立方体。即X、Y、Z各个轴分别代表RGB分量。

    以下是没有使用自动生成纹理坐标的方式写的,效果还不错。

    #define GLUT_DISABLE_ATEXIT_HACK

    #include <stdlib.h>
    #include <stdio.h>
    #include <gl/glew.h>
    #include <GL/glut.h>


    #ifdef GL_VERSION_1_2
    #define iWidth 16
    #define iHeight 16
    #define iDepth 16

    static GLubyte image[iDepth][iHeight][iWidth][3];
    static GLuint texName;
    GLfloat angleX,angleY,angleZ;

    /*  Create a 16x16x16x3 array with different color values in
    *  each array element [r, g, b].  Values range from 0 to 255.
    */

    void makeImage(void)
    {
     int s, t, r;

     for (s = 0; s < 16; s++)
      for (t = 0; t < 16; t++)
       for (r = 0; r < 16; r++) {
        image[r][t][s][0] = (GLubyte) (s * 17);
        image[r][t][s][1] = (GLubyte) (t * 17);
        image[r][t][s][2] = (GLubyte) (r * 17);
       }
    }

    void init(void)
    {   
     glClearColor (0.0, 0.0, 0.0, 0.0);
     glShadeModel(GL_FLAT);
     glEnable(GL_DEPTH_TEST);

     makeImage();
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

     glGenTextures(1, &texName);
     glBindTexture(GL_TEXTURE_3D, texName);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,
      GL_NEAREST);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,
      GL_NEAREST);
     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight,
      iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
     glEnable(GL_TEXTURE_3D);
     angleX = 0.0;
     angleY = 0.0;
     angleZ = 0.0;
    }

    void display(void)
    {
     int i;
     glPushMatrix();
     glTranslatef(1.0,0.0,-1.0);
     glRotatef(angleX,1.0,0.0,0.0);
     glRotatef(angleY,0.0,1.0,0.0);
     glRotatef(angleZ,0.0,0.0,1.0);

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
     glBegin(GL_QUADS);
     for(i = 0; i < 100; i ++)
     {
      glTexCoord3f(0.0, 0.0, (GLfloat)i * 0.01); glVertex3f(-2.25, -1.0, (GLfloat)i * 0.01);
      glTexCoord3f(0.0, 1.0, (GLfloat)i * 0.01); glVertex3f(-2.25, 1.0, (GLfloat)i * 0.01);
      glTexCoord3f(1.0, 1.0, (GLfloat)i * 0.01); glVertex3f(-0.25, 1.0, (GLfloat)i * 0.01);
      glTexCoord3f(1.0, 0.0, (GLfloat)i * 0.01); glVertex3f(-0.25, -1.0, (GLfloat)i * 0.01);

     }
     glEnd();
     glPopMatrix();
     glFlush();
    }

    void reshape(int w, int h)
    {
     glViewport(0, 0, (GLsizei) w, (GLsizei) h);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glTranslatef(0.0, 0.0, -4.0);
    }

    void keyboard(unsigned char key, int x, int y)
    {
     switch (key) {
      case 's':
      case 'S':
       angleX +=15.0;
       glutPostRedisplay();
       break;
      case 'd':
      case 'D':
       angleY += 15.0;
       glutPostRedisplay();
       break;
      case 'f':
      case 'F':
       angleZ += 15.0;
       glutPostRedisplay();
       break;
      case 27:
       exit(0);
       break;
     }
    }

    int main(int argc, char** argv)
    {
     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
     glutInitWindowSize(250, 250);
     glutInitWindowPosition(100, 100);
     glutCreateWindow(argv[0]);
     glewInit();
     init();
     glutReshapeFunc(reshape);
     glutDisplayFunc(display);
     glutKeyboardFunc (keyboard);
     glutMainLoop();
     return 0;
    }
    #else
    int main(int argc, char** argv)
    {
     fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0 or 1.1.\n");
     fprintf (stderr, "If your implementation of OpenGL has the right extensions,\n");
     fprintf (stderr, "you may be able to modify this program to make it run.\n");
     return 0;
    }
    #endif

    效果图:两个不同的角度。

        

    然后,我想把它改成自动生成三维纹理坐标的,但是没有成功。

    主要修改的代码有两处:初始化函数Init()和绘制函数Display()

    程序代码如下:

    #define GLUT_DISABLE_ATEXIT_HACK

    #include <stdlib.h>
    #include <stdio.h>
    #include <gl/glew.h>
    #include <GL/glut.h>


    #ifdef GL_VERSION_1_2
    #define iWidth 16
    #define iHeight 16
    #define iDepth 16

    static GLubyte image[iDepth][iHeight][iWidth][3];
    static GLuint texName;
    GLfloat angleX,angleY,angleZ;
    GLfloat xPlane[] = {1.0,0.0,0.0,0.0};
    GLfloat yPlane[] = {0.0,1.0,0.0,0.0};
    GLfloat zPlane[] = {0.0,0.0,1.0,0.0};
    float mat[16];

    /*  Create a 16x16x16x3 array with different color values in
    *  each array element [r, g, b].  Values range from 0 to 255.
    */

    void makeImage(void)
    {
     int s, t, r;

     for (s = 0; s < 16; s++)
      for (t = 0; t < 16; t++)
       for (r = 0; r < 16; r++) {
        image[r][t][s][0] = (GLubyte) (s * 17);
        image[r][t][s][1] = (GLubyte) (t * 17);
        image[r][t][s][2] = (GLubyte) (r * 17);
       }
    }

    void init(void)
    {   
     glClearColor (0.0, 0.0, 0.0, 0.0);
     glShadeModel(GL_FLAT);
     glEnable(GL_DEPTH_TEST);

     makeImage();
     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

     glGenTextures(1, &texName);
     glBindTexture(GL_TEXTURE_3D, texName);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,
      GL_LINEAR);
     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,
      GL_LINEAR);

     glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
     glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
     glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
     glTexGenfv(GL_S,GL_OBJECT_PLANE,xPlane);
     glTexGenfv(GL_T,GL_OBJECT_PLANE,yPlane);
     glTexGenfv(GL_R,GL_OBJECT_PLANE,zPlane);

     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight,
      iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
     glEnable(GL_TEXTURE_GEN_S);
     glEnable(GL_TEXTURE_GEN_T);
     glEnable(GL_TEXTURE_GEN_R);

     glEnable(GL_TEXTURE_3D);
     glLoadIdentity();

     angleX = 0.0;
     angleY = 0.0;
     angleZ = 0.0;
    }

    void display(void)
    {
     int i;
     glPushMatrix();
     glTranslatef(0.0,0.0,-1.0);
     glRotatef(angleX,1.0,0.0,0.0);
     glRotatef(angleY,0.0,1.0,0.0);
     glRotatef(angleZ,0.0,0.0,1.0);

     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

     for (int ii=0;ii<160;ii++){
      glPushMatrix();
      glTranslatef(0.0f,0.0f,-1.0f +(float)ii*2.0f/(float)(160-1));
      glRectf(-1.0,-1.0,1.0,1.0);
      glPopMatrix();
     }

     glPopMatrix();
     glFlush();
    }

    void reshape(int w, int h)
    {
     glViewport(0, 0, (GLsizei) w, (GLsizei) h);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0);
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glTranslatef(0.0, 0.0, -4.0);
    }

    void keyboard(unsigned char key, int x, int y)
    {
     switch (key) {
      case 's':
      case 'S':
       angleX +=15.0;
       glutPostRedisplay();
       break;
      case 'd':
      case 'D':
       angleY += 15.0;
       glutPostRedisplay();
       break;
      case 'f':
      case 'F':
       angleZ += 15.0;
       glutPostRedisplay();
       break;
      case 27:
       exit(0);
       break;
     }
    }

    int main(int argc, char** argv)
    {
     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
     glutInitWindowSize(250, 250);
     glutInitWindowPosition(100, 100);
     glutCreateWindow(argv[0]);
     glewInit();
     init();
     glutReshapeFunc(reshape);
     glutDisplayFunc(display);
     glutKeyboardFunc (keyboard);
     glutMainLoop();
     return 0;
    }
    #else
    int main(int argc, char** argv)
    {
     fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0 or 1.1.\n");
     fprintf (stderr, "If your implementation of OpenGL has the right extensions,\n");
     fprintf (stderr, "you may be able to modify this program to make it run.\n");
     return 0;
    }
    #endif

    所得到的结果:

            
     
    貌似改成自动生成之后,和预想的结果差别挺大的。不知道是为什么。好像颜色变化不像原来那样是渐变的了,颜色的跳跃很明显。希望高手指点我一下,谢谢。
  • 相关阅读:
    JMeter 压测基础(四)——Java工程测试
    Docker 实战(二)——centos7镜像安装nginx,将安装nginx的centos容器生成新的镜像,并导出
    JMeter压测基础(三)——Mysql数据库
    Jmeter压测基础(二)——Badboy功能、Jmeter参数化、检查点、集合点、动态关联、图形监控
    API 自动化框架
    Python Flask Restful
    【19】Grafana添加Zabbix为数据源
    【18】使用公共邮箱发送邮件
    xls格式转化为txt格式
    【17】自动发现磁盘脚本
  • 原文地址:https://www.cnblogs.com/unsigned/p/1688774.html
Copyright © 2011-2022 走看看