首页 > 代码库 > GLSL程序对象的C++封装
GLSL程序对象的C++封装
在OpenGL的shader编程中,最常用的可能就是程序对象了,GLSL的程序对象的创建、加载shader等步骤都是固定的,如果每次都写同样的代码,觉得十分浪费时间,所以现在就将我在Shader学习过程中自己封装的GLSLProgram类奉献出来供大家参考:
头文件如下:
/* * GLSLProgram.h * * Created * Author: zhouxuguang */ #ifndef GLSLPROGRAM_H_ #define GLSLPROGRAM_H_ #include "GLPrecompile.h" class GLSLProgram { public: GLSLProgram(); GLSLProgram(const char* pVertexSource, const char* pFragmentSource); ~GLSLProgram(); void InitWithShader(const char* pVertexSource, const char* pFragmentSource); //编译和连接程序 void LinkProgram(); //加载二进制shader程序 void LoadProgramBinary( const char * fileName, GLenum format ); //使用程序对象 void Use(); //使用固定管线 void UseFixedFunction(); //绑定属性变量 void BindAttribLocation (unsigned int index, const char *name); void BindFragDataLocation(unsigned int index , const char *name); //获得属性变量 GLint GetAttributeLocation(const char* attrName); //获得指定Uniform变量的位置 GLint GetUniformLocation( const char* uniName); GLint GetUniformBlockIndex( const char* uniName); //设置属性变量的值 //void SetAttributeVariable( char *, int ); void SetAttributeVariable( const char *, float ); void SetAttributeVariable( const char *, float, float, float ); void SetAttributeVariable( const char *, float[3] ); //设置uniform变量的值 void SetUniformVariable( const char *, int ); void SetUniformVariable( const char *, float ); void SetUniformVariable( const char *, float, float, float ); void SetUniformVariable( const char *, float[3] ); void SetUniformMatrix2f(const char* name,int count, bool transpose, const float *value); void SetUniformMatrix3f(const char* name,int count, bool transpose, const float *value); void SetUniformMatrix4f(const char* name,int count, bool transpose, const float *value); void GetActiveUniformBlockiv(const char* uniName, GLenum pname, GLint *params); void GetUniformIndices ( GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices); void GetActiveUniformsiv ( GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); //加载shader static GLuint LoadShader(GLenum shaderType, const char* pSource); static bool LoadShaderFile(const char* pShaderFile,std::string &shaderString); private: GLuint mProgram; //程序对象 GLuint mVertexShader; //顶点shader GLuint mFragmentShader; //片段shader std::map<const char *, int> mAttributeLocs; //attribute属性变量的map std::map<const char *, int> mUniformLocs; //Uniform变量的map }; #endif /* GLSLPROGRAM_H_ */
/* * GLSLProgram.cpp * * Created on: * Author: zhouxuguang */ #include "GLSLProgram.h" GLuint GLSLProgram::LoadShader(GLenum shaderType, const char* pSource) { GLuint shader = glCreateShader(shaderType); if (shader) { glShaderSource(shader, 1, &pSource, NULL); glCompileShader(shader); GLint compiled = 0; glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); if (!compiled) { GLint infoLen = 0; glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); if (infoLen) { char* buf = (char*) malloc(infoLen); if (buf != NULL) { glGetShaderInfoLog(shader, infoLen, NULL, buf); //LOGE("Could not compile shader %d:\n%s\n",shaderType, buf); free(buf); } glDeleteShader(shader); shader = 0; } } } return shader; } bool GLSLProgram::LoadShaderFile(const char *pShaderFile,std::string &shaderString) { FILE *fpin = fopen( pShaderFile, "rb" ); if( fpin == NULL ) { return false; } fseek( fpin, 0, SEEK_END ); long length = (long)ftell( fpin ); char *buffer = new char[ length ]; rewind( fpin ); fread( buffer, length, 1, fpin ); fclose( fpin ); shaderString = buffer; delete []buffer; return true; } GLSLProgram::GLSLProgram():mVertexShader(0),mFragmentShader(0),mProgram(0) { } GLSLProgram::GLSLProgram(const char* pVertexSource, const char* pFragmentSource) { InitWithShader(pVertexSource,pFragmentSource); } GLSLProgram::~GLSLProgram() { if (mProgram) { glDetachShader(mProgram, mVertexShader); glDetachShader(mProgram, mFragmentShader); glDeleteShader(mVertexShader); mVertexShader = 0; glDeleteShader(mFragmentShader); mFragmentShader = 0; glDeleteProgram(mProgram); mProgram = 0; } } void GLSLProgram::InitWithShader(const char *pVertexSource, const char *pFragmentSource) { mVertexShader = GLSLProgram::LoadShader(GL_VERTEX_SHADER, pVertexSource); if (!mVertexShader) { return; } mFragmentShader = GLSLProgram::LoadShader(GL_FRAGMENT_SHADER, pFragmentSource); if (!mFragmentShader) { return; } mProgram = glCreateProgram(); } void GLSLProgram::LinkProgram() { if (mProgram) { glAttachShader(mProgram, mVertexShader); glAttachShader(mProgram, mFragmentShader); glLinkProgram(mProgram); GLint linkStatus = GL_FALSE; glGetProgramiv(mProgram, GL_LINK_STATUS, &linkStatus); if (linkStatus != GL_TRUE) { GLint bufLength = 0; glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &bufLength); if (bufLength) { char* buf = (char*) malloc(bufLength); if (buf) { glGetProgramInfoLog(mProgram, bufLength, NULL, buf); free(buf); } } glDeleteProgram(mProgram); mProgram = 0; } } } void GLSLProgram::LoadProgramBinary(const char * fileName, GLenum format) { FILE *fpin = fopen( fileName, "rb" ); if( fpin == NULL ) { fprintf( stderr, "Cannot open input GLSL binary file ‘%s‘\n", fileName ); return; } fseek( fpin, 0, SEEK_END ); GLint length = (GLint)ftell( fpin ); GLubyte *buffer = new GLubyte[ length ]; rewind( fpin ); fread( buffer, length, 1, fpin ); fclose( fpin ); glProgramBinary( this->mProgram, format, buffer, length ); delete [] buffer; GLint success; glGetProgramiv( this->mProgram, GL_LINK_STATUS, &success ); if( !success ) { fprintf( stderr, "Did not successfully load the GLSL binary file ‘%s‘\n", fileName ); return; } } void GLSLProgram::Use() { glUseProgram(mProgram); } void GLSLProgram::UseFixedFunction() { glUseProgram(0); } void GLSLProgram::BindAttribLocation (unsigned int index, const char *name) { glBindAttribLocation(mProgram,(GLuint)index,(const GLchar*)name); } void GLSLProgram::BindFragDataLocation(unsigned int index, const char *name) { //只有桌面版本支持 } GLint GLSLProgram::GetAttributeLocation(const char* attrName) { std::map<const char *, int>::iterator iter = mAttributeLocs.find(attrName); if(iter == mAttributeLocs.end()) { mAttributeLocs[attrName] = glGetAttribLocation(mProgram, attrName); } return mAttributeLocs[attrName]; } GLint GLSLProgram::GetUniformLocation(const char* uniName) { std::map<const char*, int>::iterator iter = mUniformLocs.find(uniName); if(iter == mUniformLocs.end()) { mUniformLocs[uniName] = glGetUniformLocation(mProgram, uniName); } return mUniformLocs[uniName]; } GLint GLSLProgram::GetUniformBlockIndex(const char* uniName) { return glGetUniformBlockIndex(mProgram, uniName); } //void GLSLProgram::SetAttributeVariable( char* name, int val ) //{ // int loc; // if( ( loc = GetAttributeLocation( name ) ) >= 0 ) // { // this->Use(); // glVertexAttrib1i( loc, val ); // } //}; void GLSLProgram::SetAttributeVariable( const char* name, float val ) { int loc; if( ( loc = GetAttributeLocation( name ) ) >= 0 ) { this->Use(); glVertexAttrib1f( loc, val ); } }; void GLSLProgram::SetAttributeVariable( const char* name, float val0, float val1, float val2 ) { int loc; if( ( loc = GetAttributeLocation( name ) ) >= 0 ) { this->Use(); glVertexAttrib3f( loc, val0, val1, val2 ); } }; void GLSLProgram::SetAttributeVariable( const char* name, float vals[3] ) { int loc; if( ( loc = GetAttributeLocation( name ) ) >= 0 ) { this->Use(); glVertexAttrib3fv( loc, vals ); } }; void GLSLProgram::SetUniformVariable( const char* name, int val ) { int loc; if( ( loc = GetUniformLocation( name ) ) >= 0 ) { this->Use(); glUniform1i( loc, val ); } }; void GLSLProgram::SetUniformVariable( const char* name, float val ) { int loc; if( ( loc = GetUniformLocation( name ) ) >= 0 ) { this->Use(); glUniform1f( loc, val ); } }; void GLSLProgram::SetUniformVariable( const char* name, float val0, float val1, float val2 ) { int loc; if( ( loc = GetUniformLocation( name ) ) >= 0 ) { this->Use(); glUniform3f( loc, val0, val1, val2 ); } }; void GLSLProgram::SetUniformVariable( const char* name, float vals[3] ) { int loc; if( ( loc = GetUniformLocation( name ) ) >= 0 ) { this->Use(); glUniform3fv( loc, 3, vals ); } }; void GLSLProgram::SetUniformMatrix2f(const char* name ,int count, bool transpose, const float *value) { int loc; if( ( loc = GetUniformLocation( name ) ) >= 0 ) { this->Use(); glUniformMatrix2fv( loc, count, transpose, value ); } } void GLSLProgram::SetUniformMatrix3f(const char* name ,int count, bool transpose, const float *value) { int loc; if( ( loc = GetUniformLocation( name ) ) >= 0 ) { this->Use(); glUniformMatrix3fv( loc, count, transpose, value ); } } void GLSLProgram::SetUniformMatrix4f(const char* name ,int count, bool transpose, const float *value) { int loc; if( ( loc = GetUniformLocation( name ) ) >= 0 ) { this->Use(); glUniformMatrix4fv( loc, count, transpose, value ); } } void GLSLProgram::GetActiveUniformBlockiv(const char* uniName, GLenum pname, GLint *params) { int loc; if ( (loc = GetUniformBlockIndex(uniName)) >= 0) { this->Use(); glGetActiveUniformBlockiv(mProgram,loc,pname,params); } } void GLSLProgram::GetUniformIndices(GLsizei uniformCount, const GLchar *const*uniformNames, GLuint *uniformIndices) { glGetUniformIndices(mProgram,uniformCount,uniformNames,uniformIndices); } void GLSLProgram::GetActiveUniformsiv(GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params) { glGetActiveUniformsiv(mProgram,uniformCount,uniformIndices,pname,params); }
这里还引入了一个头文件,其实就是在不同平台上引入相应的头文件,头文件内容如下:
// // GLPrecompile.h // GLUtilBox // // Created by zhouxuguang . // Copyright © 2016年 zhouxuguang. All rights reserved. // #ifndef GLPrecompile_hpp #define GLPrecompile_hpp #include <stdio.h> #include <stdlib.h> #include <string.h> #include <string> #include <vector> #include <map> #ifdef __ANDROID__ #include <GLES/gl.h> #include <GLES2/gl2.h> #include <GLES3/gl3.h> #elif defined(__IOS__) #include <OpenGLES/ES1/gl.h> #include <OpenGLES/ES1/glext.h> #include <OpenGLES/ES2/gl.h> #include <OpenGLES/ES2/glext.h> #include <OpenGLES/ES3/gl.h> #include <OpenGLES/ES3/glext.h> #endif #endif /* GLPrecompile_hpp */
希望对大家有用 ,桌面版本的OpenGL头文件没有处理,大家有需要也可以根据自己需要改一下就OK
GLSL程序对象的C++封装
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。