cocos2dx3.x绘制自己的node

cocos2dx3.x绘制自己的node,第1张

概述3.x最大的变化就是绘制,通过绘制命令添加到渲染队列中,优化相邻两个渲染命中,如果使用的是同一张纹理,则会并到一个批次中绘制出来,具体流程可以看看之前的文章 http://www.voidcn.com/article/p-hfitcsxw-va.html 下面的例子还顺带开了vbo,vao的话opengles2.0还不支持,所以都被我注释了 头文件.h #ifndef __HELLOWORLD_S

3.x最大的变化就是绘制,通过绘制命令添加到渲染队列中,优化相邻两个渲染命中,如果使用的是同一张纹理,则会并到一个批次中绘制出来,具体流程可以看看之前的文章

http://www.jb51.cc/article/p-hfitcsxw-va.html

下面的例子还顺带开了vbo,vao的话opengles2.0还不支持,所以都被我注释了

头文件.h

#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"using namespace cocos2d;class HelloWorld : public cocos2d::Layer{public:	virtual ~HelloWorld();    static cocos2d::Scene* createScene();    virtual bool init() overrIDe;  	//重写这个方法很重要,node节点递归visit完后就会调这个draw函数,所以我们在这里添加绘制命令绑定自己的绘制函数OnDraw    virtual voID draw(Renderer *renderer,const Mat4 &transform,bool transformUpdated) overrIDe;	//自己的绘制函数    voID onDraw();	voID menuCloseCallback4(cocos2d::Ref* pSender);    CREATE_FUNC(HelloWorld);    private:    CustomCommand _customCommand;        //gluint vao;	gluint vertexVBO; //缓冲区对象句柄 - 顶点	gluint indexVBO; //缓冲区对象句柄 - 顶点索引	//当然,你可以可以gluint vbo[2]用数组去装};#endif // __HELLOWORLD_SCENE_H__

cpp
#include "HelloWorldScene.h"#include "MySprite.h"#include "CubeTexture.h"USING_NS_CC;Scene* HelloWorld::createScene(){    // 'scene' is an autorelease object    auto scene = Scene::create();    	Size size = Director::getInstance()->getWinSize();	auto layer2 = Layer::create();	Sprite* sp = Sprite::create("HelloWorld.png");	//Moveto* move = Moveto::create(5.0f,Vec2(400,400));	//sp->runAction(move);	sp->setposition(size.wIDth / 2,size.height / 2);	//sp->setScale(2.0f);	FontDeFinition fd;	fd._FontSize = 40;	FontShadow fs;	fs._shadowEnabled = true;	fs._shadowBlur = 0.1f;	fs._shadowOffset = Size(10.0f,20.0f);	fs._shadowOpacity = 1.0f;	fd._shadow = fs;	LabelTTF* lb = LabelTTF::createWithFontDeFinition("Hello world",fd);	lb->setposition(size.wIDth / 3,size.height / 3);	layer2->addChild(sp);	layer2->addChild(lb);	//scene->addChild(layer2);    // 'layer' is an autorelease object    auto layer = HelloWorld::create();    // add layer as a child to scene    scene->addChild(layer);    // return the scene    return scene;}voID HelloWorld::menuCloseCallback4(cocos2d::Ref* pSender){	auto scene = CubeTexture::createScene();	Director::getInstance()->replaceScene(scene);}// on "init" you need to initialize your instancebool HelloWorld::init(){    //////////////////////////////    // 1. super init first    if ( !Layer::init() )    {        return false;    }	auto closeItem4 = MenuItemImage::create(		"Closenormal.png","CloseSelected.png",CC_CALLBACK_1(HelloWorld::menuCloseCallback4,this));	Size visibleSize = Director::getInstance()->getVisibleSize();	Vec2 origin = Director::getInstance()->getVisibleOrigin();	closeItem4->setposition(Vec2(origin.x + visibleSize.wIDth / 2 - closeItem4->getContentSize().wIDth / 2,origin.y + visibleSize.height / 2 + closeItem4->getContentSize().height / 2));	// create menu,it's an autorelease object	auto menu = Menu::create(closeItem4,NulL);	menu->setposition(Vec2::ZERO);	this->addChild(menu,100);    //create my own program	auto glprogram = new GLProgram;	glprogram->initWithfilenames("myVertextShader.vert","myFragmentShader.frag");	glprogram->link();    //set uniform locations	glprogram->updateUniforms();    setGLProgram(glprogram); //设置为自己的shader    //glGenVertexArrays(1,&vao);    //glBindVertexArray(vao);    	glGenBuffers(1,&vertexVBO); //创建缓冲区句柄	glGenBuffers(1,&indexVBO);       return true;}voID HelloWorld::draw(cocos2d::Renderer *renderer,bool transformUpdated){    _customCommand.init(_globalZOrder); //绘制优先级    _customCommand.func = CC_CALLBACK_0(HelloWorld::onDraw,this);//绑定自定义绘制函数,由于是用自己定于的顶点数据,所以没用矩阵信息    renderer->addCommand(&_customCommand); //把渲染命令丢进绘制队列}voID HelloWorld::onDraw(){    //如果使用对等矩阵,则三角形绘制会在最前面    Director::getInstance()->pushmatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);    Director::getInstance()->loadIDentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);    Director::getInstance()->pushmatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);    Director::getInstance()->loadIDentityMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);        Mat4 modelVIEwMatrix;    Mat4::createLookAt(Vec3(0,1),Vec3(0,0),1,&modelVIEwMatrix);	modelVIEwMatrix.translate(2,2,-5);	//static float move = 0;	//modelVIEwMatrix.translate(sinf(move*0.05)*2,-5);	//move++;    //static float rotation = 0;    //modelVIEwMatrix.rotate(Vec3(1,CC_degrees_TO_radians(rotation));    //rotation++;    //if (rotation > 360) {    //    rotation = 0;    //}        Mat4 projectionMatrix;    Mat4::createPerspective(60,480/320,1.0,42,&projectionMatrix);    Director::getInstance()->multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION,projectionMatrix);    Director::getInstance()->multiplyMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW,modelVIEwMatrix);	auto glProgram = getGLProgram();	glProgram->use();	glProgram->setUniformsForBuiltins();	Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_PROJECTION);	Director::getInstance()->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);	typedef struct {		float position[3];		float color[4];	} Vertex;	//    auto size = Director::getInstance()->getVisibleSize();	Vertex data[] =	{		// Front		{ { 1,-1,0 },{ 1,1 } },{ { 1,{ 0,{ { -1,// Back		{ { 1,-2 },// left		{ { -1,// Right		{ { 1,// top		{ { 1,// Bottom		{ { 1,1 } }	};	glubyte indices[] = {		// Front		0,3,// Back		4,5,6,4,7,// left		8,9,10,11,8,// Right		12,13,14,15,12,// top		16,17,18,19,16,// Bottom		20,21,22,23,20	};	glBindBuffer(GL_ARRAY_BUFFER,vertexVBO); //绑定这个缓冲区句柄为顶点类型	glBufferData(GL_ARRAY_BUFFER,sizeof(data),data,GL_STATIC_DRAW); //申请内存大小和绑定数据,静态绘制,有几种枚举类型这里就不说了,自行百度	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,indexVBO);//绑定这个缓冲区句柄为索引类型	glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);	gluint positionLocation = glGetAttribLocation(glProgram->getProgram(),"a_position"); //获取自定义shader中的属性变量的地址	gluint colorLocation = glGetAttribLocation(glProgram->getProgram(),"a_color");	glEnabLevertexAttribarray(positionLocation);//激活	glEnabLevertexAttribarray(colorLocation);	glVertexAttribPointer(positionLocation,GL_float,GL_FALSE,sizeof(Vertex),(GLvoID*)offsetof(Vertex,position));	glVertexAttribPointer(colorLocation,color));		// 0 ~ 1 之间波动	static float colorCount = 0;	float tmp = sinf(colorCount*0.01);	tmp = tmp < 0 ? -tmp : tmp;	colorCount++;	/* ---------------------- test1, 为一个float赋值 */	//gluint ucolorLocation1 = glGetUniformlocation(glProgram->getProgram(),"specIntensity");	//float specIntensity = tmp;	//gluniform1f(ucolorLocation1,specIntensity);	/* ---------------------- test2, 为1个由4个float组成的vec4赋值 */	//gluint ucolorLocation2 = glGetUniformlocation(glProgram->getProgram(),"u_color");	//float ucolor2[] = { tmp,tmp,tmp };	//gluniform4fv(ucolorLocation2,ucolor2);	/* ---------------------- test3, 为float[]数组中的两个元素赋值 */	//gluint ucolorLocation3 = glGetUniformlocation(glProgram->getProgram(),"threshold");	//float threshold[2] = { 0.5,tmp };	//gluniform1fv(ucolorLocation3,threshold);	/* ---------------------- test4, 为vec4[]数组中的3个元素赋值 */	//gluint ucolorLocation4 = glGetUniformlocation(glProgram->getProgram(),"colors");	//float colors[12] = { 0.4,0.4,0.8,//	0.2,0.2,//	1.0,tmp };	//gluniform4fv(ucolorLocation4,colors);	/* ---------------------- test5, 为float[]数组中的某个元素赋值,根据下标索引 */	gluint ucolorLocation5 = glGetUniformlocation(glProgram->getProgram(),"threshold[0]"); //传入自定shader中的uniform变量,控制Alpha透明度	float asd = tmp;	gluniform1f(ucolorLocation5,asd);    glDrawElements(GL_TRIANGLES,36,GL_UNSIGNED_BYTE,(GLvoID*)0); //绘制三角形,由于索引也上传到缓冲区了,所以这里的索引直接传0地址    	//解除激活的缓冲区	glBindBuffer(GL_ARRAY_BUFFER,0);	glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);        CC_INCREMENT_GL_DRAWN_BATCHES_AND_VERTICES(1,36);    CHECK_GL_ERROR_DEBUG();}HelloWorld::~HelloWorld(){	//清除缓冲区句柄	glDeleteBuffers(1,&vertexVBO);	glDeleteBuffers(1,&indexVBO);}

myVertextShader.vert
attribute vec3 a_position;attribute vec4 a_color;varying vec4 v_fragmentcolor;varying vec3 normal;  voID main(){    gl_position = CC_MVPMatrix * vec4(a_position.xyz,1.0);    v_fragmentcolor = a_color;}

myFragmentShader.frag
varying vec4 v_fragmentcolor;uniform float specIntensity;uniform vec4 u_color;uniform float threshold[2];uniform vec4 colors[3];  vec4 toonify(float intensity)  {      vec4 color;      if (intensity < 0.3)         color = vec4(1.0,0.0,0.5);      else if (intensity < 0.5)         color = vec4(0.0,0.5);      else if (intensity < 0.7)         color = vec4(0.0,0.5);      else      {       color = vec4(1.0,0.5);          //discard; //最后的discard关键字只能在片断shader中使用,它将在不写入帧缓存或者深度缓存的情况下,终止当前片断的shader程序。    }      return(color);  } voID main(){	// ---------------------- test1    // gl_Fragcolor = v_fragmentcolor * vec4(1.0,specIntensity);	// ---------------------- test2    //gl_Fragcolor = v_fragmentcolor * u_color;	// ---------------------- test3    //gl_Fragcolor = v_fragmentcolor * vec4(1.0,threshold[1]);	// ---------------------- test4    //gl_Fragcolor = v_fragmentcolor * colors[2];    // ---------------------- test5    gl_Fragcolor = v_fragmentcolor * vec4(1.0,threshold[0]);    // ---------------------- test6    //gl_Fragcolor =  toonify(threshold[0]);} 

注释中的其他uniform可以解开注释,同时shader也解开

shader编写需要注意的是

如果shader中定义了uniform属性名但没有使用,会在编译shader时优化调,所以在c++中获取uniform中的变量地址会是个空地址

其次就是类型需要严格一直,在windows平台体现不出来,应为win平台用的是opengl4.0的,而手机平台的是opengles2.0标准,类型不一致在运行时导致异常崩溃,崩溃信息可以重eclipse中看到,比如 float a = 4.0 * 123就是错的,float*int,应改为 float a = 4.0 * float(123)才正确

总结

以上是内存溢出为你收集整理的cocos2dx3.x绘制自己的node全部内容,希望文章能够帮你解决cocos2dx3.x绘制自己的node所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1075418.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-26
下一篇2022-05-26

发表评论

登录后才能评论

评论列表(0条)

    保存