1. 程式人生 > >cocos2dx:cocos之Shader

cocos2dx:cocos之Shader

轉自:http://blog.csdn.net/u013235682/article/details/46687383

紋理和管線

紋理的概念

在現實生活中,物體都是有邊界的,比如一顆石頭,有一層表面,當我們給它拍個照片,就能變成一張二維的圖片了,那麼這個圖片就是石頭的紋理。

可是石頭是立體的,並不是二維的,立體這種東西,是我們人對石頭的一種感覺,如果把石頭拿在手裡,轉動這個石頭或者轉動我們的位置,我們可以看到這個石頭的多個面,於是給我們一種立體的概念。

計算機圖形學要將這種感覺給繪製出來,形成3d效果,那麼就需要一系列的資料結構來描述這種東西。紋理這個概念就這樣被提出來,石頭的每一個面,都是紋理。

管線的概念

可以想象,一個石頭的紋理也是很多的。。。計算機都要畫呀畫,好累。。。紋理是一個平面的東西,GPU用它來作為繪製的單位

於是,生產顯示卡的那幫人,就想著,要是一下子就能繪製10000個紋理就好了,因此提出了管線的概念。管線指可以獨立繪製紋理的單元,一個顯示卡有16管線,就表示它能同時渲染16個紋理,這個引數也是衡量顯示卡效能的標誌。

管線渲染流程

可程式設計管線上面的連結說了渲染流程,所以我就不說一個管線怎麼渲染紋理的了啊

可程式設計管線

就是cpu向gpu傳送渲染的內容時,同時帶一段程式過去,讓管線可以根據程式來進行一些額外的操作。

一段shader程式

看看一段shader程式吧,來自cocos2dx的cpptest資源裡的,看人家第一行的註釋,也是從別人那邊抄的

// Shader from http://www.iquilezles.org/apps/shadertoy/#ifdef GL_ESprecision highp float;#endifuniform vec2 center;uniform vec2 resolution;void main(void){    float time = CC_Time[1];    vec2 p = 2.0 * (gl_FragCoord.xy - center.xy) / resolution.xy;    // animate    float tt = mod(time,2.0)/2.0;    float ss = pow(tt,.2)*0.5 + 0.5;

    ss -= ss*0.2*sin(tt*6.2831*5.0)*exp(-tt*6.0);    p *= vec2(0.5,1.5) + ss*vec2(0.5,-0.5);    float a = atan(p.x,p.y)/3.141593;    float r = length(p);    // shape    float h = abs(a);    float d = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);    // color    float f = step(r,d) * pow(1.0-r/d,0.25);    gl_FragColor = vec4(f,0.0,0.0,1.0);}

C語言程式設計師是不是看著是不是很熟悉,shader語言很像是C語言

cocos2dx怎麼把程式送到GPU去?

很簡單,直接呼叫setShaderProgram即可

bool C01S10Shader::init(){    LayerBack::init();    // 這是一個正常的精靈,用來對比的    Sprite* sprite = Util::addSprite("Images/grossini.png", this);    sprite->setPosition(50, winSize.height/2);    {        // 這個是要用shader處理的精靈,addSprite函式是我自己寫的,沒放上來,就是建立一個精靈,放在this指標的中間        _sprite = Util::addSprite("Images/grossini.png", this);        // "Shaders/example_edgeDetection.fsh"        // 讀取shader程式,shader程式是寫在一個檔案裡的        auto fileUtiles = FileUtils::getInstance();        auto fragmentFullPath = fileUtiles->fullPathForFilename("Shaders/example_bloom.fsh");        auto fragSource = fileUtiles->getStringFromFile(fragmentFullPath);        // 通過shader程式字串去建立一個GLProgam物件        auto glprogram = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource.c_str());        CCLOG("%s\n", ccPositionTextureColor_noMVP_vert);        // 設定到這個精靈去,將來這個精靈被渲染時,這段程式也會被帶過去,GPU對這個精靈對應的紋理,進行額外的操作        _sprite->setGLProgram(glprogram);    }    return true;}