我想实现在球上贴纹理,无法实现,希望高手帮帮忙.
下面是我的代码,运行结果是一个球和一张纹理图,我想贴到球上该怎么做?#include "stdafx.h"
#include "math.h"
#include<gl/glut.h>
#include<stdlib.h>
#include <stdio.h>
//X和Z是直角三角形的两个直角边X^2+Z^2=1且Z/X=(sqrt(5)+1)/2=1.618
#define X 0.525731112119133606
#define Z 0.850650808352039932
#define checkImageWidth 64
#define checkImageHeight 64
static GLubyte checkImage[checkImageHeight][checkImageWidth][4];
static GLuint texName;
static GLfloat spin=0.0;
int i,j;
int recursion_depth=6;//递归子分割深度
void makeCheckImage(void)//创建纹理
{int a,b,c;
for(a=0;a<checkImageHeight;a++)
{
for(b=0;b<checkImageWidth;b++)
{c=((((a&0x8)==0)^((b&0x8))==0))*255;
checkImage[a][b][0]=(GLubyte)c;
checkImage[a][b][1]=(GLubyte)c;
checkImage[a][b][2]=(GLubyte)c;
checkImage[a][b][3]=(GLubyte)255;
}
}
}
//二十面体的定点数组(12个点)
static GLfloat vdata[12][3]={
{-X,0.0,Z},{X,0.0,Z},{-X,0.0,-Z},{X,0.0,-Z},
{0.0,Z,X},{0.0,Z,-X},{0.0,-Z,X},{0.0,-Z,-X},
{Z,X,0.0},{-Z,X,0.0},{Z,-X,0.0},{-Z,-X,0.0},
};
//指定哪三个点构成三角形
static GLuint tindices[20][3]={
{1,4,0},{4,9,0},{4,5,9},{8,5,4,},{1,8,4},
{1,10,8},{10,3,8},{8,3,5},{3,2,5},{3,7,2},
{3,10,7},{10,6,7},{6,11,7},{6,0,11},{6,1,0},
{10,1,6},{11,0,9},{2,11,9},{5,2,9},{11,2,7},
};//求两个向量的归一化差积
void normalize(float v[3]){
GLfloat d=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]);//求向量的模
if(d==0.0){//如果向量为零向量
return;
}
//以下代码将向量归一化
v[0]/=d;
v[1]/=d;
v[2]/=d;
}//求向量的叉积
void normcrossprod(float v1[3],float v2[3],float out[3]){
out[0]=v1[1]*v2[2]-v1[2]*v2[1];
out[1]=v1[2]*v2[0]-v1[0]*v2[2];
out[2]=v1[0]*v2[1]-v1[1]*v2[0];
//向量out是向量v1和向量v2的叉积
normalize(out);//对向量out进行归一化计算
}//绘制三角形
void drawtriangle(float *v1,float *v2,float *v3){
glBegin(GL_TRIANGLES);
    glNormal3fv(v1);//定义法线方向
glVertex3fv(v1);     glNormal3fv(v2);
glVertex3fv(v2);     glNormal3fv(v3);
glVertex3fv(v3);
glEnd();
}//进行递归子分割
void subDivide(float *v1,float *v2,float *v3,long depth){
GLfloat v12[3],v23[3],v31[3];
GLint i;
 if(depth==0){//递归深度为零,则无需进行递归子分割
drawtriangle(v1,v2,v3);
return;
} for (i=0;i<3;i++){
v12[i]=(v1[i]+v2[i])/2.0;
v23[i]=(v2[i]+v3[i])/2.0;
v31[i]=(v3[i]+v1[i])/2.0;
}
//将向量归一化
normalize(v12);
normalize(v23);
    normalize(v31);

subDivide(v1,v12,v31,depth-1);
subDivide(v2,v23,v12,depth-1);
subDivide(v3,v31,v23,depth-1);
subDivide(v12,v23,v31,depth-1);
}
//初始化光照模型及视图模型转换设置后开始实际的绘图
void display (void){
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //设置背景颜色
  
   glColor3f(0.0, 1.0, 0.5);//设置绘制图形所用颜色
for(i=0;i<20;i++){
subDivide(
&vdata[tindices[i][0]] [0],
&vdata[tindices[i][1]] [0], 
    &vdata[tindices[i][2]] [0],
     recursion_depth //最后一个参数代表执行的子分割的次数
);
}
glEnable(GL_TEXTURE_2D);
   glBindTexture(GL_TEXTURE_2D,texName);
glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
  
 // glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
//glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
//glEnable(GL_TEXTURE_GEN_S);
//glEnable(GL_TEXTURE_GEN_T); glBegin(GL_QUADS);
glTexCoord2f(0.0,0.0); glVertex3f(-2.0,-1.0,0.0);
glTexCoord2f(0.0,1.0); glVertex3f(-2.0,1.0,0.0);
glTexCoord2f(1.0,1.0); glVertex3f(0.0,1.0,0.0);
glTexCoord2f(1.0,0.0); glVertex3f(0.0,-1.0,0.0); 
glEnd();
  glDisable(GL_TEXTURE_2D); 
glFlush();//结束图形绘制的顶点给定,并最终输出至显示器完成图形的显示}
void init (void){ GLfloat mat_specular[]  = {1.0,1.0,1.0,1.0}; //定义反射光强度
    GLfloat mat_shininess[] = {80.0};            //定义镜面反射参数
GLfloat light_position[]  = {1.0,1.0,1.0,0.0}; //定义光源的位置
    GLfloat white_light[]= {1.0,1.0,1.0,1.0}; //定义光源颜色 
GLfloat lmodel_ambient[]   = {0.4,0.4,0.4,1.0}; //定义环境光亮度    glClearColor(0.0,0.0,0.0,0.0);
glShadeModel(GL_SMOOTH); //设置明暗模型为平直 

//定义材质
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);   //定义材质的镜面反射颜色
    glMaterialfv(GL_FRONT,GL_SHININESS,mat_shininess); //定义镜面反射参数
 //定义光源
glLightfv(GL_LIGHT0,GL_POSITION, light_position); //定义光源的位置
glLightfv(GL_LIGHT0,GL_DIFFUSE,white_light);   //定义光源的散射光亮度
glLightfv(GL_LIGHT0,GL_SPECULAR,white_light);  //定义光源的镜面反射光亮度
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,lmodel_ambient);   //定义光源的环境光强度 //打开光源
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);    //贴图参数
makeCheckImage();
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
glGenTextures(1,&texName); glBindTexture(GL_TEXTURE_2D,texName);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,checkImageWidth,checkImageHeight,0,GL_RGBA,GL_UNSIGNED_BYTE,checkImage);
    //glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
////glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
//glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
//glEnable(GL_TEXTURE_GEN_S);
//glEnable(GL_TEXTURE_GEN_T);
}//初始化光照模型及视图模型转换设置
void reshape(int w, int h){
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);         
    glLoadIdentity();    /*define the projection*/
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);
//gluOrtho2D(-1.5,1.5,-1.5,1.5);
    glLoadIdentity();
}
//主函数
int main(int argc, char** argv){
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow(argv[0]);
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop();
return 0;
}

解决方案 »

  1.   

    你Enable纹理的位置搞错了,下面是我帮你修改的display,使用OpenGL自动生成纹理坐标(当然如果觉得不满意也可以自己算)
    void   display   (void)

        glClear(GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);   //设置背景颜色     glEnable(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D,texName);
    //glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);  glEnable(GL_TEXTURE_GEN_S);
    glTexGeni(GL_S,GL_TEXTURE_ENV_MODE,GL_OBJECT_LINEAR);
    GLfloat params[]={1.0,0.0,0.0,0.0};
        glTexGenfv(GL_S,GL_OBJECT_PLANE,params);//  glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); 
    //  glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP); 
    //  glEnable(GL_TEXTURE_GEN_S); 
    //  glEnable(GL_TEXTURE_GEN_T); 

    glColor3f(0.0,   1.0,   0.5);//设置绘制图形所用颜色
    for(i=0;i <20;i++)

    subDivide( 
    &vdata[tindices[i][0]]   [0], 
    &vdata[tindices[i][1]]   [0], 
    &vdata[tindices[i][2]]   [0],
    recursion_depth   //最后一个参数代表执行的子分割的次数 
    ); 
    }  //  glBegin(GL_QUADS); 
    //  glTexCoord2f(0.0,0.0);   glVertex3f(-2.0,-1.0,0.0); 
    //  glTexCoord2f(0.0,1.0);   glVertex3f(-2.0,1.0,0.0);
    //  glTexCoord2f(1.0,1.0);   glVertex3f(0.0,1.0,0.0); 
    //  glTexCoord2f(1.0,0.0);   glVertex3f(0.0,-1.0,0.0); 
    //  glEnd();     glDisable(GL_TEXTURE_2D);  
    glDisable(GL_TEXTURE_GEN_S); glFlush();//结束图形绘制的顶点给定,并最终输出至显示器完成图形的显示 
      

  2.   

    谢谢你,但是还有一个问题。我加了一个功能,就是实现球的旋转。但发现这样的纹理不随着转动。
    就好象是里面的球在转,而纹理只是贴在了那个面上。
    void   display   (void)

    ......
     glRotated(angle,0.0,0.0,1.0);
    ......
      } 
    void keyboard(unsigned char key,int x,int y)
    { switch(key)
    {case 'd':    angle=angle+10;
    glutPostRedisplay();
    break;
    }
    }int   main(int   argc,   char**   argv){ 
    ......
    glutKeyboardFunc(keyboard);
    ......
    }