cocos2dx(3.X)中使用shader

原文链接:

一 shader的基本概念1 什么是shadershader即着色器,就是专门用来渲染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 语言glslglsl即OpenGL Shading Language(OpenGL着色语言),是用来在OpenGL中着色编程的语言。2 顶点着色器// vert.vshattribute 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.fshvarying 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 pointerstatic cocos2d::Scene* createScene();// Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphonevirtual 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 objectauto scene = Scene::create();// 'layer' is an autorelease objectauto layer = HelloWorld::create();// add layer as a child to scenescene->addChild(layer);// return the scenereturn scene;}// on "init" you need to initialize your instancebool HelloWorld::init(){//////////////////////////////// 1. super init firstif (!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, 0,size.width, 0,size.width / 2, size.height};float color[] = {0, 1, 0, 1,1, 0, 0, 1, 0, 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, 0, (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, GL_FLOAT, GL_FALSE, 0, (GLvoid*)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();glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 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参考:

版权声明:本文为博主原创文章,未经博主允许不得转载。

纵然伤心,也不要愁眉不展,因为你不知是谁会爱上你的笑容

cocos2dx(3.X)中使用shader

相关文章:

你感兴趣的文章:

标签云: