WINCE系统上开发OpenGL程序需具备以下条件:

1. 处理器的支持,嵌入式处理器需支持3D加速渲染(测试使用的是Telichips 8901);

2. WINCE内核的支持,定制内核时需添加OpenGL ES相关组件。

以下是具体的参考代码:

[cpp]view plaincopy

/********************************************************************

filename:WinceOpenGLDemo.cpp

created:2011-01-05

author:firehood

purpose:利用OpenGLES实现了绘制立方体和纹理效果

*********************************************************************/

//WinceOpenGLDemo.cpp:定义应用程序的入口点。

//

#include"stdafx.h"

#include"WinceOpenGLDemo.h"

#include<windows.h>

#include<commctrl.h>

#include"ImgLoader.h"

//OpenGLESIncludes

#include<GLES/gl.h>

#include<GLES/glext.h>

#include<EGL/egl.h>

#include<EGL/eglext.h>

//OpenGLlib

#pragmacomment(lib,"OpenGlLib\\libGLESv1_CM.lib")

#pragmacomment(lib,"OpenGlLib\\libEGL.lib")

//全局变量:

HINSTANCEg_hInst;//当前实例

TCHARszAppName[]=L"OpenGLES";/*Theapplicationnameandthewindowcaption*/

CImgLoaderg_Image;

//OpenGLvariables

EGLDisplayglesDisplay;//EGLdisplay

EGLSurfaceglesSurface;//EGLrenderingsurface

EGLContextglesContext;//EGLrenderingcontext

GLuinttexture[6]={0};

//立方体定点坐标

GLshortvertices[]={

-1,-1,1,

1,-1,1,

1,1,1,

-1,1,1,

-1,-1,-1,

-1,1,-1,

1,1,-1,

1,-1,-1,

-1,1,-1,

-1,1,1,

1,1,1,

1,1,-1,

-1,-1,-1,

1,-1,-1,

1,-1,1,

-1,-1,1,

1,-1,-1,

1,1,-1,

1,1,1,

1,-1,1,

-1,-1,-1,

-1,-1,1,

-1,1,1,

-1,1,-1

};

//各个面纹理坐标

GLshorttexCoords[]={

0,0,1,0,1,1,0,1,

0,0,1,0,1,1,0,1,

0,0,1,0,1,1,0,1,

0,0,1,0,1,1,0,1,

0,0,1,0,1,1,0,1,

0,0,1,0,1,1,0,1,

};

//三角形索引数据

GLbyteindices1[]={

0,1,3,2,

0,0,0,0,

0,0,0,0,

0,0,0,0,

0,0,0,0,

0,0,0,0

};

GLbyteindices2[]={

0,0,0,0,

4,5,7,6,

0,0,0,0,

0,0,0,0,

0,0,0,0,

0,0,0,0

};

GLbyteindices3[]={

0,0,0,0,

0,0,0,0,

8,9,11,10,

0,0,0,0,

0,0,0,0,

0,0,0,0

};

GLbyteindices4[]={

0,0,0,0,

0,0,0,0,

0,0,0,0,

12,13,15,14,

0,0,0,0,

0,0,0,0

};

GLbyteindices5[]={

0,0,0,0,

0,0,0,0,

0,0,0,0,

0,0,0,0,

16,17,19,18,

0,0,0,0

};

GLbyteindices6[]={

0,0,0,0,

0,0,0,0,

0,0,0,0,

0,0,0,0,

0,0,0,0,

20,21,23,22

};

//此代码模块中包含的函数的前向声明:

ATOMMyRegisterClass(HINSTANCE,LPTSTR);

BOOLInitInstance(HINSTANCE,int);

LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);

BOOLInitOGLES(HWNDhWnd);

voidCreateSurface();

BOOLLoadTexture(LPCTSTRlpFileName,GLuint*id);

voidRender();

voidClean();

intWINAPIWinMain(HINSTANCEhInstance,

HINSTANCEhPrevInstance,

LPTSTRlpCmdLine,

intnCmdShow)

{

MSGmsg;

//执行应用程序初始化:

if(!InitInstance(hInstance,nCmdShow))

{

returnFALSE;

}

BOOLdone=FALSE;

//主消息循环:

while(!done)

{

if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))

{

if(msg.message==WM_QUIT)

done=TRUE;

else

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

else

{

Render();

};

}

return(int)msg.wParam;

}

//

//函数:MyRegisterClass()

//

//目的:注册窗口类。

//

//注释:

//

ATOMMyRegisterClass(HINSTANCEhInstance,LPTSTRszWindowClass)

{

WNDCLASSwc;

wc.style=CS_HREDRAW|CS_VREDRAW;

wc.lpfnWndProc=WndProc;

wc.cbClsExtra=0;

wc.cbWndExtra=0;

wc.hInstance=hInstance;

wc.hIcon=LoadIcon(hInstance,MAKEINTRESOURCE(IDI_WINCEOPENGLDEMO));

wc.hCursor=0;

wc.hbrBackground=(HBRUSH)GetStockObject(NULL_BRUSH);

wc.lpszMenuName=0;

wc.lpszClassName=szWindowClass;

returnRegisterClass(&wc);

}

//

//函数:InitInstance(HINSTANCE,int)

//

//目的:保存实例句柄并创建主窗口

//

//注释:

//

//在此函数中,我们在全局变量中保存实例句柄并

//创建和显示主程序窗口。

//

BOOLInitInstance(HINSTANCEhInstance,intnCmdShow)

{

HWNDhWnd;

g_hInst=hInstance;//将实例句柄存储在全局变量中

if(!MyRegisterClass(hInstance,szAppName))

{

returnFALSE;

}

hWnd=CreateWindow(

szAppName,

szAppName,

WS_VISIBLE,

0,

0,

::GetSystemMetrics(SM_CXSCREEN),

::GetSystemMetrics(SM_CYSCREEN),

NULL,

NULL,

hInstance,

NULL);

if(!hWnd)

{

returnFALSE;

}

if(!InitOGLES(hWnd))

{

printf("InitOGLESfailed\n");

returnFALSE;

}

CreateSurface();

ShowWindow(hWnd,SW_SHOW);

UpdateWindow(hWnd);

returnTRUE;

}

//

//函数:WndProc(HWND,UINT,WPARAM,LPARAM)

//

//目的:处理主窗口的消息。

//

//WM_COMMAND-处理应用程序菜单

//WM_PAINT-绘制主窗口

//WM_DESTROY-发送退出消息并返回

//

//

LRESULTCALLBACKWndProc(HWNDhWnd,UINTmessage,WPARAMwParam,LPARAMlParam)

{

PAINTSTRUCTps;

HDChdc;

switch(message)

{

caseWM_CREATE:

break;

caseWM_PAINT:

hdc=BeginPaint(hWnd,&ps);

//TODO:在此添加任意绘图代码...

EndPaint(hWnd,&ps);

break;

caseWM_DESTROY:

{

Clean();

PostQuitMessage(0);

}

break;

default:

returnDefWindowProc(hWnd,message,wParam,lParam);

}

return0;

}

BOOLInitOGLES(HWNDhWnd)

{

EGLintmatchingConfigs;

EGLintmajorVersion=0;

EGLintminorVersion=0;

glesDisplay=eglGetDisplay(GetDC(hWnd));//Askforanavailabledisplay

if(glesDisplay==EGL_NO_DISPLAY||eglGetError()!=EGL_SUCCESS)

returnFALSE;

EGLConfig*configs_list;

EGLintnum_configs;

//Displayinitialization(wedon'tcareabouttheOGLESversionnumbers)

if(eglInitialize(glesDisplay,&majorVersion,&minorVersion)==EGL_FALSE)

{

printf("eglInitializefailed,eglGetError=0x%04x\n",eglGetError());

returnFALSE;

}

//findouthowmanyconfigurationsaresupported

if(eglGetConfigs(glesDisplay,NULL,0,&num_configs)==EGL_FALSE||eglGetError()!=EGL_SUCCESS)

returnFALSE;

configs_list=(EGLConfig*)malloc(num_configs*sizeof(EGLConfig));

if(configs_list==NULL)

returnFALSE;

//GetConfigurations

if(eglGetConfigs(glesDisplay,configs_list,num_configs,&num_configs)==EGL_FALSE||eglGetError()!=EGL_SUCCESS)

returnFALSE;

//Obtainthefirstconfigurationwithadepthbufferof16bits

EGLintattrs[]={

EGL_RED_SIZE,5,

EGL_GREEN_SIZE,6,

EGL_BLUE_SIZE,5,

EGL_DEPTH_SIZE,16,

EGL_NONE

};

if(!eglChooseConfig(glesDisplay,attrs,configs_list,num_configs,&matchingConfigs))

{

returneglGetError();

}

//Ifthereisn'tanyconfigurationenoughgood

if(matchingConfigs<1)

returnFALSE;

/*eglCreateWindowSurfacecreatesanonscreenEGLSurfaceandreturns

ahandletoit.AnyEGLrenderingcontextcreatedwitha

compatibleEGLConfigcanbeusedtorenderintothissurface.*/

glesSurface=eglCreateWindowSurface(glesDisplay,configs_list[0],hWnd,0);

if(!glesSurface)

returnFALSE;

//Let'screateourrenderingcontext

glesContext=eglCreateContext(glesDisplay,configs_list[0],0,0);

if(!glesContext)

returnFALSE;

//Nowwewillactivatethecontextforrendering

eglMakeCurrent(glesDisplay,glesSurface,glesSurface,glesContext);

/*Remember:becauseweareprogrammingforamobiledevice,wecant

useanyoftheOpenGLESfunctionsthatfinishin'f',wemustuse

thefixedpointversion(theyfinishin'x'*/

glClearColorx(0,0,0,0);

glShadeModel(GL_SMOOTH);

RECTrc;

GetWindowRect(hWnd,&rc);

UINTwidth=rc.right-rc.left;

UINTheight=rc.bottom-rc.top;

//设置OpenGL场景的大小

glViewport(rc.left,rc.top,width,height);

//设置投影矩阵

glMatrixMode(GL_PROJECTION);

glLoadIdentity();

//投影变换(透视投影)

floatratio=(float)width/height;

glFrustumf(-ratio,ratio,-1,1,2,10);

//glOrthox(FixedFromInt(-50),FixedFromInt(50),FixedFromInt(-50),FixedFromInt(50),FixedFromInt(-50),FixedFromInt(50));

//选择模型观察矩阵

glMatrixMode(GL_MODELVIEW);

//重置模型观察矩阵

glLoadIdentity();

returnTRUE;

}

voidCreateSurface()

{

glDisable(GL_DITHER);

//告诉系统对透视进行修正

glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_FASTEST);

//黑色背景

glClearColor(0,0,0,0);

//启用阴影平滑

glShadeModel(GL_SMOOTH);

//设置深度缓存

glClearDepthf(1.0f);

//启用深度测试

glEnable(GL_DEPTH_TEST);

//所作深度测试的类型

glDepthFunc(GL_LEQUAL);

//启用2D纹理

glEnable(GL_TEXTURE_2D);

//加载纹理

LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[0]);

LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[1]);

LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[2]);

LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[3]);

LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[4]);

LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[5]);

}

voidRender()

{

staticfloatrotation=0;

//清除屏幕和深度缓存

glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_MODELVIEW);

//重置当前的模型观察矩阵

glLoadIdentity();

//坐标变换

glTranslatef(0.0f,0.0f,-5.0f);

//设置旋转

glRotatef(rotation++,0.0f,1.0f,0.0f);

glRotatef(rotation++,1.0f,0.0f,0.0f);

glEnableClientState(GL_VERTEX_ARRAY);

glEnableClientState(GL_TEXTURE_COORD_ARRAY);

glVertexPointer(3,GL_SHORT,0,vertices);

glTexCoordPointer(2,GL_SHORT,0,texCoords);

//绘制立方体并绑定纹理

glBindTexture(GL_TEXTURE_2D,texture[0]);

glDrawElements(GL_TRIANGLE_STRIP,4,GL_UNSIGNED_BYTE,indices1);

glBindTexture(GL_TEXTURE_2D,texture[1]);

glDrawElements(GL_TRIANGLE_STRIP,8,GL_UNSIGNED_BYTE,indices2);

glBindTexture(GL_TEXTURE_2D,texture[2]);

glDrawElements(GL_TRIANGLE_STRIP,12,GL_UNSIGNED_BYTE,indices3);

glBindTexture(GL_TEXTURE_2D,texture[3]);

glDrawElements(GL_TRIANGLE_STRIP,16,GL_UNSIGNED_BYTE,indices4);

glBindTexture(GL_TEXTURE_2D,texture[4]);

glDrawElements(GL_TRIANGLE_STRIP,20,GL_UNSIGNED_BYTE,indices5);

glBindTexture(GL_TEXTURE_2D,texture[5]);

glDrawElements(GL_TRIANGLE_STRIP,24,GL_UNSIGNED_BYTE,indices6);

glDisableClientState(GL_TEXTURE_COORD_ARRAY);

glDisableClientState(GL_VERTEX_ARRAY);

eglSwapBuffers(glesDisplay,glesSurface);

}

voidClean()

{

if(glesDisplay)

{

eglMakeCurrent(glesDisplay,NULL,NULL,NULL);

if(glesContext)eglDestroyContext(glesDisplay,glesContext);

if(glesSurface)eglDestroySurface(glesDisplay,glesSurface);

eglTerminate(glesDisplay);

}

}

BOOLLoadTexture(LPCTSTRlpFileName,GLuint*id)

{

if(!g_Image.Load(lpFileName))

returnFALSE;

//创建纹理

glGenTextures(1,id);

//绑定纹理

glBindTexture(GL_TEXTURE_2D,*id);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);

glTexImage2D(GL_TEXTURE_2D,0,GL_RGB,g_Image.Width(),g_Image.Height(),0,GL_RGB,GL_UNSIGNED_BYTE,g_Image.GetBmpImage());

g_Image.Free();

returnTRUE;

}


以下实现了一个文件加载类,用以将外部图片资源转化成绘制纹理时所需的位图数据。参考代码如下:

[cpp]view plaincopy

/********************************************************************

filename:CImgLoader.h

created:2011-01-05

author:firehood

purpose:文件加载类,将外部图片资源转化成绘制纹理时所需的位图数据

图片格式支持bmp、png、jpg.

*********************************************************************/

#pragmaonce

classCImgLoader

{

public:

CImgLoader(void);

~CImgLoader(void);

public:

//加载图片资源

BOOLLoad(LPCTSTRlpFileName);

//获取位图数据

unsignedchar*GetBmpImage(void);

//释放图片资源

voidFree();

//获取图像宽度

intWidth();

//获取图像高度

intHeight();

private:

intm_Width;//图像宽度

intm_Height;//图像高度

unsignedchar*m_pImage;//指向图像数据的指针

};