Commit 3fe418bc authored by nadro's avatar nadro

- Removed texture IDs parameter from IVideoDriver::setRenderTarget method....

- Removed texture IDs parameter from IVideoDriver::setRenderTarget method. Performance gain was too low to keep this parameter available.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5152 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 07a7d9ee
...@@ -175,7 +175,7 @@ int main() ...@@ -175,7 +175,7 @@ int main()
// draw scene into render target // draw scene into render target
// set render target texture // set render target texture
driver->setRenderTarget(renderTarget, 0, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0,0,0,255)); driver->setRenderTarget(renderTarget, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(0,0,0,255));
// make cube invisible and set fixed camera as active camera // make cube invisible and set fixed camera as active camera
test->setVisible(false); test->setVisible(false);
...@@ -186,7 +186,7 @@ int main() ...@@ -186,7 +186,7 @@ int main()
// set back old render target // set back old render target
// The buffer might have been distorted, so clear it // The buffer might have been distorted, so clear it
driver->setRenderTarget((video::IRenderTarget*)0, 0, 0, video::SColor(0)); driver->setRenderTarget((video::IRenderTarget*)0, 0, video::SColor(0));
// make the cube visible and set the user controlled camera as active one // make the cube visible and set the user controlled camera as active one
test->setVisible(true); test->setVisible(true);
......
...@@ -551,26 +551,13 @@ namespace video ...@@ -551,26 +551,13 @@ namespace video
possible to render into a texture between the possible to render into a texture between the
IVideoDriver::beginScene() and endScene() method calls. IVideoDriver::beginScene() and endScene() method calls.
\param target Render target object. \param target Render target object.
\param activeTextureID Array of texture indices which should be active during
RTT process. If more than one ID will be apply, this render target will work
as a Multiple Render Target.
\param clearFlag The clear flags. \param clearFlag The clear flags.
\param clearColor The clear color for the color buffer. \param clearColor The clear color for the color buffer.
\param clearDepth The clear value for the depth buffer. \param clearDepth The clear value for the depth buffer.
\param clearStencil The clear value for the stencil buffer. \param clearStencil The clear value for the stencil buffer.
\return True if sucessful and false if not. */ \return True if sucessful and false if not. */
virtual bool setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, virtual bool setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0) = 0; f32 clearDepth = 1.f, u8 clearStencil = 0) = 0;
//! Set a render target.
bool setRenderTarget(IRenderTarget* target, u32 activeTextureID, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
f32 clearDepth = 1.f, u8 clearStencil = 0)
{
core::array<u32> idArray(1);
idArray.push_back(activeTextureID);
return setRenderTarget(target, idArray, clearFlag, clearColor);
}
//! Sets a new render target. //! Sets a new render target.
/** This will only work if the driver supports the /** This will only work if the driver supports the
......
...@@ -484,10 +484,10 @@ bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware) ...@@ -484,10 +484,10 @@ bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
} }
ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat); ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat);
RenderTargetChannel.set_used((u32)Caps.NumSimultaneousRTs); ActiveRenderTarget.set_used((u32)Caps.NumSimultaneousRTs);
for (u32 i = 0; i < RenderTargetChannel.size(); ++i) for (u32 i = 0; i < ActiveRenderTarget.size(); ++i)
RenderTargetChannel[i] = -1; ActiveRenderTarget[i] = false;
// so far so good. // so far so good.
return true; return true;
...@@ -758,7 +758,7 @@ void CD3D9Driver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag, ...@@ -758,7 +758,7 @@ void CD3D9Driver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag,
CNullDriver::setTextureCreationFlag(flag, enabled); CNullDriver::setTextureCreationFlag(flag, enabled);
} }
bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil) bool CD3D9Driver::setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)
{ {
if (target && target->getDriverType() != EDT_DIRECT3D9) if (target && target->getDriverType() != EDT_DIRECT3D9)
{ {
...@@ -768,9 +768,7 @@ bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>& ...@@ -768,9 +768,7 @@ bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>&
if (target) if (target)
{ {
RenderTargetActiveID = activeTextureID; // Store main render target.
// store main render target
if (!BackBufferSurface) if (!BackBufferSurface)
{ {
...@@ -781,44 +779,36 @@ bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>& ...@@ -781,44 +779,36 @@ bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>&
} }
} }
// set new color textures // Set new color textures.
CD3D9RenderTarget* renderTarget = static_cast<CD3D9RenderTarget*>(target); CD3D9RenderTarget* renderTarget = static_cast<CD3D9RenderTarget*>(target);
const u32 surfaceSize = core::min_(renderTarget->getSurfaceCount(), RenderTargetChannel.size()); const u32 surfaceSize = core::min_(renderTarget->getSurfaceCount(), ActiveRenderTarget.size());
for (u32 i = 0; i < activeTextureID.size(); ++i) for (u32 i = 0; i < surfaceSize; ++i)
{ {
const u32 id = activeTextureID[i]; ActiveRenderTarget[i] = true;
if (id < surfaceSize) if (FAILED(pID3DDevice->SetRenderTarget(i, renderTarget->getSurface(i))))
{ {
RenderTargetChannel[id] = 0; ActiveRenderTarget[i] = false;
if (FAILED(pID3DDevice->SetRenderTarget(id, renderTarget->getSurface(id))))
{
os::Printer::log("Error: Could not set render target.", ELL_ERROR); os::Printer::log("Error: Could not set render target.", ELL_ERROR);
RenderTargetChannel[id] = -1;
}
} }
} }
// reset other render target channels // Reset other render target channels.
for (u32 i = 0; i < RenderTargetChannel.size(); ++i) for (u32 i = surfaceSize; i < ActiveRenderTarget.size(); ++i)
{ {
if (RenderTargetChannel[i] == 1) if (ActiveRenderTarget[i])
{ {
pID3DDevice->SetRenderTarget(i, 0); pID3DDevice->SetRenderTarget(i, 0);
RenderTargetChannel[i] = -1; ActiveRenderTarget[i] = false;
}
else if (RenderTargetChannel[i] == 0)
{
RenderTargetChannel[i] = 1;
} }
} }
// set depth stencil buffer // Set depth stencil buffer.
IDirect3DSurface9* depthStencilSurface = renderTarget->getDepthStencilSurface(); IDirect3DSurface9* depthStencilSurface = renderTarget->getDepthStencilSurface();
...@@ -827,20 +817,24 @@ bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>& ...@@ -827,20 +817,24 @@ bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>&
os::Printer::log("Error: Could not set depth-stencil buffer.", ELL_ERROR); os::Printer::log("Error: Could not set depth-stencil buffer.", ELL_ERROR);
} }
// set other settings // Set other settings.
CurrentRendertargetSize = renderTarget->getSize(); CurrentRendertargetSize = renderTarget->getSize();
Transformation3DChanged = true; Transformation3DChanged = true;
} }
else if (CurrentRenderTarget != target) else if (CurrentRenderTarget != target)
{ {
// set main render target // Set main render target.
if (BackBufferSurface) if (BackBufferSurface)
{ {
ActiveRenderTarget[0] = true;
if (FAILED(pID3DDevice->SetRenderTarget(0, BackBufferSurface))) if (FAILED(pID3DDevice->SetRenderTarget(0, BackBufferSurface)))
{ {
os::Printer::log("Error: Could not set main render target.", ELL_ERROR); os::Printer::log("Error: Could not set main render target.", ELL_ERROR);
ActiveRenderTarget[0] = false;
return false; return false;
} }
...@@ -848,25 +842,25 @@ bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>& ...@@ -848,25 +842,25 @@ bool CD3D9Driver::setRenderTarget(IRenderTarget* target, const core::array<u32>&
BackBufferSurface = 0; BackBufferSurface = 0;
} }
// reset other render target channels // Reset other render target channels.
for (u32 i = 1; i < RenderTargetChannel.size(); ++i) for (u32 i = 1; i < ActiveRenderTarget.size(); ++i)
{ {
if (RenderTargetChannel[i] == 1) if (ActiveRenderTarget[i])
{ {
pID3DDevice->SetRenderTarget(i, 0); pID3DDevice->SetRenderTarget(i, 0);
RenderTargetChannel[i] = -1; ActiveRenderTarget[i] = false;
} }
} }
// set main depth-stencil stencil buffer // Set main depth-stencil stencil buffer.
if (FAILED(pID3DDevice->SetDepthStencilSurface(DepthStencilSurface))) if (FAILED(pID3DDevice->SetDepthStencilSurface(DepthStencilSurface)))
{ {
os::Printer::log("Error: Could not set main depth-stencil buffer.", ELL_ERROR); os::Printer::log("Error: Could not set main depth-stencil buffer.", ELL_ERROR);
} }
// set other settings // Set other settings.
CurrentRendertargetSize = core::dimension2d<u32>(0, 0); CurrentRendertargetSize = core::dimension2d<u32>(0, 0);
Transformation3DChanged = true; Transformation3DChanged = true;
...@@ -2852,8 +2846,8 @@ bool CD3D9Driver::reset() ...@@ -2852,8 +2846,8 @@ bool CD3D9Driver::reset()
removeAllHardwareBuffers(); removeAllHardwareBuffers();
// reset render target usage informations. // reset render target usage informations.
for (u32 i = 0; i < RenderTargetChannel.size(); ++i) for (u32 i = 0; i < ActiveRenderTarget.size(); ++i)
RenderTargetChannel[i] = -1; ActiveRenderTarget[i] = false;
if (DepthStencilSurface) if (DepthStencilSurface)
DepthStencilSurface->Release(); DepthStencilSurface->Release();
......
...@@ -58,8 +58,8 @@ namespace video ...@@ -58,8 +58,8 @@ namespace video
//! sets a material //! sets a material
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_; virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
virtual bool setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, virtual bool setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_; f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
//! sets a viewport //! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_; virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
...@@ -419,8 +419,7 @@ namespace video ...@@ -419,8 +419,7 @@ namespace video
IDirect3DSurface9* DepthStencilSurface; IDirect3DSurface9* DepthStencilSurface;
core::dimension2d<u32> CurrentRendertargetSize; core::dimension2d<u32> CurrentRendertargetSize;
core::array<s32> RenderTargetChannel; core::array<bool> ActiveRenderTarget;
core::array<u32> RenderTargetActiveID;
HWND WindowId; HWND WindowId;
core::rect<s32>* SceneSourceRect; core::rect<s32>* SceneSourceRect;
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "IImage.h" #include "IImage.h"
#include "irrMath.h" #include "irrMath.h"
#include "irrString.h"
#include "CD3D9Driver.h" #include "CD3D9Driver.h"
#include "CD3D9Texture.h" #include "CD3D9Texture.h"
...@@ -50,16 +51,25 @@ namespace irr ...@@ -50,16 +51,25 @@ namespace irr
void CD3D9RenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) void CD3D9RenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{ {
bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false;
bool textureUpdate = (Texture != texture) ? true : false; bool textureUpdate = (Texture != texture) ? true : false;
bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false;
if (depthStencilUpdate || textureUpdate) if (textureUpdate || depthStencilUpdate)
{ {
// Set color attachments. // Set color attachments.
if (textureUpdate) if (textureUpdate)
{ {
const u32 size = core::min_(texture.size(), static_cast<u32>(Driver->RenderTargetChannel.size())); if (texture.size() > Driver->ActiveRenderTarget.size())
{
core::stringc message = "This GPU supports up to ";
message += Driver->ActiveRenderTarget.size();
message += " textures per render target.";
os::Printer::log(message.c_str(), ELL_WARNING);
}
const u32 size = core::min_(texture.size(), static_cast<u32>(Driver->ActiveRenderTarget.size()));
for (u32 i = 0; i < Surface.size(); ++i) for (u32 i = 0; i < Surface.size(); ++i)
{ {
......
...@@ -619,7 +619,7 @@ ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::p ...@@ -619,7 +619,7 @@ ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::p
return new SDummyTexture(name); return new SDummyTexture(name);
} }
bool CNullDriver::setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil) bool CNullDriver::setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)
{ {
return false; return false;
} }
...@@ -654,11 +654,11 @@ bool CNullDriver::setRenderTarget(ITexture* texture, u16 clearFlag, SColor clear ...@@ -654,11 +654,11 @@ bool CNullDriver::setRenderTarget(ITexture* texture, u16 clearFlag, SColor clear
SharedRenderTarget->setTexture(texture, depthTexture); SharedRenderTarget->setTexture(texture, depthTexture);
return IVideoDriver::setRenderTarget(SharedRenderTarget, 0, clearFlag, clearColor, clearDepth, clearStencil); return setRenderTarget(SharedRenderTarget, clearFlag, clearColor, clearDepth, clearStencil);
} }
else else
{ {
return IVideoDriver::setRenderTarget(NULL, 0, clearFlag, clearColor, clearDepth, clearStencil); return setRenderTarget((IRenderTarget*)0, clearFlag, clearColor, clearDepth, clearStencil);
} }
} }
......
...@@ -98,8 +98,8 @@ namespace video ...@@ -98,8 +98,8 @@ namespace video
//! creates a Texture //! creates a Texture
virtual ITexture* addTexture(const core::dimension2d<u32>& size, const io::path& name, ECOLOR_FORMAT format = ECF_A8R8G8B8) _IRR_OVERRIDE_; virtual ITexture* addTexture(const core::dimension2d<u32>& size, const io::path& name, ECOLOR_FORMAT format = ECF_A8R8G8B8) _IRR_OVERRIDE_;
virtual bool setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, virtual bool setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_; f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
virtual bool setRenderTarget(ITexture* texture, u16 clearFlag, SColor clearColor = SColor(255,0,0,0), virtual bool setRenderTarget(ITexture* texture, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_; f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
......
...@@ -4215,7 +4215,7 @@ u32 COpenGLDriver::getMaximalPrimitiveCount() const ...@@ -4215,7 +4215,7 @@ u32 COpenGLDriver::getMaximalPrimitiveCount() const
return 0x7fffffff; return 0x7fffffff;
} }
bool COpenGLDriver::setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil) bool COpenGLDriver::setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)
{ {
if (target && target->getDriverType() != EDT_OPENGL) if (target && target->getDriverType() != EDT_OPENGL)
{ {
...@@ -4238,7 +4238,7 @@ bool COpenGLDriver::setRenderTarget(IRenderTarget* target, const core::array<u32 ...@@ -4238,7 +4238,7 @@ bool COpenGLDriver::setRenderTarget(IRenderTarget* target, const core::array<u32
if (supportForFBO) if (supportForFBO)
{ {
BridgeCalls->setFBO(renderTarget->getBufferID()); BridgeCalls->setFBO(renderTarget->getBufferID());
renderTarget->update(activeTextureID); renderTarget->update();
} }
destRenderTargetSize = renderTarget->getSize(); destRenderTargetSize = renderTarget->getSize();
......
...@@ -355,8 +355,8 @@ namespace video ...@@ -355,8 +355,8 @@ namespace video
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size, virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_; const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;
virtual bool setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, virtual bool setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_; f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
virtual void clearBuffers(u16 flag, SColor color = SColor(255,0,0,0), f32 depth = 1.f, u8 stencil = 0) _IRR_OVERRIDE_; virtual void clearBuffers(u16 flag, SColor color = SColor(255,0,0,0), f32 depth = 1.f, u8 stencil = 0) _IRR_OVERRIDE_;
...@@ -679,6 +679,8 @@ namespace video ...@@ -679,6 +679,8 @@ namespace video
void setClientActiveTexture(GLenum texture); void setClientActiveTexture(GLenum texture);
void getTexture(GLenum& type, GLuint& name) const;
void setTexture(GLuint stage, bool fixedPipeline); void setTexture(GLuint stage, bool fixedPipeline);
// Viewport calls. // Viewport calls.
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "IImage.h" #include "IImage.h"
#include "irrMath.h" #include "irrMath.h"
#include "irrString.h"
#include "COpenGLDriver.h" #include "COpenGLDriver.h"
#include "COpenGLTexture.h" #include "COpenGLTexture.h"
...@@ -90,8 +91,8 @@ bool checkFBOStatus(COpenGLDriver* Driver) ...@@ -90,8 +91,8 @@ bool checkFBOStatus(COpenGLDriver* Driver)
return false; return false;
} }
COpenGLRenderTarget::COpenGLRenderTarget(COpenGLDriver* driver) : AssignedTextureCount(0), AssignedDepth(false), AssignedStencil(false), COpenGLRenderTarget::COpenGLRenderTarget(COpenGLDriver* driver) : AssignedDepth(false), AssignedStencil(false), RequestTextureUpdate(false), RequestDepthStencilUpdate(false),
TextureUpdate(false), DepthStencilUpdate(false), BufferID(0), SupportForFBO(false), SupportForMRT(false), BridgeCalls(0), Driver(driver) BufferID(0), SupportForFBO(false), SupportForMRT(false), BridgeCalls(0), Driver(driver)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("COpenGLRenderTarget"); setDebugName("COpenGLRenderTarget");
...@@ -99,9 +100,6 @@ COpenGLRenderTarget::COpenGLRenderTarget(COpenGLDriver* driver) : AssignedTextur ...@@ -99,9 +100,6 @@ COpenGLRenderTarget::COpenGLRenderTarget(COpenGLDriver* driver) : AssignedTextur
DriverType = EDT_OPENGL; DriverType = EDT_OPENGL;
AssignedActiveTextureID.set_used(1);
AssignedActiveTextureID[0] = 0;
Size = Driver->getScreenSize(); Size = Driver->getScreenSize();
BridgeCalls = Driver->getBridgeCalls(); BridgeCalls = Driver->getBridgeCalls();
...@@ -114,6 +112,11 @@ COpenGLRenderTarget::COpenGLRenderTarget(COpenGLDriver* driver) : AssignedTextur ...@@ -114,6 +112,11 @@ COpenGLRenderTarget::COpenGLRenderTarget(COpenGLDriver* driver) : AssignedTextur
if (SupportForFBO) if (SupportForFBO)
Driver->extGlGenFramebuffers(1, &BufferID); Driver->extGlGenFramebuffers(1, &BufferID);
AssignedTexture.set_used(static_cast<u32>(Driver->MaxColorAttachments));
for (u32 i = 0; i < AssignedTexture.size(); ++i)
AssignedTexture[i] = GL_NONE;
} }
COpenGLRenderTarget::~COpenGLRenderTarget() COpenGLRenderTarget::~COpenGLRenderTarget()
...@@ -133,9 +136,14 @@ COpenGLRenderTarget::~COpenGLRenderTarget() ...@@ -133,9 +136,14 @@ COpenGLRenderTarget::~COpenGLRenderTarget()
void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{ {
TextureUpdate = TextureUpdate || Texture != texture; bool textureUpdate = (Texture != texture) ? true : false;
bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false;
if (textureUpdate || depthStencilUpdate)
{
// Set color attachments.
if (Texture != texture) if (textureUpdate)
{ {
for (u32 i = 0; i < Texture.size(); ++i) for (u32 i = 0; i < Texture.size(); ++i)
{ {
...@@ -143,6 +151,15 @@ void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITex ...@@ -143,6 +151,15 @@ void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITex
Texture[i]->drop(); Texture[i]->drop();
} }
if (texture.size() > static_cast<u32>(Driver->MaxColorAttachments))
{
core::stringc message = "This GPU supports up to ";
message += static_cast<u32>(Driver->MaxColorAttachments);
message += " textures per render target.";
os::Printer::log(message.c_str(), ELL_WARNING);
}
Texture.set_used(core::min_(texture.size(), static_cast<u32>(Driver->MaxColorAttachments))); Texture.set_used(core::min_(texture.size(), static_cast<u32>(Driver->MaxColorAttachments)));
for (u32 i = 0; i < Texture.size(); ++i) for (u32 i = 0; i < Texture.size(); ++i)
...@@ -159,11 +176,13 @@ void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITex ...@@ -159,11 +176,13 @@ void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITex
Texture[i] = 0; Texture[i] = 0;
} }
} }
RequestTextureUpdate = true;
} }
DepthStencilUpdate = DepthStencilUpdate || DepthStencil != depthStencil; // Set depth and stencil attachments.
if (DepthStencil != depthStencil) if (depthStencilUpdate)
{ {
GLuint textureID = (depthStencil && depthStencil->getDriverType() == EDT_OPENGL) ? static_cast<COpenGLTexture*>(depthStencil)->getOpenGLTextureName() : 0; GLuint textureID = (depthStencil && depthStencil->getDriverType() == EDT_OPENGL) ? static_cast<COpenGLTexture*>(depthStencil)->getOpenGLTextureName() : 0;
const ECOLOR_FORMAT textureFormat = (textureID != 0) ? depthStencil->getColorFormat() : ECF_UNKNOWN; const ECOLOR_FORMAT textureFormat = (textureID != 0) ? depthStencil->getColorFormat() : ECF_UNKNOWN;
...@@ -180,45 +199,73 @@ void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITex ...@@ -180,45 +199,73 @@ void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITex
DepthStencil = 0; DepthStencil = 0;
} }
RequestDepthStencilUpdate = true;
}
// Set size required for a viewport.
ITexture* firstTexture = getTexture();
if (firstTexture)
Size = firstTexture->getSize();
else
{
if (DepthStencil)
Size = DepthStencil->getSize();
else
Size = Driver->getScreenSize();
}
} }
} }
void COpenGLRenderTarget::update(const core::array<u32>& id) void COpenGLRenderTarget::update()
{ {
if (TextureUpdate || DepthStencilUpdate) if (RequestTextureUpdate || RequestDepthStencilUpdate)
{ {
// Set color attachments. // Set color attachments.
if (TextureUpdate) if (RequestTextureUpdate)
{ {
const u32 textureSize = Texture.size(); // Set new color textures.
const u32 stepCount = core::max_(textureSize, AssignedTextureCount);
for (u32 i = 0; i < stepCount; ++i) const u32 textureSize = core::min_(Texture.size(), AssignedTexture.size());
{
GLuint textureID = 0;
if (i < textureSize && Texture[i]) for (u32 i = 0; i < textureSize; ++i)
textureID = static_cast<COpenGLTexture*>(Texture[i])->getOpenGLTextureName(); {
GLuint textureID = (Texture[i]) ? static_cast<COpenGLTexture*>(Texture[i])->getOpenGLTextureName() : 0;
if (textureID != 0) if (textureID != 0)
{ {
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textureID, 0); AssignedTexture[i] = GL_COLOR_ATTACHMENT0 + i;
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, AssignedTexture[i], GL_TEXTURE_2D, textureID, 0);
} }
else if (i < AssignedTextureCount) else if (AssignedTexture[i] != GL_NONE)
{ {
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0); AssignedTexture[i] = GL_NONE;
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, AssignedTexture[i], GL_TEXTURE_2D, 0, 0);
os::Printer::log("Error: Could not set render target.", ELL_ERROR);
} }
} }
AssignedTextureCount = textureSize; // Reset other render target channels.
TextureUpdate = false; for (u32 i = textureSize; i < AssignedTexture.size(); ++i)
{
if (AssignedTexture[i] != GL_NONE)
{
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, AssignedTexture[i], GL_TEXTURE_2D, 0, 0);
AssignedTexture[i] = GL_NONE;
}
}
RequestTextureUpdate = false;
} }
// Set depth and stencil attachments. // Set depth and stencil attachments.
if (DepthStencilUpdate) if (RequestDepthStencilUpdate)
{ {
const ECOLOR_FORMAT textureFormat = (DepthStencil) ? DepthStencil->getColorFormat() : ECF_UNKNOWN; const ECOLOR_FORMAT textureFormat = (DepthStencil) ? DepthStencil->getColorFormat() : ECF_UNKNOWN;
...@@ -256,55 +303,29 @@ void COpenGLRenderTarget::update(const core::array<u32>& id) ...@@ -256,55 +303,29 @@ void COpenGLRenderTarget::update(const core::array<u32>& id)
AssignedStencil = false; AssignedStencil = false;
} }
DepthStencilUpdate = false; RequestDepthStencilUpdate = false;
} }
// Set size required for a viewport. // Configure drawing operation.
ITexture* firstTexture = getTexture(); if (SupportForFBO && BufferID != 0)
{
const u32 textureSize = Texture.size();
if (firstTexture) if (textureSize == 0)
Size = firstTexture->getSize(); glDrawBuffer(GL_NONE);
else if (textureSize == 1 || !SupportForMRT)
glDrawBuffer(GL_COLOR_ATTACHMENT0);
else else
{ {
if (DepthStencil) Driver->extGlDrawBuffers(core::min_(textureSize, AssignedTexture.size()), AssignedTexture.pointer());
Size = DepthStencil->getSize(); }
else
Size = Driver->getScreenSize();
} }
#ifdef _DEBUG #ifdef _DEBUG
checkFBOStatus(Driver); checkFBOStatus(Driver);
#endif #endif
} }
if ((AssignedActiveTextureID != id) && SupportForFBO && BufferID != 0)
{
const u32 size = id.size();
if (size == 0)
glDrawBuffer(GL_NONE);
else if (size == 1 || !SupportForMRT)
glDrawBuffer(GL_COLOR_ATTACHMENT0 + id[0]);
else
{
GLenum* target = new GLenum[Driver->MaxMultipleRenderTargets];
for (u32 i = 0; i < Driver->MaxMultipleRenderTargets; ++i)
target[i] = GL_NONE;
const u32 mrtSize = core::min_(size, static_cast<u32>(Driver->MaxMultipleRenderTargets));
for (u32 i = 0; i < mrtSize; ++i)
target[id[i]] = GL_COLOR_ATTACHMENT0 + id[i];
Driver->extGlDrawBuffers(mrtSize, target);
delete[] target;
}
AssignedActiveTextureID = id;
}
} }
GLuint COpenGLRenderTarget::getBufferID() const GLuint COpenGLRenderTarget::getBufferID() const
......
...@@ -30,7 +30,7 @@ public: ...@@ -30,7 +30,7 @@ public:
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) _IRR_OVERRIDE_; virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) _IRR_OVERRIDE_;
void update(const core::array<u32>& id); void update();
GLuint getBufferID() const; GLuint getBufferID() const;
...@@ -39,13 +39,12 @@ public: ...@@ -39,13 +39,12 @@ public:
ITexture* getTexture() const; ITexture* getTexture() const;
protected: protected:
core::array<u32> AssignedActiveTextureID; core::array<GLenum> AssignedTexture;
u32 AssignedTextureCount;
bool AssignedDepth; bool AssignedDepth;
bool AssignedStencil; bool AssignedStencil;
bool TextureUpdate; bool RequestTextureUpdate;
bool DepthStencilUpdate; bool RequestDepthStencilUpdate;
GLuint BufferID; GLuint BufferID;
......
...@@ -253,7 +253,7 @@ ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const i ...@@ -253,7 +253,7 @@ ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const i
return new CSoftwareTexture(surface, name, false, mipmapData); return new CSoftwareTexture(surface, name, false, mipmapData);
} }
bool CSoftwareDriver::setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil) bool CSoftwareDriver::setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)
{ {
if (target && target->getDriverType() != EDT_SOFTWARE) if (target && target->getDriverType() != EDT_SOFTWARE)
{ {
......
...@@ -36,8 +36,8 @@ namespace video ...@@ -36,8 +36,8 @@ namespace video
//! sets a material //! sets a material
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_; virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
virtual bool setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, virtual bool setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_; f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
//! sets a viewport //! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_; virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
......
...@@ -409,7 +409,7 @@ bool CBurningVideoDriver::endScene() ...@@ -409,7 +409,7 @@ bool CBurningVideoDriver::endScene()
return Presenter->present(BackBuffer, WindowId, SceneSourceRect); return Presenter->present(BackBuffer, WindowId, SceneSourceRect);
} }
bool CBurningVideoDriver::setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil) bool CBurningVideoDriver::setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor, f32 clearDepth, u8 clearStencil)
{ {
if (target && target->getDriverType() != EDT_BURNINGSVIDEO) if (target && target->getDriverType() != EDT_BURNINGSVIDEO)
{ {
......
...@@ -39,8 +39,8 @@ namespace video ...@@ -39,8 +39,8 @@ namespace video
//! sets a material //! sets a material
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_; virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
virtual bool setRenderTarget(IRenderTarget* target, const core::array<u32>& activeTextureID, u16 clearFlag, virtual bool setRenderTarget(IRenderTarget* target, u16 clearFlag, SColor clearColor = SColor(255,0,0,0),
SColor clearColor = SColor(255,0,0,0), f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_; f32 clearDepth = 1.f, u8 clearStencil = 0) _IRR_OVERRIDE_;
//! sets a viewport //! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_; virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
......
...@@ -41,9 +41,9 @@ bool testWithRenderTarget(video::E_DRIVER_TYPE driverType) ...@@ -41,9 +41,9 @@ bool testWithRenderTarget(video::E_DRIVER_TYPE driverType)
//draw the 256x256 water image on the rendertarget: //draw the 256x256 water image on the rendertarget:
driver->setRenderTarget(renderTarget,0,video::ECBF_COLOR|video::ECBF_DEPTH,video::SColor(255,0,0,255));//Rendertarget background is blue driver->setRenderTarget(renderTarget,video::ECBF_COLOR|video::ECBF_DEPTH,video::SColor(255,0,0,255));//Rendertarget background is blue
driver->draw2DImage(tex, core::position2d<s32>(0,0), core::recti(0,0,32,32)); driver->draw2DImage(tex, core::position2d<s32>(0,0), core::recti(0,0,32,32));
driver->setRenderTarget((video::IRenderTarget*)0, 0, 0); driver->setRenderTarget((video::IRenderTarget*)0, 0);
//draw the rendertarget on screen: //draw the rendertarget on screen:
//this should normally draw a 64x64 image containing a 32x32 image in the top left corner //this should normally draw a 64x64 image containing a 32x32 image in the top left corner
......
...@@ -28,7 +28,6 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType) ...@@ -28,7 +28,6 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType)
video::IRenderTarget* renderTarget = 0; video::IRenderTarget* renderTarget = 0;
core::array<video::ITexture*> renderTargetTex; core::array<video::ITexture*> renderTargetTex;
video::ITexture* renderTargetDepth = 0; video::ITexture* renderTargetDepth = 0;
core::array<u32> renderTargetID;
const core::dimension2du texsize(64,64); const core::dimension2du texsize(64,64);
bool result=true; bool result=true;
...@@ -43,11 +42,6 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType) ...@@ -43,11 +42,6 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType)
renderTargetDepth = driver->addRenderTargetTexture(texsize, "rtd", video::ECF_D16); renderTargetDepth = driver->addRenderTargetTexture(texsize, "rtd", video::ECF_D16);
renderTargetID.set_used(3);
renderTargetID[0] = 0;
renderTargetID[1] = 1;
renderTargetID[2] = 2;
renderTarget = driver->addRenderTarget(); renderTarget = driver->addRenderTarget();
renderTarget->setTexture(renderTargetTex, renderTargetDepth); renderTarget->setTexture(renderTargetTex, renderTargetDepth);
...@@ -70,9 +64,9 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType) ...@@ -70,9 +64,9 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType)
driver->beginScene(video::ECBF_COLOR, video::SColor(255, 0, 0, 0)); driver->beginScene(video::ECBF_COLOR, video::SColor(255, 0, 0, 0));
// render // render
driver->setRenderTarget(renderTarget, renderTargetID, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,0,0,0)); driver->setRenderTarget(renderTarget, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,0,0,0));
device->getSceneManager()->drawAll(); device->getSceneManager()->drawAll();
driver->setRenderTarget(0, renderTargetID, 0, video::SColor(255, 0, 0, 0)); driver->setRenderTarget((video::IRenderTarget*)0, 0, video::SColor(255, 0, 0, 0));
// draw debug rt // draw debug rt
driver->draw2DImage(renderTargetTex[0], core::position2d<s32>(0,0)); driver->draw2DImage(renderTargetTex[0], core::position2d<s32>(0,0));
...@@ -86,9 +80,9 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType) ...@@ -86,9 +80,9 @@ static bool testWithDriver(video::E_DRIVER_TYPE driverType)
driver->beginScene(video::ECBF_COLOR, video::SColor(255, 0, 0, 0)); driver->beginScene(video::ECBF_COLOR, video::SColor(255, 0, 0, 0));
// render // render
device->getSceneManager()->getActiveCamera()->setPosition(core::vector3df(0,0,-15)); device->getSceneManager()->getActiveCamera()->setPosition(core::vector3df(0,0,-15));
driver->setRenderTarget(renderTarget, renderTargetID, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,0,0,0)); driver->setRenderTarget(renderTarget, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,0,0,0));
device->getSceneManager()->drawAll(); device->getSceneManager()->drawAll();
driver->setRenderTarget(0, renderTargetID, 0, video::SColor(255,0,0,0)); driver->setRenderTarget((video::IRenderTarget*)0, 0, video::SColor(255,0,0,0));
// draw debug rt // draw debug rt
driver->draw2DImage(renderTargetTex[0], core::position2d<s32>(0,0)); driver->draw2DImage(renderTargetTex[0], core::position2d<s32>(0,0));
......
...@@ -242,7 +242,7 @@ bool rttAndText(video::E_DRIVER_TYPE driverType) ...@@ -242,7 +242,7 @@ bool rttAndText(video::E_DRIVER_TYPE driverType)
stabilizeScreenBackground(driver); stabilizeScreenBackground(driver);
driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,255, 255, 255)); driver->beginScene(video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,255, 255, 255));
driver->setRenderTarget(renderTarget, 0, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,255,0,255)); driver->setRenderTarget(renderTarget, video::ECBF_COLOR | video::ECBF_DEPTH, video::SColor(255,255,0,255));
driver->draw2DImage(driver->getTexture("../media/fireball.bmp"), core::recti(0, 0, renderTargetTex->getSize().Width, renderTargetTex->getSize().Height), core::recti(0, 0, 64, 64)); driver->draw2DImage(driver->getTexture("../media/fireball.bmp"), core::recti(0, 0, renderTargetTex->getSize().Width, renderTargetTex->getSize().Height), core::recti(0, 0, 64, 64));
guienv->getBuiltInFont()->draw(L"OMGGG =!", core::rect<s32>(120, 100, 256, 256), video::SColor(255, 0, 0, 255)); guienv->getBuiltInFont()->draw(L"OMGGG =!", core::rect<s32>(120, 100, 256, 256), video::SColor(255, 0, 0, 255));
driver->setRenderTarget((video::IRenderTarget*)0, 0, 0); driver->setRenderTarget((video::IRenderTarget*)0, 0, 0);
......
Tests finished. 1 test of 1 passed. Tests finished. 2 tests of 2 passed.
Compiled as DEBUG Compiled as DEBUG
Test suite pass at GMT Wed Sep 16 21:05:42 2015 Test suite pass at GMT Fri Oct 16 08:43:01 2015
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment