加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

cocos2dx(3.X)中使用shader

发布时间:2020-12-14 16:21:37 所属栏目:百科 来源:网络整理
导读:原文链接:http://blog.csdn.net/xufeng0991/article/details/47256583 一 shader的基本概念 1 什么是shader shader即着色器,就是专门用来渲染3D图形的一种技术。 通过shader,可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。 2 shader分类 shader

原文链接:http://blog.csdn.net/xufeng0991/article/details/47256583

一 shader的基本概念

1 什么是shader
shader即着色器,就是专门用来渲染3D图形的一种技术。
通过shader,可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。


2 shader分类
shader又分两种,一种是顶点shader(3D图形是由三角形组成的,顶点shader就是计算顶点位置,并为后期像素渲染做准备的),
另一种是像素shader,就是以像素为单位,计算光照、颜色的一系列算法。


3 shader语言
几个不同的图形API有各自的shader语言:
在DirectX中,顶点shader叫做vertex shader,像素shader叫做pixel shader;
在OpenGL中,顶点shader也叫做vertex shader,但像素shader叫做fragment shader。
此外显卡芯片厂商nVidia还推出CG显卡编程语言,也支持shader。

二 shader程序

1 语言glsl
glsl即OpenGL Shading Language(OpenGL着色语言),是用来在OpenGL中着色编程的语言。


2 顶点着色器
// vert.vsh
attribute vec4 a_position;
attribute vec4 a_color;


varying vec4 v_fragmentColor;

void main()
{
    gl_Position = CC_MVPMatrix * a_position;
    v_fragmentColor = a_color;
}

(1) 每一个Shader程序都有一个main函数;
(2) 有两种类型的变量:
attribute是从外部传进来的;
varying类型的变量是在vertex shader和fragment shader之间传递数据用的;
每一个顶点都会有attribute和varying属性,定点着色器作用于每个定点,有多少个点就会执行多少次。


3 片段着色器
// frag.fsh
varying vec4 v_fragmentColor;

void main()
{
    gl_FragColor = v_fragmentColor;
}

(1) main函数;
(2) varying类型的变量是在vertex shader和fragment shader之间传递数据用的;
(3) gl_FragColor系统内置变量,定义最终画在屏幕上面的像素点的颜色;

三 程序调用

新建cocos工程,将上面两个文件放到Resource/shaders文件夹下,修改代码如下:
// .h
#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

USING_NS_CC;

class HelloWorld : public cocos2d::Layer
{
public:
	// there's no 'id' in cpp,so we recommend returning the class instance pointer
	static cocos2d::Scene* createScene();

	// Here's a difference. Method 'init' in cocos2d-x returns bool,instead of returning 'id' in cocos2d-iphone
	virtual bool init();

	// implement the "static create()" method manually  
	CREATE_FUNC(HelloWorld);

	virtual void visit(Renderer *renderer,const Mat4 &transform,uint32_t parentFlags) override;
	void onDraw();
private:
	CustomCommand _customCommand;

	GLuint VAO;
	GLuint vertexVBO;
	GLuint colorVBO;
};

#endif // __HELLOWORLD_SCENE_H__

// .cpp

#include "HelloWorldScene.h"

Scene* HelloWorld::createScene()
{
	// 'scene' is an autorelease object
	auto scene = Scene::create();

	// 'layer' is an autorelease object
	auto layer = HelloWorld::create();

	// add layer as a child to scene
	scene->addChild(layer);

	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
bool HelloWorld::init()
{
	//////////////////////////////
	// 1. super init first
	if (!Layer::init())
	{
		return false;
	}

	auto program = CCGLProgram::createWithFilenames("shaders/vert.vsh","shaders/frag.fsh");
	program->link();
	program->updateUniforms();
	this->setGLProgram(program);

	glGenVertexArrays(1,&VAO);
	glBindVertexArray(VAO);

	glGenBuffers(1,&vertexVBO);
	glBindBuffer(GL_ARRAY_BUFFER,vertexVBO);

	auto size = Director::getInstance()->getVisibleSize();
	float vertercies[] = {
		0,size.width,size.width / 2,size.height
	};
	float color[] = {
		0,1,1
	};

	glBufferData(GL_ARRAY_BUFFER,sizeof(vertercies),vertercies,GL_STATIC_DRAW);
	GLuint positionLocation = glGetAttribLocation(program->getProgram(),"a_position");
	glEnableVertexAttribArray(positionLocation);
	glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION,2,GL_FLOAT,GL_FALSE,(GLvoid*)0);

	glGenBuffers(1,&colorVBO);
	glBindBuffer(GL_ARRAY_BUFFER,colorVBO);
	glBufferData(GL_ARRAY_BUFFER,sizeof(color),color,GL_STATIC_DRAW);

	GLuint colorLocation = glGetAttribLocation(program->getProgram(),"a_color");
	glEnableVertexAttribArray(colorLocation);
	glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR,4,(GLvoid*)0);
	
	return true;
}

void HelloWorld::visit(cocos2d::Renderer *renderer,uint32_t parentFlags)
{
	Layer::draw(renderer,transform,parentFlags);

	_customCommand.init(_globalZOrder);
	_customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw,this);
	renderer->addCommand(&_customCommand);
}

void HelloWorld::onDraw()
{
	auto glProgram = getGLProgram();
	glProgram->use();
	glProgram->setUniformsForBuiltins();


	glBindVertexArray(VAO);

	glDrawArrays(GL_TRIANGLES,3);

	CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,3);
	CHECK_GL_ERROR_DEBUG();
}



效果如下:


win7默认关闭VAO,需要手动开启:libcocos2d工程-》属性-》C/C++-》预处理器,在预处理器定义中添加CC_TEXTURE_ATLAS_USE_VAO=1 参考:http://zilongshanren.com/blog/2014/06/07/write-your-own-shader/

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读