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

学习使用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 ANDROID
		glewInit(); // android need of not?
#endif

		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);
					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 ANDROID
		const 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;"
			"}"
		};
#else
		const 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;"
			"}"
		};

#endif

		bool    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 ANDROID
		const 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;"
                "}"
            };

#endif

		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(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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wayright

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值