mirror of https://github.com/axmolengine/axmol.git
move begin(), end(),draw() to RenderTexture
This commit is contained in:
parent
fad585fbef
commit
a7a50dffcc
|
@ -37,6 +37,11 @@ THE SOFTWARE.
|
|||
#include "CCNotificationCenter.h"
|
||||
#include "CCEventType.h"
|
||||
#include "CCGrid.h"
|
||||
|
||||
#include "CCRenderer.h"
|
||||
#include "CCGroupCommand.h"
|
||||
#include "CCCustomCommand.h"
|
||||
|
||||
// extern
|
||||
#include "kazmath/GL/matrix.h"
|
||||
|
||||
|
@ -296,47 +301,6 @@ bool RenderTexture::initWithWidthAndHeight(int w, int h, Texture2D::PixelFormat
|
|||
return ret;
|
||||
}
|
||||
|
||||
void RenderTexture::begin()
|
||||
{
|
||||
kmGLMatrixMode(KM_GL_PROJECTION);
|
||||
kmGLPushMatrix();
|
||||
kmGLMatrixMode(KM_GL_MODELVIEW);
|
||||
kmGLPushMatrix();
|
||||
|
||||
Director *director = Director::getInstance();
|
||||
director->setProjection(director->getProjection());
|
||||
|
||||
const Size& texSize = _texture->getContentSizeInPixels();
|
||||
|
||||
// Calculate the adjustment ratios based on the old and new projections
|
||||
Size size = director->getWinSizeInPixels();
|
||||
float widthRatio = size.width / texSize.width;
|
||||
float heightRatio = size.height / texSize.height;
|
||||
|
||||
// Adjust the orthographic projection and viewport
|
||||
glViewport(0, 0, (GLsizei)texSize.width, (GLsizei)texSize.height);
|
||||
|
||||
|
||||
kmMat4 orthoMatrix;
|
||||
kmMat4OrthographicProjection(&orthoMatrix, (float)-1.0 / widthRatio, (float)1.0 / widthRatio,
|
||||
(float)-1.0 / heightRatio, (float)1.0 / heightRatio, -1,1 );
|
||||
kmGLMultMatrix(&orthoMatrix);
|
||||
|
||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_oldFBO);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _FBO);
|
||||
|
||||
/* Certain Qualcomm Andreno gpu's will retain data in memory after a frame buffer switch which corrupts the render to the texture. The solution is to clear the frame buffer before rendering to the texture. However, calling glClear has the unintended result of clearing the current texture. Create a temporary texture to overcome this. At the end of RenderTexture::begin(), switch the attached texture to the second one, call glClear, and then switch back to the original texture. This solution is unnecessary for other devices as they don't have the same issue with switching frame buffers.
|
||||
*/
|
||||
if (Configuration::getInstance()->checkForGLExtension("GL_QCOM"))
|
||||
{
|
||||
// -- bind a temporary texture so we can clear the render buffer without losing our texture
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _textureCopy->getName(), 0);
|
||||
CHECK_GL_ERROR_DEBUG();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _texture->getName(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTexture::beginWithClear(float r, float g, float b, float a)
|
||||
{
|
||||
_beginWithClear(r, g, b, a, 0, 0, GL_COLOR_BUFFER_BIT);
|
||||
|
@ -354,61 +318,21 @@ void RenderTexture::beginWithClear(float r, float g, float b, float a, float dep
|
|||
|
||||
void RenderTexture::_beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue, GLbitfield flags)
|
||||
{
|
||||
setClearColor(Color4F(r, g, b, a));
|
||||
|
||||
setClearDepth(depthValue);
|
||||
|
||||
setClearStencil(stencilValue);
|
||||
|
||||
setClearFlags(flags);
|
||||
|
||||
this->begin();
|
||||
|
||||
// save clear color
|
||||
GLfloat clearColor[4] = {0.0f};
|
||||
GLfloat depthClearValue = 0.0f;
|
||||
int stencilClearValue = 0;
|
||||
|
||||
if (flags & GL_COLOR_BUFFER_BIT)
|
||||
{
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE,clearColor);
|
||||
glClearColor(r, g, b, a);
|
||||
}
|
||||
|
||||
if (flags & GL_DEPTH_BUFFER_BIT)
|
||||
{
|
||||
glGetFloatv(GL_DEPTH_CLEAR_VALUE, &depthClearValue);
|
||||
glClearDepth(depthValue);
|
||||
}
|
||||
|
||||
if (flags & GL_STENCIL_BUFFER_BIT)
|
||||
{
|
||||
glGetIntegerv(GL_STENCIL_CLEAR_VALUE, &stencilClearValue);
|
||||
glClearStencil(stencilValue);
|
||||
}
|
||||
|
||||
glClear(flags);
|
||||
|
||||
// restore
|
||||
if (flags & GL_COLOR_BUFFER_BIT)
|
||||
{
|
||||
glClearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
|
||||
}
|
||||
if (flags & GL_DEPTH_BUFFER_BIT)
|
||||
{
|
||||
glClearDepth(depthClearValue);
|
||||
}
|
||||
if (flags & GL_STENCIL_BUFFER_BIT)
|
||||
{
|
||||
glClearStencil(stencilClearValue);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTexture::end()
|
||||
{
|
||||
Director *director = Director::getInstance();
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, _oldFBO);
|
||||
|
||||
// restore viewport
|
||||
director->setViewport();
|
||||
|
||||
kmGLMatrixMode(KM_GL_PROJECTION);
|
||||
kmGLPopMatrix();
|
||||
kmGLMatrixMode(KM_GL_MODELVIEW);
|
||||
kmGLPopMatrix();
|
||||
//clear screen
|
||||
CustomCommand* clearCmd = CustomCommand::getCommandPool().generateCommand();
|
||||
clearCmd->init(0, _vertexZ);
|
||||
clearCmd->func = CC_CALLBACK_0(RenderTexture::onClear, this);
|
||||
Director::getInstance()->getRenderer()->addCommand(clearCmd);
|
||||
}
|
||||
|
||||
//TODO find a better way to clear the screen, there is no need to rebind render buffer there.
|
||||
|
@ -420,16 +344,16 @@ void RenderTexture::clear(float r, float g, float b, float a)
|
|||
|
||||
void RenderTexture::clearDepth(float depthValue)
|
||||
{
|
||||
setClearDepth(depthValue);
|
||||
|
||||
this->begin();
|
||||
//! save old depth value
|
||||
GLfloat depthClearValue;
|
||||
glGetFloatv(GL_DEPTH_CLEAR_VALUE, &depthClearValue);
|
||||
|
||||
glClearDepth(depthValue);
|
||||
glClear(GL_DEPTH_BUFFER_BIT);
|
||||
CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand();
|
||||
cmd->init(0, _vertexZ);
|
||||
cmd->func = CC_CALLBACK_0(RenderTexture::onClearDepth, this);
|
||||
|
||||
Director::getInstance()->getRenderer()->addCommand(cmd);
|
||||
|
||||
// restore clear color
|
||||
glClearDepth(depthClearValue);
|
||||
this->end();
|
||||
}
|
||||
|
||||
|
@ -466,69 +390,6 @@ void RenderTexture::visit()
|
|||
_orderOfArrival = 0;
|
||||
}
|
||||
|
||||
void RenderTexture::draw()
|
||||
{
|
||||
if( _autoDraw)
|
||||
{
|
||||
begin();
|
||||
|
||||
if (_clearFlags)
|
||||
{
|
||||
GLfloat oldClearColor[4] = {0.0f};
|
||||
GLfloat oldDepthClearValue = 0.0f;
|
||||
GLint oldStencilClearValue = 0;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
if (_clearFlags & GL_STENCIL_BUFFER_BIT)
|
||||
{
|
||||
glClearStencil(oldStencilClearValue);
|
||||
}
|
||||
}
|
||||
|
||||
//! make sure all children are drawn
|
||||
sortAllChildren();
|
||||
|
||||
for(const auto &child : _children) {
|
||||
if (child != _sprite)
|
||||
{
|
||||
child->visit();
|
||||
}
|
||||
}
|
||||
|
||||
end();
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderTexture::saveToFile(const std::string& filename)
|
||||
{
|
||||
bool ret = false;
|
||||
|
@ -745,4 +606,66 @@ void RenderTexture::onClearDepth()
|
|||
glClearDepth(depthClearValue);
|
||||
}
|
||||
|
||||
void RenderTexture::draw()
|
||||
{
|
||||
if (_autoDraw)
|
||||
{
|
||||
//Begin will create a render group using new render target
|
||||
begin();
|
||||
|
||||
//clear screen
|
||||
CustomCommand* clearCmd = CustomCommand::getCommandPool().generateCommand();
|
||||
clearCmd->init(0, _vertexZ);
|
||||
clearCmd->func = CC_CALLBACK_0(RenderTexture::onClear, this);
|
||||
Director::getInstance()->getRenderer()->addCommand(clearCmd);
|
||||
|
||||
//! make sure all children are drawn
|
||||
sortAllChildren();
|
||||
|
||||
for(const auto &child: _children)
|
||||
{
|
||||
if (child != _sprite)
|
||||
child->visit();
|
||||
}
|
||||
|
||||
//End will pop the current render group
|
||||
end();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTexture::begin()
|
||||
{
|
||||
kmGLMatrixMode(KM_GL_PROJECTION);
|
||||
kmGLPushMatrix();
|
||||
kmGLGetMatrix(KM_GL_PROJECTION, &_projectionMatrix);
|
||||
|
||||
kmGLMatrixMode(KM_GL_MODELVIEW);
|
||||
kmGLPushMatrix();
|
||||
kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix);
|
||||
|
||||
GroupCommand* groupCommand = GroupCommand::getCommandPool().generateCommand();
|
||||
groupCommand->init(0, _vertexZ);
|
||||
|
||||
Renderer *renderer = Director::getInstance()->getRenderer();
|
||||
renderer->addCommand(groupCommand);
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
|
||||
CustomCommand* beginCmd = CustomCommand::getCommandPool().generateCommand();
|
||||
beginCmd->init(0, _vertexZ);
|
||||
beginCmd->func = CC_CALLBACK_0(RenderTexture::onBegin, this);
|
||||
|
||||
Director::getInstance()->getRenderer()->addCommand(beginCmd);
|
||||
}
|
||||
|
||||
void RenderTexture::end()
|
||||
{
|
||||
CustomCommand* endCmd = CustomCommand::getCommandPool().generateCommand();
|
||||
endCmd->init(0, _vertexZ);
|
||||
endCmd->func = CC_CALLBACK_0(RenderTexture::onEnd, this);
|
||||
|
||||
Renderer *renderer = Director::getInstance()->getRenderer();
|
||||
renderer->addCommand(endCmd);
|
||||
renderer->popGroup();
|
||||
}
|
||||
|
||||
NS_CC_END
|
||||
|
|
|
@ -71,102 +71,6 @@ NewRenderTexture* NewRenderTexture::create(int w, int h)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
void NewRenderTexture::draw()
|
||||
{
|
||||
if (_autoDraw)
|
||||
{
|
||||
//Begin will create a render group using new render target
|
||||
begin();
|
||||
|
||||
//clear screen
|
||||
CustomCommand* clearCmd = CustomCommand::getCommandPool().generateCommand();
|
||||
clearCmd->init(0, _vertexZ);
|
||||
clearCmd->func = CC_CALLBACK_0(NewRenderTexture::onClear, this);
|
||||
Director::getInstance()->getRenderer()->addCommand(clearCmd);
|
||||
|
||||
//! make sure all children are drawn
|
||||
sortAllChildren();
|
||||
|
||||
for(const auto &child: _children)
|
||||
{
|
||||
if (child != _sprite)
|
||||
child->visit();
|
||||
}
|
||||
|
||||
//End will pop the current render group
|
||||
end();
|
||||
}
|
||||
}
|
||||
|
||||
void NewRenderTexture::_beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue, GLbitfield flags)
|
||||
{
|
||||
setClearColor(Color4F(r, g, b, a));
|
||||
|
||||
setClearDepth(depthValue);
|
||||
|
||||
setClearStencil(stencilValue);
|
||||
|
||||
setClearFlags(flags);
|
||||
|
||||
this->begin();
|
||||
|
||||
//clear screen
|
||||
CustomCommand* clearCmd = CustomCommand::getCommandPool().generateCommand();
|
||||
clearCmd->init(0, _vertexZ);
|
||||
clearCmd->func = CC_CALLBACK_0(NewRenderTexture::onClear, this);
|
||||
Director::getInstance()->getRenderer()->addCommand(clearCmd);
|
||||
}
|
||||
|
||||
void NewRenderTexture::begin()
|
||||
{
|
||||
kmGLMatrixMode(KM_GL_PROJECTION);
|
||||
kmGLPushMatrix();
|
||||
kmGLGetMatrix(KM_GL_PROJECTION, &_projectionMatrix);
|
||||
|
||||
kmGLMatrixMode(KM_GL_MODELVIEW);
|
||||
kmGLPushMatrix();
|
||||
kmGLGetMatrix(KM_GL_MODELVIEW, &_transformMatrix);
|
||||
|
||||
GroupCommand* groupCommand = GroupCommand::getCommandPool().generateCommand();
|
||||
groupCommand->init(0, _vertexZ);
|
||||
|
||||
Renderer *renderer = Director::getInstance()->getRenderer();
|
||||
renderer->addCommand(groupCommand);
|
||||
renderer->pushGroup(groupCommand->getRenderQueueID());
|
||||
|
||||
CustomCommand* beginCmd = CustomCommand::getCommandPool().generateCommand();
|
||||
beginCmd->init(0, _vertexZ);
|
||||
beginCmd->func = CC_CALLBACK_0(NewRenderTexture::onBegin, this);
|
||||
|
||||
Director::getInstance()->getRenderer()->addCommand(beginCmd);
|
||||
}
|
||||
|
||||
void NewRenderTexture::end()
|
||||
{
|
||||
CustomCommand* endCmd = CustomCommand::getCommandPool().generateCommand();
|
||||
endCmd->init(0, _vertexZ);
|
||||
endCmd->func = CC_CALLBACK_0(NewRenderTexture::onEnd, this);
|
||||
|
||||
Renderer *renderer = Director::getInstance()->getRenderer();
|
||||
renderer->addCommand(endCmd);
|
||||
renderer->popGroup();
|
||||
}
|
||||
|
||||
void NewRenderTexture::clearDepth(float depthValue)
|
||||
{
|
||||
setClearDepth(depthValue);
|
||||
|
||||
this->begin();
|
||||
|
||||
CustomCommand* cmd = CustomCommand::getCommandPool().generateCommand();
|
||||
cmd->init(0, _vertexZ);
|
||||
cmd->func = CC_CALLBACK_0(NewRenderTexture::onClearDepth, this);
|
||||
|
||||
Director::getInstance()->getRenderer()->addCommand(cmd);
|
||||
|
||||
this->end();
|
||||
}
|
||||
|
||||
NewRenderTexture::NewRenderTexture()
|
||||
:RenderTexture()
|
||||
{
|
||||
|
|
|
@ -36,13 +36,12 @@ public:
|
|||
static NewRenderTexture* create(int w, int h, Texture2D::PixelFormat eFormat);
|
||||
static NewRenderTexture* create(int w, int h);
|
||||
|
||||
virtual void begin() override;
|
||||
virtual void end() override;
|
||||
virtual void draw() override;
|
||||
//virtual void begin() override;
|
||||
//virtual void end() override;
|
||||
|
||||
void clearDepth(float depthValue);
|
||||
//void clearDepth(float depthValue);
|
||||
protected:
|
||||
virtual void _beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue, GLbitfield flags) override;
|
||||
//virtual void _beginWithClear(float r, float g, float b, float a, float depthValue, int stencilValue, GLbitfield flags) override;
|
||||
protected:
|
||||
NewRenderTexture();
|
||||
virtual ~NewRenderTexture();
|
||||
|
|
Loading…
Reference in New Issue