游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1378|回复: 0

我用bmp图片贴一个xz平面有问题,请帮忙指点

[复制链接]

3

主题

4

帖子

0

积分

新手上路

Rank: 1

积分
0
发表于 2009-8-5 11:51:00 | 显示全部楼层 |阅读模式
我用一个bmp图片(512*512)贴图,xz平面,其实最终是想搞一个有高度值的地形图一样的东西,现在设
y=0,可是贴出来后感觉很难控制,我七八年前做过一些很简单的东西,我记得改动glLookAt(ex,ey,ez,cx,cy,cz,1,0)可以改变图形显示的大小之类的,比如我想把图片显示变小,可以把cz减小或把ez加大,只要保证图片在gluPerspective()或glOrtho()定义的空间里就行,我没用过glScalef(),不知道我说的对不对,可是现在改这些只能改变我能看到图片哪块区域,恳请大家指点,先谢谢。
#define W 128 //地图X方向上正方形的个数(两个相邻的三角形组成一个正方形)
#define L 128 //地图Z方向上正方形的个数
#define dis 4.0f //正方形的边长

#define bmpW 1024
#define bmpH 1024

//下边是执行顺序
ViewPort(0,0,width,height);
Init2(m_dc);
Draw();
//结束,下边是相关函数:
void OpenGL::Init2(HDC hdc)
{
m_hDC=hdc;
PIXELFORMATDESCRIPTOR pfd;
memset(&pfd,0,sizeof(PIXELFORMATDESCRIPTOR));
pfd.nSize=sizeof(PIXELFORMATDESCRIPTOR);
pfd.nVersion=1;
pfd.dwFlags=PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER;
pfd.iPixelType=PFD_TYPE_RGBA;
pfd.cColorBits=32;
pfd.cDepthBits=32;
pfd.iLayerType=PFD_MAIN_PLANE;
int cpf=ChoosePixelFormat(m_hDC,&pfd);
if(cpf)
{
SetPixelFormat(m_hDC,cpf,&pfd);
m_rc=wglCreateContext(m_hDC);//创建RC
}
wglMakeCurrent(m_hDC,m_rc);

InitOpenGL();
GetPixelHeight();
InitMap();
}

void OpenGL::InitOpenGL()
{
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glClearColor(0.5, 0.5, 0.5, 1.0);
// glClearColor(0.0f, 0.0f, 0.0f, 0.5f);    // Black Background
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glShadeModel(GL_SMOOTH);      // Enable Smooth Shading
glClearDepth(1.0f);        // Depth Buffer Setup
glEnable(GL_DEPTH_TEST);      // Enables Depth Testing
glDepthFunc(GL_LEQUAL);        // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

}

//用来加载纹理图片
GLuint OpenGL:oadGLTexture(CString filename)
{
GLuint intexture=0;
AUX_RGBImageRec *pic = NULL;
pic = auxDIBImageLoad(filename);

m_bmpSizex=pic->sizeX;
m_bmpSizey=pic->sizeY;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_FALSE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_FALSE);
//  glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE,GL_DECAL);//, GL_MODULATE);
glEnable(GL_TEXTURE_2D);
if(pic == NULL)
return false;
glGenTextures(1,&intexture);
glBindTexture    (GL_TEXTURE_2D,intexture);
gluBuild2DMipmaps(GL_TEXTURE_2D,4, pic->sizeX,pic->sizeY,GL_RGB,GL_UNSIGNED_BYTE,pic->data);
//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); //  Linear  Filtering  
  //glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); //  Linear  Filtering  

free(pic->data);
free(pic);

return intexture;
}


void OpenGL::ViewPort(int x, int y, int width, int height)
{
glViewport(0,0,width,height);
glMatrixMode(GL_PROJECTION);      // Select The Projection Matrix
glLoadIdentity();        // Reset The Projection Matrix

//glOrtho(-320.0f,320.0f,-320.0f,320.0f,0.0f,1000.0f);
gluPerspective(60.0f,(GLfloat)width/(GLfloat)height,0.1f,1000.0f);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);      // Select The Modelview Matrix
glLoadIdentity();
}
//初始化地形的每个顶点坐标,我觉得应该不用非把地形坐标也定义成0-1范围内,可是那样就只显示一小点点
VOID OpenGL::InitMap()
{
ground=LoadGLTexture(m_filename);//加载纹理图片

int X,Z;
for(int x=0;x <W+1;x++)
for(int z=0;z <L+1;z++)
{
map[x][z].x=float(dis*x-(W/2*dis))/float(W*dis)*2.0f;
map[x][z].z=float(dis*z-(L*dis))/float(L*dis)*2.0f;
// map[x][z].y=-rand()%200*0.003f;//顶点的高度随机产生,范围在0.0f---2.0f之间
X=x*m_bmpSizex/W;
Z=z*m_bmpSizey/L;
map[x][z].y=0.0f;//float(bmpHeight[X][Z]-255.0f)/1000.0f;
}

}

//该函数计算由p1,p2,p3三个点组成的三角形面的法向量,这个函数是从网上抄的,可是我发现有他没他都没区别
float* OpenGL::CNormal(PIXEL p1,PIXEL p2,PIXEL p3)
{

PIXEL v1,v2IXEL n;
float normal[4];
v1.x=p2.x-p1.x;
v1.y=p2.y-p1.y;
v1.z=p2.z-p1.z;

v2.x=p3.x-p1.x;
v2.y=p3.y-p1.y;
v2.z=p3.z-p1.z;

n.x=v1.y*v2.z-v1.z*v2.y;
n.y=v1.z*v2.x-v1.x*v2.z;
n.z=v1.x*v2.y-v1.y*v2.x;

double l=sqrt(n.x*n.x+n.y*n.y+n.z*n.z);
if(l!=0.0)
{
n.x=n.x/l;
n.y=n.y/l;
n.z=n.z/l;
}
else
{
n.x=0.0;
n.y=0.0;
n.z=1.0;
}
normal[0]=-n.x;
normal[1]=-n.y;
normal[2]=-n.z;
normal[3]=0.0f;
return normal;
}

//渲染地形
void OpenGL:raw()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
//glLoadIdentity();        // Reset The Current Modelview Matrix
//glTranslatef(-1.5f,0.0f,-6.0f);      // Move Left 1.5 Units And Into The Screen 6.0

glLoadIdentity();
gluLookAt(0.0f, 0.5f, 0.0f,  0.0f,20.0,-0.1, 0, 1, 0);//我不知道gluLookat放在哪里合适,说白了我还是想稀里糊涂过关可是还真不行,请高手指点
// glLoadIdentity();
PIXEL p1,p2,p3;
float* n;
glBindTexture(GL_TEXTURE_2D,ground);

glEnable(GL_CULL_FACE);
glEnable(GL_DEPTH_TEST);
glEnable(GL_LEQUAL);
glPushMatrix();
glTranslated(0.0f, 0.0f, 1.0f);
glRotated( 0.0f,1.0, 0.0, 0.0);
glRotated( 0.0f,0.0, 1.0, 0.0);
glRotated( 0.0f,1.0, 0.0, 1.0);
glPushMatrix();

// glBegin(GL_TRIANGLES);
glBegin( GL_TRIANGLE_STRIP );
// glBegin( GL_QUADS );

bool bSwitch=0;
for(int x=0;x <W;x++)
{

for(int z=0;z <=L;z++)
{

//设置三角形A的法向//w
//p1.x=map[x][z].x;
//p1.y=map[x][z].y;
//p1.z=map[x][z].z;
//p2.x=map[x+1][z].x;
//p2.y=map[x+1][z].y;
//p2.z=map[x+1][z].z;
//p3.x=map[x][z+1].x;
//p3.y=map[x][z+1].y;
//p3.z=map[x][z+1].z;
//n=CNormal(p1,p2,p3);
//glNormal3fv(n);
//m_fLBx=float(x)/float(W-1)*128.0f;
//m_fLBy=float(z)/float(L-1)*128.0f;
//m_fRBx=float(x+1.0f)/float(W-1)*128.0f;
//m_fRBy=float(z)/float(L-1)*128.0f;
//m_fRTx=float(x+1.0f)/float(W-1)*128.0f;
//m_fRTy=float(z+1.0f)/float(L-1)*128.0f;
//m_fLTx=float(x)/float(W-1)*128.0f;
//m_fLTy=float(z+1.0f)/float(L-1)*128.0f;

m_fLBx=float(x)/float(W);
m_fLBy=float(z)/float(L);
m_fRBx=float(x+1)/float(W);
m_fRBy=float(z)/float(L);
m_fRTx=float(x+1)/float(W);
m_fRTy=float(z+1)/float(L);
m_fLTx=float(x)/float(W);
m_fLTy=float(z+1)/float(L);
/*
m_fLBx=x*dis;
m_fLBy=z*dis;
m_fRBx=(x+1.0f)*dis;
m_fRBy=z*dis;
m_fRTx=(x+1.0f)*dis;
m_fRTy=(z+1.0f)*dis;
m_fLTx=x*dis;
m_fLTy=(z+1.0f)*dis;
*/
//绘制三角形A
glTexCoord2f(m_fLBx,m_fLBy);
glVertex3f(map[x][z].x,map[x][z].y,map[x][z].z);
glTexCoord2f(m_fRBx,m_fRBy);
glVertex3f(map[x+1][z].x,map[x+1][z].y,map[x+1][z].z);
// glTexCoord2f(m_fRTx,m_fLTy);
// glVertex3f(map[x][z+1].x,map[x][z+1].y,map[x][z+1].z);
//glTexCoord2f(0.0f, 0.0f);
//glVertex3f(map[x][z].x,map[x][z].y,map[x][z].z);
//glTexCoord2f(1.0f, 0.0f);
//glVertex3f(map[x+1][z].x,map[x+1][z].y,map[x+1][z].z);
//glTexCoord2f(1.0f, 1.0f);
//glVertex3f(map[x+1][z+1].x,map[x+1][z+1].y,map[x+1][z+1].z);


//设置三角形B的法向//w
//p1.x=map[x][z+1].x;
//p1.y=map[x][z+1].y;
//p1.z=map[x][z+1].z;
//p2.x=map[x+1][z].x;
//p2.y=map[x+1][z].y;
//p2.z=map[x+1][z].z;
//p3.x=map[x+1][z+1].x;
//p3.y=map[x+1][z+1].y;
//p3.z=map[x+1][z+1].z;
//n=CNormal(p1,p2,p3);
//glNormal3fv(n);

//绘制三角形B
// glTexCoord2f(m_fLTx,m_fLTy);
// glVertex3f(map[x][z+1].x,map[x][z+1].y,map[x][z+1].z);
// glTexCoord2f(m_fRBx,m_fRBy);
// glVertex3f(map[x+1][z].x,map[x+1][z].y,map[x+1][z].z);
// glTexCoord2f(m_fRTx,m_fRTy);
// glVertex3f(map[x+1][z+1].x,map[x+1][z+1].y,map[x+1][z+1].z);
// glTexCoord2f(m_fLTx,m_fLTy);
// glVertex3f(map[x][z+1].x,map[x][z+1].y,map[x][z+1].z);

// glTexCoord2f(m_fLBx,m_fLBy);
// glVertex3f(map[x][z].x,map[x][z].y,map[x][z].z);
//glTexCoord2f(1.0f, 1.0f);
//glVertex3f(map[x+1][z+1].x,map[x+1][z+1].y,map[x+1][z+1].z);
//glTexCoord2f(0.0f, 1.0f);
//glVertex3f(map[x][z+1].x,map[x][z+1].y,map[x][z+1].z);
//glTexCoord2f(0.0f, 0.0f);
//glVertex3f(map[x][z].x,map[x][z].y,map[x][z].z);
}
}
//三角形A和B是相邻的两个三角形,它们组成了一个正方形.该地形就是由100*100个这样的正方形组成的.
glEnd();
glPopMatrix();
glPopMatrix();

glFlush();
glDisable(GL_TEXTURE_2D);

SwapBuffers(m_hDC);

}

int OpenGL::GetPixelHeight()  //返回位图上点(X,Y)的R+G+B值,这也是从网上抄的,本来想的是用rgb值当作高度值,现也没用,先假设y=0呢
{
    HBITMAP  hbmp=(HBITMAP)LoadImage(NULL,m_filename,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION|LR_LOADFROMFILE);  
    CBitmap  cbmp;  
    cbmp.Attach(hbmp);  
    BITMAP  bmp;  
    cbmp.GetBitmap(&bmp);  
    cbmp.Detach();  
    UINT  *  pData  =  new  UINT[bmp.bmWidth  *  bmp.bmHeight];  
    BITMAPINFO  bmpInfo;  
    bmpInfo.bmiHeader.biSize  =  sizeof(BITMAPINFOHEADER);  
    bmpInfo.bmiHeader.biWidth  =  bmp.bmWidth;  
    bmpInfo.bmiHeader.biHeight  =  -bmp.bmHeight;  
    bmpInfo.bmiHeader.biPlanes  =  1;  
    bmpInfo.bmiHeader.biCompression  =  BI_RGB;  
    bmpInfo.bmiHeader.biBitCount  =  32;  

    GetDIBits(m_hDC,hbmp,0,bmp.bmHeight,pData,&bmpInfo,DIB_RGB_COLORS);  
    UINT  color,  r,  g,  b;  
int i=0, j=0;
for(i=0; i <bmp.bmWidth; i++)
{
for(j=0;j <bmp.bmHeight;j++)
{
color=pData[i*bmp.bmHeight+j];
b  =  color  < <  8  >>  24;  
g  =  color  < <  16  >>  24;  
r  =  color  < <  24  >>  24;  
bmpHeight[j]=r;
}
}
  //  for( i  =  0;  i  <  bmp.bmWidth  *  bmp.bmHeight;  i  ++)  

  //  {  
  //      color  =  pData;  
  //      b  =  color  < <  8  >>  24;  
  //      g  =  color  < <  16  >>  24;  
  //      r  =  color  < <  24  >>  24;  
//bmpHeight=r;
//
  //      //note  that  infact,  the  r  is  Blue,  b  =  Red,  
  // //    pData  =  RGB(r,  g,  b);  
  //  }
return 1;
}

就这些,是在vs2005上用vc的一个对话框的picture Control里显示的,如果您看起来不方便,我可以把程序发上来
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-21 16:08

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表