GLSL程式對象的C++封裝__C++

來源:互聯網
上載者:User

      在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;     //片段shaderstd::map<const char *, int>mAttributeLocs;//attribute屬性變數的mapstd::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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.