opengl 在winCE系统的使用
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;//指向图像数据的指针
};
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。