- Added new IRenderTarget interface.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@5068 dfc29bdd-3216-0410-991c-e03cc46cb475
master
nadro 2015-03-23 19:00:17 +00:00
parent 36ffff0b7c
commit 538751d85c
38 changed files with 1628 additions and 1502 deletions

View File

@ -1,6 +1,7 @@
--------------------------
Changes in 1.9 (not yet released)
- Added new IRenderTarget interface.
- Replace the swprintf and snprintf defines by swprintf_irr and snprintf_irr to avoid conflicts with the standard libraries (and other libraries).
- XBox support removed as it would need DX8 (this was about the original XBox).
- Support for Direct3D 8 removed after svn revision 5052 due to lack of maintenance.
@ -15,7 +16,6 @@ Changes in 1.9 (not yet released)
- Add a new core::rect constructor which takes a dimension parameter and set's left-top to 0.
- mtl (obj) format reader and write now regards texture scaling and translation. (thx @thanhle for noticing and patch proposal).
- Added Visual Studio 2013 project files.
- Added ability to set custom depth/stencil texture for render targets.
- Added new color formats: ECF_R8, ECF_R8G8, ECF_D16, ECF_D32, ECF_D24S8.
- Can now enable/disable backround drawing for IGUITable.
- Bugfix: Cloning CBillboardSceneNode now copies colors and sizes.

View File

@ -109,14 +109,20 @@ int main()
*/
// create render target
video::ITexture* rt = 0;
video::IRenderTarget* renderTarget = 0;
video::ITexture* renderTargetTex = 0;
scene::ICameraSceneNode* fixedCam = 0;
if (driver->queryFeature(video::EVDF_RENDER_TO_TARGET))
{
rt = driver->addRenderTargetTexture(core::dimension2d<u32>(256,256), "RTT1");
test->setMaterialTexture(0, rt); // set material of cube to render target
renderTargetTex = driver->addRenderTargetTexture(core::dimension2d<u32>(256, 256), "RTT1", video::ECF_A8R8G8B8);
video::ITexture* renderTargetDepth = driver->addRenderTargetTexture(core::dimension2d<u32>(256, 256), "DepthStencil", video::ECF_D16);
renderTarget = driver->addRenderTarget();
renderTarget->setTexture(renderTargetTex, renderTargetDepth);
test->setMaterialTexture(0, renderTargetTex); // set material of cube to render target
// add fixed camera
fixedCam = smgr->addCameraSceneNode(0, core::vector3df(10,10,-80),
@ -161,12 +167,12 @@ int main()
{
driver->beginScene(true, true, 0);
if (rt)
if (renderTarget)
{
// draw scene into render target
// set render target texture
driver->setRenderTarget(rt, true, true, video::SColor(0,0,0,255));
driver->setRenderTarget(renderTarget, 0, true, true, false, video::SColor(0, 0, 0, 255));
// make cube invisible and set fixed camera as active camera
test->setVisible(false);
@ -177,7 +183,7 @@ int main()
// set back old render target
// The buffer might have been distorted, so clear it
driver->setRenderTarget(0, true, true, 0);
driver->setRenderTarget(0, 0, false, false, false, 0);
// make the cube visible and set the user controlled camera as active one
test->setVisible(true);

65
include/IRenderTarget.h Normal file
View File

@ -0,0 +1,65 @@
// Copyright (C) 2015 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __I_RENDER_TARGET_H_INCLUDED__
#define __I_RENDER_TARGET_H_INCLUDED__
#include "IReferenceCounted.h"
#include "EDriverTypes.h"
#include "irrArray.h"
namespace irr
{
namespace video
{
class ITexture;
//! Interface of a Render Target.
class IRenderTarget : public virtual IReferenceCounted
{
public:
//! constructor
IRenderTarget() : DepthStencil(0), DriverType(EDT_NULL)
{
}
//! Set multiple textures.
/** Set multiple textures for the render target.
\param texture Array of texture objects. These textures are used for a color outputs.
\param depthStencil Depth or packed depth-stencil texture. This texture is used as depth
or depth-stencil buffer. */
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) = 0;
//! Set one texture.
void setTexture(ITexture* texture, ITexture* depthStencil)
{
core::array<ITexture*> textureArray(1);
textureArray.push_back(texture);
setTexture(textureArray, depthStencil);
}
//! Get driver type of render target.
E_DRIVER_TYPE getDriverType() const
{
return DriverType;
}
protected:
//! Textures assigned to render target.
core::array<ITexture*> Texture;
//! Depth or packed depth-stencil texture assigned to render target.
ITexture* DepthStencil;
//! Driver type of render target.
E_DRIVER_TYPE DriverType;
};
}
}
#endif

View File

@ -47,6 +47,7 @@ namespace video
class IImageWriter;
class IMaterialRenderer;
class IGPUProgrammingServices;
class IRenderTarget;
//! enumeration for geometry transformation states
enum E_TRANSFORMATION_STATE
@ -209,43 +210,6 @@ namespace video
};
struct IRenderTarget
{
IRenderTarget(ITexture* texture,
E_COLOR_PLANE colorMask=ECP_ALL,
E_BLEND_FACTOR blendFuncSrc=EBF_ONE,
E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA,
E_BLEND_OPERATION blendOp=EBO_NONE) :
RenderTexture(texture),
TargetType(ERT_RENDER_TEXTURE), ColorMask(colorMask),
BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst),
BlendOp(blendOp) {}
IRenderTarget(E_RENDER_TARGET target,
E_COLOR_PLANE colorMask=ECP_ALL,
E_BLEND_FACTOR blendFuncSrc=EBF_ONE,
E_BLEND_FACTOR blendFuncDst=EBF_ONE_MINUS_SRC_ALPHA,
E_BLEND_OPERATION blendOp=EBO_NONE) :
RenderTexture(0),
TargetType(target), ColorMask(colorMask),
BlendFuncSrc(blendFuncSrc), BlendFuncDst(blendFuncDst),
BlendOp(blendOp) {}
bool operator!=(const IRenderTarget& other) const
{
return ((RenderTexture != other.RenderTexture) ||
(TargetType != other.TargetType) ||
(ColorMask != other.ColorMask) ||
(BlendFuncSrc != other.BlendFuncSrc) ||
(BlendFuncDst != other.BlendFuncDst) ||
(BlendOp != other.BlendOp));
}
ITexture* RenderTexture;
E_RENDER_TARGET TargetType:8;
E_COLOR_PLANE ColorMask:8;
E_BLEND_FACTOR BlendFuncSrc:4;
E_BLEND_FACTOR BlendFuncDst:4;
E_BLEND_OPERATION BlendOp:4;
};
//! Interface to driver which is able to perform 2d and 3d graphics functions.
/** This interface is one of the most important interfaces of
the Irrlicht Engine: All rendering and texture manipulation is done with
@ -503,6 +467,15 @@ namespace video
The value is a safe approximation, i.e. can be larger than the
actual value of pixels. */
virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const =0;
//! Create render target.
virtual IRenderTarget* addRenderTarget() = 0;
//! Remove render target.
virtual void removeRenderTarget(IRenderTarget* renderTarget) = 0;
//! Remove all render targets.
virtual void removeAllRenderTargets() = 0;
//! Sets a boolean alpha channel on the texture based on a color key.
/** This makes the texture fully transparent at the texels where
@ -552,7 +525,7 @@ namespace video
information is multiplied.*/
virtual void makeNormalMapTexture(video::ITexture* texture, f32 amplitude=1.0f) const =0;
//! Sets a new render target. (this prototype will be removed in future)
//! Set a new render target.
/** This will only work if the driver supports the
EVDF_RENDER_TO_TARGET feature, which can be queried with
queryFeature(). Usually, rendering to textures is done in this
@ -586,48 +559,38 @@ namespace video
\return True if sucessful and false if not. */
virtual bool setRenderTarget(video::ITexture* texture,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0),
video::ITexture* depthStencil = 0) =0;
SColor color=video::SColor(0,0,0,0)) =0;
//! Sets a new render target.
virtual bool setRenderTarget(video::ITexture* texture,
video::ITexture* depthStencil,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0))
{
return setRenderTarget(texture, clearBackBuffer, clearZBuffer, color, depthStencil);
}
//! Sets new multiple render targets. (this prototype will be removed in future)
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0),
video::ITexture* depthStencil = 0) =0;
//! Sets new multiple render targets.
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
video::ITexture* depthStencil,
bool clearBackBuffer=true, bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0))
{
return setRenderTarget(texture, clearBackBuffer, clearZBuffer, color, depthStencil);
}
//! set or reset special render targets
/** This method enables access to special color buffers such as
stereoscopic buffers or auxiliary buffers.
\param target Enum value for the render target
\param clearTarget Clears the target buffer with the color
parameter
\param clearZBuffer Clears the zBuffer of the rendertarget.
Note that because the main frame buffer may share the zbuffer with
the rendertarget, its zbuffer might be partially cleared too
by this.
\param color The background color for the render target.
//! Set a render target.
/** This will only work if the driver supports the
EVDF_RENDER_TO_TARGET feature, which can be queried with
queryFeature(). Please note that you cannot render 3D or 2D
geometry with a render target as texture on it when you are rendering
the scene into this render target at the same time. It is usually only
possible to render into a texture between the
IVideoDriver::beginScene() and endScene() method calls.
\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 clearBackBuffer Clears the back buffer of the render
target with the clearColor parameter.
\param clearDepthBuffer Clears the depth buffer of the rendertarget.
\param clearStencilBuffer Clears the stencil buffer of the rendertarget.
\param clearColor The clear color for the render target.
\return True if sucessful and false if not. */
virtual bool setRenderTarget(E_RENDER_TARGET target, bool clearTarget=true,
bool clearZBuffer=true,
SColor color=video::SColor(0,0,0,0)) =0;
virtual bool setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor) = 0;
//! Set a render target.
bool setRenderTarget(IRenderTarget* target, u32 activeTextureID, bool clearBackBuffer, bool clearDepthBuffer,
bool clearStencilBuffer, SColor clearColor)
{
core::array<u32> idArray(1);
idArray.push_back(activeTextureID);
return setRenderTarget(target, idArray, clearBackBuffer, clearDepthBuffer, clearStencilBuffer, clearColor);
}
//! Sets a new viewport.
/** Every rendering operation is done into this new area.
@ -1381,6 +1344,9 @@ namespace video
//! Returns a pointer to the mesh manipulator.
virtual scene::IMeshManipulator* getMeshManipulator() =0;
//! Clear the color, depth and/or stencil buffers.
virtual void clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color) = 0;
//! Clears the ZBuffer.
/** Note that you usually need not to call this method, as it
is automatically done in IVideoDriver::beginScene() or
@ -1388,7 +1354,7 @@ namespace video
you have to render some special things, you can clear the
zbuffer during the rendering process with this method any time.
*/
virtual void clearZBuffer() =0;
_IRR_DEPRECATED_ virtual void clearZBuffer() = 0;
//! Make a screenshot of the last rendered frame.
/** \return An image created from the last rendered frame. */

View File

@ -124,6 +124,7 @@
#include "IReferenceCounted.h"
#include "irrArray.h"
#include "IRandomizer.h"
#include "IRenderTarget.h"
#include "IrrlichtDevice.h"
#include "irrList.h"
#include "irrMap.h"

View File

@ -10,6 +10,7 @@
#include "os.h"
#include "S3DVertex.h"
#include "CD3D9Texture.h"
#include "CD3D9RenderTarget.h"
#include "CD3D9MaterialRenderer.h"
#include "CD3D9ShaderMaterialRenderer.h"
#include "CD3D9NormalMapRenderer.h"
@ -31,10 +32,10 @@ namespace
CD3D9Driver::CD3D9Driver(const SIrrlichtCreationParameters& params, io::IFileSystem* io)
: CNullDriver(io, params.WindowSize), BridgeCalls(0), CurrentRenderMode(ERM_NONE),
ResetRenderStates(true), Transformation3DChanged(false),
D3DLibrary(0), pID3D(0), pID3DDevice(0), PrevRenderTarget(0),
WindowId(0), SceneSourceRect(0),
D3DLibrary(0), pID3D(0), pID3DDevice(0), BackBufferSurface(0),
DepthStencilSurface(0), WindowId(0), SceneSourceRect(0),
LastVertexType((video::E_VERTEX_TYPE)-1), VendorID(0),
MaxTextureUnits(0), MaxUserClipPlanes(0), MaxMRTs(1), NumSetMRTs(1),
MaxTextureUnits(0), MaxUserClipPlanes(0),
MaxLightDistance(0.f), LastSetLight(-1),
ColorFormat(ECF_A8R8G8B8), DeviceLost(false),
DriverWasReset(true), OcclusionQuerySupport(false),
@ -77,11 +78,8 @@ CD3D9Driver::~CD3D9Driver()
deleteAllTextures();
removeAllOcclusionQueries();
removeAllHardwareBuffers();
for (u32 i=0; i<DepthBuffers.size(); ++i)
{
DepthBuffers[i]->drop();
}
DepthBuffers.clear();
DepthStencilSurface->Release();
delete BridgeCalls;
@ -429,7 +427,6 @@ bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
MaxTextureUnits = core::min_((u32)Caps.MaxSimultaneousTextures, MATERIAL_MAX_TEXTURES);
MaxUserClipPlanes = (u32)Caps.MaxUserClipPlanes;
MaxMRTs = (s32)Caps.NumSimultaneousRTs;
OcclusionQuerySupport=(pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, NULL) == S_OK);
if (VendorID==0x10DE)//NVidia
@ -460,13 +457,10 @@ bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
// set the renderstates
setRenderStates3DMode();
// store the screen's depth buffer
DepthBuffers.push_back(new SDepthSurface());
if (SUCCEEDED(pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface))))
// store the screen's depth buffer descriptor
if (SUCCEEDED(pID3DDevice->GetDepthStencilSurface(&DepthStencilSurface)))
{
D3DSURFACE_DESC desc;
DepthBuffers[0]->Surface->GetDesc(&desc);
DepthBuffers[0]->Size.set(desc.Width, desc.Height);
DepthStencilSurface->Release();
}
else
{
@ -475,7 +469,7 @@ bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
}
D3DColorFormat = D3DFMT_A8R8G8B8;
IDirect3DSurface9* bb=0;
IDirect3DSurface9* bb = 0;
if (SUCCEEDED(pID3DDevice->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &bb)))
{
D3DSURFACE_DESC desc;
@ -489,6 +483,11 @@ bool CD3D9Driver::initDriver(HWND hwnd, bool pureSoftware)
}
ColorFormat = getColorFormatFromD3DFormat(D3DColorFormat);
RenderTargetChannel.set_used((u32)Caps.NumSimultaneousRTs);
for (u32 i = 0; i < RenderTargetChannel.size(); ++i)
RenderTargetChannel[i] = -1;
// so far so good.
return true;
}
@ -523,23 +522,7 @@ bool CD3D9Driver::beginScene(bool backBuffer, bool zBuffer, SColor color,
}
}
DWORD flags = 0;
if (backBuffer)
flags |= D3DCLEAR_TARGET;
if (zBuffer)
flags |= D3DCLEAR_ZBUFFER;
if (Params.Stencilbuffer)
flags |= D3DCLEAR_STENCIL;
if (flags)
{
hr = pID3DDevice->Clear( 0, NULL, flags, color.color, 1.0, 0);
if (FAILED(hr))
os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING);
}
clearBuffers(backBuffer, zBuffer, false, color);
hr = pID3DDevice->BeginScene();
if (FAILED(hr))
@ -780,221 +763,127 @@ void CD3D9Driver::setTextureCreationFlag(E_TEXTURE_CREATION_FLAG flag,
}
//! sets a render target
bool CD3D9Driver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil)
//! set a render target
bool CD3D9Driver::setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor)
{
// check for right driver type
if (texture && texture->getDriverType() != EDT_DIRECT3D9)
if (target && target->getDriverType() != EDT_DIRECT3D9)
{
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
os::Printer::log("Fatal Error: Tried to set a render target not owned by this driver.", ELL_ERROR);
return false;
}
// check for valid render target
if (texture && !texture->isRenderTarget())
if (target)
{
os::Printer::log("Fatal Error: Tried to set a non render target texture as render target.", ELL_ERROR);
return false;
}
RenderTargetActiveID = activeTextureID;
CD3D9Texture* tex = static_cast<CD3D9Texture*>(texture);
// store main render target
// check if we should set the previous RT back
bool ret = true;
for(u32 i = 1; i < NumSetMRTs; i++)
{
// First texture handled elsewhere
pID3DDevice->SetRenderTarget(i, NULL);
}
if (tex == 0)
{
if (PrevRenderTarget)
if (!BackBufferSurface)
{
if (FAILED(pID3DDevice->SetRenderTarget(0, PrevRenderTarget)))
if (FAILED(pID3DDevice->GetRenderTarget(0, &BackBufferSurface)))
{
os::Printer::log("Error: Could not set back to previous render target.", ELL_ERROR);
ret = false;
}
if (FAILED(pID3DDevice->SetDepthStencilSurface(DepthBuffers[0]->Surface)))
{
os::Printer::log("Error: Could not set main depth buffer.", ELL_ERROR);
}
CurrentRendertargetSize = core::dimension2d<u32>(0,0);
PrevRenderTarget->Release();
PrevRenderTarget = 0;
}
}
else
{
// we want to set a new target. so do this.
// store previous target
if (!PrevRenderTarget)
{
if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget)))
{
os::Printer::log("Could not get previous render target.", ELL_ERROR);
os::Printer::log("Could not get main render target.", ELL_ERROR);
return false;
}
}
// set new render target
// set new color textures
if (FAILED(pID3DDevice->SetRenderTarget(0, tex->getRenderTargetSurface())))
{
os::Printer::log("Error: Could not set render target.", ELL_ERROR);
return false;
}
CurrentRendertargetSize = tex->getSize();
CD3D9RenderTarget* renderTarget = static_cast<CD3D9RenderTarget*>(target);
if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface)))
const u32 surfaceSize = core::min_(renderTarget->getSurfaceCount(), RenderTargetChannel.size());
for (u32 i = 0; i < activeTextureID.size(); ++i)
{
os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR);
const u32 id = activeTextureID[i];
if (id < surfaceSize)
{
RenderTargetChannel[id] = 0;
if (FAILED(pID3DDevice->SetRenderTarget(id, renderTarget->getSurface(id))))
{
os::Printer::log("Error: Could not set render target.", ELL_ERROR);
RenderTargetChannel[id] = -1;
}
}
}
// reset other render target channels
for (u32 i = 0; i < RenderTargetChannel.size(); ++i)
{
if (RenderTargetChannel[i] == 1)
{
pID3DDevice->SetRenderTarget(i, 0);
RenderTargetChannel[i] = -1;
}
else if (RenderTargetChannel[i] == 0)
{
RenderTargetChannel[i] = 1;
}
}
// set depth stencil buffer
IDirect3DSurface9* depthStencilSurface = renderTarget->getDepthStencilSurface();
if (depthStencilSurface && FAILED(pID3DDevice->SetDepthStencilSurface(depthStencilSurface)))
{
os::Printer::log("Error: Could not set depth-stencil buffer.", ELL_ERROR);
}
// set other settings
CurrentRendertargetSize = renderTarget->getSize();
Transformation3DChanged = true;
}
Transformation3DChanged=true;
if (clearBackBuffer || clearZBuffer)
else if (CurrentRenderTarget != target)
{
DWORD flags = 0;
// set main render target
if (clearBackBuffer)
flags |= D3DCLEAR_TARGET;
if (clearZBuffer)
flags |= D3DCLEAR_ZBUFFER;
pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0);
}
return ret;
}
//! Sets multiple render targets
bool CD3D9Driver::setRenderTarget(const core::array<video::IRenderTarget>& targets,
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil)
{
if (targets.size()==0)
return setRenderTarget(0, clearBackBuffer, clearZBuffer, color, depthStencil);
u32 maxMultipleRTTs = core::min_(MaxMRTs, targets.size());
for (u32 i = 0; i < maxMultipleRTTs; ++i)
{
if (targets[i].TargetType != ERT_RENDER_TEXTURE || !targets[i].RenderTexture)
if (BackBufferSurface)
{
maxMultipleRTTs = i;
os::Printer::log("Missing texture for MRT.", ELL_WARNING);
break;
if (FAILED(pID3DDevice->SetRenderTarget(0, BackBufferSurface)))
{
os::Printer::log("Error: Could not set main render target.", ELL_ERROR);
return false;
}
BackBufferSurface->Release();
BackBufferSurface = 0;
}
// check for right driver type
// reset other render target channels
if (targets[i].RenderTexture->getDriverType() != EDT_DIRECT3D9)
for (u32 i = 1; i < RenderTargetChannel.size(); ++i)
{
maxMultipleRTTs = i;
os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING);
break;
if (RenderTargetChannel[i] == 1)
{
pID3DDevice->SetRenderTarget(i, 0);
RenderTargetChannel[i] = -1;
}
}
// check for valid render target
// set main depth-stencil stencil buffer
if (!targets[i].RenderTexture->isRenderTarget())
if (FAILED(pID3DDevice->SetDepthStencilSurface(DepthStencilSurface)))
{
maxMultipleRTTs = i;
os::Printer::log("Tried to set a non render target texture as render target.", ELL_WARNING);
break;
os::Printer::log("Error: Could not set main depth-stencil buffer.", ELL_ERROR);
}
// check for valid size
// set other settings
if (targets[0].RenderTexture->getSize() != targets[i].RenderTexture->getSize())
{
maxMultipleRTTs = i;
os::Printer::log("Render target texture has wrong size.", ELL_WARNING);
break;
}
}
if (maxMultipleRTTs==0)
{
os::Printer::log("Fatal Error: No valid MRT found.", ELL_ERROR);
return false;
CurrentRendertargetSize = core::dimension2d<u32>(0, 0);
Transformation3DChanged = true;
}
CD3D9Texture* tex = static_cast<CD3D9Texture*>(targets[0].RenderTexture);
CurrentRenderTarget = target;
// check if we should set the previous RT back
clearBuffers(clearBackBuffer, clearDepthBuffer, clearStencilBuffer, clearColor);
bool ret = true;
// we want to set a new target. so do this.
// store previous target
if (!PrevRenderTarget)
{
if (FAILED(pID3DDevice->GetRenderTarget(0, &PrevRenderTarget)))
{
os::Printer::log("Could not get previous render target.", ELL_ERROR);
return false;
}
}
// set new render target
// In d3d9 we have at most 4 MRTs, so the following is enough
D3DRENDERSTATETYPE colorWrite[4]={D3DRS_COLORWRITEENABLE, D3DRS_COLORWRITEENABLE1, D3DRS_COLORWRITEENABLE2, D3DRS_COLORWRITEENABLE3};
for (u32 i = 0; i < maxMultipleRTTs; ++i)
{
if (FAILED(pID3DDevice->SetRenderTarget(i, static_cast<CD3D9Texture*>(targets[i].RenderTexture)->getRenderTargetSurface())))
{
os::Printer::log("Error: Could not set render target.", ELL_ERROR);
return false;
}
if (i<4 && (i==0 || queryFeature(EVDF_MRT_COLOR_MASK)))
{
const DWORD flag =
((targets[i].ColorMask & ECP_RED)?D3DCOLORWRITEENABLE_RED:0) |
((targets[i].ColorMask & ECP_GREEN)?D3DCOLORWRITEENABLE_GREEN:0) |
((targets[i].ColorMask & ECP_BLUE)?D3DCOLORWRITEENABLE_BLUE:0) |
((targets[i].ColorMask & ECP_ALPHA)?D3DCOLORWRITEENABLE_ALPHA:0);
pID3DDevice->SetRenderState(colorWrite[i], flag);
}
}
for(u32 i = maxMultipleRTTs; i < NumSetMRTs; i++)
{
pID3DDevice->SetRenderTarget(i, NULL);
}
NumSetMRTs=maxMultipleRTTs;
CurrentRendertargetSize = tex->getSize();
if (FAILED(pID3DDevice->SetDepthStencilSurface(tex->DepthSurface->Surface)))
{
os::Printer::log("Error: Could not set new depth buffer.", ELL_ERROR);
}
if (clearBackBuffer || clearZBuffer)
{
DWORD flags = 0;
if (clearBackBuffer)
flags |= D3DCLEAR_TARGET;
if (clearZBuffer)
flags |= D3DCLEAR_ZBUFFER;
pID3DDevice->Clear(0, NULL, flags, color.color, 1.0f, 0);
}
return ret;
return true;
}
@ -1383,6 +1272,16 @@ u32 CD3D9Driver::getOcclusionQueryResult(scene::ISceneNode* node) const
}
//! Create render target.
IRenderTarget* CD3D9Driver::addRenderTarget()
{
CD3D9RenderTarget* renderTarget = new CD3D9RenderTarget(this);
RenderTargets.push_back(renderTarget);
return renderTarget;
}
//! draws a vertex primitive list
void CD3D9Driver::drawVertexPrimitiveList(const void* vertices,
u32 vertexCount, const void* indexList, u32 primitiveCount,
@ -2939,16 +2838,11 @@ bool CD3D9Driver::reset()
{
if (Textures[i].Surface->isRenderTarget())
{
IDirect3DBaseTexture9* tex = ((CD3D9Texture*)(Textures[i].Surface))->getDX9Texture();
IDirect3DTexture9* tex = ((CD3D9Texture*)(Textures[i].Surface))->getDX9Texture();
if (tex)
tex->Release();
}
}
for (i=0; i<DepthBuffers.size(); ++i)
{
if (DepthBuffers[i]->Surface)
DepthBuffers[i]->Surface->Release();
}
for (i=0; i<OcclusionQueries.size(); ++i)
{
if (OcclusionQueries[i].PID)
@ -2961,10 +2855,20 @@ bool CD3D9Driver::reset()
// automatically in the next render cycle.
removeAllHardwareBuffers();
// reset render target usage informations.
for (u32 i = 0; i < RenderTargetChannel.size(); ++i)
RenderTargetChannel[i] = -1;
DepthStencilSurface->Release();
DriverWasReset=true;
HRESULT hr = pID3DDevice->Reset(&present);
// restore screen depthbuffer descriptor
pID3DDevice->GetDepthStencilSurface(&DepthStencilSurface);
DepthStencilSurface->Release();
// restore RTTs
for (i=0; i<Textures.size(); ++i)
{
@ -2972,36 +2876,7 @@ bool CD3D9Driver::reset()
((CD3D9Texture*)(Textures[i].Surface))->createRenderTarget();
}
// restore screen depthbuffer
pID3DDevice->GetDepthStencilSurface(&(DepthBuffers[0]->Surface));
D3DSURFACE_DESC desc;
// restore other depth buffers
// depth format is taken from main depth buffer
DepthBuffers[0]->Surface->GetDesc(&desc);
// multisampling is taken from rendertarget
D3DSURFACE_DESC desc2;
for (i=1; i<DepthBuffers.size(); ++i)
{
for (u32 j=0; j<Textures.size(); ++j)
{
// all textures sharing this depth buffer must have the same setting
// so take first one
if (((CD3D9Texture*)(Textures[j].Surface))->DepthSurface==DepthBuffers[i])
{
((CD3D9Texture*)(Textures[j].Surface))->Texture->GetLevelDesc(0,&desc2);
break;
}
}
pID3DDevice->CreateDepthStencilSurface(DepthBuffers[i]->Size.Width,
DepthBuffers[i]->Size.Height,
desc.Format,
desc2.MultiSampleType,
desc2.MultiSampleQuality,
TRUE,
&(DepthBuffers[i]->Surface),
NULL);
}
// restore occlusion queries
for (i=0; i<OcclusionQueries.size(); ++i)
{
pID3DDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, reinterpret_cast<IDirect3DQuery9**>(&OcclusionQueries[i].PID));
@ -3254,7 +3129,7 @@ ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d<u32>& size
tex->drop();
return 0;
}
checkDepthBuffer(tex);
addTexture(tex);
tex->drop();
}
@ -3262,6 +3137,30 @@ ITexture* CD3D9Driver::addRenderTargetTexture(const core::dimension2d<u32>& size
}
//! Clear the color, depth and/or stencil buffers.
void CD3D9Driver::clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color)
{
DWORD flags = 0;
if (backBuffer)
flags |= D3DCLEAR_TARGET;
if (depthBuffer)
flags |= D3DCLEAR_ZBUFFER;
if (stencilBuffer)
flags |= D3DCLEAR_STENCIL;
if (flags)
{
HRESULT hr = pID3DDevice->Clear(0, NULL, flags, color.color, 1.0, 0);
if (FAILED(hr))
os::Printer::log("DIRECT3D9 clear failed.", ELL_WARNING);
}
}
//! Clears the ZBuffer.
void CD3D9Driver::clearZBuffer()
{
@ -3449,8 +3348,6 @@ D3DFORMAT CD3D9Driver::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const
return D3DFMT_R8G8B8;
case ECF_A8R8G8B8:
return D3DFMT_A8R8G8B8;
// Floating Point formats. Thanks to Patryk "Nadro" Nadrowski.
case ECF_R16F:
return D3DFMT_R16F;
case ECF_G16R16F:
@ -3463,6 +3360,12 @@ D3DFORMAT CD3D9Driver::getD3DFormatFromColorFormat(ECOLOR_FORMAT format) const
return D3DFMT_G32R32F;
case ECF_A32B32G32R32F:
return D3DFMT_A32B32G32R32F;
case ECF_D16:
return D3DFMT_D16;
case ECF_D24S8:
return D3DFMT_D24S8;
case ECF_D32:
return D3DFMT_D32;
}
return D3DFMT_UNKNOWN;
}
@ -3503,85 +3406,6 @@ ECOLOR_FORMAT CD3D9Driver::getColorFormatFromD3DFormat(D3DFORMAT format) const
}
void CD3D9Driver::checkDepthBuffer(ITexture* tex)
{
if (!tex)
return;
const core::dimension2du optSize = tex->getSize().getOptimalSize(
!queryFeature(EVDF_TEXTURE_NPOT),
!queryFeature(EVDF_TEXTURE_NSQUARE), true);
SDepthSurface* depth=0;
core::dimension2du destSize(0x7fffffff, 0x7fffffff);
for (u32 i=0; i<DepthBuffers.size(); ++i)
{
if ((DepthBuffers[i]->Size.Width>=optSize.Width) &&
(DepthBuffers[i]->Size.Height>=optSize.Height))
{
if ((DepthBuffers[i]->Size.Width<destSize.Width) &&
(DepthBuffers[i]->Size.Height<destSize.Height))
{
depth = DepthBuffers[i];
destSize=DepthBuffers[i]->Size;
}
}
}
if (!depth)
{
D3DSURFACE_DESC desc;
DepthBuffers[0]->Surface->GetDesc(&desc);
// the multisampling needs to match the RTT
D3DSURFACE_DESC desc2;
((CD3D9Texture*)tex)->Texture->GetLevelDesc(0,&desc2);
DepthBuffers.push_back(new SDepthSurface());
HRESULT hr=pID3DDevice->CreateDepthStencilSurface(optSize.Width,
optSize.Height,
desc.Format,
desc2.MultiSampleType,
desc2.MultiSampleQuality,
TRUE,
&(DepthBuffers.getLast()->Surface),
NULL);
if (SUCCEEDED(hr))
{
depth=DepthBuffers.getLast();
depth->Surface->GetDesc(&desc);
depth->Size.set(desc.Width, desc.Height);
}
else
{
if (hr == D3DERR_OUTOFVIDEOMEMORY)
os::Printer::log("Could not create DepthBuffer","out of video memory",ELL_ERROR);
else if( hr == E_OUTOFMEMORY )
os::Printer::log("Could not create DepthBuffer","out of memory",ELL_ERROR);
else
{
char buffer[128];
sprintf(buffer,"Could not create DepthBuffer of %ix%i",optSize.Width,optSize.Height);
os::Printer::log(buffer,ELL_ERROR);
}
DepthBuffers.erase(DepthBuffers.size()-1);
}
}
else
depth->grab();
static_cast<CD3D9Texture*>(tex)->DepthSurface=depth;
}
void CD3D9Driver::removeDepthSurface(SDepthSurface* depth)
{
for (u32 i=0; i<DepthBuffers.size(); ++i)
{
if (DepthBuffers[i]==depth)
{
DepthBuffers.erase(i);
return;
}
}
}
core::dimension2du CD3D9Driver::getMaxTextureSize() const
{
return core::dimension2du(Caps.MaxTextureWidth, Caps.MaxTextureHeight);

View File

@ -27,30 +27,15 @@ namespace irr
namespace video
{
class CD3D9CallBridge;
struct SDepthSurface : public IReferenceCounted
{
SDepthSurface() : Surface(0)
{
#ifdef _DEBUG
setDebugName("SDepthSurface");
#endif
}
virtual ~SDepthSurface()
{
if (Surface)
Surface->Release();
}
IDirect3DSurface9* Surface;
core::dimension2du Size;
};
class CD3D9RenderTarget;
class CD3D9Texture;
class CD3D9Driver : public CNullDriver, IMaterialRendererServices
{
public:
friend class CD3D9CallBridge;
friend class CD3D9RenderTarget;
friend class CD3D9Texture;
//! constructor
@ -77,13 +62,9 @@ namespace video
//! sets a material
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
//! sets a render target
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& targets,
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set a render target
virtual bool setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor) _IRR_OVERRIDE_;
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
@ -144,6 +125,9 @@ namespace video
actual value of pixels. */
virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const _IRR_OVERRIDE_;
//! Create render target.
virtual IRenderTarget* addRenderTarget() _IRR_OVERRIDE_;
//! draws a vertex primitive list
virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
@ -287,6 +271,9 @@ namespace video
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;
//! Clear the color, depth and/or stencil buffers.
virtual void clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color) _IRR_OVERRIDE_;
//! Clears the ZBuffer.
virtual void clearZBuffer() _IRR_OVERRIDE_;
@ -308,9 +295,6 @@ namespace video
//! Check if the driver was recently reset.
virtual bool checkDriverReset() _IRR_OVERRIDE_ {return DriverWasReset;}
// removes the depth struct from the DepthSurface array
void removeDepthSurface(SDepthSurface* depth);
//! Get the current color format of the color buffer
/** \return Color format of the color buffer. */
virtual ECOLOR_FORMAT getColorFormat() const _IRR_OVERRIDE_;
@ -378,9 +362,6 @@ namespace video
//! returns the current size of the screen or rendertarget
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const _IRR_OVERRIDE_;
//! Check if a proper depth buffer for the RTT is available, otherwise create it.
void checkDepthBuffer(ITexture* tex);
//! Adds a new material renderer to the VideoDriver, using pixel and/or
//! vertex shaders to render geometry.
s32 addShaderMaterial(const c8* vertexShaderProgram, const c8* pixelShaderProgram,
@ -443,8 +424,12 @@ namespace video
IDirect3D9* pID3D;
IDirect3DDevice9* pID3DDevice;
IDirect3DSurface9* PrevRenderTarget;
IDirect3DSurface9* BackBufferSurface;
IDirect3DSurface9* DepthStencilSurface;
core::dimension2d<u32> CurrentRendertargetSize;
core::array<s32> RenderTargetChannel;
core::array<u32> RenderTargetActiveID;
HWND WindowId;
core::rect<s32>* SceneSourceRect;
@ -460,12 +445,8 @@ namespace video
core::stringc VendorName;
u16 VendorID;
core::array<SDepthSurface*> DepthBuffers;
u32 MaxTextureUnits;
u32 MaxUserClipPlanes;
u32 MaxMRTs;
u32 NumSetMRTs;
f32 MaxLightDistance;
s32 LastSetLight;

View File

@ -0,0 +1,186 @@
// Copyright (C) 2015 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "CD3D9RenderTarget.h"
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
#include "IImage.h"
#include "irrMath.h"
#include "CD3D9Driver.h"
#include "CD3D9Texture.h"
namespace irr
{
namespace video
{
CD3D9RenderTarget::CD3D9RenderTarget(CD3D9Driver* driver) : DepthStencilSurface(0), Driver(driver)
{
#ifdef _DEBUG
setDebugName("CD3D9RenderTarget");
#endif
DriverType = EDT_DIRECT3D9;
Size = Driver->getScreenSize();
}
CD3D9RenderTarget::~CD3D9RenderTarget()
{
for (u32 i = 0; i < Surface.size(); ++i)
{
if (Surface[i])
Surface[i]->Release();
}
if (DepthStencilSurface)
DepthStencilSurface->Release();
for (u32 i = 0; i < Texture.size(); ++i)
{
if (Texture[i])
Texture[i]->drop();
}
if (DepthStencil)
DepthStencil->drop();
}
void CD3D9RenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{
bool depthStencilUpdate = (DepthStencil != depthStencil) ? true : false;
bool textureUpdate = (Texture != texture) ? true : false;
if (depthStencilUpdate || textureUpdate)
{
// Set color attachments.
if (textureUpdate)
{
const u32 size = core::min_(texture.size(), static_cast<u32>(Driver->RenderTargetChannel.size()));
for (u32 i = 0; i < Surface.size(); ++i)
{
if (Surface[i])
Surface[i]->Release();
}
Surface.set_used(size);
for (u32 i = 0; i < Texture.size(); ++i)
{
if (Texture[i])
Texture[i]->drop();
}
Texture.set_used(size);
for (u32 i = 0; i < size; ++i)
{
IDirect3DTexture9* currentTexture = (texture[i] && texture[i]->getDriverType() == EDT_DIRECT3D9) ?
static_cast<CD3D9Texture*>(texture[i])->getDX9Texture() : 0;
if (currentTexture)
{
Texture[i] = texture[i];
Texture[i]->grab();
IDirect3DSurface9* currentSurface = 0;
currentTexture->GetSurfaceLevel(0, &currentSurface);
Surface[i] = currentSurface;
}
else
{
Surface[i] = 0;
Texture[i] = 0;
}
}
}
// Set depth and stencil attachments.
if (depthStencilUpdate)
{
if (DepthStencilSurface)
{
DepthStencilSurface->Release();
DepthStencilSurface = 0;
}
if (DepthStencil)
{
DepthStencil->drop();
DepthStencil = 0;
DepthStencilSurface = 0;
}
IDirect3DTexture9* currentTexture = (depthStencil && depthStencil->getDriverType() == EDT_DIRECT3D9) ?
static_cast<CD3D9Texture*>(depthStencil)->getDX9Texture() : 0;
const ECOLOR_FORMAT textureFormat = (depthStencil) ? depthStencil->getColorFormat() : ECF_UNKNOWN;
if (IImage::isDepthFormat(textureFormat))
{
DepthStencil = depthStencil;
DepthStencil->grab();
IDirect3DSurface9* currentSurface = 0;
currentTexture->GetSurfaceLevel(0, &currentSurface);
DepthStencilSurface = currentSurface;
}
}
// Set size required for a viewport.
bool sizeDetected = false;
for (u32 i = 0; i < Texture.size(); ++i)
{
if (Texture[i])
{
Size = Texture[i]->getSize();
sizeDetected = true;
break;
}
}
if (!sizeDetected)
{
if (DepthStencil)
Size = DepthStencil->getSize();
else
Size = Driver->getScreenSize();
}
}
}
const core::dimension2d<u32>& CD3D9RenderTarget::getSize() const
{
return Size;
}
IDirect3DSurface9* CD3D9RenderTarget::getSurface(u32 id) const
{
return (id < Surface.size()) ? Surface[id] : 0;
}
u32 CD3D9RenderTarget::getSurfaceCount() const
{
return Surface.size();
}
IDirect3DSurface9* CD3D9RenderTarget::getDepthStencilSurface() const
{
return DepthStencilSurface;
}
}
}
#endif

View File

@ -0,0 +1,56 @@
// Copyright (C) 2015 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_OPEN_GL_RENDER_TARGET_H_INCLUDED__
#define __C_OPEN_GL_RENDER_TARGET_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_DIRECT3D_9_
#include "IRenderTarget.h"
#include "dimension2d.h"
#include "COpenGLExtensionHandler.h"
#include <d3d9.h>
namespace irr
{
namespace video
{
class CD3D9Driver;
class CD3D9RenderTarget : public IRenderTarget
{
public:
CD3D9RenderTarget(CD3D9Driver* driver);
virtual ~CD3D9RenderTarget();
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) _IRR_OVERRIDE_;
const core::dimension2d<u32>& getSize() const;
IDirect3DSurface9* getSurface(u32 id) const;
u32 getSurfaceCount() const;
IDirect3DSurface9* getDepthStencilSurface() const;
protected:
core::dimension2d<u32> Size;
core::array<IDirect3DSurface9*> Surface;
IDirect3DSurface9* DepthStencilSurface;
CD3D9Driver* Driver;
};
}
}
#endif
#endif

View File

@ -18,14 +18,12 @@ namespace video
{
//! rendertarget constructor
CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format)
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0),
HardwareMipMaps(false), IsCompressed(false)
CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& size, const io::path& name, const ECOLOR_FORMAT format)
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), HardwareMipMaps(false), IsCompressed(false)
{
#ifdef _DEBUG
#ifdef _DEBUG
setDebugName("CD3D9Texture");
#endif
#endif
Device=driver->getExposedVideoData().D3D9.D3DDev9;
if (Device)
@ -41,14 +39,12 @@ CD3D9Texture::CD3D9Texture(CD3D9Driver* driver, const core::dimension2d<u32>& si
//! constructor
CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver,
u32 flags, const io::path& name, void* mipmapData)
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), DepthSurface(0),
HardwareMipMaps(false), IsCompressed(false)
CD3D9Texture::CD3D9Texture(IImage* image, CD3D9Driver* driver, u32 flags, const io::path& name, void* mipmapData)
: ITexture(name), Texture(0), RTTSurface(0), Driver(driver), HardwareMipMaps(false), IsCompressed(false)
{
#ifdef _DEBUG
#ifdef _DEBUG
setDebugName("CD3D9Texture");
#endif
#endif
DriverType = EDT_DIRECT3D9;
HasMipMaps = Driver->getTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS);
@ -105,15 +101,6 @@ CD3D9Texture::~CD3D9Texture()
if (RTTSurface)
RTTSurface->Release();
// if this texture was the last one using the depth buffer
// we can release the surface. We only use the value of the pointer
// hence it is safe to use the dropped pointer...
if (DepthSurface)
{
if (DepthSurface->drop())
Driver->removeDepthSurface(DepthSurface);
}
if (Device)
Device->Release();
}
@ -165,17 +152,9 @@ void CD3D9Texture::createRenderTarget(const ECOLOR_FORMAT format)
}
// create texture
HRESULT hr;
DWORD usage = (IImage::isDepthFormat(ColorFormat)) ? D3DUSAGE_DEPTHSTENCIL : D3DUSAGE_RENDERTARGET;
hr = Device->CreateTexture(
Size.Width,
Size.Height,
1, // mip map level count, we don't want mipmaps here
D3DUSAGE_RENDERTARGET,
d3dformat,
D3DPOOL_DEFAULT,
&Texture,
NULL);
HRESULT hr = Device->CreateTexture(Size.Width, Size.Height, 1, usage, d3dformat, D3DPOOL_DEFAULT, &Texture, NULL);
if (FAILED(hr))
{
@ -556,7 +535,7 @@ void CD3D9Texture::unlock()
//! returns the DIRECT3D9 Texture
IDirect3DBaseTexture9* CD3D9Texture::getDX9Texture() const
IDirect3DTexture9* CD3D9Texture::getDX9Texture() const
{
return Texture;
}
@ -725,23 +704,6 @@ void CD3D9Texture::regenerateMipMapLevels(void* mipmapData)
}
//! Returns pointer to the render target surface
IDirect3DSurface9* CD3D9Texture::getRenderTargetSurface()
{
if (!IsRenderTarget)
return 0;
IDirect3DSurface9 *pRTTSurface = 0;
if (Texture)
Texture->GetSurfaceLevel(0, &pRTTSurface);
if (pRTTSurface)
pRTTSurface->Release();
return pRTTSurface;
}
void CD3D9Texture::setPitch(D3DFORMAT d3dformat)
{
switch(d3dformat)

View File

@ -52,10 +52,7 @@ public:
virtual void regenerateMipMapLevels(void* mipmapData = 0) _IRR_OVERRIDE_;
//! returns the DIRECT3D9 Texture
IDirect3DBaseTexture9* getDX9Texture() const;
//! Returns pointer to the render target surface
IDirect3DSurface9* getRenderTargetSurface();
IDirect3DTexture9* getDX9Texture() const;
private:
friend class CD3D9Driver;
@ -90,7 +87,6 @@ private:
IDirect3DTexture9* Texture;
IDirect3DSurface9* RTTSurface;
CD3D9Driver* Driver;
SDepthSurface* DepthSurface;
u32 MipLevelLocked;
bool HardwareMipMaps;

View File

@ -15,6 +15,7 @@
#include "CMeshManipulator.h"
#include "CColorConverter.h"
#include "IAttributeExchangingObject.h"
#include "IRenderTarget.h"
namespace irr
@ -82,9 +83,9 @@ IImageWriter* createImageWriterPPM();
//! constructor
CNullDriver::CNullDriver(io::IFileSystem* io, const core::dimension2d<u32>& screenSize)
: FileSystem(io), MeshManipulator(0), ViewPort(0,0,0,0), ScreenSize(screenSize),
PrimitivesDrawn(0), MinVertexCountForVBO(500), TextureCreationFlags(0),
OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false)
: CurrentRenderTarget(0), CurrentRenderTargetSize(0, 0), FileSystem(io), MeshManipulator(0),
ViewPort(0, 0, 0, 0), ScreenSize(screenSize), PrimitivesDrawn(0), MinVertexCountForVBO(500),
TextureCreationFlags(0), OverrideMaterial2DEnabled(false), AllowZWriteOnTransparent(false)
{
#ifdef _DEBUG
setDebugName("CNullDriver");
@ -211,6 +212,9 @@ CNullDriver::~CNullDriver()
if (MeshManipulator)
MeshManipulator->drop();
removeAllRenderTargets();
deleteAllTextures();
u32 i;
@ -613,33 +617,21 @@ ITexture* CNullDriver::createDeviceDependentTexture(IImage* surface, const io::p
}
//! sets a render target
bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil)
//! set a render target
bool CNullDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer, bool clearZBuffer, SColor color)
{
return false;
}
//! Sets multiple render targets
bool CNullDriver::setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil)
//! set a render target
bool CNullDriver::setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor)
{
return false;
}
//! set or reset special render targets
bool CNullDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color)
{
if (ERT_FRAME_BUFFER==target)
return setRenderTarget(0,clearTarget, clearZBuffer, color, 0);
else
return false;
}
//! sets a viewport
void CNullDriver::setViewPort(const core::rect<s32>& area)
{
@ -879,6 +871,13 @@ const core::dimension2d<u32>& CNullDriver::getScreenSize() const
}
//! get current render target
IRenderTarget* CNullDriver::getCurrentRenderTarget() const
{
return CurrentRenderTarget;
}
//! returns the current render target size,
//! or the screen size if render targets are not implemented
const core::dimension2d<u32>& CNullDriver::getCurrentRenderTargetSize() const
@ -1760,6 +1759,42 @@ u32 CNullDriver::getOcclusionQueryResult(scene::ISceneNode* node) const
}
//! Create render target.
IRenderTarget* CNullDriver::addRenderTarget()
{
return 0;
}
//! Remove render target.
void CNullDriver::removeRenderTarget(IRenderTarget* renderTarget)
{
if (!renderTarget)
return;
for (u32 i = 0; i < RenderTargets.size(); ++i)
{
if (RenderTargets[i] == renderTarget)
{
RenderTargets[i]->drop();
RenderTargets.erase(i);
return;
}
}
}
//! Remove all render targets.
void CNullDriver::removeAllRenderTargets()
{
for (u32 i = 0; i < RenderTargets.size(); ++i)
RenderTargets[i]->drop();
RenderTargets.clear();
}
//! Only used by the internal engine. Used to notify the driver that
//! the window was resized.
void CNullDriver::OnResize(const core::dimension2d<u32>& size)
@ -2331,6 +2366,12 @@ ITexture* CNullDriver::addRenderTargetTexture(const core::dimension2d<u32>& size
}
//! Clear the color, depth and/or stencil buffers.
void CNullDriver::clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color)
{
}
//! Clears the ZBuffer.
void CNullDriver::clearZBuffer()
{

View File

@ -100,17 +100,12 @@ namespace video
//! creates a Texture
virtual ITexture* addTexture(const core::dimension2d<u32>& size, const io::path& name, ECOLOR_FORMAT format = ECF_A8R8G8B8) _IRR_OVERRIDE_;
//! sets a render target
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set a render target
virtual bool setRenderTarget(ITexture* texture, bool clearBackBuffer, bool clearZBuffer, SColor color) _IRR_OVERRIDE_;
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set or reset special render targets
virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color) _IRR_OVERRIDE_;
//! set a render target
virtual bool setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor) _IRR_OVERRIDE_;
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
@ -242,6 +237,9 @@ namespace video
//! get screen size
virtual const core::dimension2d<u32>& getScreenSize() const _IRR_OVERRIDE_;
//! get current render target
IRenderTarget* getCurrentRenderTarget() const;
//! get render target size
virtual const core::dimension2d<u32>& getCurrentRenderTargetSize() const _IRR_OVERRIDE_;
@ -471,6 +469,15 @@ namespace video
actual value of pixels. */
virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const _IRR_OVERRIDE_;
//! Create render target.
virtual IRenderTarget* addRenderTarget() _IRR_OVERRIDE_;
//! Remove render target.
virtual void removeRenderTarget(IRenderTarget* renderTarget) _IRR_OVERRIDE_;
//! Remove all render targets.
virtual void removeAllRenderTargets() _IRR_OVERRIDE_;
//! Only used by the engine internally.
/** Used to notify the driver that the window was resized. */
virtual void OnResize(const core::dimension2d<u32>& size) _IRR_OVERRIDE_;
@ -584,6 +591,9 @@ namespace video
//! Returns a pointer to the mesh manipulator.
virtual scene::IMeshManipulator* getMeshManipulator() _IRR_OVERRIDE_;
//! Clear the color, depth and/or stencil buffers.
virtual void clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color) _IRR_OVERRIDE_;
//! Clears the ZBuffer.
virtual void clearZBuffer() _IRR_OVERRIDE_;
@ -796,6 +806,11 @@ namespace video
};
core::array<SOccQuery> OcclusionQueries;
core::array<IRenderTarget*> RenderTargets;
IRenderTarget* CurrentRenderTarget;
core::dimension2d<u32> CurrentRenderTargetSize;
core::array<video::IImageLoader*> SurfaceLoader;
core::array<video::IImageWriter*> SurfaceWriter;
core::array<SLight> Lights;

View File

@ -9,6 +9,7 @@
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "COpenGLTexture.h"
#include "COpenGLRenderTarget.h"
#include "COpenGLMaterialRenderer.h"
#include "COpenGLShaderMaterialRenderer.h"
#include "COpenGLSLMaterialRenderer.h"
@ -45,15 +46,11 @@ const u16 COpenGLDriver::Quad2DIndices[4] = { 0, 1, 2, 3 };
// -----------------------------------------------------------------------
#ifdef _IRR_COMPILE_WITH_WINDOWS_DEVICE_
//! Windows constructor and init code
COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params,
io::IFileSystem* io, CIrrDeviceWin32* device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), BridgeCalls(0),
COpenGLDriver::COpenGLDriver(const irr::SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceWin32* device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), BridgeCalls(0),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), RenderTargetTexture(0),
CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
FixedPipelineState(EOFPS_ENABLE),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device),
AntiAlias(params.AntiAlias), ColorFormat(ECF_R8G8B8), FixedPipelineState(EOFPS_ENABLE),
Params(params), HDc(0), Window(static_cast<HWND>(params.WindowId)), Win32Device(device),
DeviceType(EIDT_WIN32)
{
#ifdef _DEBUG
@ -479,15 +476,11 @@ bool COpenGLDriver::initDriver(CIrrDeviceWin32* device)
// -----------------------------------------------------------------------
#ifdef _IRR_COMPILE_WITH_OSX_DEVICE_
//! Windows constructor and init code
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, CIrrDeviceMacOSX *device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(),
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceMacOSX *device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), BridgeCalls(0),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), RenderTargetTexture(0),
CurrentRendertargetSize(0,0), ColorFormat(ECF_R8G8B8),
FixedPipelineState(EOFPS_ENABLE),
CurrentTarget(ERT_FRAME_BUFFER), Params(params), BridgeCalls(0),
OSXDevice(device), DeviceType(EIDT_OSX)
AntiAlias(params.AntiAlias), ColorFormat(ECF_R8G8B8), FixedPipelineState(EOFPS_ENABLE),
Params(params), OSXDevice(device), DeviceType(EIDT_OSX)
{
#ifdef _DEBUG
setDebugName("COpenGLDriver");
@ -503,15 +496,11 @@ COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
// -----------------------------------------------------------------------
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
//! Linux constructor and init code
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, CIrrDeviceLinux* device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(),
BridgeCalls(0), CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0),
ColorFormat(ECF_R8G8B8), FixedPipelineState(EOFPS_ENABLE),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
X11Device(device), DeviceType(EIDT_X11)
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceLinux* device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), BridgeCalls(0),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), ColorFormat(ECF_R8G8B8), FixedPipelineState(EOFPS_ENABLE),
Params(params), X11Device(device), DeviceType(EIDT_X11)
{
#ifdef _DEBUG
setDebugName("COpenGLDriver");
@ -593,15 +582,11 @@ bool COpenGLDriver::initDriver(CIrrDeviceLinux* device)
// -----------------------------------------------------------------------
#ifdef _IRR_COMPILE_WITH_SDL_DEVICE_
//! SDL constructor and init code
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params,
io::IFileSystem* io, CIrrDeviceSDL* device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true),
Transformation3DChanged(true), AntiAlias(params.AntiAlias),
RenderTargetTexture(0), CurrentRendertargetSize(0,0),
ColorFormat(ECF_R8G8B8), FixedPipelineState(EOFPS_ENABLE),
CurrentTarget(ERT_FRAME_BUFFER), Params(params),
BridgeCalls(0), SDLDevice(device), DeviceType(EIDT_SDL)
COpenGLDriver::COpenGLDriver(const SIrrlichtCreationParameters& params, io::IFileSystem* io, CIrrDeviceSDL* device)
: CNullDriver(io, params.WindowSize), COpenGLExtensionHandler(), BridgeCalls(0),
CurrentRenderMode(ERM_NONE), ResetRenderStates(true), Transformation3DChanged(true),
AntiAlias(params.AntiAlias), ColorFormat(ECF_R8G8B8), FixedPipelineState(EOFPS_ENABLE),
Params(params), SDLDevice(device), DeviceType(EIDT_SDL)
{
#ifdef _DEBUG
setDebugName("COpenGLDriver");
@ -623,6 +608,7 @@ COpenGLDriver::~COpenGLDriver()
CurrentTexture.clear();
// I get a blue screen on my laptop, when I do not delete the
// textures manually before releasing the dc. Oh how I love this.
removeAllRenderTargets();
deleteAllTextures();
removeAllOcclusionQueries();
removeAllHardwareBuffers();
@ -861,35 +847,6 @@ bool COpenGLDriver::endScene()
}
//! clears the zbuffer and color buffer
void COpenGLDriver::clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuffer, SColor color)
{
GLbitfield mask = 0;
if (backBuffer)
{
BridgeCalls->setColorMask(true, true, true, true);
const f32 inv = 1.0f / 255.0f;
glClearColor(color.getRed() * inv, color.getGreen() * inv,
color.getBlue() * inv, color.getAlpha() * inv);
mask |= GL_COLOR_BUFFER_BIT;
}
if (zBuffer)
{
BridgeCalls->setDepthMask(true);
mask |= GL_DEPTH_BUFFER_BIT;
}
if (stencilBuffer)
mask |= GL_STENCIL_BUFFER_BIT;
if (mask)
glClear(mask);
}
//! init call for rendering start
bool COpenGLDriver::beginScene(bool backBuffer, bool zBuffer, SColor color,
const SExposedVideoData& videoData, core::rect<s32>* sourceRect)
@ -1398,6 +1355,16 @@ u32 COpenGLDriver::getOcclusionQueryResult(scene::ISceneNode* node) const
}
//! Create render target.
IRenderTarget* COpenGLDriver::addRenderTarget()
{
COpenGLRenderTarget* renderTarget = new COpenGLRenderTarget(this);
RenderTargets.push_back(renderTarget);
return renderTarget;
}
// small helper function to create vertex buffer object adress offsets
static inline u8* buffer_offset(const long offset)
{
@ -4215,40 +4182,34 @@ IVideoDriver* COpenGLDriver::getVideoDriver()
ITexture* COpenGLDriver::addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name,
const ECOLOR_FORMAT format)
const io::path& name, const ECOLOR_FORMAT format)
{
//disable mip-mapping
bool generateMipLevels = getTextureCreationFlag(ETCF_CREATE_MIP_MAPS);
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, false);
video::ITexture* rtt = 0;
#if defined(GL_EXT_framebuffer_object)
// if driver supports FrameBufferObjects, use them
if (queryFeature(EVDF_FRAMEBUFFER_OBJECT))
{
rtt = new COpenGLFBOTexture(size, name, this, format);
addTexture(rtt);
rtt->drop();
}
else
bool supportForFBO = false;
#if defined(GL_VERSION_3_0) || defined(GL_ARB_framebuffer_object) || defined(GL_EXT_framebuffer_object)
supportForFBO = FeatureAvailable[IRR_EXT_framebuffer_object] || FeatureAvailable[IRR_ARB_framebuffer_object];
#endif
core::dimension2du destSize(size);
if (!supportForFBO)
{
// the simple texture is only possible for size <= screensize
// we try to find an optimal size with the original constraints
core::dimension2du destSize(core::min_(size.Width,ScreenSize.Width), core::min_(size.Height,ScreenSize.Height));
destSize = destSize.getOptimalSize((size==size.getOptimalSize()), false, false);
rtt = addTexture(destSize, name, ECF_A8R8G8B8);
if (rtt)
{
static_cast<video::COpenGLTexture*>(rtt)->setIsRenderTarget(true);
}
destSize = core::dimension2d<u32>(core::min_(size.Width, ScreenSize.Width), core::min_(size.Height, ScreenSize.Height));
destSize = destSize.getOptimalSize((size == size.getOptimalSize()), false, false);
}
COpenGLTexture* renderTargetTexture = new COpenGLTexture(name, size, format, this);
addTexture(renderTargetTexture);
renderTargetTexture->drop();
//restore mip-mapping
setTextureCreationFlag(ETCF_CREATE_MIP_MAPS, generateMipLevels);
return rtt;
return renderTargetTexture;
}
@ -4261,331 +4222,79 @@ u32 COpenGLDriver::getMaximalPrimitiveCount() const
}
//! set or reset render target
bool COpenGLDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil)
//! set a render target
bool COpenGLDriver::setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor)
{
// check for right driver type
if (texture && texture->getDriverType() != EDT_OPENGL)
if (target && target->getDriverType() != EDT_OPENGL)
{
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
os::Printer::log("Fatal Error: Tried to set a render target not owned by this driver.", ELL_ERROR);
return false;
}
#if defined(GL_EXT_framebuffer_object)
if (CurrentTarget==ERT_MULTI_RENDER_TEXTURES)
{
for (u32 i=0; i<MRTargets.size(); ++i)
{
if (MRTargets[i].TargetType==ERT_RENDER_TEXTURE)
{
for (++i; i<MRTargets.size(); ++i)
if (MRTargets[i].TargetType==ERT_RENDER_TEXTURE)
extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+i, GL_TEXTURE_2D, 0, 0);
}
}
MRTargets.clear();
}
bool supportForFBO = false;
#if defined(GL_VERSION_3_0) || defined(GL_ARB_framebuffer_object) || defined(GL_EXT_framebuffer_object)
supportForFBO = FeatureAvailable[IRR_EXT_framebuffer_object] || FeatureAvailable[IRR_ARB_framebuffer_object];
#endif
// check if we should set the previous RT back
if ((RenderTargetTexture != texture) ||
(CurrentTarget==ERT_MULTI_RENDER_TEXTURES))
core::dimension2d<u32> destRenderTargetSize(0, 0);
if (target)
{
BridgeCalls->setActiveTexture(GL_TEXTURE0_ARB);
ResetRenderStates=true;
if (RenderTargetTexture!=0)
COpenGLRenderTarget* renderTarget = static_cast<COpenGLRenderTarget*>(target);
if (supportForFBO)
{
RenderTargetTexture->unbindRTT();
BridgeCalls->setFBO(renderTarget->getBufferID());
renderTarget->update(activeTextureID);
}
if (texture)
{
// we want to set a new target. so do this.
BridgeCalls->setViewport(0, 0, texture->getSize().Width, texture->getSize().Height);
RenderTargetTexture = static_cast<COpenGLTexture*>(texture);
destRenderTargetSize = renderTarget->getSize();
if (RenderTargetTexture->isFrameBufferObject())
{
if (depthStencil)
{
static_cast<COpenGLFBOTexture*>(RenderTargetTexture)->setDepthTexture(depthStencil);
}
else
{
ITexture* renderBuffer = createDepthTexture(RenderTargetTexture, true);
static_cast<COpenGLFBOTexture*>(RenderTargetTexture)->setDepthTexture(renderBuffer);
renderBuffer->drop();
}
}
// calls glDrawBuffer as well
RenderTargetTexture->bindRTT();
CurrentRendertargetSize = texture->getSize();
CurrentTarget=ERT_RENDER_TEXTURE;
}
else
{
BridgeCalls->setViewport(0, 0, ScreenSize.Width, ScreenSize.Height);
RenderTargetTexture = 0;
CurrentRendertargetSize = core::dimension2d<u32>(0,0);
CurrentTarget=ERT_FRAME_BUFFER;
glDrawBuffer(Params.Doublebuffer?GL_BACK_LEFT:GL_FRONT_LEFT);
}
// we need to update the matrices due to the rendersize change.
Transformation3DChanged=true;
}
clearBuffers(clearBackBuffer, clearZBuffer, false, color);
return true;
}
//! Sets multiple render targets
bool COpenGLDriver::setRenderTarget(const core::array<video::IRenderTarget>& targets,
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil)
{
// if simply disabling the MRT via array call
if (targets.size()==0)
return setRenderTarget(0, clearBackBuffer, clearZBuffer, color, depthStencil);
// if disabling old MRT, but enabling new one as well
if ((MRTargets.size()!=0) && (targets != MRTargets))
setRenderTarget(0, clearBackBuffer, clearZBuffer, color, depthStencil);
// if no change, simply clear buffers
else if (targets == MRTargets)
{
clearBuffers(clearBackBuffer, clearZBuffer, false, color);
return true;
}
// copy to storage for correct disabling
MRTargets=targets;
u32 maxMultipleRTTs = core::min_(static_cast<u32>(MaxMultipleRenderTargets), targets.size());
// determine common size
core::dimension2du rttSize = CurrentRendertargetSize;
if (targets[0].TargetType==ERT_RENDER_TEXTURE)
{
if (!targets[0].RenderTexture)
{
os::Printer::log("Missing render texture for MRT.", ELL_ERROR);
return false;
}
rttSize=targets[0].RenderTexture->getSize();
}
for (u32 i = 0; i < maxMultipleRTTs; ++i)
{
// check for right driver type
if (targets[i].TargetType==ERT_RENDER_TEXTURE)
{
if (!targets[i].RenderTexture)
{
maxMultipleRTTs=i;
os::Printer::log("Missing render texture for MRT.", ELL_WARNING);
break;
}
if (targets[i].RenderTexture->getDriverType() != EDT_OPENGL)
{
maxMultipleRTTs=i;
os::Printer::log("Tried to set a texture not owned by this driver.", ELL_WARNING);
break;
}
// check for valid render target
if (!targets[i].RenderTexture->isRenderTarget() || !static_cast<COpenGLTexture*>(targets[i].RenderTexture)->isFrameBufferObject())
{
maxMultipleRTTs=i;
os::Printer::log("Tried to set a non FBO-RTT as render target.", ELL_WARNING);
break;
}
// check for valid size
if (rttSize != targets[i].RenderTexture->getSize())
{
maxMultipleRTTs=i;
os::Printer::log("Render target texture has wrong size.", ELL_WARNING);
break;
}
}
}
if (maxMultipleRTTs==0)
{
os::Printer::log("No valid MRTs.", ELL_ERROR);
return false;
}
// init FBO, if any
for (u32 i=0; i<maxMultipleRTTs; ++i)
{
if (targets[i].TargetType==ERT_RENDER_TEXTURE)
{
setRenderTarget(targets[i].RenderTexture, false, false, 0x0, depthStencil);
break; // bind only first RTT
}
}
// init other main buffer, if necessary
if (targets[0].TargetType!=ERT_RENDER_TEXTURE)
setRenderTarget(targets[0].TargetType, false, false, 0x0, depthStencil);
// attach other textures and store buffers into array
if (maxMultipleRTTs > 1)
{
CurrentTarget=ERT_MULTI_RENDER_TEXTURES;
core::array<GLenum> MRTs;
MRTs.set_used(maxMultipleRTTs);
for(u32 i = 0; i < maxMultipleRTTs; i++)
{
if (FeatureAvailable[IRR_EXT_draw_buffers2])
{
BridgeCalls->setColorMaskIndexed(i,
(targets[i].ColorMask & ECP_RED)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_GREEN)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_BLUE)?GL_TRUE:GL_FALSE,
(targets[i].ColorMask & ECP_ALPHA)?GL_TRUE:GL_FALSE);
if (targets[i].BlendOp==EBO_NONE)
BridgeCalls->setBlendIndexed(i, false);
else
BridgeCalls->setBlendIndexed(i, true);
}
#if defined(GL_AMD_draw_buffers_blend) || defined(GL_ARB_draw_buffers_blend)
if (FeatureAvailable[IRR_AMD_draw_buffers_blend] || FeatureAvailable[IRR_ARB_draw_buffers_blend])
{
BridgeCalls->setBlendFuncIndexed(i, getGLBlend(targets[i].BlendFuncSrc), getGLBlend(targets[i].BlendFuncDst));
switch(targets[i].BlendOp)
{
case EBO_SUBTRACT:
BridgeCalls->setBlendEquationIndexed(i, GL_FUNC_SUBTRACT);
break;
case EBO_REVSUBTRACT:
BridgeCalls->setBlendEquationIndexed(i, GL_FUNC_REVERSE_SUBTRACT);
break;
case EBO_MIN:
BridgeCalls->setBlendEquationIndexed(i, GL_MIN);
break;
case EBO_MAX:
BridgeCalls->setBlendEquationIndexed(i, GL_MAX);
break;
case EBO_MIN_FACTOR:
case EBO_MIN_ALPHA:
#if defined(GL_AMD_blend_minmax_factor)
if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
BridgeCalls->setBlendEquationIndexed(i, GL_FACTOR_MIN_AMD);
// fallback in case of missing extension
else
#endif
BridgeCalls->setBlendEquationIndexed(i, GL_MIN);
break;
case EBO_MAX_FACTOR:
case EBO_MAX_ALPHA:
#if defined(GL_AMD_blend_minmax_factor)
if (FeatureAvailable[IRR_AMD_blend_minmax_factor])
BridgeCalls->setBlendEquationIndexed(i, GL_FACTOR_MAX_AMD);
// fallback in case of missing extension
else
#endif
BridgeCalls->setBlendEquationIndexed(i, GL_MAX);
break;
default:
BridgeCalls->setBlendEquationIndexed(i, GL_FUNC_ADD);
break;
}
}
#endif
if (targets[i].TargetType==ERT_RENDER_TEXTURE)
{
GLenum attachment = GL_NONE;
#ifdef GL_EXT_framebuffer_object
// attach texture to FrameBuffer Object on Color [i]
attachment = GL_COLOR_ATTACHMENT0_EXT+i;
if ((i != 0) && (targets[i].RenderTexture != RenderTargetTexture))
extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, attachment, GL_TEXTURE_2D, static_cast<COpenGLTexture*>(targets[i].RenderTexture)->getOpenGLTextureName(), 0);
#endif
MRTs[i]=attachment;
}
else
{
switch(targets[i].TargetType)
{
case ERT_FRAME_BUFFER:
MRTs[i]=GL_BACK_LEFT;
break;
case ERT_STEREO_BOTH_BUFFERS:
MRTs[i]=GL_BACK;
break;
case ERT_STEREO_RIGHT_BUFFER:
MRTs[i]=GL_BACK_RIGHT;
break;
case ERT_STEREO_LEFT_BUFFER:
MRTs[i]=GL_BACK_LEFT;
break;
default:
MRTs[i]=GL_AUX0+(targets[i].TargetType-ERT_AUX_BUFFER0);
break;
}
}
}
extGlDrawBuffers(maxMultipleRTTs, MRTs.const_pointer());
}
clearBuffers(clearBackBuffer, clearZBuffer, false, color);
return true;
}
//! set or reset render target
bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color)
{
if (target != CurrentTarget)
setRenderTarget(0, false, false, 0x0, 0);
if (ERT_RENDER_TEXTURE == target)
{
os::Printer::log("For render textures call setRenderTarget with the actual texture as first parameter.", ELL_ERROR);
return false;
}
if (ERT_MULTI_RENDER_TEXTURES == target)
{
os::Printer::log("For multiple render textures call setRenderTarget with the texture array as first parameter.", ELL_ERROR);
return false;
}
if (Params.Stereobuffer && (ERT_STEREO_RIGHT_BUFFER == target))
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK_RIGHT);
else
glDrawBuffer(GL_FRONT_RIGHT);
}
else if (Params.Stereobuffer && ERT_STEREO_BOTH_BUFFERS == target)
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK);
else
glDrawBuffer(GL_FRONT);
}
else if ((target >= ERT_AUX_BUFFER0) && (target-ERT_AUX_BUFFER0 < MaxAuxBuffers))
{
glDrawBuffer(GL_AUX0+target-ERT_AUX_BUFFER0);
BridgeCalls->setViewport(0, 0, destRenderTargetSize.Width, destRenderTargetSize.Height);
}
else
{
if (Params.Doublebuffer)
glDrawBuffer(GL_BACK_LEFT);
if (supportForFBO)
BridgeCalls->setFBO(0);
else
glDrawBuffer(GL_FRONT_LEFT);
// exit with false, but also with working color buffer
if (target != ERT_FRAME_BUFFER)
return false;
{
COpenGLRenderTarget* prevRenderTarget = static_cast<COpenGLRenderTarget*>(CurrentRenderTarget);
COpenGLTexture* renderTargetTexture = static_cast<COpenGLTexture*>(prevRenderTarget->getTexture());
if (renderTargetTexture)
{
setActiveTexture(0, renderTargetTexture);
BridgeCalls->setTexture(0, true);
const core::dimension2d<u32> size = renderTargetTexture->getSize();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.Width, size.Height);
}
}
destRenderTargetSize = core::dimension2d<u32>(0, 0);
BridgeCalls->setViewport(0, 0, ScreenSize.Width, ScreenSize.Height);
}
CurrentTarget=target;
clearBuffers(clearTarget, clearZBuffer, false, color);
if (CurrentRenderTargetSize != destRenderTargetSize)
{
CurrentRenderTargetSize = destRenderTargetSize;
Transformation3DChanged = true;
}
CurrentRenderTarget = target;
if (!supportForFBO)
{
clearBackBuffer = true;
clearDepthBuffer = true;
}
clearBuffers(clearBackBuffer, clearDepthBuffer, clearStencilBuffer, clearColor);
return true;
}
@ -4593,10 +4302,40 @@ bool COpenGLDriver::setRenderTarget(video::E_RENDER_TARGET target, bool clearTar
// returns the current size of the screen or rendertarget
const core::dimension2d<u32>& COpenGLDriver::getCurrentRenderTargetSize() const
{
if (CurrentRendertargetSize.Width == 0)
if (CurrentRenderTargetSize.Width == 0)
return ScreenSize;
else
return CurrentRendertargetSize;
return CurrentRenderTargetSize;
}
//! Clear the color, depth and/or stencil buffers.
void COpenGLDriver::clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color)
{
GLbitfield mask = 0;
if (backBuffer)
{
BridgeCalls->setColorMask(true, true, true, true);
const f32 inv = 1.0f / 255.0f;
glClearColor(color.getRed() * inv, color.getGreen() * inv,
color.getBlue() * inv, color.getAlpha() * inv);
mask |= GL_COLOR_BUFFER_BIT;
}
if (depthBuffer)
{
BridgeCalls->setDepthMask(true);
mask |= GL_DEPTH_BUFFER_BIT;
}
if (stencilBuffer)
mask |= GL_STENCIL_BUFFER_BIT;
if (mask)
glClear(mask);
}
@ -4728,7 +4467,7 @@ IImage* COpenGLDriver::createScreenShot(video::ECOLOR_FORMAT format, video::E_RE
//! get depth texture for the given render target texture
ITexture* COpenGLDriver::createDepthTexture(ITexture* texture, bool shared)
{
if ((texture->getDriverType() != EDT_OPENGL) || (!texture->isRenderTarget()))
/*if ((texture->getDriverType() != EDT_OPENGL) || (!texture->isRenderTarget()))
return 0;
COpenGLTexture* tex = static_cast<COpenGLTexture*>(texture);
@ -4748,20 +4487,21 @@ ITexture* COpenGLDriver::createDepthTexture(ITexture* texture, bool shared)
DepthTextures.push_back(new COpenGLRenderBuffer(texture->getSize(), "depth1", this));
return DepthTextures.getLast();
}
return (new COpenGLRenderBuffer(texture->getSize(), "depth1", this));
return (new COpenGLRenderBuffer(texture->getSize(), "depth1", this));*/
return 0;
}
void COpenGLDriver::removeDepthTexture(ITexture* texture)
{
for (u32 i=0; i<DepthTextures.size(); ++i)
/*for (u32 i=0; i<DepthTextures.size(); ++i)
{
if (texture==DepthTextures[i])
{
DepthTextures.erase(i);
return;
}
}
}*/
}
@ -4916,7 +4656,7 @@ COpenGLCallBridge::COpenGLCallBridge(COpenGLDriver* driver) : Driver(driver),
AlphaMode(GL_ALWAYS), AlphaRef(0.0f), AlphaTest(false),
ClientStateVertex(false), ClientStateNormal(false), ClientStateColor(false), ClientStateTexCoord0(false),
CullFaceMode(GL_BACK), CullFace(false),
DepthFunc(GL_LESS), DepthMask(true), DepthTest(false), MatrixMode(GL_MODELVIEW),
DepthFunc(GL_LESS), DepthMask(true), DepthTest(false), FrameBufferID(0), MatrixMode(GL_MODELVIEW),
ActiveTexture(GL_TEXTURE0_ARB), ClientActiveTexture(GL_TEXTURE0_ARB), ViewportX(0), ViewportY(0)
{
FrameBufferCount = core::max_(static_cast<GLuint>(1), static_cast<GLuint>(Driver->MaxMultipleRenderTargets));
@ -5288,6 +5028,22 @@ void COpenGLCallBridge::setDepthTest(bool enable)
}
}
void COpenGLCallBridge::getFBO(GLuint& id) const
{
id = FrameBufferID;
}
void COpenGLCallBridge::setFBO(GLuint id)
{
if (FrameBufferID != id)
{
#if defined(GL_EXT_framebuffer_object)
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, id);
#endif
FrameBufferID = id;
}
}
void COpenGLCallBridge::setMatrixMode(GLenum mode)
{
if (MatrixMode != mode)

View File

@ -134,6 +134,9 @@ namespace video
actual value of pixels. */
virtual u32 getOcclusionQueryResult(scene::ISceneNode* node) const _IRR_OVERRIDE_;
//! Create render target.
virtual IRenderTarget* addRenderTarget() _IRR_OVERRIDE_;
//! draws a vertex primitive list
virtual void drawVertexPrimitiveList(const void* vertices, u32 vertexCount,
const void* indexList, u32 primitiveCount,
@ -356,17 +359,12 @@ namespace video
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;
//! sets a render target
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set a render target
virtual bool setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor) _IRR_OVERRIDE_;
//! Sets multiple render targets
virtual bool setRenderTarget(const core::array<video::IRenderTarget>& texture,
bool clearBackBuffer, bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set or reset special render targets
virtual bool setRenderTarget(video::E_RENDER_TARGET target, bool clearTarget,
bool clearZBuffer, SColor color) _IRR_OVERRIDE_;
//! Clear the color, depth and/or stencil buffers.
virtual void clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color) _IRR_OVERRIDE_;
//! Clears the ZBuffer.
virtual void clearZBuffer() _IRR_OVERRIDE_;
@ -429,9 +427,6 @@ namespace video
private:
//! clears the zbuffer and color buffer
void clearBuffers(bool backBuffer, bool zBuffer, bool stencilBuffer, SColor color);
bool updateVertexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
bool updateIndexHardwareBuffer(SHWBufferLink_opengl *HWBuffer);
@ -494,8 +489,6 @@ namespace video
u8 AntiAlias;
SMaterial Material, LastMaterial;
COpenGLTexture* RenderTargetTexture;
core::array<video::IRenderTarget> MRTargets;
class STextureStageCache
{
@ -562,7 +555,6 @@ namespace video
};
STextureStageCache CurrentTexture;
core::array<ITexture*> DepthTextures;
struct SUserClipPlane
{
SUserClipPlane() : Enabled(false) {}
@ -571,8 +563,6 @@ namespace video
};
core::array<SUserClipPlane> UserClipPlanes;
core::dimension2d<u32> CurrentRendertargetSize;
core::stringc VendorName;
core::matrix4 TextureFlipMatrix;
@ -582,9 +572,6 @@ namespace video
E_OPENGL_FIXED_PIPELINE_STATE FixedPipelineState;
//! Render target type for render operations
E_RENDER_TARGET CurrentTarget;
SIrrlichtCreationParameters Params;
//! All the lights that have been requested; a hardware limited
@ -683,6 +670,12 @@ namespace video
void setDepthTest(bool enable);
// FBO calls.
void getFBO(GLuint& id) const;
void setFBO(GLuint id);
// Matrix calls.
void setMatrixMode(GLenum mode);
@ -731,6 +724,8 @@ namespace video
bool DepthMask;
bool DepthTest;
GLuint FrameBufferID;
GLenum MatrixMode;
GLenum ActiveTexture;

View File

@ -21,7 +21,7 @@ COpenGLExtensionHandler::COpenGLExtensionHandler() :
TextureCompressionExtension(false),
MaxSupportedTextures(1), MaxTextureUnits(1), MaxLights(1),
MaxAnisotropy(1), MaxUserClipPlanes(0), MaxAuxBuffers(0),
MaxMultipleRenderTargets(1), MaxIndices(65535),
MaxMultipleRenderTargets(1), MaxColorAttachments(1), MaxIndices(65535),
MaxTextureSize(1), MaxGeometryVerticesOut(0),
MaxTextureLODBias(0.f), Version(0), ShaderLanguageVersion(0),
OcclusionQuerySupport(false)
@ -654,6 +654,13 @@ void COpenGLExtensionHandler::initExtensions(bool stencilBuffer)
glGetIntegerv(GL_MAX_DRAW_BUFFERS_ATI, &num);
MaxMultipleRenderTargets = static_cast<u8>(num);
}
#endif
#if defined(GL_EXT_framebuffer_object)
if (FeatureAvailable[IRR_EXT_framebuffer_object])
{
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &num);
MaxColorAttachments = static_cast<u8>(num);
}
#endif
glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, DimAliasedLine);
glGetFloatv(GL_ALIASED_POINT_SIZE_RANGE, DimAliasedPoint);

View File

@ -1092,6 +1092,8 @@ class COpenGLExtensionHandler
u8 MaxAuxBuffers;
//! Number of rendertargets available as MRTs
u8 MaxMultipleRenderTargets;
//! Number of color attachments available in FBO
u8 MaxColorAttachments;
//! Optimal number of indices per meshbuffer
u32 MaxIndices;
//! Maximal texture dimension

View File

@ -0,0 +1,334 @@
// Copyright (C) 2015 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#include "COpenGLRenderTarget.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "IImage.h"
#include "irrMath.h"
#include "COpenGLDriver.h"
#include "COpenGLTexture.h"
#if !defined(GL_VERSION_3_0) && !defined(GL_ARB_framebuffer_object)
#ifdef GL_EXT_framebuffer_object
#define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
#define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
#define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
#define GL_FRAMEBUFFER_UNSUPPORTED GL_FRAMEBUFFER_UNSUPPORTED_EXT
#else
#define GL_FRAMEBUFFER 0
#define GL_COLOR_ATTACHMENT0 0
#define GL_DEPTH_ATTACHMENT 0
#define GL_STENCIL_ATTACHMENT 0
#define GL_FRAMEBUFFER_COMPLETE 0
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 1
#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 2
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 3
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 4
#define GL_FRAMEBUFFER_UNSUPPORTED 5
#endif
#endif
#ifdef GL_EXT_framebuffer_object
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT
#else
#define GL_FRAMEBUFFER_INCOMPLETE_FORMATS 6
#define GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS 7
#endif
namespace irr
{
namespace video
{
bool checkFBOStatus(COpenGLDriver* Driver)
{
GLenum status = Driver->extGlCheckFramebufferStatus(GL_FRAMEBUFFER);
switch (status)
{
case GL_FRAMEBUFFER_COMPLETE:
return true;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
os::Printer::log("FBO has invalid read buffer", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
os::Printer::log("FBO has invalid draw buffer", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
os::Printer::log("FBO has one or several incomplete image attachments", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
os::Printer::log("FBO has one or several image attachments with different internal formats", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
os::Printer::log("FBO has one or several image attachments with different dimensions", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
os::Printer::log("FBO missing an image attachment", ELL_ERROR);
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
os::Printer::log("FBO format unsupported", ELL_ERROR);
break;
default:
os::Printer::log("FBO error", ELL_ERROR);
break;
}
return false;
}
COpenGLRenderTarget::COpenGLRenderTarget(COpenGLDriver* driver) : AssignedTextureCount(0), AssignedDepth(false), AssignedStencil(false),
TextureUpdate(false), DepthStencilUpdate(false), BufferID(0), SupportForFBO(false), SupportForMRT(false), BridgeCalls(0), Driver(driver)
{
#ifdef _DEBUG
setDebugName("COpenGLRenderTarget");
#endif
DriverType = EDT_OPENGL;
AssignedActiveTextureID.set_used(1);
AssignedActiveTextureID[0] = 0;
Size = Driver->getScreenSize();
BridgeCalls = Driver->getBridgeCalls();
#if defined(GL_VERSION_3_0) || defined(GL_ARB_framebuffer_object) || defined(GL_EXT_framebuffer_object)
SupportForFBO = Driver->FeatureAvailable[COpenGLDriver::IRR_EXT_framebuffer_object] || Driver->FeatureAvailable[COpenGLDriver::IRR_ARB_framebuffer_object];
#endif
SupportForMRT = SupportForFBO && Driver->MaxMultipleRenderTargets > 1 && (Driver->Version >= 200 || Driver->FeatureAvailable[COpenGLDriver::IRR_ARB_draw_buffers] ||
Driver->FeatureAvailable[COpenGLDriver::IRR_ATI_draw_buffers]);
if (SupportForFBO)
Driver->extGlGenFramebuffers(1, &BufferID);
}
COpenGLRenderTarget::~COpenGLRenderTarget()
{
if (SupportForFBO && BufferID != 0)
Driver->extGlDeleteFramebuffers(1, &BufferID);
for (u32 i = 0; i < Texture.size(); ++i)
{
if (Texture[i])
Texture[i]->drop();
}
if (DepthStencil)
DepthStencil->drop();
}
void COpenGLRenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{
TextureUpdate = TextureUpdate || Texture != texture;
if (Texture != texture)
{
for (u32 i = 0; i < Texture.size(); ++i)
{
if (Texture[i])
Texture[i]->drop();
}
Texture.set_used(core::min_(texture.size(), static_cast<u32>(Driver->MaxColorAttachments)));
for (u32 i = 0; i < Texture.size(); ++i)
{
GLuint textureID = (texture[i] && texture[i]->getDriverType() == EDT_OPENGL) ? static_cast<COpenGLTexture*>(depthStencil)->getOpenGLTextureName() : 0;
if (textureID != 0)
{
Texture[i] = texture[i];
Texture[i]->grab();
}
else
{
Texture[i] = 0;
}
}
}
DepthStencilUpdate = DepthStencilUpdate || DepthStencil != depthStencil;
if (DepthStencil != depthStencil)
{
GLuint textureID = (depthStencil && depthStencil->getDriverType() == EDT_OPENGL) ? static_cast<COpenGLTexture*>(depthStencil)->getOpenGLTextureName() : 0;
const ECOLOR_FORMAT textureFormat = (textureID != 0) ? depthStencil->getColorFormat() : ECF_UNKNOWN;
if (IImage::isDepthFormat(textureFormat))
{
DepthStencil = depthStencil;
DepthStencil->grab();
}
else
{
if (DepthStencil)
DepthStencil->drop();
DepthStencil = 0;
}
}
}
void COpenGLRenderTarget::update(const core::array<u32>& id)
{
if (TextureUpdate || DepthStencilUpdate)
{
// Set color attachments.
if (TextureUpdate)
{
const u32 textureSize = Texture.size();
const u32 stepCount = core::max_(textureSize, AssignedTextureCount);
for (u32 i = 0; i < stepCount; ++i)
{
GLuint textureID = 0;
if (i < textureSize && Texture[i])
textureID = static_cast<COpenGLTexture*>(Texture[i])->getOpenGLTextureName();
if (textureID != 0)
{
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, textureID, 0);
}
else if (i < AssignedTextureCount)
{
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0);
}
}
AssignedTextureCount = textureSize;
TextureUpdate = false;
}
// Set depth and stencil attachments.
if (DepthStencilUpdate)
{
const ECOLOR_FORMAT textureFormat = (DepthStencil) ? DepthStencil->getColorFormat() : ECF_UNKNOWN;
if (IImage::isDepthFormat(textureFormat))
{
GLuint textureID = static_cast<COpenGLTexture*>(DepthStencil)->getOpenGLTextureName();
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, textureID, 0);
if (textureFormat == ECF_D24S8)
{
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, textureID, 0);
AssignedStencil = true;
}
else
{
if (AssignedStencil)
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
AssignedStencil = false;
}
AssignedDepth = true;
}
else
{
if (AssignedDepth)
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
if (AssignedStencil)
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
AssignedDepth = false;
AssignedStencil = false;
}
DepthStencilUpdate = false;
}
// Set size required for a viewport.
ITexture* firstTexture = getTexture();
if (firstTexture)
Size = firstTexture->getSize();
else
{
if (DepthStencil)
Size = DepthStencil->getSize();
else
Size = Driver->getScreenSize();
}
#ifdef _DEBUG
checkFBOStatus(Driver);
#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[i + id[i]] = GL_COLOR_ATTACHMENT0 + id[i];
Driver->extGlDrawBuffers(mrtSize, target);
delete[] target;
}
AssignedActiveTextureID = id;
}
}
GLuint COpenGLRenderTarget::getBufferID() const
{
return BufferID;
}
const core::dimension2d<u32>& COpenGLRenderTarget::getSize() const
{
return Size;
}
ITexture* COpenGLRenderTarget::getTexture() const
{
for (u32 i = 0; i < Texture.size(); ++i)
{
if (Texture[i])
return Texture[i];
}
return 0;
}
}
}
#endif

View File

@ -0,0 +1,66 @@
// Copyright (C) 2015 Patryk Nadrowski
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
#ifndef __C_OPEN_GL_RENDER_TARGET_H_INCLUDED__
#define __C_OPEN_GL_RENDER_TARGET_H_INCLUDED__
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_OPENGL_
#include "IRenderTarget.h"
#include "dimension2d.h"
#include "COpenGLExtensionHandler.h"
namespace irr
{
namespace video
{
class COpenGLDriver;
class COpenGLCallBridge;
class COpenGLRenderTarget : public IRenderTarget
{
public:
COpenGLRenderTarget(COpenGLDriver* driver);
virtual ~COpenGLRenderTarget();
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) _IRR_OVERRIDE_;
void update(const core::array<u32>& id);
GLuint getBufferID() const;
const core::dimension2d<u32>& getSize() const;
ITexture* getTexture() const;
protected:
core::array<u32> AssignedActiveTextureID;
u32 AssignedTextureCount;
bool AssignedDepth;
bool AssignedStencil;
bool TextureUpdate;
bool DepthStencilUpdate;
GLuint BufferID;
core::dimension2d<u32> Size;
bool SupportForFBO;
bool SupportForMRT;
COpenGLCallBridge* BridgeCalls;
COpenGLDriver* Driver;
};
}
}
#endif
#endif

View File

@ -19,17 +19,15 @@ namespace irr
namespace video
{
//! constructor for usual textures
//! constructor for a standard textures
COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, void* mipmapData, COpenGLDriver* driver)
: ITexture(name), Driver(driver), Image(0), MipImage(0),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(true),
IsCompressed(false), AutomaticMipmapUpdate(false),
ReadOnlyLock(false), KeepImage(true), IsDepthTexture(false), IsRenderBuffer(false)
: ITexture(name), Driver(driver), Image(0), MipImage(0), TextureName(0), InternalFormat(GL_RGBA),
PixelFormat(GL_BGRA_EXT), PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(true),
IsCompressed(false), AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(true)
{
#ifdef _DEBUG
#ifdef _DEBUG
setDebugName("COpenGLTexture");
#endif
#endif
DriverType = EDT_OPENGL;
ColorFormat = ECF_A8R8G8B8;
@ -100,23 +98,64 @@ COpenGLTexture::COpenGLTexture(IImage* origImage, const io::path& name, void* mi
}
//! constructor for basic setup (only for derived classes)
COpenGLTexture::COpenGLTexture(const io::path& name, COpenGLDriver* driver)
: ITexture(name), Driver(driver), Image(0), MipImage(0),
TextureName(0), InternalFormat(GL_RGBA), PixelFormat(GL_BGRA_EXT),
PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0),
MipmapLegacyMode(true), IsCompressed(false),
AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(true),
IsDepthTexture(false), IsRenderBuffer(false)
//! constructor for a render target textures
COpenGLTexture::COpenGLTexture(const io::path& name, const core::dimension2d<u32>& size, ECOLOR_FORMAT format, COpenGLDriver* driver)
: ITexture(name), Driver(driver), Image(0), MipImage(0), TextureName(0), InternalFormat(GL_RGBA),
PixelFormat(GL_BGRA_EXT), PixelType(GL_UNSIGNED_BYTE), MipLevelStored(0), MipmapLegacyMode(false),
IsCompressed(false), AutomaticMipmapUpdate(false), ReadOnlyLock(false), KeepImage(false)
{
#ifdef _DEBUG
#ifdef _DEBUG
setDebugName("COpenGLTexture");
#endif
#endif
DriverType = EDT_OPENGL;
ColorFormat = ECF_A8R8G8B8;
HasMipMaps = true;
HasAlpha = true;
if (ECF_UNKNOWN == format)
format = getBestColorFormat(driver->getColorFormat());
OriginalSize = size;
Size = size;
ColorFormat = format;
switch (ColorFormat)
{
case ECF_A8R8G8B8:
case ECF_A1R5G5B5:
case ECF_A16B16G16R16F:
case ECF_A32B32G32R32F:
HasAlpha = true;
break;
default:
break;
}
GLint FilteringType = 0;
InternalFormat = getOpenGLFormatAndParametersFromColorFormat(format, FilteringType, PixelFormat, PixelType);
HasMipMaps = false;
IsRenderTarget = true;
glGenTextures(1, &TextureName);
Driver->setActiveTexture(0, this);
Driver->getBridgeCalls()->setTexture(0, true);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilteringType);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (FilteringType == GL_NEAREST)
StatesCache.BilinearFilter = false;
else
StatesCache.BilinearFilter = true;
StatesCache.WrapU = ETC_CLAMP_TO_EDGE;
StatesCache.WrapV = ETC_CLAMP_TO_EDGE;
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, OriginalSize.Width, OriginalSize.Height, 0, PixelFormat, PixelType, 0);
Driver->setActiveTexture(0, 0);
Driver->getBridgeCalls()->setTexture(0, true);
}
@ -800,47 +839,6 @@ void COpenGLTexture::regenerateMipMapLevels(void* mipmapData)
}
void COpenGLTexture::setIsRenderTarget(bool isTarget)
{
IsRenderTarget = isTarget;
}
bool COpenGLTexture::isFrameBufferObject() const
{
return false;
}
bool COpenGLTexture::isDepthTexture() const
{
return IsDepthTexture;
}
bool COpenGLTexture::isRenderBuffer() const
{
return IsRenderBuffer;
}
//! Bind Render Target Texture
void COpenGLTexture::bindRTT()
{
}
//! Unbind Render Target Texture
void COpenGLTexture::unbindRTT()
{
Driver->setActiveTexture(0, this);
Driver->getBridgeCalls()->setTexture(0, true);
// Copy Our ViewPort To The Texture
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, getSize().Width, getSize().Height);
}
//! Get an access to texture states cache.
COpenGLTexture::SStatesCache& COpenGLTexture::getStatesCache() const
{
@ -853,329 +851,9 @@ COpenGLTexture::SStatesCache& COpenGLTexture::getStatesCache() const
// helper function for render to texture
static bool checkFBOStatus(COpenGLDriver* Driver);
//! RTT FBO constructor
COpenGLFBOTexture::COpenGLFBOTexture(const core::dimension2d<u32>& size,
const io::path& name, COpenGLDriver* driver,
ECOLOR_FORMAT format)
: COpenGLTexture(name, driver), BufferID(0), DepthTexture(0)
{
#ifdef _DEBUG
setDebugName("COpenGLFBOTexture");
#endif
DriverType = EDT_OPENGL;
if (ECF_UNKNOWN == format)
format = getBestColorFormat(driver->getColorFormat());
IsDepthTexture = IImage::isDepthFormat(format);
OriginalSize = size;
Size = size;
ColorFormat = format;
switch (ColorFormat)
{
case ECF_A8R8G8B8:
case ECF_A1R5G5B5:
case ECF_A16B16G16R16F:
case ECF_A32B32G32R32F:
HasAlpha = true;
break;
default:
break;
}
GLint FilteringType = 0;
InternalFormat = getOpenGLFormatAndParametersFromColorFormat(format, FilteringType, PixelFormat, PixelType);
HasMipMaps = false;
IsRenderTarget = true;
// generate color texture
glGenTextures(1, &TextureName);
Driver->setActiveTexture(0, this);
Driver->getBridgeCalls()->setTexture(0, true);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, FilteringType);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
if (FilteringType == GL_NEAREST)
StatesCache.BilinearFilter = false;
else
StatesCache.BilinearFilter = true;
StatesCache.WrapU = ETC_CLAMP_TO_EDGE;
StatesCache.WrapV = ETC_CLAMP_TO_EDGE;
glTexImage2D(GL_TEXTURE_2D, 0, InternalFormat, OriginalSize.Width, OriginalSize.Height, 0, PixelFormat, PixelType, 0);
Driver->setActiveTexture(0, 0);
Driver->getBridgeCalls()->setTexture(0, true);
#ifdef GL_EXT_framebuffer_object
// generate FBO
Driver->extGlGenFramebuffers(1, &BufferID);
if (BufferID != 0 && !IsDepthTexture)
{
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, BufferID);
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, TextureName, 0);
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
}
#endif
}
//! destructor
COpenGLFBOTexture::~COpenGLFBOTexture()
{
if (DepthTexture)
{
bool remove = DepthTexture->isRenderBuffer();
if (DepthTexture->drop() && remove)
Driver->removeDepthTexture(DepthTexture);
}
#ifdef GL_EXT_framebuffer_object
if (BufferID)
Driver->extGlDeleteFramebuffers(1, &BufferID);
#endif
}
bool COpenGLFBOTexture::isFrameBufferObject() const
{
return true;
}
//! Bind Render Target Texture
void COpenGLFBOTexture::bindRTT()
{
#ifdef GL_EXT_framebuffer_object
if (BufferID != 0)
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, BufferID);
glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
#endif
}
//! Unbind Render Target Texture
void COpenGLFBOTexture::unbindRTT()
{
#ifdef GL_EXT_framebuffer_object
if (BufferID != 0)
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
#endif
}
//! Get depth texture.
ITexture* COpenGLFBOTexture::getDepthTexture() const
{
return DepthTexture;
}
//! Set depth texture.
bool COpenGLFBOTexture::setDepthTexture(ITexture* depthTexture)
{
if (DepthTexture == depthTexture || BufferID == 0)
return false;
#ifdef GL_EXT_framebuffer_object
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, BufferID);
if (DepthTexture)
{
if (DepthTexture->isRenderBuffer())
{
Driver->extGlFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
}
else
{
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
if (DepthTexture->getColorFormat() == ECF_D24S8)
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, 0, 0);
}
if (DepthTexture->drop())
Driver->removeDepthTexture(DepthTexture);
}
COpenGLTexture* tex = static_cast<COpenGLTexture*>(depthTexture);
DepthTexture = (tex && tex->isDepthTexture()) ? tex : 0;
if (DepthTexture)
{
DepthTexture->grab();
if (DepthTexture->isRenderBuffer())
{
COpenGLRenderBuffer* renderBuffer = static_cast<COpenGLRenderBuffer*>(DepthTexture);
Driver->extGlFramebufferRenderbuffer(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, renderBuffer->getBufferID());
}
else
{
COpenGLFBOTexture* fboDepthTexture = static_cast<COpenGLFBOTexture*>(DepthTexture);
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, fboDepthTexture->getOpenGLTextureName(), 0);
if (DepthTexture->getColorFormat() == ECF_D24S8)
Driver->extGlFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, fboDepthTexture->getOpenGLTextureName(), 0);
}
}
Driver->extGlBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
#endif
if (!checkFBOStatus(Driver))
{
os::Printer::log("FBO incomplete");
return false;
}
return true;
}
/* Render Buffer */
//! constructor
COpenGLRenderBuffer::COpenGLRenderBuffer(
const core::dimension2d<u32>& size,
const io::path& name,
COpenGLDriver* driver,
bool useStencil)
: COpenGLTexture(name, driver), BufferID(0)
{
#ifdef _DEBUG
setDebugName("COpenGLRenderBuffer");
#endif
DriverType = EDT_OPENGL;
IsDepthTexture = true;
IsRenderBuffer = true;
OriginalSize = size;
Size = size;
InternalFormat = GL_RGBA;
PixelFormat = GL_RGBA;
PixelType = GL_UNSIGNED_BYTE;
HasMipMaps = false;
#ifdef GL_EXT_framebuffer_object
// generate depth buffer
Driver->extGlGenRenderbuffers(1, &BufferID);
Driver->extGlBindRenderbuffer(GL_RENDERBUFFER_EXT, BufferID);
Driver->extGlRenderbufferStorage(GL_RENDERBUFFER_EXT, Driver->getZBufferBits(), OriginalSize.Width, OriginalSize.Height);
Driver->extGlBindRenderbuffer(GL_RENDERBUFFER_EXT, 0);
#endif
}
//! destructor
COpenGLRenderBuffer::~COpenGLRenderBuffer()
{
#ifdef GL_EXT_framebuffer_object
if (BufferID)
Driver->extGlDeleteRenderbuffers(1, &BufferID);
#endif
}
//! Bind Render Target Texture
void COpenGLRenderBuffer::bindRTT()
{
}
//! Unbind Render Target Texture
void COpenGLRenderBuffer::unbindRTT()
{
}
GLuint COpenGLRenderBuffer::getBufferID() const
{
return BufferID;
}
bool checkFBOStatus(COpenGLDriver* Driver)
{
#ifdef GL_EXT_framebuffer_object
GLenum status = Driver->extGlCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
switch (status)
{
//Our FBO is perfect, return true
case GL_FRAMEBUFFER_COMPLETE_EXT:
return true;
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
os::Printer::log("FBO has invalid read buffer", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
os::Printer::log("FBO has invalid draw buffer", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
os::Printer::log("FBO has one or several incomplete image attachments", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
os::Printer::log("FBO has one or several image attachments with different internal formats", ELL_ERROR);
break;
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
os::Printer::log("FBO has one or several image attachments with different dimensions", ELL_ERROR);
break;
// not part of fbo_object anymore, but won't harm as it is just a return value
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT
case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
os::Printer::log("FBO has a duplicate image attachment", ELL_ERROR);
break;
#endif
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
os::Printer::log("FBO missing an image attachment", ELL_ERROR);
break;
#ifdef GL_EXT_framebuffer_multisample
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
os::Printer::log("FBO wrong multisample setup", ELL_ERROR);
break;
#endif
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
os::Printer::log("FBO format unsupported", ELL_ERROR);
break;
default:
break;
}
#endif
os::Printer::log("FBO error", ELL_ERROR);
// _IRR_DEBUG_BREAK_IF(true);
return false;
}
} // end namespace video

View File

@ -72,8 +72,11 @@ public:
bool IsCached;
};
//! constructor
COpenGLTexture(IImage* surface, const io::path& name, void* mipmapData=0, COpenGLDriver* driver=0);
//! constructor for a standard textures
COpenGLTexture(IImage* surface, const io::path& name, void* mipmapData, COpenGLDriver* driver);
//! constructor for a render target textures
COpenGLTexture(const io::path& name, const core::dimension2d<u32>& size, ECOLOR_FORMAT format, COpenGLDriver* driver);
//! destructor
virtual ~COpenGLTexture();
@ -92,24 +95,6 @@ public:
//! return open gl texture name
GLuint getOpenGLTextureName() const;
//! Is it a FrameBufferObject?
virtual bool isFrameBufferObject() const;
//! Is it a depth texture?
bool isDepthTexture() const;
//! Is it a renderbuffer?
bool isRenderBuffer() const;
//! Bind RenderTargetTexture
virtual void bindRTT();
//! Unbind RenderTargetTexture
virtual void unbindRTT();
//! sets whether this texture is intended to be used as a render target.
void setIsRenderTarget(bool isTarget);
//! Get an access to texture states cache.
SStatesCache& getStatesCache() const;
@ -150,68 +135,9 @@ protected:
bool ReadOnlyLock;
bool KeepImage;
bool IsDepthTexture;
bool IsRenderBuffer;
mutable SStatesCache StatesCache;
};
//! OpenGL FBO texture.
class COpenGLFBOTexture : public COpenGLTexture
{
public:
//! FrameBufferObject constructor
COpenGLFBOTexture(const core::dimension2d<u32>& size, const io::path& name,
COpenGLDriver* driver = 0, ECOLOR_FORMAT format = ECF_UNKNOWN);
//! destructor
virtual ~COpenGLFBOTexture();
//! Is it a FrameBufferObject?
virtual bool isFrameBufferObject() const _IRR_OVERRIDE_;
//! Bind RenderTargetTexture
virtual void bindRTT() _IRR_OVERRIDE_;
//! Unbind RenderTargetTexture
virtual void unbindRTT() _IRR_OVERRIDE_;
//! Return depth texture.
ITexture* getDepthTexture() const;
//! Set depth texture.
bool setDepthTexture(ITexture* depthTexture);
protected:
GLuint BufferID;
COpenGLTexture* DepthTexture;
};
//! OpenGL Render Buffer.
class COpenGLRenderBuffer : public COpenGLTexture
{
public:
//! FrameBufferObject depth constructor
COpenGLRenderBuffer(const core::dimension2d<u32>& size, const io::path& name, COpenGLDriver* driver=0, bool useStencil=false);
//! destructor
virtual ~COpenGLRenderBuffer();
//! Bind RenderTargetTexture
virtual void bindRTT() _IRR_OVERRIDE_;
//! Unbind RenderTargetTexture
virtual void unbindRTT() _IRR_OVERRIDE_;
GLuint getBufferID() const;
protected:
GLuint BufferID;
};
} // end namespace video
} // end namespace irr

View File

@ -174,6 +174,16 @@ bool CSoftwareDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
}
//! Create render target.
IRenderTarget* CSoftwareDriver::addRenderTarget()
{
CSoftwareRenderTarget* renderTarget = new CSoftwareRenderTarget(this);
RenderTargets.push_back(renderTarget);
return renderTarget;
}
//! sets transformation
void CSoftwareDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
{
@ -226,11 +236,7 @@ bool CSoftwareDriver::beginScene(bool backBuffer, bool zBuffer, SColor color,
WindowId=videoData.D3D9.HWnd;
SceneSourceRect = sourceRect;
if (backBuffer && BackBuffer)
BackBuffer->fill(color);
if (ZBuffer && zBuffer)
ZBuffer->clear();
clearBuffers(backBuffer, zBuffer, false, color);
return true;
}
@ -253,20 +259,21 @@ ITexture* CSoftwareDriver::createDeviceDependentTexture(IImage* surface, const i
}
//! sets a render target
bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil)
//! set a render target
bool CSoftwareDriver::setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor)
{
if (texture && texture->getDriverType() != EDT_SOFTWARE)
if (target && target->getDriverType() != EDT_SOFTWARE)
{
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
os::Printer::log("Fatal Error: Tried to set a render target not owned by this driver.", ELL_ERROR);
return false;
}
if (RenderTargetTexture)
RenderTargetTexture->drop();
RenderTargetTexture = texture;
CSoftwareRenderTarget* renderTarget = static_cast<CSoftwareRenderTarget*>(target);
RenderTargetTexture = (renderTarget) ? renderTarget->getTexture() : 0;
if (RenderTargetTexture)
{
@ -278,14 +285,7 @@ bool CSoftwareDriver::setRenderTarget(video::ITexture* texture, bool clearBackBu
setRenderTarget(BackBuffer);
}
if (RenderTargetSurface && (clearBackBuffer || clearZBuffer))
{
if (clearZBuffer)
ZBuffer->clear();
if (clearBackBuffer)
RenderTargetSurface->fill(color);
}
clearBuffers(clearBackBuffer, clearDepthBuffer, clearStencilBuffer, clearColor);
return true;
}
@ -913,6 +913,17 @@ ITexture* CSoftwareDriver::addRenderTargetTexture(const core::dimension2d<u32>&
}
//! Clear the color, depth and/or stencil buffers.
void CSoftwareDriver::clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color)
{
if (backBuffer && RenderTargetSurface)
RenderTargetSurface->fill(color);
if (depthBuffer && ZBuffer)
ZBuffer->clear();
}
//! Clears the ZBuffer.
void CSoftwareDriver::clearZBuffer()
{

View File

@ -27,14 +27,18 @@ namespace video
//! queries the features of the driver, returns true if feature is available
virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const _IRR_OVERRIDE_;
//! Create render target.
virtual IRenderTarget* addRenderTarget() _IRR_OVERRIDE_;
//! sets transformation
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) _IRR_OVERRIDE_;
//! sets a material
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set a render target
virtual bool setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor) _IRR_OVERRIDE_;
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
@ -107,6 +111,9 @@ namespace video
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;
//! Clear the color, depth and/or stencil buffers.
virtual void clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color) _IRR_OVERRIDE_;
//! Clears the ZBuffer.
virtual void clearZBuffer() _IRR_OVERRIDE_;

View File

@ -335,6 +335,17 @@ bool CBurningVideoDriver::queryFeature(E_VIDEO_DRIVER_FEATURE feature) const
//! Create render target.
IRenderTarget* CBurningVideoDriver::addRenderTarget()
{
CSoftwareRenderTarget2* renderTarget = new CSoftwareRenderTarget2(this);
RenderTargets.push_back(renderTarget);
return renderTarget;
}
//! sets transformation
void CBurningVideoDriver::setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat)
{
@ -390,11 +401,7 @@ bool CBurningVideoDriver::beginScene(bool backBuffer, bool zBuffer,
WindowId = videoData.D3D9.HWnd;
SceneSourceRect = sourceRect;
if (backBuffer && BackBuffer)
BackBuffer->fill(color);
if (zBuffer && DepthBuffer)
DepthBuffer->clear();
clearBuffers(backBuffer, zBuffer, false, color);
memset ( TransformationFlag, 0, sizeof ( TransformationFlag ) );
return true;
@ -410,20 +417,21 @@ bool CBurningVideoDriver::endScene()
}
//! sets a render target
bool CBurningVideoDriver::setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil)
//! set a render target
bool CBurningVideoDriver::setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor)
{
if (texture && texture->getDriverType() != EDT_BURNINGSVIDEO)
if (target && target->getDriverType() != EDT_BURNINGSVIDEO)
{
os::Printer::log("Fatal Error: Tried to set a texture not owned by this driver.", ELL_ERROR);
os::Printer::log("Fatal Error: Tried to set a render target not owned by this driver.", ELL_ERROR);
return false;
}
if (RenderTargetTexture)
RenderTargetTexture->drop();
RenderTargetTexture = texture;
CSoftwareRenderTarget2* renderTarget = static_cast<CSoftwareRenderTarget2*>(target);
RenderTargetTexture = (renderTarget) ? renderTarget->getTexture() : 0;
if (RenderTargetTexture)
{
@ -435,14 +443,7 @@ bool CBurningVideoDriver::setRenderTarget(video::ITexture* texture, bool clearBa
setRenderTarget(BackBuffer);
}
if (RenderTargetSurface && (clearBackBuffer || clearZBuffer))
{
if (clearZBuffer)
DepthBuffer->clear();
if (clearBackBuffer)
RenderTargetSurface->fill( color );
}
clearBuffers(clearBackBuffer, clearDepthBuffer, clearStencilBuffer, clearColor);
return true;
}
@ -2237,6 +2238,20 @@ ITexture* CBurningVideoDriver::addRenderTargetTexture(const core::dimension2d<u3
}
//! Clear the color, depth and/or stencil buffers.
void CBurningVideoDriver::clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color)
{
if (backBuffer && RenderTargetSurface)
RenderTargetSurface->fill(color);
if (depthBuffer && DepthBuffer)
DepthBuffer->clear();
if (stencilBuffer && StencilBuffer)
StencilBuffer->clear();
}
//! Clears the DepthBuffer.
void CBurningVideoDriver::clearZBuffer()
{

View File

@ -30,14 +30,18 @@ namespace video
//! queries the features of the driver, returns true if feature is available
virtual bool queryFeature(E_VIDEO_DRIVER_FEATURE feature) const _IRR_OVERRIDE_;
//! Create render target.
virtual IRenderTarget* addRenderTarget() _IRR_OVERRIDE_;
//! sets transformation
virtual void setTransform(E_TRANSFORMATION_STATE state, const core::matrix4& mat) _IRR_OVERRIDE_;
//! sets a material
virtual void setMaterial(const SMaterial& material) _IRR_OVERRIDE_;
virtual bool setRenderTarget(video::ITexture* texture, bool clearBackBuffer,
bool clearZBuffer, SColor color, video::ITexture* depthStencil) _IRR_OVERRIDE_;
//! set a render target
virtual bool setRenderTarget(IRenderTarget* target, core::array<u32> activeTextureID, bool clearBackBuffer,
bool clearDepthBuffer, bool clearStencilBuffer, SColor clearColor) _IRR_OVERRIDE_;
//! sets a viewport
virtual void setViewPort(const core::rect<s32>& area) _IRR_OVERRIDE_;
@ -132,6 +136,9 @@ namespace video
virtual ITexture* addRenderTargetTexture(const core::dimension2d<u32>& size,
const io::path& name, const ECOLOR_FORMAT format = ECF_UNKNOWN) _IRR_OVERRIDE_;
//! Clear the color, depth and/or stencil buffers.
virtual void clearBuffers(bool backBuffer, bool depthBuffer, bool stencilBuffer, SColor color) _IRR_OVERRIDE_;
//! Clears the DepthBuffer.
virtual void clearZBuffer() _IRR_OVERRIDE_;

View File

@ -6,6 +6,7 @@
#ifdef _IRR_COMPILE_WITH_SOFTWARE_
#include "CSoftwareTexture.h"
#include "CSoftwareDriver.h"
#include "os.h"
namespace irr
@ -119,6 +120,54 @@ void CSoftwareTexture::regenerateMipMapLevels(void* mipmapData)
}
/* Software Render Target */
CSoftwareRenderTarget::CSoftwareRenderTarget(CSoftwareDriver* driver) : Driver(driver)
{
DriverType = EDT_SOFTWARE;
Texture.set_used(1);
Texture[0] = 0;
}
CSoftwareRenderTarget::~CSoftwareRenderTarget()
{
if (Texture[0])
Texture[0]->drop();
}
void CSoftwareRenderTarget::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{
if (Texture != texture)
{
if (Texture[0])
Texture[0]->drop();
bool textureDetected = false;
for (u32 i = 0; i < texture.size(); ++i)
{
if (texture[i] && texture[i]->getDriverType() == EDT_SOFTWARE)
{
Texture[0] = texture[i];
Texture[0]->grab();
textureDetected = true;
break;
}
}
if (!textureDetected)
Texture[0] = 0;
}
}
ITexture* CSoftwareRenderTarget::getTexture() const
{
return Texture[0];
}
} // end namespace video
} // end namespace irr

View File

@ -6,6 +6,7 @@
#define __C_SOFTWARE_TEXTURE_H_INCLUDED__
#include "ITexture.h"
#include "IRenderTarget.h"
#include "CImage.h"
namespace irr
@ -13,6 +14,8 @@ namespace irr
namespace video
{
class CSoftwareDriver;
/*!
interface for a Video Driver dependent Texture.
*/
@ -48,6 +51,23 @@ private:
CImage* Texture;
};
/*!
interface for a Video Driver dependent render target.
*/
class CSoftwareRenderTarget : public IRenderTarget
{
public:
CSoftwareRenderTarget(CSoftwareDriver* driver);
virtual ~CSoftwareRenderTarget();
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) _IRR_OVERRIDE_;
ITexture* getTexture() const;
protected:
CSoftwareDriver* Driver;
};
} // end namespace video
} // end namespace irr

View File

@ -8,6 +8,7 @@
#include "SoftwareDriver2_compile_config.h"
#include "SoftwareDriver2_helper.h"
#include "CSoftwareTexture2.h"
#include "CSoftwareDriver2.h"
#include "os.h"
namespace irr
@ -172,6 +173,54 @@ void CSoftwareTexture2::regenerateMipMapLevels(void* mipmapData)
}
/* Software Render Target 2 */
CSoftwareRenderTarget2::CSoftwareRenderTarget2(CBurningVideoDriver* driver) : Driver(driver)
{
DriverType = EDT_BURNINGSVIDEO;
Texture.set_used(1);
Texture[0] = 0;
}
CSoftwareRenderTarget2::~CSoftwareRenderTarget2()
{
if (Texture[0])
Texture[0]->drop();
}
void CSoftwareRenderTarget2::setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil)
{
if (Texture != texture)
{
if (Texture[0])
Texture[0]->drop();
bool textureDetected = false;
for (u32 i = 0; i < texture.size(); ++i)
{
if (texture[i] && texture[i]->getDriverType() == EDT_BURNINGSVIDEO)
{
Texture[0] = texture[i];
Texture[0]->grab();
textureDetected = true;
break;
}
}
if (!textureDetected)
Texture[0] = 0;
}
}
ITexture* CSoftwareRenderTarget2::getTexture() const
{
return Texture[0];
}
} // end namespace video
} // end namespace irr

View File

@ -8,6 +8,7 @@
#include "SoftwareDriver2_compile_config.h"
#include "ITexture.h"
#include "IRenderTarget.h"
#include "CImage.h"
namespace irr
@ -15,6 +16,8 @@ namespace irr
namespace video
{
class CBurningVideoDriver;
/*!
interface for a Video Driver dependent Texture.
*/
@ -87,6 +90,23 @@ private:
ECOLOR_FORMAT OriginalFormat;
};
/*!
interface for a Video Driver dependent render target.
*/
class CSoftwareRenderTarget2 : public IRenderTarget
{
public:
CSoftwareRenderTarget2(CBurningVideoDriver* driver);
virtual ~CSoftwareRenderTarget2();
virtual void setTexture(const core::array<ITexture*>& texture, ITexture* depthStencil) _IRR_OVERRIDE_;
ITexture* getTexture() const;
protected:
CBurningVideoDriver* Driver;
};
} // end namespace video
} // end namespace irr

View File

@ -519,6 +519,7 @@
<Unit filename="..\..\include\IQ3Shader.h" />
<Unit filename="..\..\include\IReadFile.h" />
<Unit filename="..\..\include\IReferenceCounted.h" />
<Unit filename="..\..\include\IRenderTarget.h" />
<Unit filename="..\..\include\ISceneCollisionManager.h" />
<Unit filename="..\..\include\ISceneLoader.h" />
<Unit filename="..\..\include\ISceneManager.h" />
@ -642,6 +643,8 @@
<Unit filename="CD3D9NormalMapRenderer.h" />
<Unit filename="CD3D9ParallaxMapRenderer.cpp" />
<Unit filename="CD3D9ParallaxMapRenderer.h" />
<Unit filename="CD3D9RenderTarget.cpp" />
<Unit filename="CD3D9RenderTarget.h" />
<Unit filename="CD3D9ShaderMaterialRenderer.cpp" />
<Unit filename="CD3D9ShaderMaterialRenderer.h" />
<Unit filename="CD3D9Texture.cpp" />
@ -834,6 +837,8 @@
<Unit filename="COpenGLNormalMapRenderer.h" />
<Unit filename="COpenGLParallaxMapRenderer.cpp" />
<Unit filename="COpenGLParallaxMapRenderer.h" />
<Unit filename="COpenGLRenderTarget.cpp" />
<Unit filename="COpenGLRenderTarget.h" />
<Unit filename="COpenGLSLMaterialRenderer.cpp" />
<Unit filename="COpenGLSLMaterialRenderer.h" />
<Unit filename="COpenGLShaderMaterialRenderer.cpp" />

View File

@ -840,6 +840,7 @@
<ClInclude Include="..\..\include\IProfiler.h" />
<ClInclude Include="..\..\include\IRandomizer.h" />
<ClInclude Include="..\..\include\IReferenceCounted.h" />
<ClInclude Include="..\..\include\IRenderTarget.h" />
<ClInclude Include="..\..\include\IrrCompileConfig.h" />
<ClInclude Include="..\..\include\irrlicht.h" />
<ClInclude Include="..\..\include\IrrlichtDevice.h" />
@ -993,11 +994,13 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
<ClInclude Include="CDefaultSceneNodeFactory.h" />
<ClInclude Include="CGeometryCreator.h" />
<ClInclude Include="CMeshCache.h" />
<ClInclude Include="CMeshManipulator.h" />
<ClInclude Include="COpenGLRenderTarget.h" />
<ClInclude Include="CProfiler.h" />
<ClInclude Include="CSceneManager.h" />
<ClInclude Include="Octree.h" />
@ -1237,11 +1240,13 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
<ClCompile Include="CDefaultSceneNodeFactory.cpp" />
<ClCompile Include="CGeometryCreator.cpp" />
<ClCompile Include="CMeshCache.cpp" />
<ClCompile Include="CMeshManipulator.cpp" />
<ClCompile Include="COpenGLRenderTarget.cpp" />
<ClCompile Include="CSceneManager.cpp" />
<ClCompile Include="C3DSMeshFileLoader.cpp" />
<ClCompile Include="CSMFMeshFileLoader.cpp" />
@ -1400,7 +1405,7 @@
<ClCompile Include="Irrlicht.cpp" />
<ClCompile Include="leakHunter.cpp" />
<ClCompile Include="os.cpp" />
<ClCompile Include="utf8.cpp" />
<ClCompile Include="utf8.cpp" />
<ClCompile Include="CProfiler.cpp" />
<ClCompile Include="lzma\LzmaDec.c" />
<ClCompile Include="zlib\adler32.c" />

View File

@ -1300,6 +1300,15 @@
<ClInclude Include="CProfiler.h">
<Filter>Irrlicht\irr</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IRenderTarget.h">
<Filter>include\video</Filter>
</ClInclude>
<ClInclude Include="CD3D9RenderTarget.h">
<Filter>Irrlicht\video\Direct3D9</Filter>
</ClInclude>
<ClInclude Include="COpenGLRenderTarget.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -2222,6 +2231,12 @@
<ClCompile Include="leakHunter.cpp">
<Filter>Irrlicht\irr</Filter>
</ClCompile>
<ClCompile Include="CD3D9RenderTarget.cpp">
<Filter>Irrlicht\video\Direct3D9</Filter>
</ClCompile>
<ClCompile Include="COpenGLRenderTarget.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -842,14 +842,15 @@
<ClInclude Include="..\..\include\EMaterialFlags.h" />
<ClInclude Include="..\..\include\IAnimatedMeshMD3.h" />
<ClInclude Include="..\..\include\IEventReceiver.h" />
<ClInclude Include="..\..\include\IProfiler.h" />
<ClInclude Include="..\..\include\IProfiler.h" />
<ClInclude Include="..\..\include\ILogger.h" />
<ClInclude Include="..\..\include\IOSOperator.h" />
<ClInclude Include="..\..\include\IRandomizer.h" />
<ClInclude Include="..\..\include\IReferenceCounted.h" />
<ClInclude Include="..\..\include\IRenderTarget.h" />
<ClInclude Include="..\..\include\IrrCompileConfig.h" />
<ClInclude Include="..\..\include\irrlicht.h" />
<ClInclude Include="..\..\include\leakHunter.h" />
<ClInclude Include="..\..\include\leakHunter.h" />
<ClInclude Include="..\..\include\IrrlichtDevice.h" />
<ClInclude Include="..\..\include\irrTypes.h" />
<ClInclude Include="..\..\include\ITimer.h" />
@ -927,7 +928,7 @@
<ClInclude Include="..\..\include\IMeshLoader.h" />
<ClInclude Include="..\..\include\IMeshManipulator.h" />
<ClInclude Include="..\..\include\IMeshSceneNode.h" />
<ClInclude Include="..\..\include\IMeshTextureLoader.h" />
<ClInclude Include="..\..\include\IMeshTextureLoader.h" />
<ClInclude Include="..\..\include\IMeshWriter.h" />
<ClInclude Include="..\..\include\IMetaTriangleSelector.h" />
<ClInclude Include="..\..\include\IParticleAffector.h" />
@ -973,7 +974,7 @@
<ClInclude Include="..\..\include\EGUIAlignment.h" />
<ClInclude Include="..\..\include\EGUIElementTypes.h" />
<ClInclude Include="..\..\include\EMessageBoxFlags.h" />
<ClInclude Include="..\..\include\EFocusFlags.h" />
<ClInclude Include="..\..\include\EFocusFlags.h" />
<ClInclude Include="..\..\include\ICursorControl.h" />
<ClInclude Include="..\..\include\IGUIButton.h" />
<ClInclude Include="..\..\include\IGUICheckbox.h" />
@ -990,7 +991,7 @@
<ClInclude Include="..\..\include\IGUIInOutFader.h" />
<ClInclude Include="..\..\include\IGUIListBox.h" />
<ClInclude Include="..\..\include\IGUIMeshViewer.h" />
<ClInclude Include="..\..\include\IGUIProfiler.h" />
<ClInclude Include="..\..\include\IGUIProfiler.h" />
<ClInclude Include="..\..\include\IGUIScrollBar.h" />
<ClInclude Include="..\..\include\IGUISkin.h" />
<ClInclude Include="..\..\include\IGUISpinBox.h" />
@ -1000,11 +1001,13 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
<ClInclude Include="CDefaultSceneNodeFactory.h" />
<ClInclude Include="CGeometryCreator.h" />
<ClInclude Include="CMeshCache.h" />
<ClInclude Include="CMeshManipulator.h" />
<ClInclude Include="COpenGLRenderTarget.h" />
<ClInclude Include="CSceneManager.h" />
<ClInclude Include="Octree.h" />
<ClInclude Include="CSMFMeshFileLoader.h" />
@ -1022,7 +1025,7 @@
<ClInclude Include="CLWOMeshFileLoader.h" />
<ClInclude Include="CMD2MeshFileLoader.h" />
<ClInclude Include="CMD3MeshFileLoader.h" />
<ClInclude Include="CMeshTextureLoader.h" />
<ClInclude Include="CMeshTextureLoader.h" />
<ClInclude Include="CMS3DMeshFileLoader.h" />
<ClInclude Include="CMY3DHelper.h" />
<ClInclude Include="CMY3DMeshFileLoader.h" />
@ -1149,8 +1152,8 @@
<ClInclude Include="COSOperator.h" />
<ClInclude Include="CTimer.h" />
<ClInclude Include="os.h" />
<ClInclude Include="CProfiler.h" />
<ClInclude Include="EProfileIDs.h" />
<ClInclude Include="CProfiler.h" />
<ClInclude Include="EProfileIDs.h" />
<ClInclude Include="lzma\LzmaDec.h" />
<ClInclude Include="lzma\Types.h" />
<ClInclude Include="zlib\crc32.h" />
@ -1228,7 +1231,7 @@
<ClInclude Include="CGUIMessageBox.h" />
<ClInclude Include="CGUIModalScreen.h" />
<ClInclude Include="CGUIProfiler.h" />
<ClInclude Include="CGUIScrollBar.h" />
<ClInclude Include="CGUIScrollBar.h" />
<ClInclude Include="CGUISkin.h" />
<ClInclude Include="CGUISpinBox.h" />
<ClInclude Include="CGUISpriteBank.h" />
@ -1244,11 +1247,13 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
<ClCompile Include="CDefaultSceneNodeFactory.cpp" />
<ClCompile Include="CGeometryCreator.cpp" />
<ClCompile Include="CMeshCache.cpp" />
<ClCompile Include="CMeshManipulator.cpp" />
<ClCompile Include="COpenGLRenderTarget.cpp" />
<ClCompile Include="CSceneManager.cpp" />
<ClCompile Include="C3DSMeshFileLoader.cpp" />
<ClCompile Include="CSMFMeshFileLoader.cpp" />
@ -1265,7 +1270,7 @@
<ClCompile Include="CLWOMeshFileLoader.cpp" />
<ClCompile Include="CMD2MeshFileLoader.cpp" />
<ClCompile Include="CMD3MeshFileLoader.cpp" />
<ClCompile Include="CMeshTextureLoader.cpp" />
<ClCompile Include="CMeshTextureLoader.cpp" />
<ClCompile Include="CMS3DMeshFileLoader.cpp" />
<ClCompile Include="CMY3DMeshFileLoader.cpp" />
<ClCompile Include="COBJMeshFileLoader.cpp" />
@ -1407,8 +1412,8 @@
<ClCompile Include="Irrlicht.cpp" />
<ClCompile Include="os.cpp" />
<ClCompile Include="utf8.cpp" />
<ClCompile Include="CProfiler.cpp" />
<ClCompile Include="leakHunter.cpp" />
<ClCompile Include="CProfiler.cpp" />
<ClCompile Include="leakHunter.cpp" />
<ClCompile Include="lzma\LzmaDec.c" />
<ClCompile Include="zlib\adler32.c" />
<ClCompile Include="zlib\compress.c" />
@ -1538,7 +1543,7 @@
<ClCompile Include="CGUIMessageBox.cpp" />
<ClCompile Include="CGUIModalScreen.cpp" />
<ClCompile Include="CGUIProfiler.cpp" />
<ClCompile Include="CGUIScrollBar.cpp" />
<ClCompile Include="CGUIScrollBar.cpp" />
<ClCompile Include="CGUISkin.cpp" />
<ClCompile Include="CGUISpinBox.cpp" />
<ClCompile Include="CGUISpriteBank.cpp" />
@ -1555,4 +1560,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -105,7 +105,7 @@
<ClInclude Include="..\..\include\IEventReceiver.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IProfiler.h">
<ClInclude Include="..\..\include\IProfiler.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\ILogger.h">
@ -123,7 +123,7 @@
<ClInclude Include="..\..\include\irrlicht.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\leakHunter.h">
<ClInclude Include="..\..\include\leakHunter.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IrrlichtDevice.h">
@ -357,7 +357,7 @@
<ClInclude Include="..\..\include\IMeshSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IMeshTextureLoader.h">
<ClInclude Include="..\..\include\IMeshTextureLoader.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IMeshWriter.h">
@ -492,7 +492,7 @@
<ClInclude Include="..\..\include\EMessageBoxFlags.h">
<Filter>include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\EFocusFlags.h">
<ClInclude Include="..\..\include\EFocusFlags.h">
<Filter>include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\ICursorControl.h">
@ -543,7 +543,7 @@
<ClInclude Include="..\..\include\IGUIMeshViewer.h">
<Filter>include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IGUIProfiler.h">
<ClInclude Include="..\..\include\IGUIProfiler.h">
<Filter>include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IGUIScrollBar.h">
@ -636,7 +636,7 @@
<ClInclude Include="CMD3MeshFileLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>
<ClInclude Include="CMeshTextureLoader.h">
<ClInclude Include="CMeshTextureLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>
<ClInclude Include="CMS3DMeshFileLoader.h">
@ -1011,10 +1011,10 @@
<ClInclude Include="os.h">
<Filter>Irrlicht\irr</Filter>
</ClInclude>
<ClInclude Include="CProfiler.h">
<ClInclude Include="CProfiler.h">
<Filter>Irrlicht\irr</Filter>
</ClInclude>
<ClInclude Include="EProfileIDs.h">
<ClInclude Include="EProfileIDs.h">
<Filter>Irrlicht\irr</Filter>
</ClInclude>
<ClInclude Include="lzma\LzmaDec.h">
@ -1248,7 +1248,7 @@
<ClInclude Include="CGUIProfiler.h">
<Filter>Irrlicht\gui</Filter>
</ClInclude>
<ClInclude Include="CGUIScrollBar.h">
<ClInclude Include="CGUIScrollBar.h">
<Filter>Irrlicht\gui</Filter>
</ClInclude>
<ClInclude Include="CGUISkin.h">
@ -1300,6 +1300,15 @@
<ClInclude Include="..\..\include\EMaterialFlags.h">
<Filter>include\video</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IRenderTarget.h">
<Filter>include\video</Filter>
</ClInclude>
<ClInclude Include="CD3D9RenderTarget.h">
<Filter>Irrlicht\video\Direct3D9</Filter>
</ClInclude>
<ClInclude Include="COpenGLRenderTarget.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -1370,7 +1379,7 @@
<ClCompile Include="CMD3MeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CMeshTextureLoader.cpp">
<ClCompile Include="CMeshTextureLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CMS3DMeshFileLoader.cpp">
@ -1793,10 +1802,10 @@
<ClCompile Include="utf8.cpp">
<Filter>Irrlicht\irr</Filter>
</ClCompile>
<ClCompile Include="CProfiler.cpp">
<ClCompile Include="CProfiler.cpp">
<Filter>Irrlicht\irr</Filter>
</ClCompile>
<ClCompile Include="leakHunter.cpp">
<ClCompile Include="leakHunter.cpp">
<Filter>Irrlicht\irr</Filter>
</ClCompile>
<ClCompile Include="lzma\LzmaDec.c">
@ -2186,7 +2195,7 @@
<ClCompile Include="CGUIProfiler.cpp">
<Filter>Irrlicht\gui</Filter>
</ClCompile>
<ClCompile Include="CGUIScrollBar.cpp">
<ClCompile Include="CGUIScrollBar.cpp">
<Filter>Irrlicht\gui</Filter>
</ClCompile>
<ClCompile Include="CGUISkin.cpp">
@ -2222,6 +2231,12 @@
<ClCompile Include="CSMFMeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CD3D9RenderTarget.cpp">
<Filter>Irrlicht\video\Direct3D9</Filter>
</ClCompile>
<ClCompile Include="COpenGLRenderTarget.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -847,6 +847,7 @@
<ClInclude Include="..\..\include\IOSOperator.h" />
<ClInclude Include="..\..\include\IRandomizer.h" />
<ClInclude Include="..\..\include\IReferenceCounted.h" />
<ClInclude Include="..\..\include\IRenderTarget.h" />
<ClInclude Include="..\..\include\IrrCompileConfig.h" />
<ClInclude Include="..\..\include\irrlicht.h" />
<ClInclude Include="..\..\include\leakHunter.h" />
@ -1000,11 +1001,13 @@
<ClInclude Include="..\..\include\IGUIToolbar.h" />
<ClInclude Include="..\..\include\IGUITreeView.h" />
<ClInclude Include="..\..\include\IGUIWindow.h" />
<ClInclude Include="CD3D9RenderTarget.h" />
<ClInclude Include="CDefaultSceneNodeAnimatorFactory.h" />
<ClInclude Include="CDefaultSceneNodeFactory.h" />
<ClInclude Include="CGeometryCreator.h" />
<ClInclude Include="CMeshCache.h" />
<ClInclude Include="CMeshManipulator.h" />
<ClInclude Include="COpenGLRenderTarget.h" />
<ClInclude Include="CSceneManager.h" />
<ClInclude Include="Octree.h" />
<ClInclude Include="CSMFMeshFileLoader.h" />
@ -1244,11 +1247,13 @@
<None Include="..\..\readme.txt" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="CD3D9RenderTarget.cpp" />
<ClCompile Include="CDefaultSceneNodeAnimatorFactory.cpp" />
<ClCompile Include="CDefaultSceneNodeFactory.cpp" />
<ClCompile Include="CGeometryCreator.cpp" />
<ClCompile Include="CMeshCache.cpp" />
<ClCompile Include="CMeshManipulator.cpp" />
<ClCompile Include="COpenGLRenderTarget.cpp" />
<ClCompile Include="CSceneManager.cpp" />
<ClCompile Include="C3DSMeshFileLoader.cpp" />
<ClCompile Include="CSMFMeshFileLoader.cpp" />

View File

@ -105,7 +105,7 @@
<ClInclude Include="..\..\include\IEventReceiver.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IProfiler.h">
<ClInclude Include="..\..\include\IProfiler.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\ILogger.h">
@ -123,7 +123,7 @@
<ClInclude Include="..\..\include\irrlicht.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\leakHunter.h">
<ClInclude Include="..\..\include\leakHunter.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IrrlichtDevice.h">
@ -357,7 +357,7 @@
<ClInclude Include="..\..\include\IMeshSceneNode.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IMeshTextureLoader.h">
<ClInclude Include="..\..\include\IMeshTextureLoader.h">
<Filter>include\scene</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IMeshWriter.h">
@ -492,7 +492,7 @@
<ClInclude Include="..\..\include\EMessageBoxFlags.h">
<Filter>include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\EFocusFlags.h">
<ClInclude Include="..\..\include\EFocusFlags.h">
<Filter>include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\ICursorControl.h">
@ -543,7 +543,7 @@
<ClInclude Include="..\..\include\IGUIMeshViewer.h">
<Filter>include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IGUIProfiler.h">
<ClInclude Include="..\..\include\IGUIProfiler.h">
<Filter>include\gui</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IGUIScrollBar.h">
@ -636,7 +636,7 @@
<ClInclude Include="CMD3MeshFileLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>
<ClInclude Include="CMeshTextureLoader.h">
<ClInclude Include="CMeshTextureLoader.h">
<Filter>Irrlicht\scene\loaders</Filter>
</ClInclude>
<ClInclude Include="CMS3DMeshFileLoader.h">
@ -1011,10 +1011,10 @@
<ClInclude Include="os.h">
<Filter>Irrlicht\irr</Filter>
</ClInclude>
<ClInclude Include="CProfiler.h">
<ClInclude Include="CProfiler.h">
<Filter>Irrlicht\irr</Filter>
</ClInclude>
<ClInclude Include="EProfileIDs.h">
<ClInclude Include="EProfileIDs.h">
<Filter>Irrlicht\irr</Filter>
</ClInclude>
<ClInclude Include="lzma\LzmaDec.h">
@ -1248,7 +1248,7 @@
<ClInclude Include="CGUIProfiler.h">
<Filter>Irrlicht\gui</Filter>
</ClInclude>
<ClInclude Include="CGUIScrollBar.h">
<ClInclude Include="CGUIScrollBar.h">
<Filter>Irrlicht\gui</Filter>
</ClInclude>
<ClInclude Include="CGUISkin.h">
@ -1300,6 +1300,15 @@
<ClInclude Include="..\..\include\EMaterialFlags.h">
<Filter>include\video</Filter>
</ClInclude>
<ClInclude Include="..\..\include\IRenderTarget.h">
<Filter>include\video</Filter>
</ClInclude>
<ClInclude Include="CD3D9RenderTarget.h">
<Filter>Irrlicht\video\Direct3D9</Filter>
</ClInclude>
<ClInclude Include="COpenGLRenderTarget.h">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\changes.txt">
@ -1370,7 +1379,7 @@
<ClCompile Include="CMD3MeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CMeshTextureLoader.cpp">
<ClCompile Include="CMeshTextureLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CMS3DMeshFileLoader.cpp">
@ -1793,10 +1802,10 @@
<ClCompile Include="utf8.cpp">
<Filter>Irrlicht\irr</Filter>
</ClCompile>
<ClCompile Include="CProfiler.cpp">
<ClCompile Include="CProfiler.cpp">
<Filter>Irrlicht\irr</Filter>
</ClCompile>
<ClCompile Include="leakHunter.cpp">
<ClCompile Include="leakHunter.cpp">
<Filter>Irrlicht\irr</Filter>
</ClCompile>
<ClCompile Include="lzma\LzmaDec.c">
@ -2186,7 +2195,7 @@
<ClCompile Include="CGUIProfiler.cpp">
<Filter>Irrlicht\gui</Filter>
</ClCompile>
<ClCompile Include="CGUIScrollBar.cpp">
<ClCompile Include="CGUIScrollBar.cpp">
<Filter>Irrlicht\gui</Filter>
</ClCompile>
<ClCompile Include="CGUISkin.cpp">
@ -2222,6 +2231,12 @@
<ClCompile Include="CSMFMeshFileLoader.cpp">
<Filter>Irrlicht\scene\loaders</Filter>
</ClCompile>
<ClCompile Include="CD3D9RenderTarget.cpp">
<Filter>Irrlicht\video\Direct3D9</Filter>
</ClCompile>
<ClCompile Include="COpenGLRenderTarget.cpp">
<Filter>Irrlicht\video\OpenGL</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Irrlicht.rc" />

View File

@ -772,6 +772,10 @@
RelativePath="..\..\include\IMaterialRendererServices.h"
>
</File>
<File
RelativePath="..\..\include\IRenderTarget.h"
>
</File>
<File
RelativePath="..\..\include\IShaderConstantSetCallBack.h"
>
@ -2211,6 +2215,14 @@
RelativePath="COpenGLParallaxMapRenderer.h"
>
</File>
<File
RelativePath="COpenGLRenderTarget.cpp"
>
</File>
<File
RelativePath="COpenGLRenderTarget.h"
>
</File>
<File
RelativePath="COpenGLShaderMaterialRenderer.cpp"
>
@ -2471,6 +2483,14 @@
RelativePath="CD3D9ParallaxMapRenderer.h"
>
</File>
<File
RelativePath="CD3D9RenderTarget.cpp"
>
</File>
<File
RelativePath="CD3D9RenderTarget.h"
>
</File>
<File
RelativePath="CD3D9ShaderMaterialRenderer.cpp"
>

View File

@ -38,7 +38,7 @@ IRRMESHOBJ = $(IRRMESHLOADER) $(IRRMESHWRITER) \
IRROBJ = CBillboardSceneNode.o CCameraSceneNode.o CDummyTransformationSceneNode.o CEmptySceneNode.o CGeometryCreator.o CLightSceneNode.o CMeshManipulator.o CMetaTriangleSelector.o COctreeSceneNode.o COctreeTriangleSelector.o CSceneCollisionManager.o CSceneManager.o CShadowVolumeSceneNode.o CSkyBoxSceneNode.o CSkyDomeSceneNode.o CTerrainSceneNode.o CTerrainTriangleSelector.o CVolumeLightSceneNode.o CCubeSceneNode.o CSphereSceneNode.o CTextSceneNode.o CTriangleBBSelector.o CTriangleSelector.o CWaterSurfaceSceneNode.o CMeshCache.o CDefaultSceneNodeAnimatorFactory.o CDefaultSceneNodeFactory.o CSceneLoaderIrr.o
IRRPARTICLEOBJ = CParticleAnimatedMeshSceneNodeEmitter.o CParticleBoxEmitter.o CParticleCylinderEmitter.o CParticleMeshEmitter.o CParticlePointEmitter.o CParticleRingEmitter.o CParticleSphereEmitter.o CParticleAttractionAffector.o CParticleFadeOutAffector.o CParticleGravityAffector.o CParticleRotationAffector.o CParticleSystemSceneNode.o CParticleScaleAffector.o
IRRANIMOBJ = CSceneNodeAnimatorCameraFPS.o CSceneNodeAnimatorCameraMaya.o CSceneNodeAnimatorCollisionResponse.o CSceneNodeAnimatorDelete.o CSceneNodeAnimatorFlyCircle.o CSceneNodeAnimatorFlyStraight.o CSceneNodeAnimatorFollowSpline.o CSceneNodeAnimatorRotation.o CSceneNodeAnimatorTexture.o
IRRDRVROBJ = CNullDriver.o COpenGLDriver.o COpenGLNormalMapRenderer.o COpenGLParallaxMapRenderer.o COpenGLShaderMaterialRenderer.o COpenGLTexture.o COpenGLSLMaterialRenderer.o COpenGLExtensionHandler.o CD3D9Driver.o CD3D9HLSLMaterialRenderer.o CD3D9NormalMapRenderer.o CD3D9ParallaxMapRenderer.o CD3D9ShaderMaterialRenderer.o CD3D9Texture.o
IRRDRVROBJ = CNullDriver.o COpenGLDriver.o COpenGLNormalMapRenderer.o COpenGLParallaxMapRenderer.o COpenGLRenderTarget.o COpenGLShaderMaterialRenderer.o COpenGLTexture.o COpenGLSLMaterialRenderer.o COpenGLExtensionHandler.o CD3D9Driver.o CD3D9HLSLMaterialRenderer.o CD3D9NormalMapRenderer.o CD3D9ParallaxMapRenderer.o CD3D9ShaderMaterialRenderer.o CD3D9Texture.o
IRRIMAGEOBJ = CColorConverter.o CImage.o CImageLoaderBMP.o CImageLoaderDDS.o CImageLoaderJPG.o CImageLoaderPCX.o CImageLoaderPNG.o CImageLoaderPSD.o CImageLoaderTGA.o CImageLoaderPPM.o CImageLoaderWAL.o CImageLoaderRGB.o \
CImageWriterBMP.o CImageWriterJPG.o CImageWriterPCX.o CImageWriterPNG.o CImageWriterPPM.o CImageWriterPSD.o CImageWriterTGA.o
IRRVIDEOOBJ = CVideoModeList.o CFPSCounter.o $(IRRDRVROBJ) $(IRRIMAGEOBJ)