码迷,mamicode.com
首页 > 其他好文 > 详细

OpenGLES---画一个矩形

时间:2016-05-27 12:36:47      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:


{目录
	RectShader  
	RectWin  窗口
	画东西的几种类型
	引用Shader中的属性(自己在Shader中写的一些需要传值的类型) glGet....
	设置Shader数据(Shader什么类型就用什么类型设置内容) glU/A...
}


-- RectShader

#include <gles2/gl2.h>
#include <assert.h>

typedef     int uniform;
typedef     int attribute;
typedef		int location; 


class ShaderId
{
public:
	ShaderId(){id=-1;};
public:
	int id;
}; 

class ShaderVeual
{
public:
	ShaderVeual(){_programId=-1;}
public:
	int  _programId;
	ShaderId  _vertex;
	ShaderId  _fragment;
};

class RectShader
{
public:
	ShaderVeual shaderveual;

	attribute   _position;
	uniform		_color;
	uniform     _MVP;

public :
	RectShader(){
		_position=-1;
		_color=-1;
		_MVP=-1;
	}

	void shaderInit(){
		const char* vs  = {
			"precision  lowp float;"//制定float的精度(lowp低精度)
			"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;"
			"}"
		};
		shaderveual=createProgram(vs,ps);
		//获取属性的位置
		_position   = glGetAttribLocation(shaderveual._programId, "_position");
		_color		= glGetUniformLocation(shaderveual._programId,"_color");
		_MVP        = glGetUniformLocation(shaderveual._programId,"_MVP");
	}

	void begin(){	
		// 使用程序
		glUseProgram(shaderveual._programId);
		//启用顶点数组
		glEnableVertexAttribArray(_position);
	}
	void end(){

		//禁用顶点数组
		glDisableVertexAttribArray(_position);
		// 使用完成
		glUseProgram(0);
	
	}

	virtual ShaderVeual createProgram( const char* vertex,const char* fragment ){
        ShaderVeual   program;
        bool  error   =   false;
        do{
            if (vertex){
				// 创建Shader (GL_VERTEX_SHADER 顶点Shader,GL_FRAGMENT_SHADER 像素Shader)
                program._vertex.id   = glCreateShader( GL_VERTEX_SHADER );
				//制定shader的源代码
                glShaderSource( program._vertex.id, 1, &vertex, 0 );
				//编译Shader
                glCompileShader( program._vertex.id );

				//检查编译状态
                GLint   compileStatus;
				/** 获取Shader编译状态
				* GL_COMPILE_STATUS  编译状态
				* GL_INFO_LOG_LENGTH                0x8B84
				* GL_SHADER_SOURCE_LENGTH           0x8B88
				* GL_SHADER_COMPILER                0x8DFA
				*/
                glGetShaderiv( program._vertex.id, GL_COMPILE_STATUS, &compileStatus );
                error   =   compileStatus == GL_FALSE;
                if( error ){//如果编译失败
                    GLchar messages[256];
					//获取编译日志
                    glGetShaderInfoLog( program._vertex.id, sizeof(messages), 0,messages);
					//提升错误框
                    assert( messages && 0 != 0);
                    break;
                }
            }
			//编译ps
            if (fragment){
				/***
				* GL_FRAGMENT_SHADER 片段Shader/像素Shader
				* glCreateShader( GL_VERTEX_SHADER );
			    *@reruen 
				****/
                program._fragment.id   = glCreateShader( GL_FRAGMENT_SHADER );
                glShaderSource( program._fragment.id, 1, &fragment, 0 );	//制定shader的源代码
                glCompileShader( program._fragment.id );//编译Shader

                GLint   compileStatus;
                glGetShaderiv( program._fragment.id, GL_COMPILE_STATUS, &compileStatus );//获取编译状态
                error   =   compileStatus == GL_FALSE;

                if( error ){
                    GLchar messages[256];
                    glGetShaderInfoLog( program._fragment.id, sizeof(messages), 0,messages);//获取Shader编译日志
                    assert( messages && 0 != 0);
                    break;
                }
            }

			//创建一个程序(加载 vs ps)
            program._programId  =   glCreateProgram( );

            if (program._vertex.id) {
                glAttachShader( program._programId, program._vertex.id);//加载 vs
            }
            if (program._fragment.id){
                glAttachShader( program._programId, program._fragment.id);//加载 ps
            }

			//链接 
            glLinkProgram( program._programId );

            GLint linkStatus;
            glGetProgramiv( program._programId, GL_LINK_STATUS, &linkStatus );//获取链接程序状态
            if (linkStatus == GL_FALSE){
                GLchar messages[256];
                glGetProgramInfoLog( program._programId, sizeof(messages), 0, messages);
                break;
            }
            glUseProgram(program._programId);//使用 shads

        } while(false);

        if (error){
            if (program._fragment.id != -1){
                glDeleteShader(program._fragment.id);//删除像素Shader
                program._fragment.id =   0;
            }
            if (program._vertex.id != -1){
                glDeleteShader(program._vertex.id);//删除顶点Shader
                program._vertex.id   =   0;
            }
            if (program._programId != -1){
                glDeleteProgram(program._programId);//删除程序
                program._programId          =   0;
            }
        }
        return  program;
	}
};

---RectWin 窗口

#include "AppWin.hpp"

#include<vector>

#include <EGL/egl.h>
#include <gles2/gl2.h>
#include "freeImage/FreeImage.h"

#include "CELLMath.hpp"
#include "RectShader.hpp"

class RectWin :public AppWin
{
protected:
	int         _width; // 视口 宽度
	int         _height;// 视口 高度

	EGLDisplay _display;
	EGLContext _context;
	EGLSurface _surface;
	EGLConfig  _config;

	RectShader  shader;

public:
	RectWin(HINSTANCE hInstance):AppWin(hInstance){}
	virtual ~RectWin(){}
	void destroy(){
		if (_display != EGL_NO_DISPLAY){//当前的Display 不等于null
			//清楚绑定的 Surface Context 
			eglMakeCurrent(_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
			if (_context != EGL_NO_CONTEXT){//不等于空Context
				//销毁上下文
				eglDestroyContext(_display, _context);
			}

			if (_surface != EGL_NO_SURFACE){//不等于空Surface
				//销毁Surface
				eglDestroySurface(_display, _surface);
			}
			//终止Dispay
			eglTerminate(_display);
		}
		//把 Display Context Surface 设置成初始化
		_display    =   EGL_NO_DISPLAY;
		_context    =   EGL_NO_CONTEXT;
		_surface    =   EGL_NO_SURFACE;
	}
	bool glInit(){
		//1:获取 Display
		_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);

		//2:初始化 egl
		EGLint  major;//返回主版本号
		EGLint  minor;//返回次版本号
		eglInitialize(_display, &major, &minor);

		//3:选择 Config
		const EGLint attribs[] ={
			//属性是一对一的初始化(类似与key->value)
			EGL_SURFACE_TYPE, EGL_WINDOW_BIT,//把数据画到窗口上
			EGL_BLUE_SIZE, 8,//R 占8个比特位
			EGL_GREEN_SIZE, 8,//G 占8个比特位
			EGL_RED_SIZE, 8, //B 占8个比特位
			EGL_DEPTH_SIZE,24,//深度值 占24个比特位  画图的深度值 (前后顺序的层)
			EGL_NONE  //这个机构结束了
		};
		EGLint 	format(0);
		EGLint	numConfigs(0);

		//让EGL为你选择一个配置
		eglChooseConfig(_display, attribs, &_config, 1, &numConfigs);
		//可以查询某个配置的某个属性
		eglGetConfigAttrib(_display, _config, EGL_NATIVE_VISUAL_ID, &format);


		//4:创建 Surface
		_surface = eglCreateWindowSurface(_display, _config, _hWnd, NULL);

		//5:创建上下文对象
		EGLint attr[] ={ EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
		//创建上下文对象
		EGLContext _context = eglCreateContext(_display, _config, EGL_NO_CONTEXT, attr);

		//6:查看 Display Surface Context 是否创建成功
		if (eglMakeCurrent(_display, _surface, _surface, _context) == EGL_FALSE){
			return false;
		}

		//查询Suface的属性 获取Suface中的宽高
		eglQuerySurface(_display, _surface, EGL_WIDTH,  &_width);
		eglQuerySurface(_display, _surface, EGL_HEIGHT, &_height);

		return true;
	}

	bool ini(){
		if(!glInit()){return false;}
		shader.shaderInit();
		return true;
	}
	void renderer(){
		//GL_DEPTH_BUFFER_BIT 深度缓冲区
		//GL_STENCIL_BUFFER_BIT 模版缓冲区
		//GL_COLOR_BUFFER_BIT 颜色缓冲区
		//清楚缓冲
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		//设置视口的大小
		glViewport(0,0,_width,_height);

		CELL::matrix4 project=CELL::ortho<float>(0,(float)_width,(float)_height,0,-100,100);
		//CELL::matrix4 project=CELL::lookAt(CELL::float3(0,0,5),CELL::float3(0,0,0),CELL::float3(0,1,0));
		shader.begin();

		float x=100;
		float y=200;
		float w=50;
		float h=50;

		//逆时针给坐标点,顺时针会出问题
		CELL::float2 pos[]={
			CELL::float2(x,y),
			CELL::float2(x,y+h),
			CELL::float2(x+w,y),
			CELL::float2(x+w,y+h)
		};
		/** 给Uniform变量赋值
		* @param location 变量
		* @param count 值数量(当前数据里面有几个值 1,2,3,4)
		* @param transpose 是否转置(true,false)
		* @param value 赋值数据
		*/
		glUniformMatrix4fv(shader._MVP,1,false,project.data());
		//给Uniform变量赋值
		glUniform4f(shader._color,1,0,0,1);

		/** 设置顶点属性
		* @param indx 属性id
		* @param size 值数量(2,3,4) 
		* @param type 数据类型 (GL_UNSIGNED_BYTE,GL_FLOAT...)
		* @param normalized  规格化(false,true)
		* @param stride 偏移量(数据的偏移量)
		* @param ptr  数据
		*/
		glVertexAttribPointer(shader._position,2,GL_FLOAT,false,sizeof(CELL::float2),pos);
		
		glDrawArrays(GL_TRIANGLE_STRIP,0,4);

		shader.end();

		eglSwapBuffers(_display,_surface);
	}


};

运行结果

技术分享



源码下载地址 (不是完整工程,只有用到的工程文件)

http://pan.baidu.com/s/1slaLzQ1


-- 画东西的几种类型

#define GL_POINTS   点 n/2个点,n是点数

#define GL_LINES    线(两个点确定一条线) n/1个线
#define GL_LINE_STRIP  线带,首尾不相连接(线带,第一个的尾和第二个的首相连 有3个点可以画2条线,首尾不相连接)
#define GL_LINE_LOOP  线环,首尾可以相连(线环,有3个点可以画3条线,首尾可以相连)

#define GL_TRIANGLES   三角形 (三个点画一个三角形)
#define GL_TRIANGLE_STRIP 三角形带, n-2个三角形,n是点数 (有4个点,可以画2个三角形,前三个点是一个三角形,后一个点和理它近的两个点组成一个三角形)
#define GL_TRIANGLE_FAN  三角形扇 (三角形扇,圆心,圆上一点,画n个三角形组成一个圆)

/*** 绘制数组
* @param mode 绘画的模式(点,线,三角形)
* @param first 顶点数组 第几个开始
* @param count 顶点数组 大小
*/
glDrawArrays (GLenum mode, GLint first, GLsizei count);


引用Shader中的属性(自己在Shader中写的一些需要传值的类型) glGet....

类似这样

typedef     int attribute;
attribute   _position;
const char* vs  = {
	...
	"attribute  vec2    _position;"
	...
};
_position   = glGetAttribLocation(shaderveual._programId, "_position");


设置Shader数据(Shader什么类型就用什么类型设置内容) glU/A...

类似这样

//逆时针给坐标点,顺时针会出问题
CELL::float2 pos[]={
	CELL::float2(x,y),
	CELL::float2(x,y+h),
	CELL::float2(x+w,y),
	CELL::float2(x+w,y+h)
};
...
glVertexAttribPointer(shader._position,2,GL_FLOAT,false,sizeof(CELL::float2),pos);
glDrawArrays(GL_TRIANGLE_STRIP,0,4);
...


OpenGLES---画一个矩形

标签:

原文地址:http://blog.csdn.net/gamecocos2dx/article/details/51490398

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!