cocos2d-x – Cocos2dx:Sprite3D不会渲染到纹理

cocos2d-x – Cocos2dx:Sprite3D不会渲染到纹理,第1张

概述我使用RenderTexture将包含其所有节点的图层渲染纹理,然后在该纹理上应用OpenGL着色器以创建后期处理效果.除Sprite3D和Billboard节点外,它的工作正常.它已在他们的论坛上被问过几次而没有任何回应.我想知道是否有人让这个工作. 这是一个例子: Layer* gameLayer = Layer::create();this->addChild(gameLayer, 0) 我使用RenderTexture将包含其所有节点的图层渲染到纹理,然后在该纹理上应用OpenGL着色器以创建后期处理效果.除Sprite3D和Billboard节点外,它的工作正常.它已在他们的论坛上被问过几次而没有任何回应.我想知道是否有人让这个工作.

这是一个例子:

Layer* gameLayer = Layer::create();this->addChild(gameLayer,0);auto dir = Director::getInstance()->getWinSize();Camera *camera = Camera::createPerspective(60,(GLfloat)dir.wIDth / dir.height,1,1000);camera->setposition3D(Vec3(0,100,100));camera->lookAt(Vec3(0,0),Vec3(0,0));gameLayer->addChild(camera); //add camera to the scene// You'll get a NulL camera insIDe BillBoard::calculateBillbaordtransform() function// if you call visit()/*auto billboard = BillBoard::create("cocos2d-x.png",BillBoard::Mode::VIEW_POINT_ORIENTED);billboard->setposition(Vec2(VisibleRect::center().x,VisibleRect::center().y));gameLayer->addChild(billboard,100);*/// This one won't render into the textureSprite3D* sprite3D = Sprite3D::create("blend_test/character_3_animations_test.c3b");sprite3D->setScale(5.0f); //sets the object scale in floatsprite3D->setRotation3D(Vec3(0.0f,0.0f,0.0f));//sprite3D->setposition3D(Vec3(VisibleRect::center().x,VisibleRect::center().y,0.0f)); //sets sprite positionsprite3D->setposition(Vec2(VisibleRect::center().x,VisibleRect::center().y));gameLayer->addChild(sprite3D,1); //adds sprite to scene,z-index: 1// This one works just fine and appears black and white as expected// in the resulting textureSprite* sprite2D = Sprite::create("cocos2d-x.png");sprite2D->setposition(Vec2(VisibleRect::center().x,VisibleRect::center().y));gameLayer->addChild(sprite2D);// Black and white OpenGL shaderGLProgram* glProgram = GLProgram::createWithfilenames("shaders/gray.vert","shaders/gray.frag");glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_color,GLProgram::VERTEX_ATTRIB_position);glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_position,GLProgram::VERTEX_ATTRIB_color);glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_TEX_COORD,GLProgram::VERTEX_ATTRIB_TEX_COORD);glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_TEX_COORD1,GLProgram::VERTEX_ATTRIB_TEX_COORD1);glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_TEX_COORD2,GLProgram::VERTEX_ATTRIB_TEX_COORD2);glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_TEX_COORD3,GLProgram::VERTEX_ATTRIB_TEX_COORD3);glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_norMAL,GLProgram::VERTEX_ATTRIB_norMAL);glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_BLEND_WEIGHT,GLProgram::VERTEX_ATTRIB_BLEND_WEIGHT);glProgram->bindAttribLocation(GLProgram::ATTRIBUTE_name_BLEND_INDEX,GLProgram::VERTEX_ATTRIB_BLEND_INDEX);glProgram->link();glProgram->updateUniforms();RenderTexture* renderTexture = RenderTexture::create(VisibleRect::wIDth(),VisibleRect::height());renderTexture->retain();Sprite* ppSprite = Sprite::createWithTexture(renderTexture->getSprite()->getTexture());ppSprite->setTextureRect(Rect(0,ppSprite->getTexture()->getContentSize().wIDth,ppSprite->getTexture()->getContentSize().height));ppSprite->setAnchorPoint(Point::ZERO);ppSprite->setposition(Point::ZERO);ppSprite->setFlippedY(true);ppSprite->setGLProgram(glProgram);this->addChild(ppSprite,100);renderTexture->beginWithClear(0.0f,0.0f);auto renderer = _director->getRenderer();auto& parenttransform = _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);gameLayer->visit(renderer,parenttransform,true);//gameLayer->visit();renderTexture->end();ppSprite->setTexture(renderTexture->getSprite()->getTexture());
解决方法 Cocos2d-x v3.11.1(本文截至本文)及以下版本不能正确支持带Sprite3D的RenderTextures,因为有明显的深度缓冲区错误.

这个BUG有一个GitHub issue.但现在存在一种解决方法:

...sprite3D->setForce2DQueue(true); // puts your Sprite3D on same render queue as the RenderTexture. More info below....auto rt = RenderTexture::create(1280,720,Texture2D::PixelFormat::RGBA8888,GL_DEPTH24_STENCIL8); // By default a depth buffer isn't createdrt->setKeepMatrix(true); // required......rt->beginWithClear(0,1); // required,clears the depth buffer

此外,需要对RenderTexture.cpp进行更改.这修复了Cocos2d-x中的清除深度缓冲区错误.

voID RenderTexture::onClear(){    // save clear color    GLfloat oldClearcolor[4] = {0.0f};    GLfloat oldDepthClearValue = 0.0f;    Glint oldStencilClearValue = 0;    GLboolean oldDepthWrite = GL_FALSE;    // backup and set    if (_clearFlags & GL_color_BUFFER_BIT)    {        glGetfloatv(GL_color_CLEAR_VALUE,oldClearcolor);        glClearcolor(_clearcolor.r,_clearcolor.g,_clearcolor.b,_clearcolor.a);    }    if (_clearFlags & GL_DEPTH_BUFFER_BIT)    {        glGetfloatv(GL_DEPTH_CLEAR_VALUE,&oldDepthClearValue);        glClearDepth(_clearDepth);        glGetBooleanv(GL_DEPTH_WRITEMASK,&oldDepthWrite);        glDepthMask(true);    }    if (_clearFlags & GL_STENCIL_BUFFER_BIT)    {        glGetIntegerv(GL_STENCIL_CLEAR_VALUE,&oldStencilClearValue);        glClearStencil(_clearStencil);    }    // clear    glClear(_clearFlags);    // restore    if (_clearFlags & GL_color_BUFFER_BIT)    {        glClearcolor(oldClearcolor[0],oldClearcolor[1],oldClearcolor[2],oldClearcolor[3]);    }    if (_clearFlags & GL_DEPTH_BUFFER_BIT)    {        glClearDepth(oldDepthClearValue);        glDepthMask(oldDepthWrite);    }    if (_clearFlags & GL_STENCIL_BUFFER_BIT)    {        glClearStencil(oldStencilClearValue);    }}

有关详细信息,请参见the issue.我还做了一个example gist的解决方法.截图如下.

我不确定广告牌,但这种解决方法也可能解决它.

有关Cocos2d-x渲染队列的信息:

Sprite3D需要与RenderTexture位于同一渲染队列中. Cocos2d-x(截至v3.7左右)现在有5个渲染队列:

>全球Z订单< 0
> 3D不透明
> 3D透明
>全球Z订单== 0(2D默认)
>全球Z订单> 0

您可以使用setGlobalZOrder(1)将Sprite3D和RenderTexture放在最后一个队列中,或者只使用sprite3D-> setForce2DQueue(true)将Sprite3D放入2D队列中.

总结

以上是内存溢出为你收集整理的cocos2d-x – Cocos2dx:Sprite3D不会渲染到纹理全部内容,希望文章能够帮你解决cocos2d-x – Cocos2dx:Sprite3D不会渲染到纹理所遇到的程序开发问题。

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

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

原文地址: http://outofmemory.cn/web/1000050.html

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

发表评论

登录后才能评论

评论列表(0条)

保存