返回
顶部

修改密码

cocos2dx(3.X)中使用shader

+1

-1

收藏

+1

-1

点赞0

评论0

一 shader的基本概念1 什么是shadershader即着色器,就是专门用来渲染3D图形的一种技术。通过shader,可以自己编写显卡渲染画面的算法,使画面更漂亮、更逼真。2 shader分类shader又分两种,一种是顶点shader(3D图形是由三角形组成的,顶点shader就是计算顶点位置,并为后期…

一 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


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 draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override;
    void onDraw(const cocos2d::Mat4& transform, uint32_t flags);


private:
    cocos2d::CustomCommand _customCommand;
};


#endif // __HELLOWORLD_SCENE_H__

// .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;
    }


    // init shader
    auto glProgram = GLProgram::createWithFilenames(shaders/vert.vsh, shaders/frag.fsh);
    auto state = GLProgramState::getOrCreateWithGLProgram(glProgram);
    setGLProgramState(state);


    return true;
}


void HelloWorld::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
    _customCommand.init(_globalZOrder, transform, flags);
    _customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw, this, transform, flags);
    renderer->addCommand(&_customCommand);
}


void HelloWorld::onDraw(const Mat4& transform, uint32_t flags)
{
    auto glProgram = getGLProgram();
    glProgram->use();
    glProgram->setUniformsForBuiltins();


    // 绘制三角形
    auto size = Director::getInstance()->getWinSize();
    // 三个顶点的坐标
    float vertercies[] = { 0, 0,
        size.width, 0,
        size.width / 2, size.height };
    // 三个顶点的RGBA
    float color[] = { 0, 1, 0, 1,
        1, 0, 0, 1,
        0, 0, 1, 1 };


    //激活名字为position和color的vertex attribute
    GL::enableVertexAttribs(GL::VERTEX_ATTRIB_FLAG_POSITION | GL::VERTEX_ATTRIB_FLAG_COLOR);


    //分别给position和color指定数据源
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertercies);
    glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, color);


    //绘制三角形,所谓的draw call就是指这个函数调用
    glDrawArrays(GL_TRIANGLES, 0, 3);
    //通知cocos2d-x 的renderer,让它在合适的时候调用这些OpenGL命令
    CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1, 3);
    //如果出错了,可以使用这个函数来获取出错信息
    CHECK_GL_ERROR_DEBUG();
}

效果如下:
\

扫一扫在手机打开

评论
已有0条评论
0/150
提交
热门评论
相关推荐
今日要闻
换一批
热点排行