cocos2dx(3.X)中使用shader
2016-10-15 19:34
441 查看
原文链接:http://blog.csdn.net/xufeng0991/article/details/47256583
通过shader,可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。
另一种是像素shader,就是以像素为单位,计算光照、颜色的一系列算法。
在DirectX中,顶点shader叫做vertex shader,像素shader叫做pixel shader;
在OpenGL中,顶点shader也叫做vertex shader,但像素shader叫做fragment shader。
此外显卡芯片厂商NVIDIA还推出CG显卡编程语言,也支持shader。
编写vertex Shader和fragment shader源码。
创建两个shader 实例:GLuint glCreateShader(GLenum type); [gl.createShader]
给Shader实例指定源码。 glShaderSource [gl.shaderSource]
编译shaer源码 void glCompileShader(GLuint shader) [gl.compileShader]
创建shader program – GLuint glCreateProgram(void) [gl.createProgram]
绑定shader到program 。 void glAttachShader(GLuint program, GLuint shader)。每个program必须绑定一个vertex shader 和一个fragment shader。 [gl.attachShader]
链接program 。 void glLinkProgram(GLuint program) [gl.linkProgram]
使用porgram 。 void glUseProgram(GLuint program) [gl.useProgram]
对于使用独立shader编译器编译的二进制shader代码,可使用glShaderBinary来加载到一个shader实例中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
3 片段着色器
1
2
3
4
5
6
7
8
9
10
11
12
13
三 程序调用
新建cocos工程,将上面两个文件放到Resource/shaders文件夹下,修改代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
一 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开发流程
编写vertex Shader和fragment shader源码。
创建两个shader 实例:GLuint glCreateShader(GLenum type); [gl.createShader]
给Shader实例指定源码。 glShaderSource [gl.shaderSource]
编译shaer源码 void glCompileShader(GLuint shader) [gl.compileShader]
创建shader program – GLuint glCreateProgram(void) [gl.createProgram]
绑定shader到program 。 void glAttachShader(GLuint program, GLuint shader)。每个program必须绑定一个vertex shader 和一个fragment shader。 [gl.attachShader]
链接program 。 void glLinkProgram(GLuint program) [gl.linkProgram]
使用porgram 。 void glUseProgram(GLuint program) [gl.useProgram]
对于使用独立shader编译器编译的二进制shader代码,可使用glShaderBinary来加载到一个shader实例中。
三 shader程序
1 语言glsl
glsl即OpenGL Shading Language(OpenGL着色语言),是用来在OpenGL中着色编程的语言。2 顶点着色器
// vert.vsh // 顶点着色器,VBO/VAO提供的每个顶点都执行一遍顶点着色器,输出一个varying和gl_Position等 // 变量修饰: // attribute: 只读,随不同顶点变化的全局变量,应用程序传入,只能用在顶点着色器中 // uniform: 只读,随不同图元变化的全局变量,应用程序传入, // varying: 在顶点shader中可写,在片断shader中只读,用于在顶点着色器和片段着色器之间传递数据 // 输入: attribute, 输出:varying+gl_positon + gl_Position + gl_PointSize attribute vec4 a_position; attribute vec4 a_color; varying vec4 v_fragmentColor; // 每一个Shader程序都有一个main函数 void main() { // gl开头的变量名是系统内置的变量 gl_Position = CC_MVPMatrix * a_position;// 每个点固有的Varying,表示点的空间位置。 v_fragmentColor = a_color; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
3 片段着色器
// frag.fsh // 片元着色器,光栅化输出的每个片元都执行一遍片段着色器,生成一个或多个(多重渲染)颜色值作为输出 // 输入: varying, 输出: gl_FragColor + gl_FragDepth //用于在顶点着色器和片段着色器之间传递数据,因此类型必须完全一直 varying vec4 v_fragmentColor; // 每一个Shader程序都有一个main函数 void main() { // gl开头的变量名是系统内置的变量 gl_FragColor = v_fragmentColor;// gl_FragColor 定义最终画在屏幕上面的像素点的颜色 }
1
2
3
4
5
6
7
8
9
10
11
12
13
三 程序调用
新建cocos工程,将上面两个文件放到Resource/shaders文件夹下,修改代码如下:
// .h #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" USING_NS_CC; class HelloWorld : public cocos2d::Layer { public: static cocos2d::Scene* createScene(); virtual bool init(); CREATE_FUNC(HelloWorld); virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags); void onDraw(); private: CustomCommand _customCommand; GLuint _vao; GLuint _vertVBO; GLuint _colorVBO; }; #endif // __HELLOWORLD_SCENE_H__
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// .cpp #include "HelloWorldScene.h" USING_NS_CC; 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; } /* 在OpenGL中,GLSL的shader使用的流程与C语言相似,每个shader类似一个C模块,首先需要单独编译(compile), 然后一组编译好的shader连接(link)成一个完整程序。 */ auto program = CCGLProgram::createWithFilenames("shader/vert.vsh", "shader/frag.fsh"); program->link(); program->updateUniforms(); this->setGLProgram(program); /* 使用VBO和VAO的步骤都差不多,步骤如下: 1 glGenXXX 2 glBindXXX */ // 创建和绑定vao glGenVertexArrays(1, &_vao); glBindVertexArray(_vao); // 创建和绑定vbo glGenBuffers(1, &_vertVBO);// 生成VBO glBindBuffer(GL_ARRAY_BUFFER, _vertVBO); // 关联到当前的VAO auto size = Director::getInstance()->getVisibleSize(); float vertercies[] = {// 三角形顶点位置 0, 0, // 第1个点坐标 size.width, 0, // 第2个点坐标 size.width / 2, size.height // 第3个点坐标 }; // 给VBO设置数据 glBufferData(GL_ARRAY_BUFFER, sizeof(vertercies), vertercies, GL_STATIC_DRAW); // 获得变量a_position在内存中的位置 GLuint positionLocation = glGetAttribLocation(program->getProgram(), "a_position"); glEnableVertexAttribArray(positionLocation); // 提交包含数据的数组指针 glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); // 设置颜色 float color[] = {// 三角形顶点颜色RGBA 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1 }; glGenBuffers(1, &_colorVBO); glBindBuffer(GL_ARRAY_BUFFER, _colorVBO); glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_STATIC_DRAW); // 获得变量a_color在内存中的位置 GLuint colorLocation = glGetAttribLocation(program->getProgram(), "a_color"); glEnableVertexAttribArray(colorLocation); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0); glBindVertexArray(0); glBindBuffer(GL_ARRAY_BUFFER, 0); return true; } void HelloWorld::visit(cocos2d::Renderer *renderer, const Mat4 &transform, 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(); /* VAO里的VBOs都设置好了以后,在绘制的地方只需要设置当前绑定的VAO是哪个, 就能按照初始化的VAO来绘制,即调用glDrawArrays */ // 设置当前绑定的VAO glBindVertexArray(_vao); // 绘制三角形 glDrawArrays(GL_TRIANGLES, 0, 3); // 解绑当前VAO,但并不释放 glBindVertexArray(0); CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 3); CHECK_GL_ERROR_DEBUG(); }
相关文章推荐
- Cocos2dx - CCSprite使用 shader生成自己想要的颜色的图片
- Cocos2dx 定义可以修改颜色的Sprite(shader的使用)
- Cocos2dx - CCSprite使用 shader生成自己想要的颜色的图片
- Cocos2dx-JS 在 Sprite 上使用 Shader
- 在Cocos2dx 3.10中第一次使用shader
- Cocos2dx Shader 使用系列之一:OpenGL Shader Language介绍
- cocos2dx(3.X)中使用shader
- Cocos2dx - CCSprite使用 shader生成自己想要的颜色的图片
- 第一次使用cocos2dx3.3自带的shader
- Cocos2dx 使用Shader使精灵变灰
- cocos2dx中 Node 在shader使用v_texCoord
- cocos2dx-js Shader的使用(高斯模糊)
- Cocos2dx - CCSprite使用 shader生成自己想要的颜色的图片
- cocos2dx Shader的使用
- Cocos2dx Shader 使用系列之一:OpenGL Shader Language介绍
- 六 cocos2dx(3.X)中使用shader
- 【C/S通信交互之Http篇】Cocos2dx(Client)使用Curl与Jetty(Server)实现手机网游Http通信框架(内含解决curl.h头文件找不到问题)
- 转载,在cocos2dx中使用iad
- BlackBerry PlayBook NDK 2.0 使用Cocos2dx详细步骤
- 【iOS-cocos2d-X 游戏开发之十一】New CCSprite()带来的错误&使用CCUserDefault及pvr.ccz在Cocos2dx中要注意!