Render-fucking-targets, motherfuckers!

This commit is contained in:
Emmanuel BENOîT 2017-09-30 14:59:15 +02:00
parent 8cd18913aa
commit 7e223ff2f4
5 changed files with 264 additions and 15 deletions

View file

@ -11,7 +11,8 @@ DEMO = \
main.o \
imgui_impl_sdl.o \
utilities.o \
texture.o
texture.o \
rendertarget.o
DEMO_DEPS = $(DEMO:%.o=.%.d)

13
copy.glsl Normal file
View file

@ -0,0 +1,13 @@
#version 450 core
layout( location = 0 ) uniform sampler2D u_InputTexture;
layout( location = 0 ) out vec4 color;
void main( void )
{
vec2 tmp = gl_FragCoord.xy / vec2( 1280. , 720. );
color = textureLod( u_InputTexture , tmp , 0 );
//color.xy *= .75 + tmp * .25;
}

48
main.cc
View file

@ -3,6 +3,7 @@
#include "imgui_impl_sdl.h"
#include "utilities.hh"
#include "texture.hh"
#include "rendertarget.hh"
/*= T_Main ===================================================================*/
@ -27,7 +28,11 @@ struct T_Main
T_Camera camera;
T_FilesWatcher watcher;
std::unique_ptr< T_ShaderProgram > program;
std::unique_ptr< T_ShaderProgram > spRaymarch;
std::unique_ptr< T_ShaderProgram > spCopy;
std::unique_ptr< T_Texture > txRaymarchOutput;
std::unique_ptr< T_Rendertarget > rtRaymarchOutput;
void startIteration( );
void handleCapture( );
@ -60,8 +65,10 @@ T_Main::T_Main( )
ImGui_ImplSdl_Init( window );
initProgram( );
//T_Texture textureTest( 512 , 512 , E_TexType::R8 );
txRaymarchOutput = std::make_unique< T_Texture >(
1280 , 720 , E_TexType::RGBA8 );
rtRaymarchOutput = std::make_unique < T_Rendertarget >(
T_RendertargetSetup( ).add( *txRaymarchOutput ).create( ) );
}
void T_Main::mainLoop( )
@ -158,12 +165,9 @@ void T_Main::makeUI( )
void T_Main::render( )
{
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
glViewport( 0 , 0 , (int) dspSize.x, (int) dspSize.y );
glClearColor( 1 , 0 , 1 , 1 );
glClear( GL_COLOR_BUFFER_BIT );
if ( program->activate( ) ) {
if ( spRaymarch->activate( ) && rtRaymarchOutput->activate( ) ) {
glClearColor( 0 , 1 , 1 , 1 );
glClear( GL_COLOR_BUFFER_BIT );
enum {
U_TIME = 0 ,
U_RESOLUTION = 1 ,
@ -190,6 +194,17 @@ void T_Main::render( )
glRectf( -1, -1 , 1 , 1 );
}
T_Rendertarget::MainOutput( );
glClearColor( 1 , 0 , 1 , 1 );
glClear( GL_COLOR_BUFFER_BIT );
if ( spCopy->activate( ) ) {
T_TextureBinding tb( 0 );
tb.set( 0 , *txRaymarchOutput );
tb.bind( );
glRectf( -1, -1 , 1 , 1 );
glBindTexture( GL_TEXTURE_2D , 0 );
}
glUseProgram( 0 );
ImGui::Render( );
SDL_GL_SwapWindow( window );
@ -198,12 +213,17 @@ void T_Main::render( )
void T_Main::initProgram( )
{
program = std::make_unique< T_ShaderProgram >(
spRaymarch = std::make_unique< T_ShaderProgram >(
GL_FRAGMENT_SHADER , watcher );
program->addFile( "raymarch-header.glsl" );
program->addFile( "map.glsl" );
program->addFile( "raymarcher.glsl" );
program->load( );
spRaymarch->addFile( "raymarch-header.glsl" );
spRaymarch->addFile( "map.glsl" );
spRaymarch->addFile( "raymarcher.glsl" );
spRaymarch->load( );
spCopy = std::make_unique< T_ShaderProgram >( GL_FRAGMENT_SHADER ,
watcher );
spCopy->addFile( "copy.glsl" );
spCopy->load( );
}

146
rendertarget.cc Normal file
View file

@ -0,0 +1,146 @@
#include "externals.hh"
#include "texture.hh"
#include "rendertarget.hh"
T_RendertargetSetup::T_RendertargetSetup( )
: hasAttachments_( false )
{ }
T_RendertargetSetup& T_RendertargetSetup::add(
__rw__ T_Texture& texture ,
__rd__ const uint32_t level )
{
checkAttachment( texture , level );
colorAttachments_.push_back( T_Attachment_{ texture , level } );
return *this;
}
T_RendertargetSetup& T_RendertargetSetup::depth(
__rw__ T_Texture& texture )
{
assert( !depthAttachment_ );
checkAttachment( texture , 0 );
depthAttachment_ = std::make_unique< T_Attachment_ >( texture , 0 );
return *this;
}
void T_RendertargetSetup::checkAttachment(
__rw__ T_Texture const& texture ,
__rd__ const uint32_t level )
{
const uint32_t tw( texture.width( ) >> level ) ,
th( texture.height( ) >> level );
if ( hasAttachments_ ) {
assert( tw == width_ );
assert( th == height_ );
} else {
width_ = tw;
height_ = th;
hasAttachments_ = true;
}
}
T_Rendertarget T_RendertargetSetup::create( )
{
const auto nca( colorAttachments_.size( ) );
assert( hasAttachments_ );
assert( nca != 0 );
// Generate / setup the GL framebuffer
GLuint id( 0 );
glGenFramebuffers( 1 , &id );
glBindFramebuffer( GL_FRAMEBUFFER , id );
for ( auto i = 0u ; i < nca ; i ++ ) {
glFramebufferTexture( GL_FRAMEBUFFER ,
GL_COLOR_ATTACHMENT0 + i ,
colorAttachments_[ i ].texture->id( ) ,
colorAttachments_[ i ].level );
}
if ( depthAttachment_ ) {
glFramebufferTexture( GL_FRAMEBUFFER ,
GL_DEPTH_ATTACHMENT ,
depthAttachment_->texture->id( ) ,
depthAttachment_->level );
}
assert( glCheckFramebufferStatus( GL_FRAMEBUFFER ) == GL_FRAMEBUFFER_COMPLETE );
glBindFramebuffer( GL_FRAMEBUFFER , 0 );
assert( glGetError( ) == GL_NO_ERROR );
// Reset config
hasAttachments_ = false;
colorAttachments_.clear( );
depthAttachment_.reset( );
return T_Rendertarget( id , nca , width_ , height_ );
}
/*============================================================================*/
T_Rendertarget::T_Rendertarget(
__rd__ const uint32_t id ,
__rd__ const uint32_t nCats ,
__rd__ const uint32_t width ,
__rd__ const uint32_t height )
: id_( id ) , nCats_( nCats ) , width_( width ) , height_( height )
{ }
T_Rendertarget::T_Rendertarget(
__rw__ T_Rendertarget&& other ) noexcept
: id_( 0 ) , nCats_( other.nCats_ ) , width_( other.width_ ) ,
height_( other.height_ )
{
std::swap( id_ , other.id_ );
}
T_Rendertarget& T_Rendertarget::operator =(
__rw__ T_Rendertarget&& other ) noexcept
{
std::swap( id_ , other.id_ );
std::swap( nCats_ , other.nCats_ );
std::swap( width_ , other.width_ );
std::swap( height_ , other.height_ );
return *this;
}
T_Rendertarget::~T_Rendertarget( )
{
if ( id_ != 0 ) {
glDeleteFramebuffers( 1 , &id_ );
}
}
bool T_Rendertarget::activate( )
{
if ( id_ != 0 ) {
#ifdef INTRUSIVE_TRACES
printf( "ACTIVATING FB %d (%dx%d, %d c.a.)\n" ,
id_ , width_ , height_ , nCats_ );
#endif
if ( nCats_ != buffers_.size( ) ) {
buffers_.clear( );
for ( auto i = 0u ; i < nCats_ ; i ++ ) {
buffers_.push_back( GL_COLOR_ATTACHMENT0 + i );
}
}
glBindFramebuffer( GL_FRAMEBUFFER , id_ );
glViewport( 0 , 0 , width_ , height_ );
glDrawBuffers( nCats_ , &buffers_[ 0 ] );
assert( glCheckFramebufferStatus( GL_FRAMEBUFFER )
== GL_FRAMEBUFFER_COMPLETE );
assert( glGetError( ) == GL_NO_ERROR );
}
return id_ != 0;
}
void T_Rendertarget::MainOutput( )
{
auto const& dspSize( ImGui::GetIO( ).DisplaySize );
glBindFramebuffer( GL_FRAMEBUFFER , 0 );
glViewport( 0 , 0 , (int) dspSize.x, (int) dspSize.y );
}

69
rendertarget.hh Normal file
View file

@ -0,0 +1,69 @@
#pragma once
#ifndef REAL_BUILD
# include "externals.hh"
# include "texture.hh"
#endif
struct T_Rendertarget;
struct T_RendertargetSetup
{
T_RendertargetSetup( );
T_RendertargetSetup& add(
__rw__ T_Texture& texture ,
__rd__ const uint32_t level = 0 );
T_RendertargetSetup& depth(
__rw__ T_Texture& texture );
T_Rendertarget create( );
private:
struct T_Attachment_ {
T_Texture* texture;
uint32_t level;
T_Attachment_(
__rw__ T_Texture& texture ,
__rd__ const uint32_t level )
: texture( &texture ) , level( level )
{}
};
void checkAttachment(
__rw__ T_Texture const& texture ,
__rd__ const uint32_t level );
bool hasAttachments_;
uint32_t width_ , height_;
std::vector< T_Attachment_ > colorAttachments_;
std::unique_ptr< T_Attachment_ > depthAttachment_;
};
struct T_Rendertarget
{
T_Rendertarget( ) = delete;
T_Rendertarget( T_Rendertarget const& ) = delete;
T_Rendertarget(
__rd__ const GLuint id ,
__rd__ const uint32_t nCats ,
__rd__ const uint32_t width ,
__rd__ const uint32_t height );
T_Rendertarget( __rw__ T_Rendertarget&& other ) noexcept;
T_Rendertarget& operator =(
__rw__ T_Rendertarget&& ) noexcept;
~T_Rendertarget( );
bool activate( );
static void MainOutput( );
private:
GLuint id_;
uint32_t nCats_ , width_ , height_;
std::vector< GLenum > buffers_;
};