My 1st OpenGL ES program for wince5 HTC touchhd
Cheungmine
After lunch, I had nothing to worry about. I looked at my cell phone (HTC touchhd) and suddenly wanted to compile an OpenGL program for fun. Download the OpenGL ES development kit from csdn.
After decompression, several files are found in the bin/ARM/release directory:
Libgles_cm.dll
Libgles_cm.lib
Libgles_cm.exp
And so on. I'm going to copy libgles_cm.dll to Windows on my mobile phone, prompting that this file already exists. Do you want to overwrite it? Of course it is not covered. It turns out that my touchhd supports OGL. Great. Compile the example tutorial 1 code immediately. In fact, it is to create a Win32 mobile program empty project, the platform is Windows Mobile 6.0 professional, and then copy the tutorial1.h and tutorial1.cpp files to my project and add them to the project. If the compilation fails, the system prompts that the file directory does not exist. Add the include directory and included library option immediately. Compiled. However, after deployment, it runs and fails.
If the code in the result example is incorrect, the correct code is as follows:
# Ifndef _ tutorial0000h <br/> # DEFINE _ tutorial0000h <br/> # include <windows. h> // needed include for Window System CILS <br/> // OpenGL ES except des <br/> # include <gles/GL. h> <br/>/* EGL is the "machine" that glues OpenGL ES with the underlying <br/> processing Wing System. we need it to create a suitable context and a drawable window */<br/> # include <gles/EGL. h> <br/>/* because we are building software device dependent (the PDA), we have care about <br/> its limitations. PDA's doesn' t have a FPU unit, so all floating point Operations <br/> are emulated in the CPU. to have real data type, PDA's uses reals with a fixed point <br/> format. for a fixed point number we only need an integer, with the same size (in bytes) <br/> that a float, that is, a normal int number. the first 16 bits of the int will be the <br/> "integer" part, and the last 16 bits will be the "real" part. this will cause a lack <br/> of precision, but it is better than Emulate all FPU In the CPU. to convert an integer <br/> number to a fixed point number we need to displace its bits to the left, as the fixedfromint <br/> function does. in this chapter we only will need the conversion int-> fixed point. <br/> other conversions will be showed when needed, in later chapters. A complete description of <br/> the fixed point maths is beyond the purpose of this set of tutorials, but the topic will <br/> be widely covered through the chapters. <br/> OpenGL ES offers us a set of functions that works with fixed point (glfixed ). these <br/> functions are available through the OpenGL ES oes_fixed_point extension. <br/> A little word about the OpenGL ES extensions: they are divided into two categories: <br/> those that are fully integrated into the profile definition (core additions ); and those <br/> that remain extensions (profile extensions ). core additions do not use extension suffixes <br/> and does not requires initialization, whereas profile extensions retain their extension suffixes. <br/> oes_fixed_point is a core addition. the other extensions are listed and explained in the <br/> OpenGL ES 1.1 specification. */</P> <p> # define precision 16 <br/> # define one (1 <precision) <br/> # define zero 0 <br/> inline glfixed fixedfromint (INT value) {return value <precision ;}; <br/> int winapi winmain (hinstance hinst, hinstance hprevinst, lptstr lpcmdline, int ncmdshow); <br/> lresult callback (hwnd, uint message, wparam, lparam); <br/> bool initogles (); // Our GL initialization function <br/> void render (); // Our render function <br/> void clean (); // our clean function. it will clean all used resources <br/> # endif <br/>
# Include "tutorial1.h" // we need the defines and prototypes of there <br/> // cheungmine <br/> # pragma comment (Lib, "E: /gu2005/GCE/opengl_es_wce/ogl-es-bin-0.83/Dist/bin/ARM/debug/libgles_cm.lib ") <br/> // some useful global handles <br/> hinstance hinst; // will hold the current instance of the application <br/> hwnd; // a handle to the window we will create <br/> HDC; // a handle to the device C Ontext of the window. needed to <br/> // create the OpenGL ES context <br/> // OpenGL variables <br/> egldisplay glesdisplay; // EGL display <br/> eglsurface glessurface; // EGL rendering surface <br/> eglcontext glescontext; // EGL rendering context <br/> tchar szappname [] = l "opengles "; /* The application name and the window caption */<br/>/* this is the winmain function. here we will create the renderi Ng window, initialize OpenGL ES, write the message loop, and, at the end, clean all and release all used resources */<br/> int winapi winmain (hinstance, hinstance hprevinstance, lptstr lpcmdline, int ncmdshow) <br/>{< br/> MSG; // This is the message variable for the message loop <br/> wndclasswc; /* This structure will hold some init values for our window */<br/> hinst = hinstance; // I Nitialization of our global variable <br/> bool done = false; </P> <p>/* this block of code is to ensure that the user only can run one <br/> instance of the application. first we search for a window with the <br/> same class name, if found, we will focus it and return */<br/> If (hwnd = findwindow (szappname, szappname) <br/>{< br/>/* set focus to foremost Child Window. the "| 0x01" is used to <br /> Bring any owned windows to the foreground and activate them. */<br/> setforegroundwindow (hwnd) (ulong) hwnd | 0x00000001); <br/> return 0; <br/>}</P> <p> WC. style = cs_hredraw | cs_vredraw;/* will force a redraw <br/> If the window is resized, both horizontally or vertically */<br/> WC. lpfnwndproc = (wndproc) wndproc;/* This is a function pointer, <br/> to tell the OS what function shoshould C All when a message needs to be <br/> processed */<br/> WC. cbclsextra = 0; <br/> WC. cbwndextra = 0; <br/> WC. hinstance = hinstance; <br/> WC. hicon = loadicon (hinstance, null); // load default icon <br/> WC. hcursor = 0; // default cursor <br/> WC. hbrbackground = 0; // We don't care about the background color <br/> WC. lpszmenuname = NULL; // This application does not have a menu <br/> WC. lpszclassname = Szappname;/* important, here we must fill the <br/> application Class Name (the class name is not the same than the <br/> caption of the window, but every times they are the same) */<br/> // before creating the window, we must register this new window class <br/> If (! Registerclass (& WC) <br/> return false; </P> <p> hwnd = createwindow (szappname, // class name <br/> szappname, // caption string <br/> ws_visible, // window style <br/> cw_usedefault, cw_usedefault, // Starting [x, y] POS. <br/> cw_usedefault, cw_usedefault, // width and height <br/> null, null, // parent window and menu handle <br/> hinst, null ); /* instance handle. custom value to <br/> pass in the creation wit H The wm_create message */</P> <p> If (! Hwnd) return false; <br/> If (! Initogles () return false; // OpenGL ES initialization </P> <p> // bring the window to front, focus it and refresh it <br/> showwindow (hwnd, ncmdshow); <br/> updatewindow (hwnd); </P> <p> // message loop <br/> while (! Done) <br/>{< br/> If (peekmessage (& MSG, null, pm_remove) <br/>{< br/> If (MSG. message = wm_quit) <br/> done = true; <br/> else <br/>{< br/> translatemessage (& MSG ); <br/> dispatchmessage (& MSG); <br/>}< br/> else <br/> render (); <br/>}< br/> // clean up all <br/> clean (); <br/> return 0; <br/>}< br/> // ---------------------------------------------------------------------------- <br/> lresult Callback wndproc (hwnd, uint message, wparam, lparam) <br/>{< br/> switch (Message) <br/>{< br/> case wm_paint: <br/> validaterect (hwnd, null); // needed to avoid new wm_paint messages <br/> return 0; <br/> case wm_destroy: <br/> postquitmessage (0); <br/> return 0; <br/>}; <br/> return defwindowproc (hwnd, message, wparam, lparam ); <br/>}< br/> //---------------------------------- -------------------------------------- <Br/> bool initogles () <br/>{< br/> eglint matchingconfigs; </P> <p> HDC = getwindowdc (hwnd ); <br/> glesdisplay = eglgetdisplay (HDC); // ask for an available display <br/> If (glesdisplay = egl_no_display | eglgeterror ()! = Egl_success) <br/> return false; </P> <p> eglconfig * configs_list; <br/> eglint num_configs; <br/> // display initialization (we don't care about the ogles version numbers) <br/> If (eglinitialize (glesdisplay, null, null) = egl_false | eglgeterror ()! = Egl_success) <br/> return false; <br/> // find out how many comprehensions are supported <br/> If (eglgetconfigs (glesdisplay, null, 0, & num_configs) = egl_false | eglgeterror ()! = Egl_success) <br/> return false; <br/> configs_list = (eglconfig *) malloc (num_configs * sizeof (eglconfig )); <br/> If (configs_list = NULL) <br/> return false; <br/> // get configurations <br/> If (eglgetconfigs (glesdisplay, configs_list, num_configs, & num_configs) = egl_false | eglgeterror ()! = Egl_success) <br/> return false; <br/> // obtain the first configuration with a depth buffer of 16 bits <br/> eglint attrs [3] = {egl_depth_size, 16, egl_none }; <br/> If (! Eglchooseconfig (glesdisplay, attrs, configs_list, num_configs, & matchingconfigs) <br/>{< br/> return eglgeterror (); <br/>}< br/> // if there isn't any configuration enough good <br/> If (matchingconfigs <1) <br/> return false; <br/>/* eglcreatewindowsurface creates an onscreen eglsurface and returns <br/> a handle to it. any EGL rendering context created with a <br/> compatible eglconfig can be Used to render into this surface. */<br/> glessurface = eglcreatewindowsurface (glesdisplay, configs_list [0], hwnd, 0); <br/> If (! Glessurface) <br/> return false; </P> <p> // Let's create our rendering context <br/> glescontext = eglcreatecontext (glesdisplay, configs_list [0], 0, 0); <br/> If (! Glescontext) <br/> return false; <br/> // now we will activate the context for rendering <br/> eglmakecurrent (glesdisplay, glessurface, glessurface, glescontext ); </P> <p>/* Remember: because we are programming for a mobile device, we cant <br/> use any of the OpenGL ES functions that finish in 'F ', we must use <br/> the fixed point version (they finish in 'X' */<br/> glclearcolorx (0, 0, 0, 0 ); <br/> glshademodel (gl_smooth); <br/>/* in order to set a viewport that fits entirely our window, we need <br/> to know the window dimensions. they cocould be obtained through the <br/> wince call getwindowrect, using our window handle */<br/> rect R; <br/> getwindowrect (hwnd, & R ); <br/> glviewport (R. left, R. top, R. right-R. left, R. bottom-R. top); </P> <p>/* setup of the projection matrix. we will use an ortho cube centered <br/> at (100, 0) with units of edge */<br/> glmatrixmode (gl_projection ); <br/> glloadidentity (); <br/> glorthox (fixedfromint (-50), fixedfromint (50), <br/> fixedfromint (-50), fixedfromint (50 ), <br/> fixedfromint (-50), fixedfromint (50); <br/> glmatrixmode (gl_modelview); <br/> glloadidentity (); <br/> return true; <br/>}< br/> // rotate <br/> void render () <br/>{< br/> static int rotation = 0; <br/>/* vertex 1 vertex 2 vertex 3 */<br/> glshort vertexarray [9] = {-25,-25, 0, 25,-25, 0, 0 }; <br/> glubyte colorarray [12] = {255, 0, 0,255 }; </P> <p> glclear (gl_color_buffer_bit | gl_depth_buffer_bit); <br/> glloadidentity (); <br/> gltranslatex (0, 0, fixedfromint (-10 )); <br/> glrotatex (fixedfromint (rotation ++), 0, one, 0); <br/> // enable the vertices array <br/> glableclientstate (gl_vertex_array ); <br/> glvertexpointer (3, gl_short, 0, vertexarray); <br/> // 3 = XYZ coordinates, gl_short = data type, 0 = 0 stride bytes </P> <p> // enable the vertex color array <br/> glableclientstate (gl_color_array); <br/> glcolorpointer (4, gl_unsigned_byte, 0, colorarray); <br/> // 4 = rgba format, gl_unsigned_byte = data type, 0 = 0 stide bytes <br/> gldrawarrays (gl_triangles, 0, 3 ); <br/>/* We want draw triangles, 0 = first element (vertice), 3 = number of <br/> items (vertices) to draw from the array */<br/> gldisableclientstate (gl_vertex_array); <br/> histogram (gl_color_array); </P> <p> eglswapbuffers (glesdisplay, glessurface ); <br/>}< br/> // configure <br/> void clean () <br/>{< br/> If (glesdisplay) <br/>{< br/> eglmakecurrent (glesdisplay, null, null); <br/> If (glescontext) egldestroycontext (glesdisplay, glescontext ); <br/> If (glessurface) egldestroysurface (glesdisplay, glessurface); <br/> eglterminate (glesdisplay ); <br/>}< br/> // we have to destroy the window too <br/> destroywindow (hwnd); <br/> unregisterclass (szappname, hinst ); <br/>}
Run, the result is displayed, very good. An OGL window is in my mobile phone. A slowly rotating triangle in the middle.
Okay, it's time to work. Let's get started. In the future, I will also release some OGL es, whether I write or copy it myself, so that I can enjoy it after a meal.
Below is the link I have seen:
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
You will learn more from above like me.