理解OpenGL渲染管线,对于学习OpenGL非常重要。下面是OpenGL渲染管线的示意图:(图中淡蓝色区域是可以编程的阶段)
此图是从wiki中拿过来的,OpenGL的渲染管线主要包括:
准备顶点数据(通过VBO、VAO和Vertex attribute来传递数据给OpenGL)
顶点处理(这里主要由Vertex Shader来完成,从上图中可以看出,它还包括可选的tessellation和Geometry shader阶段)
顶点后处理(主要包括ClipPing,顶点坐标归一化和vIEwport变换)
Primitive组装(比如3点组装成一个3角形)
光栅化成一个个像素
使用Fragment shader来处理这些像素
采样处理(主要包括Scissor Test,Depth Test,Blending,Stencil Test等)。
OpenGL Shader Language,简称GLSL,它是一种类似于C语言的专门为GPU设计的语言,它可以放在GPU里面被并行运行。 opengl es的着色器有.fsh和.vsh两个文件。这两个文件在被编译和链接后就可以产生可执行程序与GPU交互。 .vsh 是 vertex shader,用与顶点计算,可以理解控制顶点的位置,在这个文件中我们通常会传入当前顶点的位置,和纹理的坐标。 例如:attribute vec4 position; attribute vec4 inputTextureCoordinate;varying vec2 textureCoordinate;precision mediump float;uniform float overTurn;voID main(){gl_position = position; if (overTurn>0.0) { textureCoordinate = vec2(inputTextureCoordinate.x,overTurn-inputTextureCoordinate.y); } else textureCoordinate = vec2(inputTextureCoordinate.x,inputTextureCoordinate.y);}
首先,每一个Shader程序都有一个main函数,这一点和c语言是一样的。
这里面有两种类型的变量,一种是attribute,另一种是varying.
attribute是从外部传进来的,每一个顶点都会有这两个属性,所以它也叫做vertex attribute(顶点属性)。
而varying类型的变量是在vertex shader和fragment shader之间传递数据用的。
这里的变量命名规则保持跟c一样就行了,注意gl_开头的变量名是系统内置的变量,所以大家在定义自己的变量名时,请不要以gl_开头。
而CC_MVPMatrix是一个mat4类型的变量,它是在cocos2d-x内部设置进来的。
即:
attribute:外部传入vsh文件的变量 每帧的渲染的可变参数 变化率高 用于定义每个点。
varying:用于 vsh和fsh之间相互传递的参数。
precisionmediump float 定义中等精度的浮点数。
uniform 外部传入vsh文件的变量 变化率较低 对于可能在整个渲染过程没有改变 只是个常量。
在main()当overTurn大于0的时候,函数里面做的事情就是将纹理y轴反转。
vertex shader是作用于每一个顶点的,如果vertex有三个点,那么vertex shader会被执行三次。
.fsh 是片段shader。在这里面我可以对于每一个像素点进行重新计算。
varying highp vec2 textureCoordinate;precision mediump float;uniform sampler2D vIDeoFrame;vec4 memoryRender(vec4 color){ float gray; gray = color.r*0.3+color.g*0.59+color.b*0.11; color.r = gray; color.g = gray; color.b = gray; color.r += color.r*1.5; color.g = color.g*2.0; if(color.r > 255.0) color.r = 255.0; if(color.g > 255.0) color.g = 255.0; return color;}voID main(){ vec4 pixelcolor; pixelcolor = texture2D(vIDeoFrame,textureCoordinate); gl_Fragcolor = memoryRender(pixelcolor);}
varyinghighpvec2textureCoordinate就是从vsh中传过来了纹理坐标。
uniformsampler2DvIDeoFrame是我们真正的纹理贴图。
texture2D(vIDeoFrame,textureCoordinate) 将纹理中的每个像素点颜色取出到pixelcolor。
可以用memoryRender(pixelcolor)将取到像素点重新加工。
fragment shader中也有一个main函数,同时我们看到这里也声明了一个与vertex shader相同的变量textureCoordinate。前面我们讲过,这个变量是用来在vertex shader和fragment shader之间传递数据用的。所以,它们的参数类型必须完全相同。如果一个是vec3,一个是vec4,shader编译的时候是会报错的。
而gl_Fragcolor我们知道它肯定是一个系统内置变量了,它的作用是定义最终画在屏幕上面的像素点的颜色。
总结:
对于着色器的编程并不是很困难,完全是C的语法。但是deBUG比较麻烦,对于类型的约束也很严格,必须是相同类型的才能进行算术运算。我们理解了这两个文件之后,就可以发挥我们的想象对纹理图片做出各种的处理。
另有人总结:
vsh 负责搞定像素位置,填写gl_Posizion 变量,偶尔搞定一下点大小的问题,填写 gl_PixelSize。
fsh 负责搞定像素外观,填写 gl_Fragcolor ,偶尔配套填写另外一组变量。
他们都是一个像素运行一次的,也可能运行多次。为了“这一像素”而努力计算。
程序的版本是cocos2dx 3.0.vs 2012.
代码如下:
#ifndef __GLTesting_H_#define __GLTesting_H_#include "cocos2d.h"USING_NS_CC;class GLTestingLayer : public cocos2d::Layer{public: static cocos2d::Scene* createScene(); virtual bool init(); voID menuCloseCallback(cocos2d::Ref* pSender); CREATE_FUNC(GLTestingLayer); voID graySprite(Sprite * sprite); virtual voID visit( Renderer* renderer,const kmMat4 &parenttransform,bool parenttransformUpdated ) overrIDe; voID onDraw();private: CustomCommand _command;};#endif // ! __GLTesting_H_GLTestingLayerGLTestingLayer
#include "GLTestingLayer.h"cocos2d::Scene* GLTestingLayer::createScene(){ auto scene = Scene::create(); auto layer = GLTestingLayer::create(); scene->addChild(layer); return scene;}bool GLTestingLayer::init(){ if ( !Layer::init() ) { return false; } this->setposition(0,0); Size visibleSize = Director::getInstance()->getVisibleSize(); auto sprite = Sprite::create("HelloWorld.png"); sprite->setAnchorPoint(Point(0.5,0.5)); sprite->setposition(Point(visibleSize.wIDth / 2,visibleSize.height / 2)); this->addChild(sprite); graySprite(sprite); this->setShaderProgram( shadercache::getInstance()->getProgram(GLProgram::SHADER_name_position_color)); return true; }voID GLTestingLayer::menuCloseCallback( cocos2d::Ref* pSender ){}voID GLTestingLayer::graySprite( Sprite * sprite ){ if(sprite) { GLProgram * p = new GLProgram(); p->initWithfilenames("gray.vsh","gray.fsh"); p->bindAttribLocation(GLProgram::ATTRIBUTE_name_position,GLProgram::VERTEX_ATTRIB_position); p->bindAttribLocation(GLProgram::ATTRIBUTE_name_color,GLProgram::VERTEX_ATTRIB_color); p->bindAttribLocation(GLProgram::ATTRIBUTE_name_TEX_COORD,GLProgram::VERTEX_ATTRIB_TEX_COORDS); p->link(); p->updateUniforms(); sprite->setShaderProgram(p); } }voID GLTestingLayer::visit( Renderer* renderer,bool parenttransformUpdated ){ Layer::visit( renderer,parenttransform,parenttransformUpdated ); _command.init(_globalZOrder); _command.func = CC_CALLBACK_0(GLTestingLayer::onDraw,this); Director::getInstance()->getRenderer()->addCommand(&_command);}voID GLTestingLayer::onDraw(){ auto glProgram = this->getShaderProgram(); glProgram->use(); glProgram->setUniformsForBuiltins(); glPointSize( 10.0f); glcolor4f( 0.0f,1.0f,0.0f,1.0f); auto size = Director::getInstance()->getWinSize(); float vertercIEs[] = { 100,100,200,300,100 }; float color[] = { 1,1,1 }; GL::enabLevertexAttribs(GL::VERTEX_ATTRIB_FLAG_position | GL::VERTEX_ATTRIB_FLAG_color ); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_position,2,GL_float,GL_FALSE,vertercIEs ); glVertexAttribPointer(GLProgram::VERTEX_ATTRIB_color,4,GL_TRUE,color); // 绘制三角形 glDrawArrays(GL_TRIANGLES,3 ); //通知cocos2d-x 的renderer,让它在合适的时候调用这些OpenGL命令 CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,3); CHECK_GL_ERROR_DEBUG();}GLTestingLayer.cppGLTestingLayer.cpp
内有利用shader使得sprite变灰的代码。
下面是变灰所用到的vsh和fsh文件。
attribute vec4 a_position;attribute vec2 a_texCoord;attribute vec4 a_color; varying vec4 v_fragmentcolor;varying vec2 v_texCoord; voID main() { gl_position = CC_PMatrix * a_position; v_fragmentcolor = a_color; v_texCoord = a_texCoord;}gray.vshgray.vsh gray.fsh
varying vec4 v_fragmentcolor; varying vec2 v_texCoord; uniform sampler2D CC_Texture0; voID main() { vec4 v_orcolor = v_fragmentcolor * texture2D(CC_Texture0,v_texCoord); float gray = dot(v_orcolor.rgb,vec3(0.299,0.587,0.114)); gl_Fragcolor = vec4(gray,gray,v_orcolor.a);} gray.fsh转自:http://www.cnblogs.com/slysky/p/3949718.HTML 总结
以上是内存溢出为你收集整理的opengl之vsh、fsh简易介绍+cocos2dx 3.0 shader 变灰全部内容,希望文章能够帮你解决opengl之vsh、fsh简易介绍+cocos2dx 3.0 shader 变灰所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)