我的第1个OpenGL ES程序 for WinCE5 HTC TouchHD

我的第1个OpenGL ES程序 for WinCE5 HTC TouchHD

cheungmine

中午吃过饭,闲来无事,看着我的手机(HTC TouchHD),忽然想编一个OpenGL程序玩玩。CSDN上下载了OpenGL ES的开发包。

解压之后发现了:bin/arm/Release目录下有几个文件:

              libGLES_CM.dll

              libGLES_CM.lib

              libGLES_CM.exp

等等。就准备把  libGLES_CM.dll  拷贝到我的手机的Windows下,提示已经有了这个文件,要不要覆盖?当然不覆盖。原来我的TouchHD支持OGL啊。太好了,马上编译例子Tutorial 1代码。其实就是新建一个Win32的移动程序空项目,平台是Windows Mobile 6.0Professional,然后把tutorial1.h和tutorial1.cpp文件拷贝到我的项目里,并添加到项目。编译不通过,提示文件目录不存在。马上添加包含目录和包含的库选项。编译通过。但是部署后,运行,失败。

 

网上搜,结果例子代码有问题,改正后的代码如下:

 

  1. #ifndef _TUTORIAL1_H   
  2. #define _TUTORIAL1_H   
  3. #include <windows.h> //needed include for window system calls   
  4. //OpenGL ES Includes   
  5. #include <GLES/gl.h>   
  6. /*EGL is the "machine" that glues OpenGL ES with the underlying 
  7. windowing system. We need it to create a suitable context and a drawable window*/  
  8. #include <GLES/egl.h>   
  9. /*Because we are building software device dependent (the PDA), we have care about  
  10. its limitations. PDA's doesn't have a FPU unit, so all floating point operations  
  11. are emulated in the CPU. To have real data type, PDA's uses reals with a fixed point 
  12. format. For a fixed point number we only need an integer, with the same size (in bytes) 
  13. that a float, that is, a normal int number. The first 16 bits of the int will be the  
  14. "integer" part, and the last 16 bits will be the "real" part. This will cause a lack  
  15. of precision, but it is better than emulate all FPU in the CPU. To convert an integer  
  16. number to a fixed point number we need to displace its bits to the left, as the FixedFromInt  
  17. function does. In this chapter we only will need the conversion int->fixed point. 
  18. Other conversions will be showed when needed, in later chapters. A complete description of  
  19. the fixed point maths is beyond the purpose of this set of tutorials, but the topic will 
  20. be widely covered through the chapters.  
  21. OpenGL ES offers us a set of functions that works with fixed point (Glfixed). These  
  22. functions are available through the OpenGL ES OES_fixed_point extension.  
  23. A little word about the OpenGL ES extensions: They are divided into two categories:  
  24. those that are fully integrated into the profile definition (core additions); and those 
  25. that remain extensions (profile extensions). Core additions do not use extension suffixes 
  26. and does not requires initialization, whereas profile extensions retain their extension suffixes. 
  27. OES_fixed_point is a core addition. The other extensions are listed and explained in the  
  28. OpenGL ES 1.1 specification.*/  
  29.   
  30. #define PRECISION 16       
  31. #define ONE (1 << PRECISION)   
  32. #define ZERO 0   
  33. inline GLfixed FixedFromInt(int value) {return value << PRECISION;};  
  34. int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPTSTR lpCmdLine,int nCmdShow);  
  35. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);  
  36. BOOL InitOGLES();// Our GL initialization function   
  37. void Render();  // Our Render function   
  38. void Clean();   //Our clean function. It will clean all used resources   
  39. #endif  

 

 

  1. #include "tutorial1.h" //We need the defines and prototypes of there   
  2. // cheungmine  
  3. #pragma comment(lib, "E:/GU2005/GCE/OpenGL_ES_WCE/ogl-es-bin-0.83/dist/bin/arm/Debug/libGLES_CM.lib")   
  4. //Some useful global handles   
  5. HINSTANCE hInst; //Will hold the current instance of the application   
  6. HWND hWnd; // A handle to the window we will create   
  7. HDC hDC;   // A handle to the device context of the window. Needed to    
  8.      //create the OpenGL ES context   
  9. // OpenGL variables   
  10. EGLDisplay glesDisplay;  // EGL display   
  11. EGLSurface glesSurface;  // EGL rendering surface   
  12. EGLContext glesContext;  // EGL rendering context   
  13. TCHAR szAppName[] = L"OpenGLES"/*The application name and the window caption*/  
  14. /*This is the WinMain function. Here we will create the rendering window, initialize OpenGL ES, write the message loop, and, at the end, clean all and release all used resources*/  
  15. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,  int nCmdShow)  
  16. {  
  17.   MSG msg; //This is the message variable for the message loop   
  18.   WNDCLASS  wc; /*This structure will hold some init values for our window*/  
  19.   hInst = hInstance; // Initialization of our global variable   
  20.   bool done = FALSE;   
  21.         
  22.   /*This block of code is to ensure that the user only can run one 
  23.     instance of the application. First we search for a window with the  
  24.     same class name, if found, we will focus it and return*/  
  25.   if(hWnd = FindWindow(szAppName, szAppName))   
  26.   {  
  27.     /* Set focus to foremost child window. The "| 0x01" is used to  
  28.        bring any owned windows to the foreground and activate them.*/  
  29.     SetForegroundWindow((HWND)((ULONG) hWnd | 0x00000001));  
  30.     return 0;  
  31.   }   
  32.           
  33.   wc.style          = CS_HREDRAW | CS_VREDRAW; /*Will force a redraw  
  34.   if the window is resized, both horizontally or vertically*/  
  35.   wc.lpfnWndProc    = (WNDPROC) WndProc; /*this is a function pointer, 
  36.   to tell the OS what function should call when a message needs to be  
  37.   processed*/  
  38.   wc.cbClsExtra     = 0;  
  39.   wc.cbWndExtra     = 0;  
  40.   wc.hInstance      = hInstance;  
  41.   wc.hIcon          = LoadIcon(hInstance, NULL);//Load default icon   
  42.   wc.hCursor          = 0; // Default cursor   
  43.   wc.hbrBackground  = 0; //We don't care about the background color   
  44.   wc.lpszMenuName     = NULL; //This application does not have a menu   
  45.   wc.lpszClassName  = szAppName; /*Important, here we must fill the 
  46.    application class name (the class name is not the same than the  
  47.    caption of the window, but many times they are the same)*/  
  48.   //Before creating the window, we must register this new window class   
  49.   if(!RegisterClass(&wc))  
  50.     return FALSE;  
  51.       
  52.   hWnd=CreateWindow(szAppName, //Class Name   
  53.                     szAppName, //Caption string   
  54.                     WS_VISIBLE,//Window style   
  55.                     CW_USEDEFAULT,CW_USEDEFAULT,//Starting [x,y] pos.   
  56.                     CW_USEDEFAULT, CW_USEDEFAULT, //Width and height   
  57.                     NULL, NULL, //Parent window and menu handle   
  58.                     hInst, NULL); /*Instance handle. Custom value to  
  59.                     pass in the creation with the WM_CREATE message*/  
  60.                         
  61.   if(!hWnd) return FALSE;  
  62.   if(!InitOGLES()) return FALSE; //OpenGL ES Initialization   
  63.     
  64.   //Bring the window to front, focus it and refresh it   
  65.   ShowWindow(hWnd, nCmdShow);   
  66.   UpdateWindow(hWnd);  
  67.    
  68.   //Message Loop   
  69.   while(!done)  
  70.   {  
  71.     if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))  
  72.     {  
  73.       if(msg.message==WM_QUIT)  
  74.         done=TRUE;  
  75.         else  
  76.       {   
  77.           TranslateMessage(&msg);  
  78.           DispatchMessage(&msg);  
  79.         }  
  80.     }  
  81.     else                                          
  82.         Render();  
  83.   }  
  84.   //Clean up all   
  85.   Clean();  
  86.   return 0;  
  87. }  
  88. //----------------------------------------------------------------------------   
  89. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  90. {  
  91.   switch (message)   
  92.   {       
  93.   case WM_PAINT:      
  94.     ValidateRect(hWnd,NULL); //Needed to avoid new WM_PAINT messages   
  95.     return 0;   
  96.   case WM_DESTROY:  
  97.     PostQuitMessage(0);  
  98.     return 0;    
  99.   };  
  100.   return DefWindowProc(hWnd, message, wParam, lParam);     
  101. }  
  102. //----------------------------------------------------------------------------   
  103. BOOL InitOGLES()  
  104. {    
  105.   EGLint matchingConfigs;     
  106.     
  107.   hDC = GetWindowDC(hWnd);  
  108.   glesDisplay = eglGetDisplay(hDC);  //Ask for an available display   
  109.   if( glesDisplay == EGL_NO_DISPLAY || eglGetError() != EGL_SUCCESS )  
  110.       return FALSE;  
  111.     
  112.   EGLConfig *configs_list;  
  113.   EGLint     num_configs;  
  114.   // Display initialization (we don't care about the OGLES version numbers)   
  115.   if( eglInitialize( glesDisplay, NULL, NULL ) == EGL_FALSE || eglGetError() != EGL_SUCCESS )  
  116.       return FALSE;  
  117.   // find out how many configurations are supported   
  118.   if ( eglGetConfigs( glesDisplay, NULL, 0, &num_configs)==EGL_FALSE || eglGetError() != EGL_SUCCESS )  
  119.       return FALSE;  
  120.   configs_list = (EGLConfig*) malloc(num_configs * sizeof(EGLConfig));  
  121.   if (configs_list == NULL)  
  122.       return FALSE;  
  123.   // Get Configurations   
  124.   if( eglGetConfigs( glesDisplay, configs_list, num_configs, &num_configs)== EGL_FALSE || eglGetError() != EGL_SUCCESS )  
  125.       return FALSE;  
  126.   // Obtain the first configuration with a depth buffer of 16 bits   
  127.   EGLint attrs[3] = { EGL_DEPTH_SIZE, 16, EGL_NONE };  
  128.   if (!eglChooseConfig(glesDisplay, attrs, configs_list, num_configs, &matchingConfigs))  
  129.   {  
  130.       return eglGetError();  
  131.   }  
  132.   // If there isn't any configuration enough good   
  133.   if (matchingConfigs < 1)    
  134.       return FALSE;     
  135.   /*eglCreateWindowSurface creates an onscreen EGLSurface and returns  
  136.   a handle  to it. Any EGL rendering context created with a  
  137.   compatible EGLConfig can be used to render into this surface.*/  
  138.   glesSurface = eglCreateWindowSurface(glesDisplay, configs_list[0], hWnd, 0);    
  139.   if(!glesSurface)   
  140.       return FALSE;  
  141.     
  142.   // Let's create our rendering context   
  143.   glesContext=eglCreateContext(glesDisplay, configs_list[0], 0, 0);  
  144.   if(!glesContext)   
  145.       return FALSE;  
  146.   //Now we will activate the context for rendering     
  147.   eglMakeCurrent(glesDisplay, glesSurface, glesSurface, glesContext);   
  148.       
  149.   /*Remember: because we are programming for a mobile device, we cant  
  150.   use any of the OpenGL ES functions that finish in 'f', we must use  
  151.   the fixed point version (they finish in 'x'*/  
  152.   glClearColorx(0, 0, 0, 0);  
  153.   glShadeModel(GL_SMOOTH);    
  154.   /*In order to set a viewport that fits entirely our window, we need  
  155.   to know the window dimensions. They could be obtained through the    
  156.   WinCE call GetWindowRect, using our window handle*/  
  157.   RECT r;  
  158.   GetWindowRect(hWnd, &r);    
  159.   glViewport(r.left, r.top, r.right - r.left, r.bottom - r.top);      
  160.       
  161.   /*Setup of the projection matrix. We will use an ortho cube centered  
  162.   at (0,0,0) with 100 units of edge*/  
  163.   glMatrixMode(GL_PROJECTION);  
  164.   glLoadIdentity();      
  165.   glOrthox(FixedFromInt(-50), FixedFromInt(50),   
  166.            FixedFromInt(-50), FixedFromInt(50),   
  167.            FixedFromInt(-50), FixedFromInt(50));  
  168.   glMatrixMode(GL_MODELVIEW);  
  169.   glLoadIdentity();  
  170.   return TRUE;  
  171. }  
  172. //----------------------------------------------------------------------------   
  173. void Render()  
  174. {  
  175.   static int rotation = 0;  
  176.                   /* Vertex 1    Vertex 2    Vertex 3*/                             
  177.   GLshort vertexArray[9] = {-25,-25,0,   25,-25,0,     0,25,0 };  
  178.   GLubyte colorArray[12] = {255,0,0,0,   0,255,0,0,    0,0,255,0};  
  179.     
  180.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
  181.   glLoadIdentity();    
  182.   glTranslatex(0, 0, FixedFromInt(-10));  
  183.   glRotatex(FixedFromInt(rotation++), 0, ONE,0);    
  184.   //Enable the vertices array     
  185.   glEnableClientState(GL_VERTEX_ARRAY);  
  186.   glVertexPointer(3, GL_SHORT, 0, vertexArray);  
  187.   //3 = XYZ coordinates, GL_SHORT = data type, 0 = 0 stride bytes   
  188.       
  189.   //Enable the vertex color array   
  190.   glEnableClientState(GL_COLOR_ARRAY);  
  191.   glColorPointer(4,GL_UNSIGNED_BYTE, 0, colorArray);  
  192.   //4 = RGBA format, GL_UNSIGNED_BYTE = data type,0=0 stide    bytes   
  193.   glDrawArrays(GL_TRIANGLES, 0, 3);  
  194.   /*We want draw triangles, 0 = first element(vertice), 3 = number of  
  195.     items (vertices) to draw from the array*/    
  196.   glDisableClientState(GL_VERTEX_ARRAY);  
  197.   glDisableClientState(GL_COLOR_ARRAY);  
  198.       
  199.   eglSwapBuffers(glesDisplay, glesSurface);  
  200. }  
  201. //----------------------------------------------------------------------------   
  202. void Clean()  
  203. {  
  204.   if(glesDisplay)  
  205.   {  
  206.     eglMakeCurrent(glesDisplay, NULL, NULL, NULL);    
  207.     if(glesContext) eglDestroyContext(glesDisplay, glesContext);  
  208.     if(glesSurface) eglDestroySurface(glesDisplay, glesSurface);  
  209.     eglTerminate(glesDisplay);  
  210.   }  
  211.   //We have to destroy the window too   
  212.   DestroyWindow(hWnd);  
  213.   UnregisterClass(szAppName, hInst);    
  214. }  

 

运行,结果出来了,很好。一个OGL窗口在我的手机里。中间一个缓缓转动的三角形。

好了,该干活了。就闲扯到这里。以后我还会陆续发布一些OGL ES的东西,无论我自己写的还是抄来的,权作茶余饭后的消遣。

下面是我看过的链接:

 

http://sourceforge.net/projects/ogl-es/files/

 

http://wiki.forum.nokia.com/index.php/OpenGL_ES%E7%AE%80%E4%BB%8B

 

http://blog.csdn.net/dymx101/archive/2010/02/03/5284348.aspx

posted @ 2012-10-21 01:21  小城zjc  阅读(176)  评论(0)    收藏  举报