跨平台二维绘图程序(二)——着色器shader

来源:互联网 发布:佛山数控编程培训机构 编辑:程序博客网 时间:2024/06/05 05:09

学习使用GLES,首先要写着色器。

      与OpenGL ES1.x渲染管线相比,OpenGL ES 2.0渲染管线中“顶点着色器”取代了OpenGL ES 1.x渲染管线中的“变换和光照”;“片元着色器”取代了OpenGL ES 1.x渲染管线中的“纹理环境和颜色求和”、“雾”以及“Alpha测试”。 这使得开发人员在使用OpenGL ES 2.0API进行开发时,可以通过编写顶点及片元着色器程序,来完成一些顶点变换和纹理颜色计算工作,实现更加灵活、精细化的计算与渲染。


以上内容转载自:

http://blog.sina.com.cn/s/blog_923fdd9b0102vbe0.html

文章对着色器做了一些介绍,在GLES的使用步骤为:glCreateProgram->glAttachShader->glLinkProgram->glUseProgram。在之后使用纹理之后才知道,一个程序里可能同时存在多个program,在绘制不同对象时需要切换使用glUseProgram。在出现错误的时候错误日志非常关键,调试的时候发现同样的shader代码在windows平台可以绘制,但是在ubuntu中就无法显示,错误日志可能提示语言的版本不支持。这些错误与系统GPU有关系。以下为包含着色器的Program封装,包括常规程序和带纹理的程序。


#pragma once// 矩阵操作#include <math.h>#include "glm/mat4x4.hpp"#include "glm/ext.hpp"class ShaderId{public:ShaderId(){_shaderId = -1;}int _shaderId;};class ProgramId{public:int         _programId;ShaderId    _vertex;ShaderId    _fragment;public:ProgramId(){_programId = -1;}public:/***   加载函数*/virtual bool  createProgram(const char* vertex, const char* fragment){#ifndef ANDROIDglewInit(); // android need of not?#endifbool        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);GLUtil::instance()->outputString(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);GLUtil::instance()->outputString(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);GLUtil::instance()->outputString(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(const glm::mat4& mat){glUseProgram(_programId);glm::mat4 matTemp = mat;// *m_view/* * module*/;GLfloat *mvp = (GLfloat*)glm::value_ptr(matTemp);glUniformMatrix4fv(this->mvp(), 1, GL_FALSE, mvp);}virtual void end(){glUseProgram(0);}virtual bool initialize(){ return false; }virtual GLint position() { return -1; }virtual GLint color() { return -1; }virtual GLint texure() { return -1; }virtual GLint mvp() { return -1; }virtual GLint uv() { return -1; }};class   PROGRAM_P2_AC4 :public ProgramId{public:typedef int attribute;typedef int uniform;protected:attribute   _position;attribute   _color;uniform     _MVP;public:virtual GLint position() { return _position; }virtual GLint color() { return _color; }virtual GLint texure() { return -1; }virtual GLint mvp() { return _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 vec3 _position;""attribute vec4 _color;""varying   vec4 _outColor;""void main()""{""   vec4    pos =   vec4(_position, 1.);""   _outColor   =   _color;""   gl_Position =   _MVP * pos;""}"};const char* ps ={"precision  lowp float; ""varying   vec4 _outColor;""void main()""{""   gl_FragColor   =   _outColor;""}"};*/#ifdef ANDROIDconst char* vs ={"attribute vec3 _position;""attribute vec4 _color;""varying vec4 _outColor;""uniform mat4 _MVP;""void main()""{""   vec4    pos =   vec4(_position, 1.);""   _outColor   =   _color;""   gl_Position =   _MVP * pos;""}"};const char* ps ={"precision mediump float;""varying  vec4 _outColor;""void main()""{""   gl_FragColor = _outColor;""}"};#elseconst char* vs ={"#version 130\n""in vec3 _position;""in vec4 _color;""out vec4 _outColor;""uniform mat4 _MVP;""void main()""{""   vec4    pos =   vec4(_position, 1.);""   _outColor   =   _color;""   gl_Position =   _MVP * pos;""}"};const char* ps ={"#version 130\n""in vec4 _outColor;""out vec4 FragColor;""void main()""{""   FragColor = _outColor;""}"};#endifbool    res = createProgram(vs, ps);if (res){_position = glGetAttribLocation(_programId, "_position");_color = glGetAttribLocation(_programId, "_color");_MVP = glGetUniformLocation(_programId, "_MVP");}return  res;}/***   使用程序*/virtual void begin(const glm::mat4& mat){ProgramId::begin(mat);glEnableVertexAttribArray(_position);glEnableVertexAttribArray(_color);}/***   使用完成*/virtual void    end(){glDisableVertexAttribArray(_position);glDisableVertexAttribArray(_color);glUseProgram(0);}};class   PROGRAM_P2_UV_AC4 :public PROGRAM_P2_AC4{public:typedef int attribute;typedef int uniform;protected://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 GLint uv() { return _uv; }virtual GLint texure() { return _texture; }/// 初始化函数virtual bool    initialize(){#ifdef ANDROIDconst char* vs ={"precision lowp float; ""uniform   mat4 _MVP;""attribute vec3 _position;""attribute vec2 _uv;""attribute vec4 _color;""varying   vec4 _outColor;""varying   vec2 _outUV;""void main()""{""   vec4    pos =   vec4(_position, 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""}"};#else            const char* vs =            {                    "#version 130\n"                    "in vec3 _position;"                    "in vec2 _uv;"                    "in vec4 _color;"                    "out vec4 _outColor;"                    "out vec2 _outUV;"                    "uniform mat4 _MVP;"                    "void main()"                    "{"                    "   vec4    pos =   vec4(_position, 1.);"                    "   _outColor   =   _color;"                    "   _outUV   =   _uv;"                    "   gl_Position =   _MVP * pos;"                    "}"            };            const char* ps =            {"#version 130\n""uniform   sampler2D _texture;""in vec4 _outColor;""in vec2 _outUV;""out vec4 FragColor;""void main()""{"                "   vec4    tColor  =   texture2D(_texture,_outUV);\n"                "   FragColor = tColor * _outColor;"                "}"            };#endifbool    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(const glm::mat4& mat){ProgramId::begin(mat);glEnableVertexAttribArray(_position);glEnableVertexAttribArray(_uv);glEnableVertexAttribArray(_color);}/***   使用完成*/virtual void    end(){glDisableVertexAttribArray(_position);glDisableVertexAttribArray(_uv);glDisableVertexAttribArray(_color);glUseProgram(0);}};

代码编写参考了:

http://blog.csdn.net/hb707934728/article/details/71486631?locationNum=4&fps=1

主要做的改动:

(1)着色语言,区分android,区分版本,区分坐标——尤其是z坐标引入保证深度测试能够生效(vec4    pos =   vec4(_position, 1.););

(2)纹理程序继承自常规程序而非基础程序类;

(3)引入了变换矩阵(用于旋转缩放平移等运算);



阅读全文
1 0
原创粉丝点击