COCOS2DX has two render queues, Renderqueue and Transparentrenderqueue. We can see from the Code of Renderer::render ():
voidRenderer::render () {//Uncomment this once everything are rendered by new renderer//Glclear (Gl_color_buffer_bit | Gl_depth_buffer_bit); //todo:setup camera or MVP_isrendering =true; if(_glviewassigned) {//Process Render Commands//1. Sort render commands based on ID for(Auto &Renderqueue: _rendergroups) {Renderqueue.sort (); } visitrenderqueue (_rendergroups[0]); Flush (); //Process Render Commands//draw transparent objects here, don't batch for transparent objects if(0<_transparentrendergroups.size ()) {_transparentrendergroups.sort (); Glenable (gl_depth_test); Visittransparentrenderqueue (_transparentrendergroups); Gldisable (gl_depth_test); }} clean (); _isrendering=false;}
The Renderqueue is drawn first, the depth detection is not enabled, and the Transparentrenderqueue is then drawn to enable depth detection.
In general, we use Renderqueue, which has the following properties:
1. Renderqueue inside the thing is completely according to ZOrder to determine the order of the rendering, zorder the smaller the more forward.
2. If the ZOrder is equal, it is determined by the order in the Chlid queue, first joined to the front of the queue.
3. You can use Glblendfunc for color blending and 2D shader (because color blending requires disabling depth caching or setting the depth cache to read-only)
To enable depth detection, we need to put the drawing object into the Transparentrenderqueue, by setting the OnDraw callback, and setting the command tansparent to ture, such as:
_customcommand.init (1This, transform, flags); _customcommand.settransparent ( true ); renderer->addcommand (&_customcommand);
To put a sprite in Transparentrenderqueue, modify the sprite as above::d raw (), or override it in a subclass.
Since transparentrenderqueue cannot use color blending (although modifying the render module can be done, it is generally best not to modify the COCOS2DX code), we mainly use the renderqueue.
Just use Renderqueue to draw 3D scenes often encounter the following problems, first paste code:
Auto Marisa = Ccgsprite::create ("Textures/marisa.png"); Marisa->setanchorpoint (VEC2 (0.5,0)); Marisa->setposition3d (VEC3 (origin.x, ORIGIN.Y- $,0)); AddChild (Marisa,0); auto Mare= Ccgsprite::create ("Textures/mare.png"); Mare->setanchorpoint (VEC2 (0.5,0)); Mare->setposition3d (VEC3 (origin.x, ORIGIN.Y- $, - +)); AddChild (Mare,0); auto Spr3d= Sprite3d::create ("Sprite3dtest/boss1.obj"); Spr3d->setscale ( -. f); Spr3d->settexture ("Sprite3dtest/boss.png"); Spr3d->setposition3d (VEC3 (origin.x, ORIGIN.Y,- -)); Spr3d->runaction (Repeatforever::create (Rotateby::create (3, the)) ; AddChild (spr3d); auto Ground= Ccgsprite::create ("textures/grasshr.jpg"); ground->setposition3d (VEC3 (origin.x, ORIGIN.Y- $,0)); ground->setrotation3d (VEC3 (- -,0,0)); AddChild (Ground,0);
There are 4 sprites in the scene except for animated characters, including a 3D sprite Spr3d, and a ground that rotates 90 degrees around the x-axis. If you press the code above, you will get the following effect:
The parallel part of the XY plane is OK, but the ground perpendicular to the XY plane is pressed against all sprites, which is not caused by depth detection.
Speaking of this, we have to say ZOrder and Positionz relations.
When I call Setposition3d,setpositionz, I actually do two things:
1. Set transform according to Positionz, that is, the actual rendering in the scene position.
2. Set the value of Globalzorder with Positionz, and Globalzorder determines the rendering order.
The reason for the above problem is that ground's ZOrder is the largest (0, 1000, 500, 0), and the Addchild is after zorder the same big Marisa.
So it's the last render.
So, if we do not want to move the ground position and want to move the ground to the end, then set the ground ZOrder individually:
Auto ground = Ccgsprite::create ("textures/grasshr.jpg"); ground 0 ) ); ground->setrotation3d (VEC3 (-00)); ground Setglobalzorder (-0);
The following effects are modified:
The difference between Globalzorder and Localzorder is that Globalzorder changes the order in which objects are rendered throughout the scene, whereas Localzorder changes the order in which objects are rendered under their parent nodes.
Because the parent node of this example is scene, the effect of Globalzorder and Localzorder is the same.
COCOS2DX depth Detection and ZOrder