第一个基于C++的opengles画正方形

来源:互联网 发布:江门网络推广公司 编辑:程序博客网 时间:2024/05/20 11:21

#pragma once#include <assert.h>class ShaderId{public:ShaderId(){_shaderId = -1;}   int _shaderId;};//程序class ProgramId{public:int _programId;ShaderId _vertext;ShaderId _fragment;public:ProgramId(){_programId = -1;}public://加载shader函数到GPUbool createProgram(const char* vertex, const char* fragment){bool error = false;do{//加载顶点shaderif (vertex){_vertext._shaderId = glCreateShader(GL_VERTEX_SHADER);glShaderSource(_vertext._shaderId, 1, &vertex, 0);//编译glCompileShader(_vertext._shaderId);GLint compileStatus;//获取编译状态glGetShaderiv(_vertext._shaderId, GL_COMPILE_STATUS, &compileStatus);error = compileStatus == GL_FALSE;if (errno){GLchar messages[256];glGetShaderInfoLog(_vertext._shaderId, sizeof(messages), 0, messages);assert(messages && 0 != 0);break;}}//加载片元shaderif (fragment){_fragment._shaderId = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(_fragment._shaderId, 1, &fragment, 0);//编译glCompileShader(_fragment._shaderId);GLint compileStatus;//获取编译状态glGetShaderiv(_fragment._shaderId, GL_COMPILE_STATUS, &compileStatus);errno = compileStatus == GL_FALSE;if (errno){GLchar message[256];glGetShaderInfoLog(_fragment._shaderId, sizeof(message), 0, message);assert(message && 0 != 0);break;}}_programId = glCreateProgram();if (_vertext._shaderId){glAttachShader(_programId, _vertext._shaderId);}if (_fragment._shaderId){glAttachShader(_programId, _fragment._shaderId);}glLinkProgram(_programId);GLint linkStatus;glGetProgramiv(_programId, GL_LINK_STATUS, &linkStatus);if (linkStatus==GL_FALSE){GLchar messages[256];glGetProgramInfoLog(_programId,sizeof(messages),0,messages);break;}glUseProgram(_programId);} while (false);if (errno){if (_fragment._shaderId){glDeleteShader(_fragment._shaderId);_fragment._shaderId = 0;}if (_vertext._shaderId){glDeleteShader(_vertext._shaderId);_vertext._shaderId = 0;}if (_programId){glDeleteProgram(_programId);_programId = 0;}}return true;}//使用程序virtual void begin(){glUseProgram(_programId);}//使用完成virtual void end(){glUseProgram(0);}};class PROGRAM_P2_C4 :public ProgramId{public:typedef int attribute;typedef int uniform;public:attribute _position;uniform _color;uniform _MVP;public:PROGRAM_P2_C4(){_position = -1;_color = -1;_MVP = -1;}~PROGRAM_P2_C4(){ }//初始化函数virtual bool initialize(){//顶点shader有多少个顶点,就会被执行多少次const char* vs = {"precision lowp float;"//指定float的精度"uniform mat4 _MVP;""attribute vec2 _position;""void main()""{""vec4 pos=vec4(_position,0,1);""gl_Position=_MVP*pos;""}"};const char* ps={"precision lowp float;""uniform vec4 _color;""void main()""{""gl_FragColor=_color;""}"};bool res = createProgram(vs, ps);if (res){//获得shader中变量的引用_position = glGetAttribLocation(_programId, "_position");_color = glGetUniformLocation(_programId, "_color");_MVP = glGetUniformLocation(_programId, "_MVP");}return res;}//使用程序virtual void begin(){glUseProgram(_programId);glEnableVertexAttribArray(_position);}//使用完成virtual void end(){glDisableVertexAttribArray(_position);glUseProgram(0);}};


#pragma once#include <Windows.h>#include <tchar.h>#include <egl/egl.h>#include <gles2/gl2.h>#include "CELLMath.hpp"#include "CELLShader.hpp"namespace CELL{class CELLWinApp{public://实例句柄HINSTANCE _hInstance;//窗口句柄HWND _hWnd;//窗口的宽度int _width;//窗口的高度int _height;//EGL 是 OpenGL ES 和底层 Native 平台视窗系统之间的接口//for gles2.0EGLConfig _config; //Surface的EGL配置EGLSurface _surface;//系统窗口或frame buffer句柄EGLContext _context;//openGL ES图形上下文EGLDisplay _display;//系统显示ID或句柄//增加shaderPROGRAM_P2_C4 _shader;public:CELLWinApp(HINSTANCE hInstance) :_hInstance(hInstance){WNDCLASSEX  winClass;winClass.lpszClassName = _T("CELLWinApp");winClass.cbSize = sizeof(winClass);winClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;winClass.lpfnWndProc = wndProc;winClass.hInstance = hInstance;winClass.hIcon = 0;winClass.hIconSm = 0;winClass.hCursor = LoadCursor(hInstance, IDC_ARROW);winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);winClass.lpszMenuName = NULL;winClass.cbClsExtra = 0;winClass.cbWndExtra = 0;RegisterClassEx(&winClass);}virtual ~CELLWinApp(){UnregisterClass(_T("CELLWinApp"), _hInstance);}//初始化opengles2.0bool initOpenGLES20(){//EGLint int数据类型const EGLint attribs[]={EGL_SURFACE_TYPE,EGL_WINDOW_BIT,EGL_BLUE_SIZE,8,EGL_GREEN_SIZE,8,EGL_RED_SIZE,8,EGL_DEPTH_SIZE,24,EGL_NONE};EGLint format(0);EGLint numConfigs(0);EGLint major;EGLint minor;//1--任何使用EGL的应用程序必须执行的第一个操作就是创建和//初始化与本地EGL显示的连接 eglGetDisplay打开与EGL显示服务器的连接//_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);//2--初始化EGL参数含义 display:指定EGL显示连接 major:指定EGL实现返回的主版本号,可能为NULL//minor:指定EGL实现返回的次版本号,可能为NULLeglInitialize(_display, &major, &minor);//3--让EGL选择匹配的EGLConfig  参数含义:display:指定EGL显示连接//attribs:指定configs匹配的属性列表,config:指定配置列表,1:指定配置的大小 numConfigs:指定返回的配置大小eglChooseConfig(_display, attribs, &_config, 1, &numConfigs);//查询EGLConfig属性 参数含义:display:指定EGL显示连接,config:指定要查询的配置//EGL_NATIVE_VISUAL_ID:指定返回的特定属性 format:指定返回值eglGetConfigAttrib(_display,_config,EGL_NATIVE_VISUAL_ID,&format);//4--创建屏幕上的渲染区域:EGL窗口//参数含义,display:指定EGL显示连接,config:指定配置,hWnd:指定原生窗口,最后一个参数//指定窗口属性列表,可能为NULL_surface = eglCreateWindowSurface(_display, _config, _hWnd, NULL);//5--创建一个渲染上下文,参数含义,display:指定EGL显示连接//config:指定配置,0(shareContext):允许多个EGL上下文共享特定类型的数据,//attr:属性列表EGLint attr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };_context = eglCreateContext(_display, _config, 0, attr);//6--指定某个EGLContext为当前上下文(因为一个应用可能创建多个EGLContext用于不同的用途,所以//需要关联特定的EGLContext和渲染表面,即指定当前上下文)//参数含义,display:指定EGL显示连接 surface:指定EGL绘图表面//surface:指定EGL读取表面 context:指定连接到该表面的渲染上下文if (eglMakeCurrent(_display,_surface,_surface,_context)==EGL_FALSE){return false;}//surface的属性查询eglQuerySurface(_display, _surface, EGL_WIDTH, &_width);eglQuerySurface(_display, _surface, EGL_HEIGHT, &_height);return true;}//销毁opengles2.0void destroyOpenGLES20(){if (_display!=EGL_NO_DISPLAY){eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);if (_context!=EGL_NO_CONTEXT){eglDestroyContext(_display,_context);}if (_surface!=EGL_NO_SURFACE){eglDestroySurface(_display, _surface);}eglTerminate(_display);}_display = EGL_NO_DISPLAY;_context = EGL_NO_CONTEXT;_surface = EGL_NO_SURFACE;}protected:static LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){CELLWinApp* pThis = (CELLWinApp*)GetWindowLong(hWnd,GWL_USERDATA);if (pThis){return pThis->onEvent(hWnd,msg,wParam,lParam);}if (WM_CREATE==msg){CREATESTRUCT* pCreate = (CREATESTRUCT*)lParam;SetWindowLong(hWnd,GWL_USERDATA,(DWORD_PTR)pCreate->lpCreateParams);}return DefWindowProc(hWnd,msg,wParam,lParam);}public://事件函数virtual LRESULT onEvent(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){switch (msg){case WM_CLOSE:case WM_DESTROY:{::PostQuitMessage(0);}break;case WM_MOUSEMOVE:break;default:return DefWindowProc(hWnd,msg,wParam,lParam);}return S_OK;}virtual void render(){//清空缓冲区glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);//视口,在windows 窗口指定的位置和大小上绘制opengl内容glViewport(0, 0, _width, _height);//创建一个投影矩阵CELL::matrix4 screenProj = CELL::ortho<float>(0, float(_width), float(_height), 0, -100.0f, 100);_shader.begin();{float x = 100;float y = 100;float w = 100;float h = 100;//要绘制的点的坐标CELL::float2 pos[] ={CELL::float2(x, y),CELL::float2(x + w, y),CELL::float2(x, y + h),CELL::float2(x + w, y + h),};//void glUniformMatrix4fv(GLint location,  GLsizei count,  GLboolean transpose,  const GLfloat *value); //location:指明要更改的uniform变量的位置 count:指明要更改的矩阵个数  transpose:是否要转置矩阵 必须为GL_FALSE //value:指明一个指向count个元素的指针,用来更新指定的uniform变量glUniformMatrix4fv(_shader._MVP,1,false,screenProj.data());glUniform4f(_shader._color, 0, 1, 0, 1);//void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,const GLvoid * pointer)//指定了渲染时索引值为index的顶点属性数组的数据格式和位置//index :指定要修改的顶点属性的索引值 size:指定每个顶点属性的组建数量,必须为1,2,3或4,初始值为4//type:指定数组中每个组建的数据类型,初始值 GL_FLOAT//normalized:是否归一化//stride:连续顶点属性之间的偏移量//pointer:顶点数组指针glVertexAttribPointer(_shader._position, 2, GL_FLOAT, false, sizeof(CELL::float2), pos);//按照设置的绘制方式开始绘制  //第一个参数是绘制方式,第二个参数是从数组缓存中的哪一位开始绘制,第三个参数是数组中顶点的数量glDrawArrays(GL_TRIANGLE_STRIP,0,4);}_shader.end();}//主函数int main(int width, int height){_hWnd = CreateWindowEx(NULL,_T("CELLWinApp"),_T("CELLWinApp"),WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,CW_USEDEFAULT,width,height,NULL,NULL,_hInstance,this);if (_hWnd == 0){return  -1;}UpdateWindow(_hWnd);ShowWindow(_hWnd,SW_SHOW);if (!initOpenGLES20()){return false;}_shader.initialize();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{render();eglSwapBuffers(_display, _surface);}}//销毁Opengles20destroyOpenGLES20();return 0;}};}


#include "CELLWinApp.hpp"int APIENTRY _tWinMain(HINSTANCE hInstance,                       HINSTANCE hPrevInstance,                       LPTSTR    lpCmdLine,                       int       nCmdShow){    UNREFERENCED_PARAMETER(hPrevInstance);    UNREFERENCED_PARAMETER(hInstance);    UNREFERENCED_PARAMETER(lpCmdLine);    UNREFERENCED_PARAMETER(nCmdShow);    CELL::CELLWinApp  app(hInstance);    app.main(800,600);    return 0;}


0 0
原创粉丝点击