|
我用一个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,v2 IXEL 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里显示的,如果您看起来不方便,我可以把程序发上来 |
|