WinCE OpenGL绘制立方体和纹理贴图

最近工作之余,开始学习OpenGL,  想到WINCE也是支持OpenGL的,只不过是嵌入式的OpenGL ES。于是尝试写了一个WINCE下的OpenGL测试程序,实现了绘制立方体和纹理。效果图如下:

      

      需要注意的是,WINCE系统上开发OpenGL程序需具备以下条件:

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

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

      以下是具体的参考代码:

  1. /******************************************************************** 
  2. filename:   WinceOpenGLDemo.cpp 
  3. created:    2011-01-05 
  4. author:     firehood 
  5. purpose:    利用OpenGL ES实现了绘制立方体和纹理效果 
  6. *********************************************************************/  
  7.   
  8. // WinceOpenGLDemo.cpp : 定义应用程序的入口点。  
  9. //  
  10.   
  11. #include "stdafx.h"  
  12. #include "WinceOpenGLDemo.h"  
  13. #include <windows.h>  
  14. #include <commctrl.h>  
  15. #include "ImgLoader.h"  
  16. // OpenGL ES Includes     
  17. #include <GLES/gl.h>  
  18. #include <GLES/glext.h>  
  19. #include <EGL/egl.h>  
  20. #include <EGL/eglext.h>  
  21.   
  22. // OpenGL lib  
  23. #pragma comment(lib, "OpenGlLib\\libGLESv1_CM.lib")     
  24. #pragma comment(lib, "OpenGlLib\\libEGL.lib")  
  25.   
  26. // 全局变量:  
  27. HINSTANCE   g_hInst;            // 当前实例  
  28. TCHAR       szAppName[] = L"OpenGLES";        /*The application name and the window caption*/  
  29. CImgLoader  g_Image;  
  30. // OpenGL variables     
  31. EGLDisplay glesDisplay;  // EGL display     
  32. EGLSurface glesSurface;  // EGL rendering surface     
  33. EGLContext glesContext;  // EGL rendering context    
  34.   
  35. GLuint texture[6] = {0};    
  36.   
  37. // 立方体定点坐标  
  38. GLshort vertices[] = {    
  39.     -1,-1,1,    
  40.     1,-1,1,    
  41.     1,1,1,    
  42.     -1,1,1,    
  43.   
  44.     -1,-1,-1,    
  45.     -1,1,-1,    
  46.     1,1,-1,    
  47.     1,-1,-1,    
  48.   
  49.     -1,1,-1,    
  50.     -1,1,1,    
  51.     1,1,1,    
  52.     1,1,-1,    
  53.   
  54.     -1,-1,-1,    
  55.     1,-1,-1,    
  56.     1,-1,1,    
  57.     -1,-1,1,    
  58.   
  59.     1,-1,-1,    
  60.     1,1,-1,    
  61.     1,1,1,    
  62.     1,-1,1,    
  63.   
  64.     -1,-1,-1,    
  65.     -1,-1,1,    
  66.     -1,1,1,    
  67.     -1,1,-1  
  68. };    
  69.   
  70. // 各个面纹理坐标  
  71. GLshort texCoords[] = {    
  72.     0,0,1,0,1,1,0,1,        
  73.     0,0,1,0,1,1,0,1,       
  74.     0,0,1,0,1,1,0,1,       
  75.     0,0,1,0,1,1,0,1,       
  76.     0,0,1,0,1,1,0,1,       
  77.     0,0,1,0,1,1,0,1,       
  78. };    
  79.   
  80. // 三角形索引数据  
  81. GLbyte indices1[] = {    
  82.     0,1,3,2,    
  83.     0,0,0,0,    
  84.     0,0,0,0,    
  85.     0,0,0,0,    
  86.     0,0,0,0,    
  87.     0,0,0,0   
  88. };   
  89. GLbyte indices2[] = {    
  90.     0,0,0,0,    
  91.     4,5,7,6,    
  92.     0,0,0,0,    
  93.     0,0,0,0,    
  94.     0,0,0,0,    
  95.     0,0,0,0   
  96. };   
  97. GLbyte indices3[] = {    
  98.     0,0,0,0,    
  99.     0,0,0,0,    
  100.     8,9,11,10,    
  101.     0,0,0,0,    
  102.     0,0,0,0,    
  103.     0,0,0,0   
  104. };    
  105. GLbyte indices4[] = {    
  106.     0,0,0,0,    
  107.     0,0,0,0,    
  108.     0,0,0,0,    
  109.     12,13,15,14,    
  110.     0,0,0,0,    
  111.     0,0,0,0  
  112. };    
  113. GLbyte indices5[] = {    
  114.     0,0,0,0,    
  115.     0,0,0,0,    
  116.     0,0,0,0,    
  117.     0,0,0,0,    
  118.     16,17,19,18,    
  119.     0,0,0,0  
  120. };    
  121. GLbyte indices6[] = {    
  122.     0,0,0,0,    
  123.     0,0,0,0,    
  124.     0,0,0,0,    
  125.     0,0,0,0,    
  126.     0,0,0,0,    
  127.     20,21,23,22  
  128. };  
  129.   
  130. // 此代码模块中包含的函数的前向声明:  
  131. ATOM            MyRegisterClass(HINSTANCELPTSTR);  
  132. BOOL            InitInstance(HINSTANCEint);  
  133. LRESULT CALLBACK    WndProc(HWNDUINTWPARAMLPARAM);  
  134.   
  135. BOOL InitOGLES(HWND hWnd);  
  136. void CreateSurface();  
  137. BOOL LoadTexture(LPCTSTR lpFileName,GLuint *id);  
  138. void Render();  
  139. void Clean();  
  140.   
  141. int WINAPI WinMain(HINSTANCE hInstance,  
  142.                    HINSTANCE hPrevInstance,  
  143.                    LPTSTR    lpCmdLine,  
  144.                    int       nCmdShow)  
  145. {  
  146.     MSG msg;  
  147.   
  148.     // 执行应用程序初始化:  
  149.     if (!InitInstance(hInstance, nCmdShow))   
  150.     {  
  151.         return FALSE;  
  152.     }  
  153.   
  154.     BOOL done = FALSE;  
  155.     // 主消息循环:  
  156.     while(!done)    
  157.     {    
  158.         if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))    
  159.         {    
  160.             if(msg.message==WM_QUIT)    
  161.                 done = TRUE;    
  162.             else    
  163.             {     
  164.                 TranslateMessage(&msg);    
  165.                 DispatchMessage(&msg);    
  166.             }    
  167.         }    
  168.         else  
  169.         {  
  170.             Render();  
  171.         };  
  172.     }    
  173.   
  174.     return (int) msg.wParam;  
  175. }  
  176.   
  177. //  
  178. //  函数: MyRegisterClass()  
  179. //  
  180. //  目的: 注册窗口类。  
  181. //  
  182. //  注释:  
  183. //  
  184. ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)  
  185. {  
  186.     WNDCLASS wc;  
  187.   
  188.     wc.style         = CS_HREDRAW | CS_VREDRAW;  
  189.     wc.lpfnWndProc   = WndProc;  
  190.     wc.cbClsExtra    = 0;  
  191.     wc.cbWndExtra    = 0;  
  192.     wc.hInstance     = hInstance;  
  193.     wc.hIcon         = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINCEOPENGLDEMO));  
  194.     wc.hCursor       = 0;  
  195.     wc.hbrBackground = (HBRUSH) GetStockObject(NULL_BRUSH);  
  196.     wc.lpszMenuName  = 0;  
  197.     wc.lpszClassName = szWindowClass;  
  198.   
  199.     return RegisterClass(&wc);  
  200. }  
  201.   
  202. //  
  203. //   函数: InitInstance(HINSTANCE, int)  
  204. //  
  205. //   目的: 保存实例句柄并创建主窗口  
  206. //  
  207. //   注释:  
  208. //  
  209. //        在此函数中,我们在全局变量中保存实例句柄并  
  210. //        创建和显示主程序窗口。  
  211. //  
  212. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)  
  213. {  
  214.     HWND hWnd;  
  215.   
  216.     g_hInst = hInstance; // 将实例句柄存储在全局变量中  
  217.   
  218.     if (!MyRegisterClass(hInstance, szAppName))  
  219.     {  
  220.         return FALSE;  
  221.     }  
  222.   
  223.     hWnd = CreateWindow(  
  224.         szAppName,  
  225.         szAppName,  
  226.         WS_VISIBLE,  
  227.         0,  
  228.         0,  
  229.         ::GetSystemMetrics(SM_CXSCREEN),  
  230.         ::GetSystemMetrics(SM_CYSCREEN),  
  231.         NULL,  
  232.         NULL,  
  233.         hInstance,  
  234.         NULL);  
  235.   
  236.     if (!hWnd)  
  237.     {  
  238.         return FALSE;  
  239.     }  
  240.      
  241.     if(!InitOGLES(hWnd))  
  242.     {  
  243.         printf("InitOGLES failed\n");  
  244.         return FALSE;  
  245.     }  
  246.     CreateSurface();  
  247.   
  248.     ShowWindow(hWnd, SW_SHOW);  
  249.     UpdateWindow(hWnd);  
  250.   
  251.     return TRUE;  
  252. }  
  253.   
  254. //  
  255. //  函数: WndProc(HWND, UINT, WPARAM, LPARAM)  
  256. //  
  257. //  目的: 处理主窗口的消息。  
  258. //  
  259. //  WM_COMMAND  - 处理应用程序菜单  
  260. //  WM_PAINT    - 绘制主窗口  
  261. //  WM_DESTROY  - 发送退出消息并返回  
  262. //  
  263. //  
  264. LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)  
  265. {  
  266.     PAINTSTRUCT ps;  
  267.     HDC hdc;  
  268.   
  269.     switch (message)   
  270.     {  
  271.         case WM_CREATE:  
  272.             break;  
  273.         case WM_PAINT:  
  274.             hdc = BeginPaint(hWnd, &ps);  
  275.               
  276.             // TODO: 在此添加任意绘图代码...  
  277.               
  278.             EndPaint(hWnd, &ps);  
  279.             break;  
  280.         case WM_DESTROY:  
  281.             {  
  282.                 Clean();  
  283.                 PostQuitMessage(0);  
  284.             }  
  285.             break;  
  286.   
  287.         default:  
  288.             return DefWindowProc(hWnd, message, wParam, lParam);  
  289.     }  
  290.     return 0;  
  291. }  
  292.   
  293. BOOL InitOGLES(HWND hWnd)  
  294. {      
  295.     EGLint matchingConfigs;       
  296.     EGLint majorVersion = 0;    
  297.     EGLint minorVersion = 0;    
  298.   
  299.     glesDisplay = eglGetDisplay(GetDC(hWnd));  //Ask for an available display   
  300.     if( glesDisplay == EGL_NO_DISPLAY || eglGetError() != EGL_SUCCESS )    
  301.         return FALSE;    
  302.   
  303.     EGLConfig *configs_list;    
  304.     EGLint     num_configs;    
  305.     // Display initialization (we don't care about the OGLES version numbers)     
  306.     if( eglInitialize( glesDisplay, &majorVersion, &minorVersion) == EGL_FALSE)    
  307.     {  
  308.         printf("eglInitialize failed, eglGetError = 0x%04x\n",eglGetError());  
  309.         return FALSE;    
  310.     }  
  311.     // find out how many configurations are supported     
  312.     if ( eglGetConfigs( glesDisplay, NULL, 0, &num_configs)==EGL_FALSE || eglGetError() != EGL_SUCCESS )    
  313.         return FALSE;    
  314.     configs_list = (EGLConfig*) malloc(num_configs * sizeof(EGLConfig));    
  315.     if (configs_list == NULL)    
  316.         return FALSE;    
  317.     // Get Configurations     
  318.     if( eglGetConfigs( glesDisplay, configs_list, num_configs, &num_configs)== EGL_FALSE || eglGetError() != EGL_SUCCESS )    
  319.         return FALSE;    
  320.     // Obtain the first configuration with a depth buffer of 16 bits     
  321.     EGLint attrs[] = {  
  322.         EGL_RED_SIZE,      5,  
  323.         EGL_GREEN_SIZE,    6,  
  324.         EGL_BLUE_SIZE,     5,  
  325.         EGL_DEPTH_SIZE,   16,  
  326.         EGL_NONE  
  327.     };  
  328.     if (!eglChooseConfig(glesDisplay, attrs, configs_list, num_configs, &matchingConfigs))    
  329.     {    
  330.         return eglGetError();    
  331.     }    
  332.     // If there isn't any configuration enough good     
  333.     if (matchingConfigs < 1)      
  334.         return FALSE;       
  335.     /*eglCreateWindowSurface creates an onscreen EGLSurface and returns   
  336.     a handle  to it. Any EGL rendering context created with a   
  337.     compatible EGLConfig can be used to render into this surface.*/    
  338.     glesSurface = eglCreateWindowSurface(glesDisplay, configs_list[0], hWnd, 0);      
  339.     if(!glesSurface)     
  340.         return FALSE;    
  341.   
  342.     // Let's create our rendering context     
  343.     glesContext=eglCreateContext(glesDisplay, configs_list[0], 0, 0);    
  344.     if(!glesContext)     
  345.         return FALSE;    
  346.     //Now we will activate the context for rendering       
  347.     eglMakeCurrent(glesDisplay, glesSurface, glesSurface, glesContext);     
  348.   
  349.     /*Remember: because we are programming for a mobile device, we cant   
  350.     use any of the OpenGL ES functions that finish in 'f', we must use   
  351.     the fixed point version (they finish in 'x'*/    
  352.     glClearColorx(0, 0, 0, 0);    
  353.     glShadeModel(GL_SMOOTH);      
  354.    
  355.     RECT rc;    
  356.     GetWindowRect(hWnd, &rc);    
  357.     UINT width = rc.right - rc.left;  
  358.     UINT height = rc.bottom - rc.top;  
  359.     // 设置OpenGL场景的大小     
  360.     glViewport(rc.left, rc.top, width, height);        
  361.   
  362.     // 设置投影矩阵     
  363.     glMatrixMode(GL_PROJECTION);    
  364.     glLoadIdentity();  
  365.       
  366.     // 投影变换(透视投影)  
  367.     float ratio = (float) width / height;    
  368.     glFrustumf(-ratio, ratio, -1, 1, 2, 10);  
  369.     //glOrthox(FixedFromInt(-50),FixedFromInt(50), FixedFromInt(-50), FixedFromInt(50), FixedFromInt(-50), FixedFromInt(50));  
  370.       
  371.     // 选择模型观察矩阵     
  372.     glMatrixMode(GL_MODELVIEW);     
  373.     // 重置模型观察矩阵     
  374.     glLoadIdentity();    
  375.   
  376.     return TRUE;    
  377. }  
  378.   
  379. void CreateSurface()    
  380. {    
  381.     glDisable(GL_DITHER);    
  382.   
  383.     // 告诉系统对透视进行修正     
  384.     glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);    
  385.     // 黑色背景     
  386.     glClearColor(0, 0, 0, 0);    
  387.       
  388.     // 启用阴影平滑     
  389.     glShadeModel(GL_SMOOTH);    
  390.       
  391.     // 设置深度缓存  
  392.     glClearDepthf(1.0f);    
  393.     // 启用深度测试     
  394.     glEnable(GL_DEPTH_TEST);    
  395.     // 所作深度测试的类型  
  396.     glDepthFunc(GL_LEQUAL);    
  397.       
  398.     // 启用2D纹理  
  399.     glEnable(GL_TEXTURE_2D);   
  400.     // 加载纹理  
  401.     LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[0]);  
  402.     LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[1]);  
  403.     LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[2]);  
  404.     LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[3]);  
  405.     LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[4]);  
  406.     LoadTexture(_T("\\NAND2\\OpenGlRes\\1.png"),&texture[5]);  
  407. }  
  408.   
  409. void Render()  
  410. {  
  411.     static float rotation = 0;  
  412.     // 清除屏幕和深度缓存     
  413.     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);    
  414.   
  415.     glMatrixMode(GL_MODELVIEW);    
  416.     // 重置当前的模型观察矩阵     
  417.     glLoadIdentity();    
  418.   
  419.     // 坐标变换  
  420.     glTranslatef(0.0f, 0.0f, -5.0f);    
  421.   
  422.     // 设置旋转     
  423.     glRotatef(rotation++, 0.0f, 1.0f, 0.0f);    
  424.     glRotatef(rotation++, 1.0f, 0.0f, 0.0f);    
  425.       
  426.     glEnableClientState(GL_VERTEX_ARRAY);    
  427.     glEnableClientState(GL_TEXTURE_COORD_ARRAY);   
  428.   
  429.     glVertexPointer(3, GL_SHORT, 0, vertices);    
  430.     glTexCoordPointer(2, GL_SHORT, 0, texCoords);     
  431.   
  432.     // 绘制立方体并绑定纹理  
  433.     glBindTexture(GL_TEXTURE_2D, texture[0]);  
  434.     glDrawElements(GL_TRIANGLE_STRIP, 4,  GL_UNSIGNED_BYTE, indices1);    
  435.     glBindTexture(GL_TEXTURE_2D, texture[1]);  
  436.     glDrawElements(GL_TRIANGLE_STRIP, 8,  GL_UNSIGNED_BYTE, indices2);    
  437.     glBindTexture(GL_TEXTURE_2D, texture[2]);  
  438.     glDrawElements(GL_TRIANGLE_STRIP, 12,  GL_UNSIGNED_BYTE, indices3);    
  439.     glBindTexture(GL_TEXTURE_2D, texture[3]);  
  440.     glDrawElements(GL_TRIANGLE_STRIP, 16,  GL_UNSIGNED_BYTE, indices4);    
  441.     glBindTexture(GL_TEXTURE_2D, texture[4]);  
  442.     glDrawElements(GL_TRIANGLE_STRIP, 20,  GL_UNSIGNED_BYTE, indices5);    
  443.     glBindTexture(GL_TEXTURE_2D, texture[5]);  
  444.     glDrawElements(GL_TRIANGLE_STRIP, 24,  GL_UNSIGNED_BYTE, indices6);    
  445.   
  446.     glDisableClientState(GL_TEXTURE_COORD_ARRAY);    
  447.     glDisableClientState(GL_VERTEX_ARRAY);    
  448.   
  449.     eglSwapBuffers(glesDisplay, glesSurface);    
  450. }  
  451.   
  452. void Clean()  
  453. {    
  454.     if(glesDisplay)    
  455.     {    
  456.         eglMakeCurrent(glesDisplay, NULL, NULL, NULL);      
  457.         if(glesContext) eglDestroyContext(glesDisplay, glesContext);    
  458.         if(glesSurface) eglDestroySurface(glesDisplay, glesSurface);    
  459.         eglTerminate(glesDisplay);    
  460.     }  
  461. }     
  462.   
  463. BOOL LoadTexture(LPCTSTR lpFileName,GLuint *id)  
  464. {  
  465.     if(!g_Image.Load(lpFileName))  
  466.         return FALSE;  
  467.       
  468.     // 创建纹理  
  469.     glGenTextures(1, id);  
  470.     // 绑定纹理  
  471.     glBindTexture(GL_TEXTURE_2D, *id);  
  472.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);  
  473.     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);   
  474.   
  475.     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, g_Image.Width(), g_Image.Height(), 0, GL_RGB, GL_UNSIGNED_BYTE, g_Image.GetBmpImage());   
  476.   
  477.     g_Image.Free();  
  478.   
  479.     return TRUE;  
  480. }  


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

  1. /******************************************************************** 
  2. filename:   CImgLoader.h 
  3. created:    2011-01-05 
  4. author:     firehood 
  5.  
  6. purpose:    文件加载类,将外部图片资源转化成绘制纹理时所需的位图数据 
  7.             图片格式支持bmp、png、jpg. 
  8. *********************************************************************/  
  9. #pragma once  
  10.   
  11. class CImgLoader  
  12. {  
  13. public:  
  14.     CImgLoader(void);  
  15.     ~CImgLoader(void);  
  16. public:  
  17.     // 加载图片资源  
  18.     BOOL Load(LPCTSTR lpFileName);  
  19.     // 获取位图数据  
  20.     unsigned char* GetBmpImage(void);  
  21.     // 释放图片资源  
  22.     void Free();  
  23.     // 获取图像宽度  
  24.     int Width();  
  25.     // 获取图像高度  
  26.     int Height();  
  27. private:  
  28.     int m_Width;                  // 图像宽度  
  29.     int m_Height;                 // 图像高度  
  30.     unsigned char *m_pImage;      // 指向图像数据的指针  
  31. };  

 

  1. /******************************************************************** 
  2. filename:   CImgLoader.cpp 
  3. created:    2011-01-05 
  4. author:     firehood 
  5.  
  6. purpose:    文件加载类,将外部图片资源转化成绘制纹理时所需的位图数据 
  7.             图片格式支持bmp、png、jpg. 
  8. *********************************************************************/  
  9.   
  10. #include "StdAfx.h"  
  11. #include "ImgLoader.h"  
  12. // IImage Includer  
  13. #include <imaging.h>  
  14. #include <initguid.h>  
  15. #include <imgguids.h>   
  16. // IImage lib  
  17. #pragma comment(lib, "Imaging.lib")  
  18.   
  19. CImgLoader::CImgLoader(void)  
  20. {  
  21.     m_pImage = NULL;  
  22.     m_Width = 0;  
  23.     m_Height = 0;  
  24. }  
  25.   
  26. CImgLoader::~CImgLoader(void)  
  27. {  
  28. }  
  29.   
  30. // 加载图片资源  
  31. BOOL CImgLoader::Load(LPCTSTR lpFileName)  
  32. {  
  33.     IImagingFactory *pImgFactory = NULL;  
  34.     IImage *pImage = NULL;  
  35.     IBitmapImage *pBmpImg = NULL;  
  36.     //   
  37.     CoInitializeEx(NULL, COINIT_MULTITHREADED);  
  38.     if (!SUCCEEDED(CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **) &pImgFactory)))   
  39.         return FALSE;  
  40.     if (!SUCCEEDED(pImgFactory->CreateImageFromFile(lpFileName, &pImage)))   
  41.         return FALSE;  
  42.     // 获取图像大小信息  
  43.     ImageInfo ImgInfo;  
  44.     pImage->GetImageInfo(&ImgInfo);  
  45.   
  46.     m_Width = ImgInfo.Width;  
  47.     m_Height = ImgInfo.Height;  
  48.   
  49.     if (FAILED(pImgFactory->CreateBitmapFromImage(  
  50.         pImage,m_Width,m_Height,PixelFormat24bppRGB,  
  51.         InterpolationHintDefault,&pBmpImg)))  
  52.     {  
  53.         return FALSE;  
  54.     }  
  55.     RECT rect = {0,0,m_Width,m_Height};  
  56.     BitmapData *BmpData = new BitmapData;  
  57.   
  58.     if (FAILED(pBmpImg->LockBits(&rect,  
  59.         ImageLockModeRead|ImageLockModeWrite,  
  60.         PixelFormat24bppRGB,BmpData)))  
  61.     {  
  62.         return FALSE;  
  63.     }  
  64.     int line = BmpData->Stride;  
  65.     LPBYTE lpData, lpLine, lpCurPixel;   
  66.     lpData = lpLine = (LPBYTE)BmpData->Scan0;   // 获取BMP位图实际值的地址指针  
  67.     // 若为Bottom-Up(从下到上)的位图,则指向buffer的结尾  
  68.     // 若为Top-Down(从上到下)的位图,则指向buffer的开头  
  69.     // int nBytesPP = nBPP >> 3;     // 左移三位即除以8,获取图像每像素字节数  
  70.     m_pImage = new unsigned char[m_Width * m_Height * 3];  
  71.     memset(m_pImage, 0, m_Width * m_Height * 3);  
  72.     if(m_pImage == NULL)  
  73.         return FALSE;  
  74.     if (line>0)  
  75.     {  
  76.         int pos = m_Width * m_Height * 3-1;  
  77.         for(int i = 0; i<m_Height; i++)                  // 行  
  78.         {  
  79.             lpLine = lpData + i * line;               // 获取图像每一行地址指针  
  80.             for(int j = m_Width-1; j>-1; j--)           // 列  
  81.             {  
  82.                 lpCurPixel = lpLine + j * 3;          // 获取每行每像素地址指针  
  83.                 m_pImage[pos--] = *lpCurPixel ;       // R  
  84.                 m_pImage[pos--] = *(lpCurPixel + 1);  // G  
  85.                 m_pImage[pos--] = *(lpCurPixel + 2);  // B  
  86.             }  
  87.         }  
  88.     }  
  89.     else  
  90.     {  
  91.         int pos = 0 ;  
  92.         for(int i = m_Height-1; i>-1; i--)               // 行  
  93.         {  
  94.             lpLine = lpData + i * line;               // 获取图像每一行地址指针  
  95.             for(int j = 0; j<m_Width; j++)              // 列  
  96.             {  
  97.                 lpCurPixel = lpLine + j * 3;          // 获取每行每像素地址指针  
  98.                 m_pImage[pos++] = *(lpCurPixel + 2);  // R  
  99.                 m_pImage[pos++] = *(lpCurPixel + 1);  // G  
  100.                 m_pImage[pos++] = *lpCurPixel;        // B  
  101.             }  
  102.         }  
  103.     }  
  104.     if (FAILED(pBmpImg->UnlockBits(BmpData)))  
  105.     {  
  106.         return FALSE;  
  107.     }  
  108.     delete BmpData;  
  109.     pBmpImg = NULL;  
  110.     pImage->Release();   
  111.     pImgFactory->Release();   
  112.     return TRUE;  
  113. }  
  114.   
  115. // 获取图片数据  
  116. unsigned char* CImgLoader::GetBmpImage(void)  
  117. {  
  118.     return m_pImage;  
  119. }  
  120.   
  121. // 获取图像宽度  
  122. int CImgLoader::Width()  
  123. {  
  124.     return m_Width;  
  125. }  
  126.   
  127. // 获取图像高度  
  128. int CImgLoader::Height()  
  129. {  
  130.     return m_Height;  
  131. }  
  132.   
  133. // 释放图片资源  
  134. void CImgLoader::Free()  
  135. {  
  136.     if(m_pImage)  
  137.     {  
  138.         delete []m_pImage;  
  139.         m_pImage = NULL;  
  140.     }  
  141. }  
posted @ 2012-10-21 20:21  小城zjc  阅读(289)  评论(0)    收藏  举报