3D游戏引擎开发工具OpenGL

OpenGL(全写Open Graphics Library)是个定义了一个跨 编程语言 、跨平台的 编程接口 的规格,它用于三维图象(二维的亦可)。OpenGL是个专业的图形 程序接口 ,是一个功能强大,调用方便的底层图形库。
 
Silicon Graphics,Microsoft, HP,Intel达成协议联合开发下一代3D API——Fahrenheit。但不了了之,因为 微软 的打算是把OpenGL的技术用到D3D里并且以此之名驱除OpenGL的威胁。(估计DirectX 8 Graphics即是剩下 微软 独自开发的Fahrenheit,吸收了OpenGL的很多东西。)
OpenGL豪气不减当年!
OpenGL依然是唯一能与微软单独控制的D3D对立的API,尽管 Silicon Graphics 不再以任何微软不能接受的方式推行OpenGL。游戏开发这是独立的,并且很多关键人物在用OpenGL,因此,硬件厂商正努力提高对其支持。D3D仍不能支持高端 图像 和专业应用,而OpenGL主宰着这些土地。在开放原码社区,Mesa项目正提供独立于微软的OpenGL驱动。
 
OpenGL开发游戏引擎
 
方法一:

首先获取位图句柄
HBITMAP hBmp = (HBITMAP) ::LoadImage (AfxGetResourceHandle(),MAKEINTRESOURCE(IDB_BITMAP1), IMAGE_BITMAP, 0, 0,LR_CREATEDIBSECTION);
然后根据位图句柄得到位图信息
BITMAP BM;
::GetObject (hBmp, sizeof (BM), &BM);
最后根据位图信息中的RGB值建立纹理
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, BM.bmWidth, BM.bmHeight,GL_BGR_EXT, GL_UNSIGNED_BYTE,BM.bmBits);
 
方法二:

首先用OpenGL辅助库获得位图信息
 AUX_RGBImageRec* TextureImage[1];
 TextureImage[0]=auxDIBImageLoad("1.bmp");
然后建立纹理
 gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
 
方法三:
从底层做,需要了解bmp文件的结构,首先读取bmp文件结构,包括文件头、信息头和数据,数据用于后面定义纹理;

long ImageWidth=256;
long ImageHeight=256;
GLubyte Image[256][256][3];
void ReadHeader(FILE *fp , BITMAPFH * p_bitmapheader , BITMAPIH *p_bitmapinfo)
{
fseek(fp, 0, SEEK_SET);
fread( &p_bitmapheader->bfType,sizeof(unsigned short), 1, fp );
fseek(fp, 2, SEEK_SET);
fread( &p_bitmapheader->bfSize,sizeof(unsigned long), 1, fp );
fseek(fp, 6, SEEK_SET);
fread( &p_bitmapheader->bfReserved1,sizeof(unsigned short), 1, fp );
fseek(fp, 8, SEEK_SET);
fread( &p_bitmapheader->bfReserved2,sizeof(unsigned short), 1, fp );
fseek(fp, 10, SEEK_SET);
fread( &p_bitmapheader->bfOffBits,sizeof(unsigned long), 1, fp );
fseek(fp, 14, SEEK_SET);
fread( &p_bitmapinfo->biSize, sizeof(unsigned long), 1, fp );
fseek(fp, 18, SEEK_SET);
fread( &p_bitmapinfo->biWidth, sizeof(unsigned long), 1, fp );

fseek(fp, 22, SEEK_SET);
fread( &p_bitmapinfo->biHeight, sizeof(unsigned long), 1, fp );

fseek(fp, 26, SEEK_SET);
fread( &p_bitmapinfo->biPlanes, sizeof(unsigned short), 1, fp );

fseek(fp, 28, SEEK_SET);
fread( &p_bitmapinfo->biBitCount, sizeof(unsigned short), 1, fp );

fseek(fp, 30, SEEK_SET);
fread( &p_bitmapinfo->biCompression, sizeof(unsigned long), 1, fp );

fseek(fp, 34, SEEK_SET);
fread( &p_bitmapinfo->biSizeImage, sizeof(unsigned long), 1, fp );

fseek(fp, 38, SEEK_SET);
fread( &p_bitmapinfo->biXPelsPerMeter, sizeof(unsigned long), 1, fp );

fseek(fp, 42, SEEK_SET);
fread( &p_bitmapinfo->biYPelsPerMeter, sizeof(unsigned long), 1, fp );

fseek(fp, 46, SEEK_SET);
fread( &p_bitmapinfo->biClrUsed, sizeof(unsigned long), 1, fp );
fseek(fp, 50, SEEK_SET);
fread( &p_bitmapinfo->biClrImportant, sizeof(unsigned long), 1, fp );

}
void ReadBitmapFile()
{
BITMAPFH bitmapheader;
BITMAPIH bitmapinfo;
FILE *fp;

fp = fopen("6.bmp" , "r");
if(!fp)
{
puts("Read file failed.");
return;
}

ReadHeader(fp, &bitmapheader , &bitmapinfo);

if(bitmapinfo.biBitCount != 24)
{
puts("UNSUPPORT") ;
return;
}
ImageWidth = bitmapinfo.biWidth;
ImageHeight = bitmapinfo.biHeight;

int i=bitmapheader.bfOffBits;
while(i<bitmapheader.bfSize)
{
for(int j=0;j<ImageWidth;j++)
for(int k=0;k<ImageHeight;k++)
{
fseek(fp, i, SEEK_SET) ;
fread(Image[j][k]+2, 1, 1, fp);
fseek(fp, i+1, SEEK_SET) ;
fread(Image[j][k]+1, 1, 1, fp);
fseek(fp, i+2, SEEK_SET) ;
fread(Image[j][k], 1, 1, fp);

i=i+3;

}

fclose(fp) ;
}
90 glTexImage2D(GL_TEXTURE_2D,0,3,ImageWidth,ImageHeight,0,GL_RGB,GL_UNSIGNED_BYTE,&Image[0][0][0]);

#include <gl\glext.h>
这是因为后面的GL_BGR_EXT是定义在这个头文件里的,因为BMP格式是按Blue,Green,Red顺序储存图像数据的,这与OpenGL中正好相反。GL_BGR_EXT就是完成两者之间的转换的。

下面就是不用AUX库来加载BMP图片作为纹理的函数:

 bool LoadTexture(LPTSTR szFileName, GLuint &texid)      // Creates Texture From A Bitmap File
 {
 HBITMAP hBMP;              // Handle Of The Bitmap
 BITMAP BMP;              // Bitmap Structure
 
 glGenTextures(1, &texid);           // Create The Texture
 hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL), szFileName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE );
 
 if (!hBMP)               // Does The Bitmap Exist?
return FALSE;             // If Not Return False

GetObject(hBMP, sizeof(BMP), &BMP);         // Get The Object
// hBMP:        Handle To Graphics Object
// sizeof(BMP): Size Of Buffer For Object Information
// &BMP:        Buffer For Object Information

glPixelStorei(GL_UNPACK_ALIGNMENT, 4);        // Pixel Storage Mode (Word Alignment / 4 Bytes)

// Typical Texture Generation Using Data From The Bitmap
glBindTexture(GL_TEXTURE_2D, texid);         // Bind To The Texture ID
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Min Filter
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Mag Filter
glTexImage2D(GL_TEXTURE_2D, 0, 3, BMP.bmWidth, BMP.bmHeight, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits);

DeleteObject(hBMP);             // Delete The Object

return TRUE;              // Loading Was Successful
}

 

 

OpenGL加载3d模型:
 
OpenGL.cpp
 

//
#include "stdafx.h"
#include "OpenGL.h"
//
GLfloat r;
CString test;
//
OpenGL::OpenGL()
{ hFont  =CreateFont(-12,0,0,0,400,0,0,0,GB2312_CHARSET,0,0,0,FF_MODERN,"Arial");
 hFont0 =CreateFont(-48,0,0,0,800,0,0,0,GB2312_CHARSET,0,0,0,FF_MODERN,"黑体");
 m_Fram=0;//
 m_Time = timeGetTime();    //
 tim=0;                              //刷屏速度
 Font=new CGLFont() ;
}
OpenGL::~OpenGL()
{ CleanUp();
}
BOOL OpenGL::SetupPixelFormat(HDC hDC0)//检测安装OpenGL
{ int nPixelFormat;       // 象素点格式
 hDC=hDC0;
 PIXELFORMATDESCRIPTOR pfd = {
     sizeof(PIXELFORMATDESCRIPTOR),    // pfd结构的大小
     1,                                // 版本号
     PFD_DRAW_TO_WINDOW |              // 支持在窗口中绘图
     PFD_SUPPORT_OPENGL |              // 支持 OpenGL
     PFD_DOUBLEBUFFER,                 // 双缓存模式
     PFD_TYPE_RGBA,                    // RGBA 颜色模式
     16,                               // 24 位颜色深度
     0, 0, 0, 0, 0, 0,                 // 忽略颜色位
     0,                                // 没有非透明度缓存
     0,                                // 忽略移位位
     0,                                // 无累加缓存
     0, 0, 0, 0,                       // 忽略累加位
     16,                               // 32 位深度缓存    
     0,                                // 无模板缓存
     0,                                // 无辅助缓存
     PFD_MAIN_PLANE,                   // 主层
     0,                                // 保留
     0, 0, 0                           // 忽略层,可见性和损毁掩模
 };
 if (!(nPixelFormat = ChoosePixelFormat(hDC, &pfd)))
  { MessageBox(NULL,"没找到合适的显示模式","Error",MB_OK|MB_ICONEXCLAMATION);
       return FALSE;
  }
 SetPixelFormat(hDC,nPixelFormat,&pfd);//设置当前设备的像素点格式
 hRC = wglCreateContext(hDC);          //获取渲染描述句柄
 wglMakeCurrent(hDC, hRC);             //激活渲染描述句柄

 m_baiscobj=new baiscobj();
 m_baiscobj->light0();

 return TRUE;
}
void OpenGL::init(int Width, int Height)
{ glViewport(0,0,Width,Height);   // 设置OpenGL视口大小。 
 glMatrixMode(GL_PROJECTION);   // 设置当前矩阵为投影矩阵。
 glLoadIdentity();      // 重置当前指定的矩阵为单位矩阵
 gluPerspective       // 设置透视图
  ( 54.0f,       // 透视角设置为 45 度
    (GLfloat)Width/(GLfloat)Height, // 窗口的宽与高比
    0.1f,        // 视野透视深度:近点1.0f
    3000.0f       // 视野透视深度:始点0.1f远点1000.0f
  );
 // 这和照象机很类似,第一个参数设置镜头广角度,第二个参数是长宽比,后面是远近剪切。
 glMatrixMode(GL_MODELVIEW);    // 设置当前矩阵为模型视图矩阵
 glLoadIdentity();      // 重置当前指定的矩阵为单位矩阵
// 
//====================================================
}
void OpenGL::Render()//OpenGL图形处理
{ glClearColor(0.0f, 0.0f, 0.3f, 1.0f);    // 设置刷新背景色
 glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);// 刷新背景
 glLoadIdentity();         // 重置当前的模型观察矩阵
//
 m_baiscobj->DisplayScene(); 
 m_baiscobj->CreateSkyBox(3,6,3,6);
 m_baiscobj->DrawSand(); 
 srand(100);
 for(int i=0;i<300;i++)
 {float x= RAND_COORD((MAP_W-1)*MAP_SCALE);
  float z= RAND_COORD((MAP_W-1)*MAP_SCALE);
  float size=4.0f+rand()%4; 
  float h=-size/10; 
  int   cactus=rand()%4+11;
  m_baiscobj->ShowTree(x,z,size,h,cactus);
 }
 m_baiscobj->picter(MAP+10,0,-MAP); 
 m_baiscobj->Scene(0,MAP+30,13.6f,-MAP-20, 0,   0,0.35f);
 m_baiscobj->Scene(1,MAP+30,19.0f,-MAP,   100,   r,0.2f);
 m_baiscobj->Scene(2,MAP+30,20.0f,-MAP,   165,r+90,0.5f);
//
 text();
 SwapBuffers(hDC);         // 切换缓冲区
}
void OpenGL::CleanUp()
{  wglMakeCurrent(hDC, NULL);                       //清除OpenGL
  wglDeleteContext(hRC);                           //清除OpenGL

}
///
void OpenGL::text()
{ DWORD Dura =(timeGetTime()-m_Time)/1000;
 if(Dura>0) tim=m_Fram/Dura;
 m_Fram++;
 char str[128];
 sprintf(str, "刷屏: %2d 帧/秒 %s",tim,test);
 Font->settext(350,550,str,hFont,1,1,1.0f);
 Font->settext(419,258,"+",hFont,1,0,0);
}

OpenGL.h
 

// OpenGL.h: interface for the OpenGL class.
//
//

#if !defined(AFX_OPENGL_H__17B7289C_7956_41C5_89B9_621E3C435389__INCLUDED_)
#define AFX_OPENGL_H__17B7289C_7956_41C5_89B9_621E3C435389__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "baiscobj.h"
#include "GLFont.h"
class OpenGL 
{ public: OpenGL();
 virtual ~OpenGL();
 public:
 baiscobj* m_baiscobj;
 HDC  hDC;   // GDI设备描述表
 HGLRC hRC;      // 永久着色描述表
 BOOL SetupPixelFormat(HDC hDC);
 void init(int Width, int Height);
 void Render();
 void CleanUp();
/
 CGLFont* Font;
 int  m_Time,m_Fram,tim;
 HFONT hFont,hFont0;
 void text();
};

#endif // !defined(AFX_OPENGL_H__17B7289C_7956_41C5_89B9_621E3C435389__INCLUDED_)

 

GLFont.h

 

// GLFont.h: interface for the CGLFont class.

#if !defined(AFX_GLFONT_H__88F1F000_50F5_452A_B95E_60ED83712FA5__INCLUDED_)
#define AFX_GLFONT_H__88F1F000_50F5_452A_B95E_60ED83712FA5__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class CGLFont 
{
public:
 void entext(float x,float y, LPCTSTR str,HFONT hFont,float r,float g,float b);
 void c3dtext(LPCTSTR str,HFONT hFont,float z);
 void Printfc3d(CString strText,HFONT hFont,float z=0.05f);
 void Printftext(int x, int y, LPCTSTR lpszText,HFONT hFont);
 void settext(float x,float y,CString str,HFONT Font,float r,float g,float b);

 CGLFont();
 virtual ~CGLFont();
protected:
 HFONT hFont;
};

#endif // !defined(AFX_GLFONT_H__88F1F000_50F5_452A_B95E_60ED83712FA5__INCLUDED_)

 

GLFont.cpp
 

#include "stdafx.h"

#include "GLFont.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
//unsigned int Base;
//

CGLFont::CGLFont()
{
}
CGLFont::~CGLFont()
{
}
void CGLFont::entext( float x,float y, LPCTSTR str, HFONT hFont,
       float r, float g, float b)
{  HDC hdc = wglGetCurrentDC(); 
 SelectObject(hdc, hFont);
 unsigned int Base = glGenLists(96);
 wglUseFontBitmaps(hdc, 32, 96,Base);
 glDisable(GL_TEXTURE_2D);
 glDisable(GL_LIGHTING);
 glPushAttrib(GL_LIST_BIT); 
 glColor3f(r,g,b);
 glRasterPos2f(x/100, y/100);
  glListBase(Base - 32);
  glCallLists(strlen(str), GL_UNSIGNED_BYTE, str);
 glPopAttrib();
 glEnable(GL_LIGHTING);
 glEnable(GL_TEXTURE_2D);
 glDeleteLists(Base, 96);
}

//
void CGLFont::c3dtext(LPCTSTR str,HFONT hFont,float z)
{ glDisable(GL_TEXTURE_2D);
 glDisable(GL_LIGHTING);
 Printfc3d("立体汉字",hFont,z);
 glEnable(GL_LIGHTING);  
 glEnable(GL_TEXTURE_2D);
}
void CGLFont::Printfc3d(CString strText,HFONT hFont,float z)
{ HDC hdc = wglGetCurrentDC();
 HFONT hOldFont=(HFONT)::SelectObject(hdc,hFont);
 UCHAR * pChar=(UCHAR*)strText.GetBuffer(strText.GetLength());
 int   nListNum; 
 DWORD dwChar; 
 GLYPHMETRICSFLOAT pgmf[1];
 glPushMatrix();  
 for(int i = 0; i < strText.GetLength(); i++)
 { if(IsDBCSLeadByte((BYTE)pChar[i]))
  { dwChar=(DWORD)((pChar[i]<<8)|pChar[i+1]);
    i++;
  }
   else dwChar = pChar[i];
   nListNum = glGenLists(1); 
   wglUseFontOutlines( hdc, 
        dwChar, 
        1,
        nListNum, 
        0.0f,
        z,
        WGL_FONT_POLYGONS,
        pgmf 
      );
   glCallList(nListNum); 
   glDeleteLists(nListNum, 1);  
 } 
 glPopMatrix();   
 strText.ReleaseBuffer();
 ::SelectObject(hdc,hOldFont);
}

void CGLFont:: settext (float x,float y,CString str,HFONT Font,float r,float g,float b)
 
{   glLoadIdentity();
 glPushAttrib(GL_CURRENT_BIT);
 glDisable(GL_TEXTURE_2D);
 glDisable(GL_LIGHTING);
 glColor3f(r,g,b); 
   glTranslatef(-(420-x)/800,(260-y)/600,-1.0f);
   Printftext (0,0, str,Font);   
 glEnable(GL_LIGHTING);    
 glEnable(GL_TEXTURE_2D);
 glPopAttrib();
}
void CGLFont:: Printftext (int x, int y, LPCTSTR lpszText,HFONT hFont)
{ CBitmap bitmap;
  BITMAP bm;
  SIZE size;
  HDC MDC = ::CreateCompatibleDC(0);
  SelectObject(MDC,hFont); 
  ::GetTextExtentPoint32(MDC,lpszText,strlen(lpszText),&size);
  bitmap.CreateBitmap(size.cx, size.cy, 1, 1, NULL);
  HBITMAP oldBmp=(HBITMAP)SelectObject(MDC,bitmap);
  SetBkColor  (MDC, RGB(0,     0,   0));
  SetTextColor(MDC, RGB(255, 255, 255));
  TextOut(MDC, 0, 0, lpszText, strlen(lpszText));
  bitmap.GetBitmap(&bm);
  size.cx = (bm.bmWidth + 31) & (~31);
  int bufsize =size.cy * size.cx;
  struct {  BITMAPINFOHEADER bih;
   RGBQUAD col[2];
    }bic;
  BITMAPINFO *binf = (BITMAPINFO *)&bic;
  binf->bmiHeader.biSize     = sizeof(binf->bmiHeader);//
  binf->bmiHeader.biWidth    = bm.bmWidth;
  binf->bmiHeader.biHeight   = bm.bmHeight;
  binf->bmiHeader.biPlanes   = 1;  
  binf->bmiHeader.biBitCount = 1;
  binf->bmiHeader.biCompression = BI_RGB;
  binf->bmiHeader.biSizeImage   = bufsize;
  UCHAR* Bits = new UCHAR[bufsize]; 
  ::GetDIBits(MDC,bitmap,0,bm.bmHeight,Bits,binf,DIB_RGB_COLORS);
                                     
  glPixelStorei(GL_UNPACK_ALIGNMENT ,1);
  glRasterPos2i(x,y);
  glBitmap(size.cx,size.cy,0,0,0,0,Bits);
  delete Bits;   
  SelectObject(MDC, oldBmp); 
  ::DeleteDC(MDC);
}

BAISCOBJ.H
 

// baiscobj.h: interface for the baiscobj class.
//
//

#if !defined(AFX_BAISCOBJ_H__6F90C6A0_F5E4_4482_BA6B_136D5C922B31__INCLUDED_)
#define AFX_BAISCOBJ_H__6F90C6A0_F5E4_4482_BA6B_136D5C922B31__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class baiscobj 
{
public:
 baiscobj();
 virtual ~baiscobj();
public:
 float  g_terrain [MAP_W*MAP_W][3];
 GLuint  g_index  [MAP_W*MAP_W* 2];
 float  g_texcoord [MAP_W*MAP_W][2];
 void  InitTerrain(float h); 
 void  DrawSand(); 
 float  GetHeight(float x, float z);

 float     g_eye [3];
 float     g_look[3];
 float     rad_xz; 
 float     g_Angle;
 float     g_elev; 
 BOOL  DisplayScene(); 

 UINT  g_cactus[16];
 BITMAPINFOHEADER  g_bit;
 unsigned char    *g_imageData;
 void  CreateSkyBox(int a,int wi,int he,int le);
 void  texture(UINT textur);
 void  light0();   

 void  picter(float x,float y,float z);
 bool  LoadT8(char *filename, GLuint &texture);
 void  LoadT16(char *filename, GLuint &texture);
 unsigned char* LoadBit(char *filename, BITMAPINFOHEADER *bitmap);

 void  ShowTree(float x,float z,float h,float s,int cactus);
 void  ShowTree0(float x,float z,float h,float s,int cactus);

 CLoad3DS* m_3ds;
 void load3dobj(char* dir,char* cn,int a);
 void Scene(int obj,float x,float h,float z,float r,int re,float size);
};

#endif // !defined(AFX_BAISCOBJ_H__6F90C6A0_F5E4_4482_BA6B_136D5C922B31__INCLUDED_)

 
BAISCOBJ.CPP
 

#include "stdafx.h"
#include "baiscobj.h"
#include "../include/BITMAP.H"

extern GLfloat r;
float  gao=1.8f;
extern CString test;
//
baiscobj::baiscobj()
{ g_eye[0]= MAP;//
 g_eye[2]=-MAP;//
 g_Angle=0;//
 g_elev=-0;//

 char appdir[256];
 GetCurrentDirectory(256,appdir);
 CString dir=appdir;
 if(dir.Right(8)!="运行程序")
 SetCurrentDirectory("../运行程序");

 g_imageData = LoadBit("data/images/Terrain1.bmp",&g_bit); //调等高地形图
 LoadT8("data/images/sand0.bmp",  g_cactus[0]); //地面帖图
 LoadT8("data/images/4RBack.bmp",g_cactus[2]); //天空贴图后
 LoadT8("data/images/4Front.bmp",g_cactus[3]); //天空贴图前
 LoadT8("data/images/4Top.bmp",  g_cactus[4]); //天空贴图顶
 LoadT8("data/images/4Left.bmp", g_cactus[5]); //天空贴图左
 LoadT8("data/images/4Right.bmp",g_cactus[6]); //天空贴图右
 LoadT16("data/images/CACTUS0.BMP",g_cactus[11]);    //树1帖图
 LoadT16("data/images/CACTUS1.BMP",g_cactus[12]);    //树2帖图
 LoadT16("data/images/CACTUS2.BMP",g_cactus[13]);    //树3帖图
 LoadT16("data/images/CACTUS3.BMP",g_cactus[14]);    //树4帖图
 InitTerrain(5);//初始化地面
 m_3ds=new CLoad3DS();
 load3dobj("data/3ds/","航天发射台.3DS",0);
 load3dobj("data/3ds/","直升机0.3ds",1);//car.3ds
 load3dobj("data/3ds/","飞机1.3ds",2);//car.3ds
 glEnable(GL_TEXTURE_2D);
}
baiscobj::~baiscobj()
{ for(int i=0;i<16;i++) glDeleteTextures(1, &g_cactus[i]);
 glDisableClientState(GL_VERTEX_ARRAY);
 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
void baiscobj::light0()
{ GLfloat light_position[] = {1.0,5.0,1.0,1.0};
 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);
 glEnable(GL_DEPTH_TEST);
 glEnable(GL_COLOR_MATERIAL);
}
BOOL baiscobj::DisplayScene()
{ float speed=0.5f;
  float x=g_eye[0],y=g_eye[2],z=g_eye[2];
  if (KEY_DOWN(VK_SHIFT))  speed   =speed*2;
  if (KEY_DOWN(VK_LEFT))   g_Angle-=speed*2;
  if (KEY_DOWN(VK_RIGHT))  g_Angle+=speed*2;
  rad_xz = float (3.13149* g_Angle/180.0f);
  if (KEY_DOWN(33))     g_elev +=speed;
  if (KEY_DOWN(34))     g_elev -=speed;
  if (g_elev<-360)     g_elev  =-360;
  if (g_elev> 360)     g_elev  = 360;
  if (KEY_DOWN(VK_UP)) 
  { g_eye[2]+=(float)sin(rad_xz)*speed; 
    g_eye[0]+=(float)cos(rad_xz)*speed; 
  }
  if (KEY_DOWN(VK_DOWN))
  { g_eye[2]-=(float)sin(rad_xz)*speed; 
    g_eye[0]-=(float)cos(rad_xz)*speed; 
  }
  if(g_eye[0]<  MAP_SCALE)   g_eye[0]=  MAP_SCALE;
  if(g_eye[0]> (MAP_W-2)*MAP_SCALE) g_eye[0]= (MAP_W-2)*MAP_SCALE;
  if(g_eye[2]<-(MAP_W-2)*MAP_SCALE) g_eye[2]=-(MAP_W-2)*MAP_SCALE;
  if(g_eye[2]> -MAP_SCALE)   g_eye[2]= -MAP_SCALE;
  g_eye[1] =GetHeight((float)g_eye[0],(float)g_eye[2])+gao;
  g_look[0] = (float)(g_eye[0] +100*cos(rad_xz));
  g_look[2] = (float)(g_eye[2] +100*sin(rad_xz));
  g_look[1] = g_eye[1] +g_elev; 
  gluLookAt(g_eye[0],g_eye[1],g_eye[2],
   g_look[0],g_look[1],g_look[2],
   0.0,1.0,0.0 
     );
  int r0=abs((int)g_Angle);
  test.Format("[方位=%03d X=%3.0f y=%3.0f 高=%2.1f 俯仰角=%2.0f,re=%03.0f]",
    r0%360,g_eye[0],-g_eye[2],g_eye[1],g_elev,r);
  return TRUE;
}
//==========================================================================
void baiscobj::InitTerrain(float h)
{ int index = 0;
  int Vertex;
  for (int z = 0; z < MAP_W; z++)
   for (int x = 0; x < MAP_W; x++)
    { Vertex = z * MAP_W + x;
      g_terrain [Vertex][0] = float(x)*MAP_SCALE;
      g_terrain [Vertex][1] = (float)(g_imageData[(z*MAP_W+x)*3]/3);
      g_terrain [Vertex][2] = -float(z)*MAP_SCALE;
      g_texcoord[Vertex][0] = (float) x;
     g_texcoord[Vertex][1] = (float) z; 
     g_index [index++] = Vertex;
     g_index [index++] = Vertex+ MAP_W;
   }
  glEnableClientState(GL_VERTEX_ARRAY); 
  glVertexPointer    (3,GL_FLOAT,0,g_terrain);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glTexCoordPointer  (2,GL_FLOAT,0,g_texcoord);
}
void baiscobj::DrawSand()
{ glBindTexture(GL_TEXTURE_2D, g_cactus[0]);
  glTexEnvf    (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  for (int z = 0; z < MAP_W-1; z++)
    glDrawElements(GL_TRIANGLE_STRIP,MAP_W*2,GL_UNSIGNED_INT,&g_index[z*MAP_W*2]);
}
float baiscobj::GetHeight(float x, float z)
{  float CameraX = x/MAP_SCALE;
 float CameraZ =-z/MAP_SCALE; 
 int Col0 = int(CameraX); 
 int Row0 = int(CameraZ);
 int Col1 = Col0 + 1;
 int Row1 = Row0 + 1;
 if (Col1 > MAP_W) Col1 = 0;
 if (Row1 > MAP_W) Row1 = 0;
 float h00=g_terrain[Col0 + Row0*MAP_W][1];
 float h01=g_terrain[Col1 + Row0*MAP_W][1];
 float h11=g_terrain[Col1 + Row1*MAP_W][1];
 float h10=g_terrain[Col0 + Row1*MAP_W][1];
 float tx =CameraX - int(CameraX);
 float ty =CameraZ - int(CameraZ);
 float txty = tx * ty;
 return h00*(1.0f-ty-tx+txty)
   + h01*(tx-txty)
   + h11*txty
   + h10*(ty-txty);
}
void baiscobj::CreateSkyBox(int a,int wi,int he,int le)
{ float width =MAP*wi;
 float height=MAP*he;
 float length=MAP*le;
 float x = MAP  -width /2;
 float y = MAP/a-height/2;
 float z = -MAP -length/2;
///
 texture(g_cactus[2]);
 glBegin(GL_QUADS);
  glTexCoord2f(1.0f,0.0f); glVertex3f(x+width,y,   z);
  glTexCoord2f(1.0f,1.0f); glVertex3f(x+width,y+height,z);
  glTexCoord2f(0.0f,1.0f); glVertex3f(x,  y+height,z);
  glTexCoord2f(0.0f,0.0f); glVertex3f(x,  y,   z);
 glEnd();
 texture(g_cactus[3]);
 glBegin(GL_QUADS);
  glTexCoord2f(1.0f,0.0f); glVertex3f(x,  y,   z+length);
  glTexCoord2f(1.0f,1.0f); glVertex3f(x,  y+height,z+length);
  glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z+length);
  glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y,   z+length);
 glEnd();

 texture(g_cactus[4]);
 glBegin(GL_QUADS); 
  glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z);
  glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y+height,z+length);
  glTexCoord2f(1.0f,0.0f); glVertex3f(x,  y+height,z+length);
  glTexCoord2f(1.0f,1.0f); glVertex3f(x,  y+height,z);
 glEnd();
 texture(g_cactus[5]);
 glBegin(GL_QUADS);
  glTexCoord2f(1.0f,1.0f); glVertex3f(x,  y+height,z); 
  glTexCoord2f(0.0f,1.0f); glVertex3f(x,  y+height,z+length);
  glTexCoord2f(0.0f,0.0f); glVertex3f(x,  y,   z+length);
  glTexCoord2f(1.0f,0.0f); glVertex3f(x,  y,   z);  
 glEnd();
 texture(g_cactus[6]);
 glBegin(GL_QUADS);
  glTexCoord2f(0.0f,0.0f); glVertex3f(x+width,y,   z);
  glTexCoord2f(1.0f,0.0f); glVertex3f(x+width,y,   z+length);
  glTexCoord2f(1.0f,1.0f); glVertex3f(x+width,y+height,z+length);
  glTexCoord2f(0.0f,1.0f); glVertex3f(x+width,y+height,z);
 glEnd();
}
void baiscobj::texture(UINT textur)
{ glBindTexture  (GL_TEXTURE_2D, textur);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
}
//==========================================================================
void baiscobj::picter(float x,float y,float z)
{y=GetHeight(x,z);
glDisable(GL_TEXTURE_2D);
 glPushAttrib(GL_CURRENT_BIT);
 glPushMatrix();
 glTranslatef(x,y+0.5f,z);
 glColor3f(0.0f,1.0f,0.2f);
 auxSolidCube(1);
 glTranslatef(0.0f,0.8f,0.0f);
 glColor3f(0.0f,0.0f,1.0f);
 auxSolidBox(.2f,1.3f,.2f);
 glPopMatrix();
 glPushMatrix();
 glTranslatef(x,y+2.5f,z);
 glRotatef(r-90,0.0,1.0,0.0);
 //=======================================
 glColor3f(1.0f,1.0f,1.0f);
 glRotatef(45, 1.0, 0.0, 0.0);
 auxWireCone(1.5,0.6f); 
 //=======================================
 glRotatef(180, 1.0, 0.0, 0.0);
 glTranslatef(0.0f,0.0f,-0.7f);
 auxWireCone(0.2f,2.0f); 
 glColor3f(FRAND,0,0);
 glTranslatef(0.0f,0.0f,2.0f);
 auxSolidSphere(0.1f);
 glPopMatrix();
 glPushMatrix();
 glTranslatef(x,y+10.0f,z);
 glRotatef(r, 0.0, 1.0, 0.0);
 glTranslatef(x/15,0,0);
 //=============================================
 glColor3f(1.0f,0.0f,0.0f);
 glRotatef(180, 0.0, 1.0, 0.0);
 auxSolidCone(.2,0.6);
 //=============================================
 glColor3f(1.0f,1.0f,1.0f);
 glRotatef(90, 1.0, 0.0, 0.0);
 glTranslatef(0.0f,-1.0f,0); 
 auxSolidCylinder(.2f,1);
 glRotatef(-270, 1.0, 0.0, 0.0);
 glColor3f(FRAND+.6f,0.2f,0.0f);
 glTranslatef(0.0f,-0.0f,-0.2f);
 auxSolidCone(.2,1.5);
 glPopMatrix();
 glEnable(GL_TEXTURE_2D);
 glPopAttrib();
 r+=1.0f;if(r>360) r=0;
 glEnable(GL_TEXTURE_2D);
}
bool baiscobj::LoadT8(char *filename, GLuint &texture)
{ AUX_RGBImageRec *pImage = NULL;
 pImage = auxDIBImageLoad(filename);
 if(pImage == NULL)  return false;
 glGenTextures(1, &texture); 
 glBindTexture    (GL_TEXTURE_2D,texture);
 gluBuild2DMipmaps(GL_TEXTURE_2D,4, pImage->sizeX,
       pImage->sizeY,GL_RGB, GL_UNSIGNED_BYTE,pImage->data);
 free(pImage->data);
 free(pImage); 
 return true;
}
void baiscobj::LoadT16(char *filename, GLuint &texture)
{ glGenTextures(1, &texture); 
  glBindTexture(GL_TEXTURE_2D, texture);
  BITMAPINFOHEADER bitHeader;
  unsigned char *buffer; 
  buffer=LoadBitmapFileWithAlpha(filename,&bitHeader);
  gluBuild2DMipmaps ( GL_TEXTURE_2D, 
       4,   
       bitHeader.biWidth,
       bitHeader.biHeight,
       GL_RGBA,
       GL_UNSIGNED_BYTE,
       buffer 
     );
  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_MIN_FILTER,GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
  free(buffer); 
}
unsigned char * baiscobj::LoadBit(char *filename, BITMAPINFOHEADER *bitmap)
{ FILE *filePtr; 
  BITMAPFILEHEADER  Header;
  unsigned char    *Image;
  unsigned int      imageIdx = 0;
  unsigned char     tempRGB; 
  filePtr = fopen(filename, "rb");
  if (filePtr == NULL)    return NULL;
  fread(&Header, sizeof(BITMAPFILEHEADER), 1, filePtr);
  if (Header.bfType != BITMAP_ID)
  { fclose(filePtr);
    return NULL;
  }
  fread(bitmap, sizeof(BITMAPINFOHEADER), 1, filePtr);
  fseek(filePtr, Header.bfOffBits, SEEK_SET);
  Image = (unsigned char*)malloc(bitmap->biSizeImage);
  if (!Image)
  { free(Image);
    fclose(filePtr);
    return NULL;
  }
  fread(Image, 1, bitmap->biSizeImage, filePtr);
  if (Image == NULL)
  { fclose(filePtr);
    return NULL;
  }
  for (imageIdx = 0; imageIdx < bitmap->biSizeImage; imageIdx+=3)
  { tempRGB = Image[imageIdx];
    Image[imageIdx] = Image[imageIdx + 2];
    Image[imageIdx + 2] = tempRGB;
  }
  fclose(filePtr);
  return Image;
}
/
void baiscobj::ShowTree(float x,float z,float h,float s,int cactus)
{ glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_ALPHA_TEST);
  glAlphaFunc(GL_GREATER, 0);
  float mat[16];
  glGetFloatv(GL_MODELVIEW_MATRIX, mat);
  vector3_t X(mat[0], mat[4], mat[8]);
  vector3_t Z(mat[1], mat[5], mat[9]);
  glBindTexture(GL_TEXTURE_2D, g_cactus[cactus]);
  vector3_t pos(x,0.0,-z);
  pos.y = GetHeight(x, -z) + h + s;
  glBegin(GL_QUADS);
  glTexCoord2f(0.0,0.0);glVertex3fv((pos+(X+Z)*-h).v);//左下点
  glTexCoord2f(1.0,0.0);glVertex3fv((pos+(X-Z)* h).v);//右下点
  glTexCoord2f(1.0,1.0);glVertex3fv((pos+(X+Z)* h).v);//右上点
  glTexCoord2f(0.0,1.0);glVertex3fv((pos+(Z-X)* h).v);//左上点
  glEnd();
  glDisable(GL_ALPHA);
  glDisable(GL_BLEND);
}
void baiscobj::ShowTree0(float x,float z,float h,float s,int cactus)
{ glPushMatrix();//
  float y = GetHeight(x,-z) + h + s;
  glTranslatef(x,y, -z);
  glRotatef(180, 1.0, 0.0, 0.0);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glEnable(GL_ALPHA_TEST);
  glAlphaFunc(GL_GREATER, 0);
 glBindTexture(GL_TEXTURE_2D, g_cactus[cactus]);
// glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);//
 glBegin(GL_QUADS);
  glTexCoord2f(1.0f, 0.0f); glVertex3f(-h, h, 0.0f);  // 右上点
  glTexCoord2f(0.0f, 0.0f); glVertex3f( h, h, 0.0f);  // 右上点
  glTexCoord2f(0.0f, 1.0f); glVertex3f( h,-h, 0.0f);  // 右下点
  glTexCoord2f(1.0f, 1.0f); glVertex3f(-h,-h, 0.0f);  // 左下点
 glEnd();
  glDisable(GL_ALPHA);
  glDisable(GL_BLEND);
  glPopMatrix();
}

void baiscobj::load3dobj(char* dir,char* cn,int a)
{ char appdir[256];
 GetCurrentDirectory(256,appdir);
 SetCurrentDirectory(dir);
 m_3ds->Init(cn,a);
 SetCurrentDirectory(appdir);
}
void baiscobj::Scene(int obj,float x,float h,float z,float r,int re,float size)
{
  glPushMatrix();
  int y=GetHeight(x,z)+h;
  glTranslatef(x,y,z);
  glRotatef(re, 0.0, 1.0, 0.0);
  if(obj>0) glRotatef(-20, 1.0, 0.0, 0.0);
  m_3ds->show3ds(obj,0,0.0f,r,size);
  glPopMatrix();
}

 
main.cpp
 

#include "stdafx.h"
#include "OpenGL.h"
//
OpenGL* m_OpenGL;
HDC  hDC;  // GDI设备句柄,将窗口连接到 GDI( 图形设备接口)
HGLRC hRC=NULL; // 渲染描述句柄,将OpenGL调用连接到设备描述表
HWND hWnd=NULL; // 保存 Windows 分配给程序的窗口句柄
int  Width = 800;// 窗口宽
int  Height= 600;// 窗口高
int  bits  = 16; // 颜色深度


void GameLoop()
{   MSG msg;
    BOOL fMessage;
    PeekMessage(&msg, NULL, 0U, 0U, PM_NOREMOVE);
    while(msg.message != WM_QUIT) // 消息循环
    {   fMessage = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
        if(fMessage)    //有消息
   { TranslateMessage(&msg);
              DispatchMessage(&msg);
   }
        else  m_OpenGL->Render(); //无消息
    }
}
LRESULT WINAPI MsgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam )// 消息处理
{ switch(message)
 { case WM_CREATE:      // 建立窗口
   hDC = GetDC(hWnd);    // 获取当前窗口的设备句柄
   m_OpenGL->SetupPixelFormat(hDC);// 调用显示模式安装功能
   return 0;  break;
  case WM_CLOSE:      // 关闭窗口
   m_OpenGL->CleanUp();   // 结束处理
   PostQuitMessage(0);
   return 0;  break;
  case WM_SIZE:      // 窗口尺寸变化
   Height = HIWORD(lParam);  // 窗口的高
   Width  = LOWORD(lParam);  // 窗口的宽
   if (Height==0) Height=1;  // 防止被0 除
   m_OpenGL->init(Width,Height);
   return 0;  break;
  case WM_DESTROY:     // 退出消息
            PostQuitMessage(0);
            return 0;  break;

        case WM_KEYUP:      // 按ESC退出,全屏模式必需要加入的退出方式。
            switch (wParam)
            { case VK_ESCAPE:
     m_OpenGL->CleanUp(); // 结束处理
        PostQuitMessage(0);
        return 0;break;
            }
  default:   break;
 }
 return (DefWindowProc(hWnd, message, wParam, lParam));
}
INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,INT )// WinMain程序入口
{   // 注册窗口类
 bool fullScreen =TRUE;
 DWORD dwExStyle;  // Window 扩展风格
 DWORD dwStyle;  // Window 窗口风格
 RECT windowRect;  // 窗口尺寸
 int  nX=0,nY=0;
/* if (MessageBox(NULL,"使用全屏模式吗?", "将进入OpenGL,选择显示模式",
             MB_YESNO|MB_ICONQUESTION|MB_SYSTEMMODAL)==IDNO)
  {fullScreen =false;}   // 选择窗口模式
 if (fullScreen)      // 选择全屏模式
 { DEVMODE dmScr;     // 设备模式
  memset(&dmScr,0,sizeof(dmScr)); // 确保内存分配
  dmScr.dmSize=sizeof(dmScr);  // Devmode 结构的大小
  dmScr.dmPelsWidth = Width;  // 屏幕宽
  dmScr.dmPelsHeight= Height;  // 屏幕高
  dmScr.dmBitsPerPel= 16;   // 色彩深度
  dmScr.dmDisplayFrequency=75; // 刷屏速度
  dmScr.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT|DM_DISPLAYFREQUENCY;
  if (ChangeDisplaySettings(&dmScr, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
   {fullScreen=FALSE;}
  dwExStyle=WS_EX_APPWINDOW;  // Window 扩展风格
  dwStyle=WS_POPUP;    // Window 窗口风格
  ShowCursor(FALSE);    // 隐藏鼠标
 }
 else*/
 { dwExStyle=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE; // 使窗口具有3D外观
  dwStyle=WS_OVERLAPPEDWINDOW;    // 使用标准窗口
  //WS_OVERLAPPEDWINDOW是有标题栏,窗口菜单,最大、小化按钮和可调整尺寸的窗口
  int wid=GetSystemMetrics(SM_CXSCREEN);  // 获取当前屏幕宽
  int hei=GetSystemMetrics(SM_CYSCREEN);  // 获取当前屏幕高
  nX=(wid-Width)/2;nY=(hei-Height)/2;   // 计算窗口居中用
 }
//-------------------------------------------------------------------
 AdjustWindowRectEx(&windowRect,dwStyle,FALSE,dwExStyle);
         //根据窗口风格来调整窗口尺寸达到要求的大小
 char cc[]="tml";
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L, 0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                      cc, NULL };
    RegisterClassEx( &wc );
 m_OpenGL=new OpenGL();//
 hWnd = CreateWindowEx(NULL,cc,"学OpenGL编3D游戏 [ 8.显示3D模型 ]          键盘(↑进 ↓退 →右 ←左 UP仰 DOWM俯)",
        dwStyle|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
        nX, nY,Width, Height,
        NULL,NULL,hInst,NULL); // 创建窗口
 ShowWindow( hWnd, SW_SHOWDEFAULT );    // 显示窗口
 UpdateWindow( hWnd );       // 刷新窗口
 GameLoop();          // 进入消息循环
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书共分两篇,第一篇介绍了Android 3D游戏开发的基础知识,主要对OpenGL ES的相关内容进行了介绍。   章 名主 要 内 容   第1章 英雄还看今朝—Android简介本章介绍了市场上主流的手机平台,同时也分析了未来手机平台的发展趋势及Android平台的前景   第2章 数风流人物—当前流行游戏类型简介本章以分类的方式简要地介绍了当前流行的游戏的玩法,游戏的视觉效果,游戏的设计及《仙剑》等著名游戏的历史   第3章 不积跬步,无以至千里—游戏开发基础知识本章初步介绍了游戏开发的基础知识   第4章 千里之行,始于足下—3D开发基础知识本章介绍了3D开发中的基础知识,包括OpenGL ES的介绍及OpenGL ES中绘制模型的原理,并通过点、线和三角形的绘制介绍了OpenGL ES中模型的几种绘制方式。最后介绍了3D场景中常用的两种投影方式,并通过例子比较了这两种投影的区别   第5章 愿君多采撷,此物最相思—光照效果的开发本章介绍了光照的基础知识,包括环境光、散射光及镜面光   第6章 为伊消得人憔悴——纹理映射本章主要介绍了纹理的基础知识,以及纹理的不同拉伸方式和纹理过滤高级技术,从绘制三角形开始到绘制地月系,可能会经历很长时间,但是这对以后的学习是有帮助的   第7章 海阔凭鱼跃,天高任鸟飞—3D基本形状的构建在本章中介绍了圆柱体、圆锥体、圆环、抛物面、双曲面和螺旋面在OpenGL ES中的渲染方法。这些基本形状在3D世界中应用广泛,在构造一些复杂物体时,经常会运用这些基本形状来进行拼装组合   第8章 执子之手,与子偕老—坐标变换本章介绍了坐标变换的应用。绘制3D场景的过程,主要是旋转和平移操作的组合,通过合理的堆栈操作,就比较容易绘制出所需的3D场景   第9章 孤帆远影碧空尽—摄像机与雾特效在本章中,首先对摄像机及其配置做了介绍。摄像机在3D编程中至关重要,没有正确的配置,摄像机可能不能获得想要的场景效果。然后对雾特效做了具体介绍,应用雾特效可以使场景更加逼真,并且可以减少场景渲染量来提高性能   第10章 假作真时真亦假—混合本章主要为读者介绍了混合,从混合的背景知识到如何配置源因子和目标因子。在介绍源因子和目标因子的时候,向读者介绍了一些预定义常量和一些常用的组合方式,以及如何启用混合   第11章 蓦然回首,那人却在灯火阑珊处—3D高级技术本章主要为读者介绍了3D的一部分高级技术。每一项技术通过讲解其原理和案例,使读者对3D高级技术有一定的了解   第12章 心有灵犀一点通—传感器在本章中,向读者介绍了Android中传感器的相关知识。包括传感器的种类、配置,并且着重介绍了姿态传感器的应用   第13章 千锤万凿出深山—游戏中的数学与物理在本章中对3D游戏中可能会用到的数学及物理知识进行了简单的介绍,这在3D游戏开发中是相当重要的。游戏中的核心算法,基本上都要用到数学和物理知识。一款游戏的性能很大程度上取决于游戏设计的算法   第14章 山舞银蛇,原驰蜡象—AI基本理念本章主要介绍了AI、AI引擎的基本组成与设计,以及游戏AI中图的搜索和模糊逻辑,其中游戏AI中图的搜索为本章的重点。在本章中详细介绍了5种算法的原理与实现   第15章 独上高楼,望尽天涯路—开发小秘籍本章介绍了地图设计器、多键技术、虚拟键盘、查找表技术、状态机、AABB边界框、穿透效应、拾取技术,以及天空盒和天空穹在OpenGL ES中的应用 第二篇以7个比较大的案例来说明Android平台下3D游戏的开发流程,通过这7个案例的讲解,读者对3D游戏的开发将会有更深层次的理解。   章 名主 要 内 容   第16章 体育类游戏——《疯狂投篮》本章介绍了Android 3D游戏《疯狂投篮》的开发。通过该案例向读者介绍了在Android平台下进行3D游戏开发的相关知识和基本流程,并对游戏开发中的编程技巧进行了介绍,并主要介绍了篮球与地面、墙面及篮框的碰撞检测及运动动画的实现方法   第17章 益智类游戏——《旋转积木》本章介绍了Android 3D游戏《旋转积木》的开发。主要介绍了积木旋转的不同状态的实现方法和地图设计器的应用   第18章 休闲类游戏——《摩天大楼》本章介绍了Android 3D游戏《摩天大楼》的开发。主要介绍了楼层与楼层之间的衔接与碰撞及掉落后翻转动画的实现   第19章 动作类游戏——《3D空战》本章介绍了Android 3D游戏《3D空战》的开发。主要介绍了飞机的构造方法和我方战机与敌方战机的操控及动画实现   第20章 桌面类游戏——《激情台球》本章介绍了Android 3D游戏《激情台球》的开发。主要介绍了台球与台球的碰撞检测实现、台球与球桌的碰撞检测实现和进球的判定实现   第21章 射击类游戏——《抢滩登陆》本章介绍了Android 3D游戏《抢滩登陆》的开发。主要运用了灰度图生成技术并且主要介绍了坦克运动的实现方法及炮弹碰撞检测的实现   第22章 竞技类游戏——《乡村飙车》本章介绍了Android 3D游戏《乡村飙车》的开发。主要介绍了运用分层绘制和拼接绘制的策略进行场景的优化绘制,并且对场景部件进行了分类控制   本书面向的读者   本书的内容详细,且几乎涵盖了Android 3D游戏开发所有相关的技术,并向读者介绍了真实项目的开发流程,主要面向以下读者。   Android的初学者   本书详细介绍了OpenGL ES的基础知识,并对Android 3D游戏程序的开发进行了介绍。作为一名Android的初学者,通过本书的学习可以快速全面地掌握Android 3D游戏开发的相关知识,稳健地步入Android 3D游戏开发人员的行列。   有一定Android基础且希望学习Android 3D游戏开发的读者   有一定Android基础的读者通过阅读本书的前半部分便可快速掌握OpenGL ES的基础知识,然后通过7个真实案例的学习迅速掌握Android平台下应用程序的开发。   在职的开发人员
OpenGL3D游戏(含全部源程序)讲述3D游戏的编写方法。 《学OpenGL3D游戏》重在游戏的实现方案。全书以一个完整(基本)的3D游戏为主线,采用循序渐进的方法,从建立OpenGL图形环境入手,讲解3D基本图形、构图原理;从引入摄像机,建立天空、山地、树木,到3D模型使用和3D动画模型的显示。用鱼骨方式讲解相关知识技术,完整地展示了3D游戏的编写过程。● 特点 重在游戏的基本实现方法 搭建一个基本功能的游戏环境 最新的外部功能模块的使用● 提供《学OpenGL3D游戏》的教学演示课件 《学OpenGL3D游戏》的教学课件。用多媒体的表现手法将学习过程完全显示在你面前,使用者可以随时查看所选章节的知识要点提示,可以观看程序的制作过程和效果,也可以马上进入到VC编辑器对范例程序修修改改,在实践中加深对知识的理解;还可以进入到网上论坛和朋友们讨论学习心得。● 内容提要第1 章 OpenGL的程序框架__Windows、OpenGL程序框架的建立。第2 章 OpenGL的基本图形__在OpenGL图形界面上作一些简单的图形。第3 章 OpenGL的组合图形__用简单图形来构成两个复杂一点的3D模型。第4 章 摄像漫游__________有了摄像机你就可以在OpenGL场景中自由地漫游了。第5 章 开天辟地__________在OpenGL场景中有了天空、大地、景物。第6 章 OpenGL中显示文字__介绍了OpenGL中文字的几种显示方式。第7 章 特殊的平面_树_____栽些树种些草,让这个OpenGL世界充满生机。第8 章 显示3D模型________在OpenGL场景中显示3DS格式的模型。第9 章 使用MD2动画模型___OpenGL场景中出现了活生生的人(3D动画模型)。第10 章 使用MDL动画模型__介绍一种更先进的动画模型—3D骨骼动画。第11章 射击、爆炸________逼真的爆炸效果,是用程序仿真爆炸的物理过程。第12章 碰撞检测__________加入碰撞检测后,游戏才有真实的感觉。第13章 游戏进度保存______场景(或进度)保存和调入是游戏必不可少的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值