#include <EGL/egl.h> #include <GLES/gl.h> #include "ximage.h" #pragma comment(lib, "libEGL.lib") #pragma comment(lib, "libGLESv1_CM.lib") #define glF(x) ((GLfixed)((x)*(1<<16))) #define GL_F GL_FIXED typedef GLfixed GLf; #define PI 3.141592653 class COpenGLES { public: COpenGLES(void); ~COpenGLES(void); EGLConfig m_EGLXConfig; EGLContext m_EGLXContext; EGLSurface m_EGLXSurface; EGLDisplay m_EGLXDisplay; EGLint m_EGLXNumOfConfigs; EGLint max_num_config; NativeDisplayType g_dpy; HWND m_hwnd; BOOL CreateEGL(HWND hwnd); void DeleteEGL(); void glPerspectivef(GLfloat fov, GLfloat aspect, GLfloat near_val, GLfloat far_val); void SetProjectToOrtho(void); void SetProjectToFrustum(); void EGLFlush(); bool Init(HWND m_hWnd); void InitGLES(); void CloseGLES(); };
cpp
COpenGLES::COpenGLES(void) { } COpenGLES::~COpenGLES(void) { } BOOL COpenGLES::CreateEGL(HWND hwnd) { m_hwnd = hwnd; EGLint const attrib_list[] = { EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_ALPHA_SIZE, 0, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, EGL_SURFACE_TYPE, EGL_WINDOW_BIT, EGL_SAMPLE_BUFFERS, GL_FALSE, EGL_NONE }; EGLint ai32ContextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE }; EGLConfig *configs = NULL; g_dpy = ::GetDC(hwnd); EGLint major, minor, num_config; m_EGLXDisplay = eglGetDisplay( g_dpy ); if ( EGL_NO_DISPLAY == m_EGLXDisplay ) { printf( "eglGetDisplay() failed (error 0x%x)\n", eglGetError() ); return 0; } if ( EGL_FALSE == eglInitialize( m_EGLXDisplay, &major, &minor ) ) { printf( "eglInitialize() failed (error 0x%x)\n", eglGetError() ); return 0; } if ( EGL_FALSE == eglGetConfigs(m_EGLXDisplay, NULL, 0, &max_num_config) ) { return 0; } if(max_num_config <= 0) { return 0; } configs = (EGLConfig *)malloc( sizeof( EGLConfig) * max_num_config ); if ( NULL == configs ) { return 0; } printf("max_num_config=%d\n",max_num_config);//23 if ( EGL_FALSE == eglChooseConfig( m_EGLXDisplay, attrib_list, configs,max_num_config, &m_EGLXNumOfConfigs ) ) { printf( "eglChooseConfig() failed (error 0x%x)\n", eglGetError() ); return 0; } printf("m_EGLXNumOfConfigs=%d\n",m_EGLXNumOfConfigs);//8 if ( 0 == m_EGLXNumOfConfigs ) { printf( "eglChooseConfig() was unable to find a suitable config\n" ); return 0; } for (int i=0; i<m_EGLXNumOfConfigs; i++ ) { EGLint value; eglGetConfigAttrib( m_EGLXDisplay, configs[i], EGL_RED_SIZE, &value ); if ( 5 != value ) continue; eglGetConfigAttrib( m_EGLXDisplay, configs[i], EGL_GREEN_SIZE, &value ); if ( 6 != value ) continue; eglGetConfigAttrib( m_EGLXDisplay, configs[i], EGL_BLUE_SIZE, &value ); if ( 5 != value ) continue; eglGetConfigAttrib( m_EGLXDisplay, configs[i], EGL_ALPHA_SIZE, &value ); if ( 0 != value ) continue; eglGetConfigAttrib( m_EGLXDisplay, configs[i], EGL_SAMPLES, &value ); if ( 4 != value ) continue; m_EGLXConfig = configs[i]; printf("i=%d\n",i); break; } m_EGLXSurface = eglCreateWindowSurface( m_EGLXDisplay, m_EGLXConfig, hwnd, 0 ); printf("m_EGLXSurface=%d\n",m_EGLXSurface);//m_EGLXSurface=536870913 if ( EGL_NO_SURFACE == m_EGLXSurface ) { printf( "eglCreateWindowSurface failed (error 0x%x)\n", eglGetError() ); return 0; } m_EGLXContext = eglCreateContext( m_EGLXDisplay, m_EGLXConfig, EGL_NO_CONTEXT, ai32ContextAttribs );//创建RC if ( EGL_NO_CONTEXT == m_EGLXContext ) { printf( "eglCreateContext failed (error 0x%x)\n", eglGetError() ); return 0; } if ( EGL_FALSE == eglMakeCurrent( m_EGLXDisplay, m_EGLXSurface, m_EGLXSurface, m_EGLXContext ) ) { printf( "eglMakeCurrent failed (error 0x%x)\n", eglGetError() ); return 0; } eglSwapInterval(m_EGLXDisplay,0); free( configs ); return true; } void COpenGLES::DeleteEGL() { eglMakeCurrent(m_EGLXDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(m_EGLXDisplay, m_EGLXContext); eglDestroySurface(m_EGLXDisplay, m_EGLXSurface); eglTerminate(m_EGLXDisplay); } void COpenGLES::glPerspectivef(GLfloat fov, GLfloat aspect, GLfloat near_val, GLfloat far_val) { GLfloat top = (GLfloat)(tan(fov*0.5) * near_val); GLfloat bottom = -top; GLfloat left = aspect * bottom; GLfloat right = aspect * top; printf("left = %lf,right = %lf,bottom = %lf ,top = %lf,near =%lf,far = %lf\n", left,right,bottom,top,near_val,far_val); glFrustumx(glF(left), glF(right), glF(bottom), glF(top), glF(near_val),glF(far_val)); } void COpenGLES::InitGLES() { //设置视口大小 //设置裁剪区域 //glScissor(0,0,800,480); //设置模型视图矩阵 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //打开状态 glEnable(GL_NORMALIZE); //自动归一化法向量 glEnable(GL_COLOR_MATERIAL);//允许颜色材质 glEnable(GL_DEPTH_TEST); //将被遮挡的表面隐藏掉 glEnable(GL_TEXTURE_2D); glEnable(GL_CULL_FACE);//不计算多边形背面 //背面不贴图 glCullFace(GL_BACK); glFrontFace(GL_CCW); //多边形逆时针方向是正面 glDepthFunc(GL_LEQUAL); //对透视进行修正 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glClearColor(0.0f, 1.0f, 0.0f, 0.5f); // Black Background glClearDepthf(1.0f); /*glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_NOTEQUAL,0.0f);*/ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); //(源,目标) //启动阴影平滑 glShadeModel(GL_SMOOTH); glDisableClientState(GL_COLOR_ARRAY); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); //取消抖动 glDisable(GL_DITHER); //完成 glFinish(); } //************************************ // Method: OrthoBegin // FullName: COpenGLES::OrthoBegin // Access: public // Returns: void // Qualifier: // Parameter: void 平行投影 范围是左下角(0,0)右上角(800,480) //************************************ void COpenGLES::SetProjectToOrtho(void) { glViewport(0, 0, 800, 480); glDisable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrthof(0.0f, 800.0f, 0.0f, 480.0f, -10.0f, 10.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void COpenGLES::SetProjectToFrustum() { glViewport(0,0,800,480); //设置重置投影 glMatrixMode(GL_PROJECTION); glLoadIdentity(); //透视处理 //glPerspectivef(45.0f,(GLfloat)800/(GLfloat)480,0.01f,1000.0f); glFrustumx(glF(-5.0f), glF(5.0f), glF(-3.0f), glF(3.0f), glF(10.0f),glF(1000.0f));//左右上下近远 //near far 参数均为正值,left为负值,right为正值,top为正值,bottom为负值 //left(right)与bottom(top)保持屏幕的纵横比关系 glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //完成 glFinish(); } void COpenGLES::EGLFlush() { glFlush(); eglSwapBuffers(m_EGLXDisplay,m_EGLXSurface); } bool COpenGLES::Init(HWND m_hWnd) { if(!CreateEGL(m_hWnd)) return false; InitGLES(); SetProjectToFrustum();//开始默认设置为透视投影矩阵 return TRUE; } void COpenGLES::CloseGLES() { DeleteEGL(); RETAILMSG(1,(TEXT("==APP==END\n"))); }
使用:
COpenGLES gl; gl.Init(m_hWnd); gl.SetProjectToOrtho();
在函数CreateEGL中
m_EGLXSurface = eglCreateWindowSurface( m_EGLXDisplay, m_EGLXConfig, hwnd, 0 );
第三个参数,可以传入对话框的句柄,这样,opengles与gdi使用同一个窗口。
如果传入null,GDI无法在窗口上绘图。这样如果要在屏幕上输出字符比较麻烦。(这种情况,我先将字符转为纹理,再输出)。