Cocos2d-x   发布时间:2022-05-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了cocos2dx3.x绘制自己的node大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

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

http://www.voidcn.com/article/p-hfitcsxw-va.html

@H_618_1@下面的例子还顺带开了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:
    Customcatommand _customcatommand;
    
    //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 instance
bool 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)
{
    _customcatommand.init(_globalZOrder); //绘制优先级
    _customcatommand.func = CC_CALLBACK_0(HelloWorld::onDraw,this);//绑定自定义绘制函数,由于是用自己定于的顶点数据,所以没用矩阵信息
    renderer->addCommand(&_customcatommand); //把渲染命令丢进绘制队列
}

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所遇到的程序开发问题。

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

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。