转自:
http://www.oschina.net/question/565065_79818
一个图形引擎,总是由构建点,线,面的绘制功能写起来的。点,线,面。构成了最初的图形基础。所以说,掌握点,线,面是掌握引擎的基础。
在Cocos2d-x 1.0版本中,提供了使用OpenGL API来创建点,线,面的例子DrawPrimitivesTest。而在2.0中,同样的例子名称,而内部实现却差别巨大。我们知道,在Cocos2d-x 2.0版本,相较于1.0,增加了shader的支持,而DrawPrimitivesTest这个例子,就是学习基础Shader的最好教程。
学前提示:
OpenGL着色语言(GLSL――OpenGL Shading Language)是用来在OpenGL中着色编程的语言,也即开发人员写的短小的自定义程序,他们是在图形卡的GPU (Graphic Processor Unit图形处理单元)上执行的,代替了固定的渲染管线的一部分。比如:视图转换、投影转换等。GLSL(GL Shading Language)的着色器代码分成2个部分:Vertex Shader(顶点着色器)和Fragment(片断着色器),有时还会有Geometry Shader(几何着色器)。负责运行顶点着色的是顶点着色器。它可以得到当前OpenGL 中的状态,GLSL内置变量进行传递。
打开TestCpp工程,找到Classes下的DrawPrimitivesTest目录。打开两个文件:
DrawPrimitivesTest.h/cpp
- #ifndef _DRAW_PRIMITIVES_TEST_H_
- #define _DRAW_PRIMITIVES_TEST_H_
- //包含Cocos2d头文件
- ----#include "cocos2d.h"
- //使用TestScene这个CCScene类
- #include "../testBasic.h"
- //定义派生于CCLayer的类DrawPrimitivesTest,重载draw用于进行手动渲染处理
- class DrawPrimitivesTest : public CCLayer
- {
- public:
- //构造
- DrawPrimitivesTest();
- //析构
- virtual void draw();
- };
- //定义派生于TestScene的类DrawPrimitiveTestScene,做为TestCpp工程中TestController类集中管理的各个小功能例子的场景
- class DrawPrimitivesTestScene : public TestScene
- {
- public:
- //重载启动此功能例子的场景函数
- virtual void runThisTest();
- };
- #endif
OK,头文件看完了,现在看CPP文件:
- #include "DrawPrimitivesTest.h"
- //构造函数
- DrawPrimitivesTest::DrawPrimitivesTest()
- {
- }
- //手动处理的渲染函数
- void DrawPrimitivesTest::draw()
- {
- //取得屏幕大小
- CCSize s = CCDirector::sharedDirector()->getWinSize();
- //检测是否有OpenGL错误发生,如果有则打印错误
- CHECK_GL_ERROR_DEBUG();
- //平滑模式,即高洛德着色
- // glEnable(GL_LINE_SMOOTH);
- //绘制一条件,参1为起点,参2为终点,ccp为生成CCPoint的宏
- ccDrawLine( ccp(0, 0), ccp(s.width, s.height) );
- //检测是否有OpenGL错误发生,如果有则打印错误
- CHECK_GL_ERROR_DEBUG();
- //设置线宽
- glLineWidth( 5.0f );
- //设置后面要进行绘制时所用的色彩
- ccDrawColor4B(255,0,0,255);
- //绘制线条
- ccDrawLine( ccp(0, s.height), ccp(s.width, 0) );
- //检测是否有OpenGL错误发生,如果有则打印错误
- CHECK_GL_ERROR_DEBUG();
- //设置点的大小
- ccPointSize(64);
- //设置后面要进行绘制时所用的色彩
- ccDrawColor4B(0,0,255,128);
- //绘制一个点
- ccDrawPoint( ccp(s.width / 2, s.height / 2) );
- //检测是否有OpenGL错误发生,如果有则打印错误
- CHECK_GL_ERROR_DEBUG();
- // 绘制四个点
- //这里创建位置点数组
- CCPoint points[] = { ccp(60,60), ccp(70,70), ccp(60,70), ccp(70,60) };
- ccPointSize(4);
- //设置后面要进行绘制时所用的色彩
- ccDrawColor4B(0,255,255,255);
- //使用位置点数组做为四个顶点的位置进行绘制
- ccDrawPoints( points, 4);
- //检测是否有OpenGL错误发生,如果有则打印错误
- CHECK_GL_ERROR_DEBUG();
- //绘制一个绿色圆
- glLineWidth(16);
- //设置后面要进行绘制时所用的色彩
- ccDrawColor4B(0, 255, 0, 255);
- //绘制圆函数,参1是中心点,参2为半径,参3为圆的逆时针旋转角度,参4为圆的平均切分段数,最后一个参数是指定是否从圆分段起止点位置向圆中心连线,这里不进行连线
- ccDrawCircle( ccp(s.width/2, s.height/2), 100, 0, 10, false);
- //检测是否有OpenGL错误发生,如果有则打印错误
- CHECK_GL_ERROR_DEBUG();
- //绘制一个蓝色圆,进行连线
- glLineWidth(2);
- //设置后面要进行绘制时所用的色彩
- ccDrawColor4B(0, 255, 255, 255);
- //这里使用了一个宏CC_DEGREES_TO_RADIANS把角度值转为弧度。转动了90度,目的是为了让中心连线垂直显示。
- ccDrawCircle( ccp(s.width/2, s.height/2), 50, CC_DEGREES_TO_RADIANS(90), 50, true);
- //继续检错
- CHECK_GL_ERROR_DEBUG();
- // 绘制多边形线框。
- ccDrawColor4B(255, 255, 0, 255);
- glLineWidth(10);
- CCPoint vertices[] = { ccp(0,0), ccp(50,50), ccp(100,50), ccp(100,100), ccp(50,100) };
- //这里绘制多边形线框函数,使用上面的顶点数组做为多边形线框的顶点位置,第二个参数为顶点数量,第三个参数指定是否首尾自动连接形成封闭线框。
- //注:其实这个函数拆成两个函数比较好,一个是去掉最后一个参数的ccDrawPoly,用于绘制默认封闭的多边形线框。另一个ccDrawLineList用于绘制线段列。
- ccDrawPoly( vertices, 5, false);
- //继续检错
- CHECK_GL_ERROR_DEBUG();
- //绘制实体多边形
- glLineWidth(1);
- CCPoint filledVertices[] = { ccp(0,120), ccp(50,120), ccp(50,170), ccp(25,200), ccp(0,170) };
- //这里绘制内部填充指定色彩的多边形
- ccDrawSolidPoly(filledVertices, 5, ccc4f(0.5f, 0.5f, 1, 1 ) );
- // 绘制封闭多边形线框,这里就是个三角形线框了。
- ccDrawColor4B(255, 0, 255, 255);
- glLineWidth(2);
- CCPoint vertices2[] = { ccp(30,130), ccp(30,230), ccp(50,200) };
- ccDrawPoly( vertices2, 3, true);
- CHECK_GL_ERROR_DEBUG();