- {
- 1:获取 Display
- 2:初始化 egl
- 3:选择 Config
- 4:创建 Surface
- 5:创建上下文对象
- 6:查看 Display Surface Context 是否创建成功
- 7:绘制
- 8:销毁 OpenGLES
- }
- #include <EGL/egl.h>
- #include <gles2/gl2.h>
- #include "freeImage/FreeImage.h"
- class WinApp {
- public:
- WinApp(HINSTANCE hInstance);
- virtual~WinApp(void);
- virtual LRESULT onEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
- static LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
- int main(int wWidth,int wHegith);
- bool configurationInit();
- void draw();//画
- void destroy();//销毁
- private:
- HINSTANCE _hInstance; //实例句柄
- HWND _hWnd;//窗口句柄
- protected;
- int _width; // 视口宽度
- int _height;// 视口高度
- EGLDisplay _display;
- EGLContext _context;
- EGLSurface _surface;
- EGLConfig _config;
- };
1.下载AMD的OpenGL ES2.0的模拟器,地址: http://www.opengles-book.com/ESEmulator.2009-04-28-v1.4.APRIL_2009_RELEASE.msi
2.下载OpenGL ES2.0实例代码,用《OpenGL ES2.0 Programming guide》里的例子代码,地址: http://www.opengles-book.com/OpenGL_ES_Programming_Guide_v1.0.2.zip.
3.下载Visual Studio, 会写点程序的都懂。
教程:
1. 解压上面下载的例子代码。
2.安装OpenGL ES2.0模拟器, 将安装目录下的AMD\OpenGL ES 2.0 Emulator v1.1\bin 以及AMD\OpenGL ES 2.0 Emulator v1.1\lib 里的 libEGL.dll 、 libGLESv2.dll 和 libEGL.lib 、libGLESv2.lib分别拷贝至VS的bin和lib文件夹下。
3.接着打开例子代码里的工程就可以了。
之后就可以通过修改例子来实现在windows上练习实践opengles2.0了。这样的好处是用c/c++实现编程,之后方便移植至Android、iOS等系统,再者还可以利用起强大的VS。
- #include "WinApp.h"
- bool WinApp::configurationInit(){
- //1:获取 Display
- _display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- //2:初始化 egl
- EGLint major;//返回主版本号
- EGLint minor;//返回次版本号
- eglInitialize(_display, &major, &minor);
- //3:选择 Config
- const EGLint attribs[] ={
- //属性是一对一的初始化(类似与key->value)
- EGL_SURFACE_TYPE, EGL_WINDOW_BIT,//把数据画到窗口上
- EGL_BLUE_SIZE, 8,//R 占8个比特位
- EGL_GREEN_SIZE, 8,//G 占8个比特位
- EGL_RED_SIZE, 8, //B 占8个比特位
- EGL_DEPTH_SIZE,24,//深度值 占24个比特位 画图的深度值 (前后顺序的层)
- EGL_NONE //这个机构结束了
- };
- EGLint format(0);
- EGLint numConfigs(0);
- //让EGL为你选择一个配置
- eglChooseConfig(_display, attribs, &_config, 1, &numConfigs);
- //可以查询某个配置的某个属性
- eglGetConfigAttrib(_display, _config, EGL_NATIVE_VISUAL_ID, &format);
- 4:创建 Surface
- _surface = eglCreateWindowSurface(_display, _config, _hWnd, NULL);
- //5:创建上下文对象
- EGLint attr[] ={ EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
- //创建上下文对象
- _context = eglCreateContext(_display, _config, EGL_NO_CONTEXT, attr);
- //6:查看 Display Surface Context 是否创建成功
- if (eglMakeCurrent(_display, _surface, _surface, _context) == EGL_FALSE){
- return false;
- }
- //查询Suface的属性 获取Suface中的宽高
- eglQuerySurface(_display, _surface, EGL_WIDTH, &_width);
- eglQuerySurface(_display, _surface, EGL_HEIGHT, &_height);
- return true;
- }
- void WinApp::draw(){
- //glDrawArrays(GL_TRIANGLE_STRIP,0,0);
- glClearColor(0,0,1,1);//刷屏
- //清除颜色GL_COLOR_BUFFER_BIT 和 清除深度值GL_DEPTH_BUFFER_BIT
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glViewport(0,0,_width,_height);//绘制区域
- //绘制
- eglSwapBuffers(_display,_surface);
- }
- void WinApp::destroy(){
- if (_display != EGL_NO_DISPLAY){//当前的Display 不等于null
- //清楚绑定的 Surface Context
- eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (_context != EGL_NO_CONTEXT){//不等于空Context
- //销毁上下文
- eglDestroyContext(_display, _context);
- }
- if (_surface != EGL_NO_SURFACE){//不等于空Surface
- //销毁Surface
- eglDestroySurface(_display, _surface);
- }
- //终止Dispay
- eglTerminate(_display);
- }
- //把 Display Context Surface 设置成初始化
- _display = EGL_NO_DISPLAY;
- _context = EGL_NO_CONTEXT;
- _surface = EGL_NO_SURFACE;
- }
- //---------------------窗口----------------------
- WinApp::WinApp(HINSTANCE hInstance):_hInstance(hInstance){
- WNDCLASSEX winClass;
- winClass.lpszClassName = _T("CELLWinApp");//指向类名称的指针(窗口名字)
- winClass.cbSize = sizeof(winClass);//WNDCLASSEX 的大小
- winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;//窗口风格
- winClass.lpfnWndProc = wndProc;//窗口处理函数的指针
- winClass.hInstance = hInstance;//本模块的实例句柄
- winClass.hIcon = 0;//图标
- winClass.hIconSm = 0;//和窗口类关联的小图标,如果该值为NULL,则把hIcon中的图标转换成大小合适的小图标
- winClass.hCursor = LoadCursor(hInstance, IDC_ARROW);//鼠标句柄
- winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);//背景画刷的句柄。
- winClass.lpszMenuName = NULL;//指向菜单的指针
- winClass.cbClsExtra = 0;
- winClass.cbWndExtra = 0;
- //1:注册窗口
- //随后在调用Createwindow函数和CreatewindowEx函数中使用的窗口注册一个窗口类。
- RegisterClassEx(&winClass);
- }
- LRESULT CALLBACK WinApp::wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
- //获取窗口属性
- WinApp* pThis = (WinApp*)GetWindowLong(hWnd,GWL_USERDATA);
- if (pThis) {
- return pThis->onEvent(hWnd,msg,wParam,lParam);
- }
- if (WM_CREATE == msg){ //窗口创建完成时发来的消息
- CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;
- //获取当前对象(CreateWindowEx函数中最后一个参数)
- DWORD_PTR pCreateParams = (DWORD_PTR)pCreate->lpCreateParams;
- /**设置窗口属性
- * @param HWND hWnd 窗口句柄
- * @param int nlndex
- * @param LONG dwNewLong
- */
- SetWindowLong(hWnd,GWL_USERDATA,pCreateParams);
- }
- return DefWindowProc( hWnd, msg, wParam, lParam );
- }
- //事件函数
- LRESULT WinApp::onEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
- switch (msg){ //处理得到的消息
- case WM_CLOSE://处理窗口关闭时的消息
- case WM_DESTROY://销毁
- {
- ::PostQuitMessage(0);
- }
- break;
- case WM_LBUTTONDOWN: //鼠标左键被按下的消息
- break;
- case WM_RBUTTONDOWN://鼠标右键被按下的消息
- break;
- case WM_MOUSEMOVE://鼠标移动
- break;
- case WM_KEYDOWN://监听键盘按键
- switch (wParam){
- case VK_LEFT:
- break;
- default:
- break;
- }
- break;
- default:
- return DefWindowProc( hWnd, msg, wParam, lParam );
- }
- return S_OK;
- }
- WinApp::~WinApp(void){
- //注销一个窗口类,类释放所需的内存
- UnregisterClass(_T("CELLWinApp"),_hInstance);
- destroy();
- }
- int WinApp::main(int wWidth,int wHegith){
- //2:创建窗口
- //创建一个具有扩展风格的层叠式窗口、弹出式窗口或子窗口,其他与CreateWindow函数相同。关于创建窗口和其他参数的内容,请参看CreateWindow。
- /**创建一个具有扩展风格的层叠式窗口、弹出式窗口或子窗口
- * @param DWORD dwExStyle 窗口的扩展风格
- * @param LPCWSTR lpClassName 指向注册类名的指针
- * @param LPCWSTR lpWindowName 指向窗口名称的指针
- * @param DWORD dwStyle 窗口风格
- * @param int X 窗口的水平位置
- * @param int Y 窗口的垂直位置
- * @param int nWidth 窗口的宽度
- * @param int nHeight 窗口的高度
- * @param HWND hWndParent 父窗口的句柄
- * @param HMENU hMenu 菜单的句柄或是子窗口的标识符
- * @param HINSTANCE hInstance 应用程序实例的句柄
- * @param LPVOID lpParam 指向窗口的创建数据
- */
- _hWnd = CreateWindowEx( NULL, _T("CELLWinApp"), _T("CELLWinApp"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, wWidth, wHegith, NULL, NULL, _hInstance,this );
- if (_hWnd == 0) {
- return -1;
- }
- //3:更新显示窗口
- ShowWindow(_hWnd,SW_SHOW);//SW_MAXIMIZE 扩大窗口,SW_SHOW
- configurationInit();
- //4:消息循环
- MSG msg = {0};
- while(msg.message != WM_QUIT) { //消息不等于退出
- //毁坏,结束
- if (msg.message == WM_DESTROY || msg.message == WM_CLOSE){
- break;
- }
- //有消息返回真,无消息返回假
- if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ){//有消息:处理消息
- TranslateMessage( &msg );//消息处理
- DispatchMessage( &msg );//分发给那个窗口(程序中有好多窗口,那个点击了,就分发给那个)
- }else{//无消息:则进行渲染绘制或睡眠
- // Sleep(1);
- draw();
- }
- }
- return 0;
- }
画出一个蓝色的界面就可以了