Added abstract RenderTarget class for rendering to texture, and a renderToTexture method in IrrDriver

This commit is contained in:
Elderme 2015-12-30 12:02:11 +01:00
parent 8ce03609d1
commit 956ae27eca
15 changed files with 347 additions and 63 deletions

View File

@ -18,11 +18,15 @@
#ifndef HEADER_ABSTRACT_RENDERER_HPP
#define HEADER_ABSTRACT_RENDERER_HPP
#include "graphics/gl_headers.hpp"
#include "graphics/rtts.hpp"
#include "graphics/sphericalHarmonics.hpp"
#include <irrlicht.h>
#include <string>
#include <vector>
class RenderTarget;
struct GlowData {
irr::scene::ISceneNode * node;
@ -94,11 +98,14 @@ public:
return m_current_screen_size;
}
/*
// ------------------------------------------------------------------------
void toggleWireframe() { m_wireframe = !m_wireframe; }
// ------------------------------------------------------------------------
void toggleMipVisualization() { m_mipviz = !m_mipviz; }*/
/*virtual GLuint renderToTexture(size_t width,
size_t height,
irr::scene::ICameraSceneNode* camera,
float dt,
const std::string &rtt_name) { return 0;}*/
virtual void renderToTexture(RenderTarget *render_target,
irr::scene::ICameraSceneNode* camera,
float dt) {}
};
#endif //HEADER_ABSTRACT_RENDERER_HPP

View File

@ -31,6 +31,7 @@
#include "graphics/per_camera_node.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/referee.hpp"
#include "graphics/render_target.hpp"
#include "graphics/shader_based_renderer.hpp"
#include "graphics/shaders.hpp"
#include "graphics/shadow_matrices.hpp"
@ -199,6 +200,43 @@ GPUTimer &IrrDriver::getGPUTimer(unsigned i)
return m_perf_query[i];
}
RenderTarget* IrrDriver::addRenderTarget(const irr::core::dimension2du &dimension,
const std::string &name)
{
RenderTarget* render_target;
if(CVS->isGLSL())
render_target = new GL3RenderTarget(dimension);
else
render_target = new GL1RenderTarget(dimension, name);
m_render_targets[name] = render_target;
return render_target;
}
void IrrDriver::removeRenderTarget(const std::string &name)
{
m_render_targets.erase(name);
}
/*GLuint IrrDriver::renderToTexture(size_t width,
size_t height,
irr::scene::ICameraSceneNode* camera,
float dt,
const std::string &rtt_name)
{
return m_renderer->renderToTexture(width, height, camera, dt, rtt_name);
}*/
void IrrDriver::renderToTexture(RenderTarget *render_target,
irr::scene::ICameraSceneNode* camera,
float dt)
{
m_renderer->renderToTexture(render_target, camera, dt);
}
// ----------------------------------------------------------------------------
#if defined(__linux__) && !defined(ANDROID)

View File

@ -71,6 +71,7 @@ class PostProcessing;
class LightNode;
class ShadowImportance;
class ShadowMatrices;
class RenderTarget;
enum STKRenderingPass
{
@ -205,6 +206,8 @@ private:
float m_ssao_radius;
float m_ssao_k;
float m_ssao_sigma;
std::map<std::string, RenderTarget*> m_render_targets;
#ifdef DEBUG
/** Used to visualise skeletons. */
@ -316,14 +319,18 @@ public:
void unsetTextureErrorMessage();
class GPUTimer &getGPUTimer(unsigned);
void draw2dTriangle(const core::vector2df &a, const core::vector2df &b,
const core::vector2df &c,
const video::ITexture *texture = NULL,
const video::SColor *ca=NULL,
const video::SColor *cb=NULL,
const video::SColor *cc=NULL);
RenderTarget* addRenderTarget(const irr::core::dimension2du &dimension,
const std::string &name);
void removeRenderTarget(const std::string &name);
/*GLuint renderToTexture(size_t width,
size_t height,
irr::scene::ICameraSceneNode* camera,
float dt,
const std::string &rtt_name);*/
void renderToTexture(RenderTarget *render_target,
irr::scene::ICameraSceneNode* camera,
float dt);
// ------------------------------------------------------------------------
/** Convenience function that loads a texture with default parameters

View File

@ -24,6 +24,7 @@
#include "graphics/glwrap.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/mlaa_areamap.hpp"
#include "graphics/render_target.hpp"
#include "graphics/shaders.hpp"
#include "graphics/shared_gpu_objects.hpp"
#include "graphics/stk_mesh_scene_node.hpp"
@ -1385,13 +1386,15 @@ static void renderDoF(const FrameBuffer &fbo, GLuint rtt)
} // renderDoF
// ----------------------------------------------------------------------------
void PostProcessing::applyMLAA()
void PostProcessing::applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer,
const FrameBuffer& mlaa_blend_framebuffer,
const FrameBuffer& mlaa_colors_framebuffer)
{
const core::vector2df &PIXEL_SIZE =
core::vector2df(1.0f / UserConfigParams::m_width,
1.0f / UserConfigParams::m_height);
irr_driver->getFBO(FBO_MLAA_TMP).bind();
mlaa_tmp_framebuffer.bind();
glEnable(GL_STENCIL_TEST);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
@ -1405,17 +1408,17 @@ void PostProcessing::applyMLAA()
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
// Pass 2: blend weights
irr_driver->getFBO(FBO_MLAA_BLEND).bind();
mlaa_blend_framebuffer.bind();
glClear(GL_COLOR_BUFFER_BIT);
MLAABlendWeightSHader::getInstance()->render(m_areamap, PIXEL_SIZE);
// Blit in to tmp1
FrameBuffer::Blit(irr_driver->getFBO(FBO_MLAA_COLORS),
irr_driver->getFBO(FBO_MLAA_TMP));
FrameBuffer::Blit(mlaa_colors_framebuffer,
mlaa_tmp_framebuffer);
// Pass 3: gather
irr_driver->getFBO(FBO_MLAA_COLORS).bind();
mlaa_colors_framebuffer.bind();
MLAAGatherSHader::getInstance()->render(PIXEL_SIZE);
// Done.
@ -1437,7 +1440,8 @@ void PostProcessing::renderLightning(core::vector3df intensity)
// ----------------------------------------------------------------------------
/** Render the post-processed scene */
FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
bool isRace)
bool isRace,
GL3RenderTarget *specified_render_target)
{
FrameBuffer *in_fbo = &irr_driver->getFBO(FBO_COLORS);
FrameBuffer *out_fbo = &irr_driver->getFBO(FBO_TMP1_WITH_DS);
@ -1640,17 +1644,24 @@ FrameBuffer *PostProcessing::render(scene::ICameraSceneNode * const camnode,
return in_fbo;
glEnable(GL_FRAMEBUFFER_SRGB);
irr_driver->getFBO(FBO_MLAA_COLORS).bind();
if(specified_render_target == NULL)
out_fbo = &irr_driver->getFBO(FBO_MLAA_COLORS);
else
out_fbo = specified_render_target->getFrameBuffer();
out_fbo->bind();
renderPassThrough(in_fbo->getRTT()[0],
irr_driver->getFBO(FBO_MLAA_COLORS).getWidth(),
irr_driver->getFBO(FBO_MLAA_COLORS).getHeight());
out_fbo = &irr_driver->getFBO(FBO_MLAA_COLORS);
out_fbo->getWidth(),
out_fbo->getHeight());
if (UserConfigParams::m_mlaa) // MLAA. Must be the last pp filter.
{
PROFILER_PUSH_CPU_MARKER("- MLAA", 0xFF, 0x00, 0x00);
ScopedGPUTimer Timer(irr_driver->getGPUTimer(Q_MLAA));
applyMLAA();
applyMLAA(irr_driver->getFBO(FBO_MLAA_TMP),
irr_driver->getFBO(FBO_MLAA_BLEND),
*out_fbo);
PROFILER_POP_CPU_MARKER();
}
glDisable(GL_FRAMEBUFFER_SRGB);

View File

@ -24,6 +24,7 @@
#include "graphics/camera.hpp"
class FrameBuffer;
class GL3RenderTarget;
#include <vector>
@ -100,7 +101,9 @@ public:
/** Render tex. Used for blit/texture resize */
void renderPassThrough(unsigned tex, unsigned width, unsigned height);
void renderTextureLayer(unsigned tex, unsigned layer);
void applyMLAA();
void applyMLAA(const FrameBuffer& mlaa_tmp_framebuffer,
const FrameBuffer& mlaa_blend_framebuffer,
const FrameBuffer& mlaa_colors_framebuffer);
void renderMotionBlur(unsigned cam, const FrameBuffer &in_fbo,
FrameBuffer &out_fbo);
@ -108,7 +111,8 @@ public:
void renderLightning(core::vector3df intensity);
/** Render the post-processed scene */
FrameBuffer *render(scene::ICameraSceneNode * const camnode, bool isRace);
FrameBuffer *render(scene::ICameraSceneNode * const camnode, bool isRace,
GL3RenderTarget *specified_render_target = NULL);
/** Use motion blur for a short time */
void giveBoost(unsigned int cam_index);

View File

@ -0,0 +1,67 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "graphics/central_settings.hpp"
#include "graphics/render_target.hpp"
//-----------------------------------------------------------------------------
GL1RenderTarget::GL1RenderTarget(const irr::core::dimension2du &dimension,
const std::string &name)
{
}
//-----------------------------------------------------------------------------
GLuint GL1RenderTarget::getTextureId() const
{
}
//-----------------------------------------------------------------------------
irr::core::dimension2du GL1RenderTarget::getTextureSize() const
{
}
//-----------------------------------------------------------------------------
GL3RenderTarget::GL3RenderTarget(const irr::core::dimension2du &dimension)
{
glGenTextures(1, &m_texture_id);
glBindTexture(GL_TEXTURE_2D, m_texture_id);
if (CVS->isARBTextureStorageUsable())
glTexStorage2D(GL_TEXTURE_2D, 1, GL_SRGB8_ALPHA8, dimension.Width, dimension.Height);
else
glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB8_ALPHA8, dimension.Width, dimension.Height, 0, GL_BGR, GL_UNSIGNED_BYTE, 0);
std::vector<GLuint> somevector;
somevector.push_back(m_texture_id);
m_frame_buffer = new FrameBuffer(somevector, dimension.Width, dimension.Height);
}
//-----------------------------------------------------------------------------
GL3RenderTarget::~GL3RenderTarget()
{
glDeleteTextures(1, &m_texture_id);
delete m_frame_buffer;
}
//-----------------------------------------------------------------------------
irr::core::dimension2du GL3RenderTarget::getTextureSize() const
{
return irr::core::dimension2du(m_frame_buffer->getWidth(),
m_frame_buffer->getHeight());
}

View File

@ -0,0 +1,65 @@
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2014-2015 SuperTuxKart-Team
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_RENDER_TARGET_HPP
#define HEADER_RENDER_TARGET_HPP
#include "graphics/glwrap.hpp"
#include <irrlicht.h>
#include <string>
class RenderTarget
{
public:
virtual GLuint getTextureId() const = 0;
virtual irr::core::dimension2du getTextureSize() const = 0;
};
class GL1RenderTarget: public RenderTarget
{
private:
irr::video::ITexture *m_render_target_texture;
public:
GL1RenderTarget(const irr::core::dimension2du &dimension,
const std::string &name);
GLuint getTextureId() const;
irr::core::dimension2du getTextureSize() const;
};
class GL3RenderTarget: public RenderTarget
{
private:
FrameBuffer *m_frame_buffer;
GLuint m_texture_id;
public:
GL3RenderTarget(const irr::core::dimension2du &dimension);
~GL3RenderTarget();
GLuint getTextureId() const { return m_texture_id; }
irr::core::dimension2du getTextureSize() const;
FrameBuffer* getFrameBuffer() { return m_frame_buffer; }
};
#endif

View File

@ -290,26 +290,3 @@ RTT::~RTT()
}
}
FrameBuffer* RTT::render(scene::ICameraSceneNode* camera, float dt)
{
irr_driver->setRTT(this); //FIXME
irr_driver->getSceneManager()->setActiveCamera(camera);
irr_driver->getRenderer()->computeMatrixesAndCameras(camera, m_width, m_height);
irr_driver->getRenderer()->updateLightsInfo(camera, dt);
irr_driver->getRenderer()->uploadLightingData();
irr_driver->getRenderer()->renderScene(camera, dt, false, true);
FrameBuffer* frame_buffer = irr_driver->getPostProcessing()->render(camera, false);
// reset
glViewport(0, 0,
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
irr_driver->setRTT(NULL); //FIXME
glBindFramebuffer(GL_FRAMEBUFFER, 0);
irr_driver->getSceneManager()->setActiveCamera(NULL);
return frame_buffer;
}

View File

@ -143,6 +143,9 @@ class RTT
public:
RTT(size_t width, size_t height);
~RTT();
size_t getWidth () const { return m_width ; }
size_t getHeight() const { return m_height; }
FrameBuffer &getShadowFrameBuffer() { return *m_shadow_FBO; }
FrameBuffer &getRadianceHintFrameBuffer() { return *m_RH_FBO; }
@ -152,15 +155,13 @@ public:
unsigned getRenderTarget(enum TypeRTT target) const { return RenderTargetTextures[target]; }
FrameBuffer& getFBO(enum TypeFBO fbo) { return FrameBuffers[fbo]; }
FrameBuffer* render(irr::scene::ICameraSceneNode* camera, float dt);
private:
unsigned RenderTargetTextures[RTT_COUNT];
PtrVector<FrameBuffer> FrameBuffers;
unsigned DepthStencilTexture;
int m_width;
int m_height;
size_t m_width;
size_t m_height;
unsigned shadowColorTex, shadowDepthTex;
unsigned RSM_Color, RSM_Normal, RSM_Depth;

View File

@ -22,6 +22,7 @@
#include "graphics/graphics_restrictions.hpp"
#include "graphics/lod_node.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/render_target.hpp"
#include "graphics/rtts.hpp"
#include "graphics/shaders.hpp"
#include "graphics/stk_scene_manager.hpp"
@ -802,3 +803,79 @@ void ShaderBasedRenderer::render(float dt)
}
/*GLuint ShaderBasedRenderer::renderToTexture(size_t width,
size_t height,
irr::scene::ICameraSceneNode* camera,
float dt,
const std::string &rtt_name)
{
if(m_rtts == NULL)
m_rtts = new RTT(width, height);
else
{
if((m_rtts->getWidth() != width) || (m_rtts->getHeight() != height))
{
delete m_rtts;
m_rtts = new RTT(width, height);
}
}
irr_driver->getSceneManager()->setActiveCamera(camera);
computeMatrixesAndCameras(camera, width, height);
updateLightsInfo(camera, dt);
uploadLightingData();
renderScene(camera, dt, false, true);
FrameBuffer* frame_buffer = irr_driver->getPostProcessing()->render(camera, false);
GLuint render_target = frame_buffer->getRTT()[0];
// reset
glViewport(0, 0,
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
irr_driver->getSceneManager()->setActiveCamera(NULL);
return render_target;
}*/
void ShaderBasedRenderer::renderToTexture(RenderTarget *render_target,
irr::scene::ICameraSceneNode* camera,
float dt)
{
irr::core::dimension2du texture_size = render_target->getTextureSize();
size_t width = texture_size.Width ;
size_t height = texture_size.Height;
if(m_rtts == NULL)
m_rtts = new RTT(width, height);
else
{
if((m_rtts->getWidth() != width) || (m_rtts->getHeight() != height))
{
delete m_rtts;
m_rtts = new RTT(width, height);
}
}
irr_driver->getSceneManager()->setActiveCamera(camera);
computeMatrixesAndCameras(camera, width, height);
updateLightsInfo(camera, dt);
uploadLightingData();
renderScene(camera, dt, false, true);
FrameBuffer* frame_buffer = irr_driver->getPostProcessing()->render(camera, false, dynamic_cast<GL3RenderTarget*>(render_target));
//TODO
// reset
glViewport(0, 0,
irr_driver->getActualScreenSize().Width,
irr_driver->getActualScreenSize().Height);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
irr_driver->getSceneManager()->setActiveCamera(NULL);
}

View File

@ -104,6 +104,16 @@ public:
void clearGlowingNodes() override;
void render(float dt);
/*GLuint renderToTexture(size_t width,
size_t height,
irr::scene::ICameraSceneNode* camera,
float dt,
const std::string &rtt_name) override;*/
void renderToTexture(RenderTarget *render_target,
irr::scene::ICameraSceneNode* camera,
float dt) override;
};
#endif //HEADER_SHADER_BASED_RENDERER_HPP

View File

@ -21,6 +21,7 @@
#include "guiengine/widgets/model_view_widget.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/post_processing.hpp"
#include "graphics/render_target.hpp"
#include "graphics/rtts.hpp"
#include <IAnimatedMesh.h>
@ -45,6 +46,7 @@ IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, false,
m_light = NULL;
m_type = WTYPE_MODEL_VIEW;
m_rtt_provider = NULL;
m_render_target = NULL;
m_rotation_mode = ROTATE_OFF;
// so that the base class doesn't complain there is no icon defined
@ -59,6 +61,7 @@ ModelViewWidget::~ModelViewWidget()
delete m_rtt_provider;
m_rtt_provider = NULL;
//TODO: remove render target
}
// -----------------------------------------------------------------------------
void ModelViewWidget::add()
@ -162,14 +165,21 @@ void ModelViewWidget::update(float delta)
if (!CVS->isGLSL())
return;
if (m_rtt_provider == NULL)
/*if (m_rtt_provider == NULL)
{
std::string name = "model view ";
name += m_properties[PROP_ID].c_str();
m_rtt_provider = new RTT(512, 512);
}*/
if (m_render_target == NULL)
{
std::string name = "model view ";
name += m_properties[PROP_ID].c_str();
m_render_target = irr_driver->addRenderTarget(irr::core::dimension2du(512,512), name);
}
if (m_rtt_main_node == NULL)
{
setupRTTScene(m_models, m_model_location, m_model_scale, m_model_frames);
@ -179,7 +189,9 @@ void ModelViewWidget::update(float delta)
m_rtt_main_node->setVisible(true);
m_frame_buffer = m_rtt_provider->render(m_camera, GUIEngine::getLatestDt());
//m_frame_buffer = m_rtt_provider->render(m_camera, GUIEngine::getLatestDt());
irr_driver->renderToTexture(m_render_target, m_camera, GUIEngine::getLatestDt());
m_frame_buffer = dynamic_cast<GL3RenderTarget*>(m_render_target)->getFrameBuffer();
m_rtt_main_node->setVisible(false);
}

View File

@ -51,6 +51,7 @@ namespace GUIEngine
std::vector<int> m_model_frames;
RTT* m_rtt_provider;
RenderTarget *m_render_target;
float angle;

View File

@ -28,6 +28,7 @@
#include "graphics/irr_driver.hpp"
#include "graphics/screen_quad.hpp"
#include "graphics/shaders.hpp"
#include "graphics/render_target.hpp"
#include "graphics/rtts.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
@ -55,7 +56,7 @@ QuadGraph::QuadGraph(const std::string &quad_file_name,
m_mesh = NULL;
m_mesh_buffer = NULL;
m_lap_length = 0;
m_new_rtt = NULL;
m_render_target = NULL;
QuadSet::create();
QuadSet::get()->init(quad_file_name);
m_quad_filename = quad_file_name;
@ -73,8 +74,9 @@ QuadGraph::~QuadGraph()
}
if(UserConfigParams::m_track_debug)
cleanupDebugMesh();
if (m_new_rtt != NULL)
delete m_new_rtt;
//if (m_render_target != NULL)
// delete m_render_target;
//irr_driver->removeRenderTarget(name); //TODO
} // ~QuadGraph
// -----------------------------------------------------------------------------
@ -990,11 +992,12 @@ void QuadGraph::makeMiniMap(const core::dimension2du &dimension,
*oldRttMinimap = NULL;
*newRttMinimap = NULL;
RTT* newRttProvider = NULL;
//RTT* newRttProvider = NULL;
IrrDriver::RTTProvider* oldRttProvider = NULL;
if (CVS->isGLSL())
{
m_new_rtt = newRttProvider = new RTT(dimension.Width, dimension.Height);
//m_new_rtt = newRttProvider = new RTT(dimension.Width, dimension.Height);
m_render_target = irr_driver->addRenderTarget(dimension, name);
}
else
{
@ -1081,7 +1084,9 @@ void QuadGraph::makeMiniMap(const core::dimension2du &dimension,
if (CVS->isGLSL())
{
frame_buffer = newRttProvider->render(camera, GUIEngine::getLatestDt());
//frame_buffer = newRttProvider->render(camera, GUIEngine::getLatestDt());
irr_driver->renderToTexture(m_render_target, camera, GUIEngine::getLatestDt());
frame_buffer = dynamic_cast<GL3RenderTarget*>(m_render_target)->getFrameBuffer();
}
else
{

View File

@ -37,6 +37,7 @@ namespace irr
using namespace irr;
class CheckLine;
class RenderTarget;
class RTT;
class FrameBuffer;
@ -56,7 +57,8 @@ class QuadGraph : public NoCopy
private:
static QuadGraph *m_quad_graph;
RTT* m_new_rtt;
//RTT* m_new_rtt;
RenderTarget *m_render_target;
/** The actual graph data structure. */
std::vector<GraphNode*> m_all_nodes;