OpenGL高手请进来看看!!!很急啊!!!

时间:2022-08-09 16:12:53
我的一个程序里面用两个正交的矩形贴上纹理位图来表现一棵树,但是却看到了奇怪的现象----同时出现了一棵正确的树和一棵横过来的树,怎么会同时出现两棵树呢?
我用的函数如下:
glNormal3f(0.0, 0.0, 1.0);
gluBeginPolygon(tess);
for (ii = 0; ii < 4; ii ++)
gluTessVertex(tess, treestruct2[ii], treestruct2[ii]);
gluEndPolygon(tess);
其中treestruct2是一个描述树的向量,五维的,即(x,y,z,s,t).

static GLdouble    treestruct[][5] =  /* tree struct points */
        {
/* { x, y, z, s, t } */
{ -5.0,  0.0,  0.0, 0.0, 0.0 },
{  5.0,  0.0,  0.0, 1.0, 0.0 },
{  5.0, 10.0,  0.0, 1.0, 1.0 },
{ -5.0, 10.0,  0.0, 1.0, 0.0 },
{  0.0,  0.0,  5.0, 0.0, 0.0 },
{  0.0,  0.0, -5.0, 1.0, 0.0 },
{  0.0, 10.0, -5.0, 1.0, 1.0 },
{  0.0, 10.0,  5.0, 1.0, 0.0 }
};
static GLdouble treestruct2[8][5];
还多开了一个treestruct2是因为,其实有很多树,每棵被种到的地方都不一样,因此用一个新的二维数组来实时计算.
for(k = 0; k < 8; k++)
{
for(l = 0; l < 3; l++)
treestruct2[k][l] = treestruct[k][l] + tp->v[l];
treestruct2[k][3] = treestruct[k][3];
treestruct2[k][4] = treestruct[k][4];
}
艾,我该贴的代码都已经贴上了,请明白的人看一看,能否知道为什么会出现两棵树的现象?
另外,怎样在OpenGL里面使用透明色?也就是说,在编辑位图的时候,指定一种颜色,比如说黑色,以后只要碰上黑色,OpenGL就知道让它透明!!!否则我的树就算画对了,边上也有一个大矩形框呀,多难看啊!!!
以前好像DirectX里面有直接支持此类操作的函数啊,DDSetColorKey(lpDDSBoy[2],RGB(0,0,0));就行了,OpenGL里面怎么玩啊?
谢谢拉.

5 个解决方案

#1


你去看一看融合

#2


这个问题我最有体会
首先,你一定要用RGBA象素模式而不能用RGB,也就是一个象素用4位表示,第4位就表示是否透明。这样就比DDSetColorKey更灵活,程序中很多相关部分都要换过来
下面是我的一段读去24位图的过程ALPHAFLAG设为TURE即可。
int ReadBitmap24(char* filename,char *image24,int *width2,int *length2,int ALPHAFLAG)
{   char *image;
    FILE *fp;
if(fp=fopen(filename,"r"))
     { int width,length;
   fseek(fp,18L,0);
   fread(&width,4,1,fp);*width2=width;
       fread(&length,4,1,fp);*length2=length;

   image=new char[width*length*3];
   fseek(fp,54L,0);
   fread(image,1,width*length*3,fp);
   fclose(fp);
   long a;
   if(ALPHAFLAG)
   { for(a=0;a<width*length;a++)
 { image24[4*a]=(GLubyte)image[a*3+2]; // R
   image24[4*a+1]=(GLubyte)image[a*3+1]; // G
   image24[4*a+2]=(GLubyte)image[a*3];
   if(image[a*3+2]==0&&image[a*3+1]==0&&image[a*3]==0)image24[4*a+3]=0;
    else image24[4*a+3]=(GLubyte)255;
 }
   }else
 for(a=0;a<width*length;a++)
 { image24[3*a]=image[a*3]; // R
   image24[3*a+1]=image[a*3+1]; // G
   image24[3*a+2]=image[a*3+2];
 }
   delete image;
   return(1);
     }else return(0);
}
第二,在需要透明的绘制过程中,用Alpha检测技术,绘制结束最好关掉,否则会比较慢
下面是我的一段绘制正交贴花数的代码,效果很好
(如果不要求透明可以不用融合技术glEnable(GL_BLEND),不过要想绘制透明物体也必须用RGBA象素模式)
void Tree::Draw()
{ glBindTexture(GL_TEXTURE_2D,TreeName[TexIndex]);
  glPushMatrix();
   DrawTransf(0,0,0,0.707f,0.707f);
   glEnable(GL_ALPHA_TEST);//开启Alpha检测技术
   glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);glVertex3f(-DownWidth/2,Lowh,0);//glVertex3f(-UpWidth/2,Height,0);
    glTexCoord2f(1.0f,0.0f);glVertex3f(DownWidth/2,Lowh,0);
    glTexCoord2f(1.0f,1.0f);glVertex3f(UpWidth/2,Height,0);
    glTexCoord2f(0.0f,1.0f);glVertex3f(-UpWidth/2,Height,0);
   glEnd();
   glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);glVertex3f(0,Lowh,-DownWidth/2);
    glTexCoord2f(1.0f,0.0f);glVertex3f(0,Lowh,DownWidth/2);
    glTexCoord2f(1.0f,1.0f);glVertex3f(0,Height,UpWidth/2);
    glTexCoord2f(0.0f,1.0f);glVertex3f(0,Height,-UpWidth/2);
   glEnd();
   glDisable(GL_ALPHA_TEST);//关闭Alpha检测技术
  glPopMatrix();
}

#3


补充一点
glAlphaFunc(GL_GREATER,0.10f);//纹理象素中A值大于0.10*255的才能显示
如果还要用透明,则要设定
glBlendFunc(GL_SRC_ALPHA,GL_ONE);//设置混合函数原因子=纹理A,目的因子=1

#4


树横过来是因为贴图坐标有问题(第二个树)
其他的楼上的都已经回答了

#5


o , 来晚了! :)
随便说一点,交流好了。
opengl的透明色我觉得用色彩的位蒙版来实现也可以,一定的颜色位根本就写不进去。

#1


你去看一看融合

#2


这个问题我最有体会
首先,你一定要用RGBA象素模式而不能用RGB,也就是一个象素用4位表示,第4位就表示是否透明。这样就比DDSetColorKey更灵活,程序中很多相关部分都要换过来
下面是我的一段读去24位图的过程ALPHAFLAG设为TURE即可。
int ReadBitmap24(char* filename,char *image24,int *width2,int *length2,int ALPHAFLAG)
{   char *image;
    FILE *fp;
if(fp=fopen(filename,"r"))
     { int width,length;
   fseek(fp,18L,0);
   fread(&width,4,1,fp);*width2=width;
       fread(&length,4,1,fp);*length2=length;

   image=new char[width*length*3];
   fseek(fp,54L,0);
   fread(image,1,width*length*3,fp);
   fclose(fp);
   long a;
   if(ALPHAFLAG)
   { for(a=0;a<width*length;a++)
 { image24[4*a]=(GLubyte)image[a*3+2]; // R
   image24[4*a+1]=(GLubyte)image[a*3+1]; // G
   image24[4*a+2]=(GLubyte)image[a*3];
   if(image[a*3+2]==0&&image[a*3+1]==0&&image[a*3]==0)image24[4*a+3]=0;
    else image24[4*a+3]=(GLubyte)255;
 }
   }else
 for(a=0;a<width*length;a++)
 { image24[3*a]=image[a*3]; // R
   image24[3*a+1]=image[a*3+1]; // G
   image24[3*a+2]=image[a*3+2];
 }
   delete image;
   return(1);
     }else return(0);
}
第二,在需要透明的绘制过程中,用Alpha检测技术,绘制结束最好关掉,否则会比较慢
下面是我的一段绘制正交贴花数的代码,效果很好
(如果不要求透明可以不用融合技术glEnable(GL_BLEND),不过要想绘制透明物体也必须用RGBA象素模式)
void Tree::Draw()
{ glBindTexture(GL_TEXTURE_2D,TreeName[TexIndex]);
  glPushMatrix();
   DrawTransf(0,0,0,0.707f,0.707f);
   glEnable(GL_ALPHA_TEST);//开启Alpha检测技术
   glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);glVertex3f(-DownWidth/2,Lowh,0);//glVertex3f(-UpWidth/2,Height,0);
    glTexCoord2f(1.0f,0.0f);glVertex3f(DownWidth/2,Lowh,0);
    glTexCoord2f(1.0f,1.0f);glVertex3f(UpWidth/2,Height,0);
    glTexCoord2f(0.0f,1.0f);glVertex3f(-UpWidth/2,Height,0);
   glEnd();
   glBegin(GL_QUADS);
    glTexCoord2f(0.0f,0.0f);glVertex3f(0,Lowh,-DownWidth/2);
    glTexCoord2f(1.0f,0.0f);glVertex3f(0,Lowh,DownWidth/2);
    glTexCoord2f(1.0f,1.0f);glVertex3f(0,Height,UpWidth/2);
    glTexCoord2f(0.0f,1.0f);glVertex3f(0,Height,-UpWidth/2);
   glEnd();
   glDisable(GL_ALPHA_TEST);//关闭Alpha检测技术
  glPopMatrix();
}

#3


补充一点
glAlphaFunc(GL_GREATER,0.10f);//纹理象素中A值大于0.10*255的才能显示
如果还要用透明,则要设定
glBlendFunc(GL_SRC_ALPHA,GL_ONE);//设置混合函数原因子=纹理A,目的因子=1

#4


树横过来是因为贴图坐标有问题(第二个树)
其他的楼上的都已经回答了

#5


o , 来晚了! :)
随便说一点,交流好了。
opengl的透明色我觉得用色彩的位蒙版来实现也可以,一定的颜色位根本就写不进去。