OpenGL ES是针对手机、PDA和游戏主机等嵌入式设备制定的编程接口,是由OpenGL的不同版本演化而来,目前已有OpenGL ES1.x和OpenGL ES2.0,OpenGL ES2.0添加了对可编程管线的支持.OpenGL ES1.X又有OpenGL ES1.0和OpenGL ES1.1,前者支持定点实数(fixed)和浮点数(float),后者只支持定点数(fixed)
库来自Vicent Mobile 3D Rendering Library 的ogles-bin-1.0.0,解压后拷贝include文件夹到Mobile的SDK下的Include文件夹下,拷贝bin文件夹下的debug和release到工程文件下的debug和release下
新建智能项目工程HelloOpenGL_Quad
如下配置工程的DLL和LIB
这里对opengles库使用的是静态引用,因此要在工程中设好对.lib的引用路径和附加库设置:
初始化设备,OpenGL是具备平台无关性的,所谓的平台无关,只是为OpenGL提供了不同平台的不同接口,使其建立起opengl的显示环境.这里用到的是EGL规范.那么先建立一个初始化设备函数BOOL InitOGLDevice(HWND hwnd),参数是当前窗口句柄.
获取显示输出设备接口,EGL就是我们进行设备初始化工作的关键API,因此这里用到的函数都是eglXXXXXX,获取显示接口函数包括eglGetDisplay(NativeDisplayType native_display)和eglGetCurrentDisplay(),前面一个是建立一个显示接口,后者是从当前的opengl环境返回一个opengl接口
g_eglDisplay = eglGetDisplay( GetDC( hwnd ) );
初始化显示设备,这是一个内部初始化的过程,可能为显示结构内部变量给初值
eglInitialize( g_eglDisplay, &major, &minor )
frame buffer属性定义,再使用eglChooseConfig找到最匹配这项属性列表的配置定义,并返回配置项,返回的配置被使用来建立表面和状态机,
EGLint attrib_list[] =
{
EGL_DEPTH_SIZE, 16,
EGL_RED_SIZE, 5,
EGL_GREEN_SIZE, 6,
EGL_BLUE_SIZE, 5,
EGL_NONE
};
eglChooseConfig(g_eglDisplay, attrib_list, configs_list, num_config, &num_config)
根据配置描述一个设备表面
eglCreateWindowSurface( g_eglDisplay, configs_list[0], hwnd, NULL );
返回一个相关属性设置的状态机
eglCreateContext( g_eglDisplay, configs_list[0], EGL_NO_CONTEXT , attrib_list );
建立Opengl当前环境
eglMakeCurrent( g_eglDisplay, g_eglSurface, g_eglSurface, g_eglContext );
至此一个完整可用的Opengl渲染平台就建立好了,事实上整个创建的概念与windows directe3D Mobile有些相似.
现在要建立渲染配置
这句类似于d3dm device的clear函数
glClearColor(0.5f,0.5f,0.5f,1.0f);
下面是对渲染的一系列配置,glDisable和glEnable被用来打开或关闭一些渲染的配置,比如光照,双面渲染,贴图支持,Z缓冲支持
glDisable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc( GL_LEQUAL );
glClearDepthf( 5.0f );
glEnable(GL_TEXTURE_2D);
这是对贴图渲染的配置,规定贴图的算法
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
至此,渲染的配置就完成了,现在要建立贴图需要用到glTexImage2D函数
TString tstrMaskBk1=GetProgramDirT()+_T("1.bmp");
HBITMAP hbitmap = ::SHLoadImageFile(tstrMaskBk1.c_str());
GetObject(hbitmap,sizeof(BITMAP),&texturemap);
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 512, 128 , 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, texturemap.bmBits);
开始在屏幕上画出图形,在画图形之前先要为图形设入顶点坐标
GLfloat box_array[] = {
// FRONT
-0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
// BACK
-0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
//// LEFT
-0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f,
-0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f,
// RIGHT
0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f,
0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
};
法线
GLfloat box_normalarray[] = {
// FRONT
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
// BACK
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
//// LEFT
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
//// RIGHT
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
};
贴图坐标
GLfloat box_uvarray[] = {
// FRONT
0.0f, 1.0f, 0.25f, 1.0f,
0.0f, 0.0f, 0.25f, 0.0f,
// BACK
0.25f, 1.0f, 0.5f, 1.0f,
0.25f, 0.0f, 0.5f, 0.0f,
// LEFT
0.5f, 1.0f, 0.75f, 1.0f,
0.5f, 0.0f, 0.75f, 0.0f,
//// RIGHT
0.75f, 1.0f, 1.0f, 1.0f,
0.75f, 0.0f, 1.0f, 0.0f,
};
将顶点序列,法线序列,贴图坐标序列放入缓冲,法线序列一般在曲面绘制很重要
glVertexPointer(3, GL_FLOAT, 0, box_array);
glNormalPointer(GL_FLOAT,0,box_normalarray);
glTexCoordPointer(2,GL_FLOAT,0,box_uvarray);
打开顶点序列绘制模式,法线序列模式,顶点贴图模式
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
首先清空帧缓冲区和Z缓冲
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
透视单位矩阵转换,ugluLookAtf和ugluPerspectivef是对照像机视角的扩展
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//ugluLookAtf( 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
glFrustumf(-1.0f,1.0f,-1.0f,1.0f,2.0f,5.0f);
//ugluPerspectivef(3.14f/4,1.0f,3.0f,4.0f);
单位位置矩阵转换
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//GLfloat xrot=2*3.14f;
GLfloat yrot=m_icreas*3.14f;
这两个函数让立方体绕着x和y轴旋转
//glRotatef(xrot, 1.0f, 0.0f, 0.0f);
glTranslatef(0.0f,0.0f,-3.0f);
glRotatef(yrot, 0.0f, 1.0f, 0.0f);
根据顶点坐标,画出三角基元构成最终的图形
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 4, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 8, 4);
glDrawArrays(GL_TRIANGLE_STRIP, 12, 4);
对屏幕进行刷新提高操作速度
面缓冲交换,把数据提交显示
glFlush();
eglSwapBuffers(g_eglDisplay, g_eglSurface);