opengles之修改已有纹理glTexSubImage2D函数用法

来源:互联网 发布:sublime text3下载mac 编辑:程序博客网 时间:2024/05/29 14:09

shader实现类:

#pragma once#include <assert.h>class    ShaderId{public:ShaderId(){_shaderId = -1;}int _shaderId;};/***   程序*/class   ProgramId{public:int         _programId;ShaderId    _vertex;ShaderId    _fragment;public:ProgramId(){_programId = -1;}public:/***   加载函数*/bool    createProgram(const char* vertex, const char* fragment){bool        error = false;do{if (vertex){_vertex._shaderId = glCreateShader(GL_VERTEX_SHADER);glShaderSource(_vertex._shaderId, 1, &vertex, 0);glCompileShader(_vertex._shaderId);GLint   compileStatus;glGetShaderiv(_vertex._shaderId, GL_COMPILE_STATUS, &compileStatus);error = compileStatus == GL_FALSE;if (error){GLchar messages[256];glGetShaderInfoLog(_vertex._shaderId, sizeof(messages), 0, messages);assert(messages && 0 != 0);break;}}if (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);error = compileStatus == GL_FALSE;if (error){GLchar messages[256];glGetShaderInfoLog(_fragment._shaderId, sizeof(messages), 0, messages);assert(messages && 0 != 0);break;}}_programId = glCreateProgram();if (_vertex._shaderId){glAttachShader(_programId, _vertex._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 (error){if (_fragment._shaderId){glDeleteShader(_fragment._shaderId);_fragment._shaderId = 0;}if (_vertex._shaderId){glDeleteShader(_vertex._shaderId);_vertex._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(){const char* vs ={"precision lowp 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){_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);}};class   PROGRAM_P2_AC4 :public ProgramId{public:typedef int attribute;typedef int uniform;public:attribute   _position;attribute   _color;uniform     _MVP;public:PROGRAM_P2_AC4(){_position = -1;_color = -1;_MVP = -1;}~PROGRAM_P2_AC4(){}/// 初始化函数virtual bool    initialize(){const char* vs ={"precision lowp float; ""uniform   mat4 _MVP;""attribute vec2 _position;""attribute vec4 _color;""varying   vec4 _outColor;""void main()""{""   vec4    pos =   vec4(_position,0,1);""   _outColor   =   _color;""   gl_Position =   _MVP * pos;""}"};const char* ps ={"precision  lowp float; ""varying   vec4 _outColor;""void main()""{""   gl_FragColor   =   _outColor;""}"};bool    res = createProgram(vs, ps);if (res){_position = glGetAttribLocation(_programId, "_position");_color = glGetAttribLocation(_programId, "_color");_MVP = glGetUniformLocation(_programId, "_MVP");}return  res;}/***   使用程序*/virtual void    begin(){glUseProgram(_programId);glEnableVertexAttribArray(_position);glEnableVertexAttribArray(_color);}/***   使用完成*/virtual void    end(){glDisableVertexAttribArray(_position);glDisableVertexAttribArray(_color);glUseProgram(0);}};class   PROGRAM_P2_UV_AC4 :public ProgramId{public:typedef int attribute;typedef int uniform;public:attribute   _position;attribute   _color;attribute   _uv;uniform     _MVP;uniform     _texture;public:PROGRAM_P2_UV_AC4(){_position = -1;_color = -1;_uv = -1;_texture = -1;_MVP = -1;}~PROGRAM_P2_UV_AC4(){}/// 初始化函数virtual bool    initialize(){const char* vs ={"precision lowp float; ""uniform   mat4 _MVP;""attribute vec2 _position;""attribute vec2 _uv;""attribute vec4 _color;""varying   vec4 _outColor;""varying   vec2 _outUV;""void main()""{""   vec4    pos =   vec4(_position,0,1);""   _outColor   =   _color;""   _outUV      =   _uv;""   gl_Position =   _MVP * pos;""}"};const char* ps ={"precision  lowp float; ""uniform   sampler2D _texture;\n""varying   vec4      _outColor;\n""varying   vec2      _outUV;\n""void main()""{""   vec4    tColor  =   texture2D(_texture,_outUV);\n""   gl_FragColor    =   tColor * _outColor;\n""}"};bool    res = createProgram(vs, ps);if (res){_position = glGetAttribLocation(_programId, "_position");_color = glGetAttribLocation(_programId, "_color");_uv = glGetAttribLocation(_programId, "_uv");_texture = glGetUniformLocation(_programId, "_texture");_MVP = glGetUniformLocation(_programId, "_MVP");}return  res;}/***   使用程序*/virtual void    begin(){glUseProgram(_programId);glEnableVertexAttribArray(_position);glEnableVertexAttribArray(_uv);glEnableVertexAttribArray(_color);}/***   使用完成*/virtual void    end(){glDisableVertexAttribArray(_position);glDisableVertexAttribArray(_uv);glDisableVertexAttribArray(_color);glUseProgram(0);}};

窗口实现类:

#pragma once#include <Windows.h>#include <tchar.h>#include <math.h>#include <EGL/egl.h>#include <gles2/gl2.h>#include "freeImage/FreeImage.h"#include "CELLMath.hpp"#include "CELLShader.hpp"namespace   CELL{class   CELLWinApp{public://! 实例句柄HINSTANCE   _hInstance;//! 窗口句柄HWND        _hWnd;//! 窗口的高度int         _width;//! 窗口的宽度int         _height;/// for gles2.0EGLConfig   _config;EGLSurface  _surface;EGLContext  _context;EGLDisplay  _display;//! 增加shaderPROGRAM_P2_UV_AC4  _shader;unsigned        _textureId;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);_textureId = 0;}virtual ~CELLWinApp(){UnregisterClass(_T("CELLWinApp"), _hInstance);}/***   初始化 OpenGLES2.0*/bool    initOpenGLES20(){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);EGLintnumConfigs(0);EGLint  major;EGLint  minor;//! 1_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);//! 2initeglInitialize(_display, &major, &minor);//! 3eglChooseConfig(_display, attribs, &_config, 1, &numConfigs);eglGetConfigAttrib(_display, _config, EGL_NATIVE_VISUAL_ID, &format);//! 4 _surface = eglCreateWindowSurface(_display, _config, _hWnd, NULL);//! 5EGLint attr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };_context = eglCreateContext(_display, _config, 0, attr);//! 6if (eglMakeCurrent(_display, _surface, _surface, _context) == EGL_FALSE){return false;}eglQuerySurface(_display, _surface, EGL_WIDTH, &_width);eglQuerySurface(_display, _surface, EGL_HEIGHT, &_height);return  true;}/***   销毁OpenGLES2.0*/void    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;}virtual unsigned    loadTexture(const char* fileName){unsigned    textureId = 0;//1 获取图片格式FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0);//2 加载图片FIBITMAP    *dib = FreeImage_Load(fifmt, fileName, 0);//3 转化为rgb 24色dib = FreeImage_ConvertTo24Bits(dib);//4 获取数据指针BYTE    *pixels = (BYTE*)FreeImage_GetBits(dib);int     width = FreeImage_GetWidth(dib);int     height = FreeImage_GetHeight(dib);for (size_t i = 0; i < width * height * 3; i += 3){BYTE temp = pixels[i];pixels[i] = pixels[i + 2];pixels[i + 2] = temp;}/***   产生一个纹理Id,可以认为是纹理句柄,后面的操作将书用这个纹理id*/glGenTextures(1, &textureId);/***   使用这个纹理id,或者叫绑定(关联)*/glBindTexture(GL_TEXTURE_2D, textureId);/***   指定纹理的放大,缩小滤波,使用线性方式,即当图片放大的时候插值方式*/glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);/**当纹理坐标超出[0,0]到[1,1]的范围时纹理坐标的处理由wrap参数指定,*1--GL_REPEAT:坐标的整数部分被忽略,重复纹理,这是OpenGL纹理默认的处理方式.*2--GL_MIRRORED_REPEAT: 纹理也会被重复,但是当纹理坐标的整数部分是奇数时会使用镜像重复。*3--GL_CLAMP_TO_EDGE: 坐标会被截断到[0,1]之间。结果是坐标值大的被截断到纹理的边缘部分,形成了一个拉伸的边缘(stretched edge pattern)。*/glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);/***   将图片的rgb数据上传给opengl.*/glTexImage2D(GL_TEXTURE_2D,      //! 指定是二维图片0,                  //! 指定为第一级别,纹理可以做mipmap,即lod,离近的就采用级别大的,远则使用较小的纹理GL_RGB,             //! 纹理的使用的存储格式width,              //! 宽度,老一点的显卡,不支持不规则的纹理,即宽度和高度不是2^n。height,             //! 宽度,老一点的显卡,不支持不规则的纹理,即宽度和高度不是2^n。0,                  //! 是否的边GL_RGB,             //! 数据的格式,bmp中,windows,操作系统中存储的数据是bgr格式GL_UNSIGNED_BYTE,   //! 数据是8bit数据pixels);char    subData[100 * 100 * 3];memset(subData, 255, sizeof(subData));/**功能:提供修改图像的功能,因为修改一个纹理比重新创建一个纹理开销小很多,对于一些视频捕捉程序可以先将视频图像存储在更大的初始图像中(图像大小要是2^n,opengl2.0后没有这个限制),创建一个渲染用的纹理,然后反复调用glTexSubImage2D(修改的图像区域不用是2^n)函数从视频图像区域读取到渲染纹理图像中,渲染用的纹理图像只需要创建一次即可。函数原型 glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)target:必须是glCopyTexImage2D中对应的target可用值level:mipmap等级xoffset,yoffset是要修改的图像左上角偏移,width,height是要修改的图像宽高像素修改的范围在原图之外并不受影响format,type:表示图像的数据格式和类型pixels:子图像的纹理数据*/glTexSubImage2D(GL_TEXTURE_2D, 0, 100, 100, 100, 100, GL_RGB, GL_UNSIGNED_BYTE, subData);/***   释放内存*/FreeImage_Unload(dib);return  textureId;}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(){struct  Vertex{CELL::float2    pos;CELL::float2    uv;CELL::Rgba4Byte color;};//! 清空缓冲区glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);//! 视口,在Windows窗口指定的位置和大小上绘制OpenGL内容glViewport(0, 0, _width, _height);//! 创建一个投影矩阵glBindTexture(GL_TEXTURE_2D, _textureId);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 = 400;float   h = 400;float   rt = 2;Vertex  vertex[] ={CELL::float2(x, y), CELL::float2(0, 0), CELL::Rgba4Byte(255, 255, 255, 255),CELL::float2(x + w, y), CELL::float2(rt, 0), CELL::Rgba4Byte(255, 255, 255, 255),CELL::float2(x, y + h), CELL::float2(0, rt), CELL::Rgba4Byte(255, 255, 255, 255),CELL::float2(x + w, y + h), CELL::float2(rt, rt), CELL::Rgba4Byte(255, 255, 255, 255),};CELL::matrix4       matMVP = screenProj;glUniformMatrix4fv(_shader._MVP, 1, false, matMVP.data());glUniform1i(_shader._texture, 0);glVertexAttribPointer(_shader._position, 2, GL_FLOAT, false, sizeof(Vertex), vertex);glVertexAttribPointer(_shader._uv, 2, GL_FLOAT, false, sizeof(Vertex), &vertex[0].uv);glVertexAttribPointer(_shader._color, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &vertex[0].color);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();_textureId = loadTexture("Debug/data/image/5.jpg");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);}}/***   销毁OpenGLES20*/destroyOpenGLES20();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;}


完整项目下载地址:http://download.csdn.net/detail/hb707934728/9837754

2 0
原创粉丝点击