#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无法在窗口上绘图。这样如果要在屏幕上输出字符比较麻烦。(这种情况,我先将字符转为纹理,再输出)。