Browse Source

scene: add render buffers and a temporary postprocess

legacy
Sam Hocevar 8 years ago
parent
commit
afc48d2927
5 changed files with 121 additions and 29 deletions
  1. +1
    -0
      src/Makefile.am
  2. +33
    -0
      src/gpu/blit.lolfx
  3. +21
    -12
      src/gpu/postprocess.lolfx
  4. +1
    -0
      src/lol-core.vcxproj
  5. +65
    -17
      src/scene.cpp

+ 1
- 0
src/Makefile.am View File

@@ -99,6 +99,7 @@ liblol_core_sources = \
gpu/tile.lolfx gpu/palette.lolfx gpu/line.lolfx \
gpu/emptymaterial.lolfx \
gpu/testmaterial.lolfx \
gpu/blit.lolfx \
gpu/postprocess.lolfx \
\
gpu/lolfx.cpp \


+ 33
- 0
src/gpu/blit.lolfx View File

@@ -0,0 +1,33 @@
[vert.glsl]

#version 130

in vec2 in_position;
out vec2 pass_position;

void main()
{
pass_position = in_position;
gl_Position = vec4(in_position, 0.0, 1.0);
}

[frag.glsl]

#version 130

#if defined GL_ES
precision highp float;
#endif

uniform sampler2D u_buffer;

in vec2 pass_position;
out vec4 out_color;

void main(void)
{
vec2 pos = pass_position;
vec2 texcoords = pos * 0.5 + vec2(0.5, 0.5);
out_color = vec4(texture2D(u_buffer, texcoords).rgb, 1);
}


+ 21
- 12
src/gpu/postprocess.lolfx View File

@@ -1,35 +1,44 @@
[vert.glsl]

#version 120
#version 130

attribute vec2 in_Position;

varying vec2 pass_Position;
in vec2 in_position;
out vec2 pass_position;

void main()
{
pass_Position = in_Position;
gl_Position = vec4(in_Position, 0.0, 1.0);
pass_position = in_position;
gl_Position = vec4(in_position, 0.0, 1.0);
}

[frag.glsl]

#version 120
#version 130

#if defined GL_ES
precision highp float;
#endif

uniform sampler2D u_texture;
uniform sampler2D u_buffer;
uniform sampler2D u_prev_buffer;
uniform sampler2D u_prev_final;

varying vec2 pass_Position;
in vec2 pass_position;
out vec4 out_color;

void main(void)
{
vec2 pos = pass_Position;
vec2 pos = pass_position;

vec2 texcoords = pos * 0.5 + vec2(0.5, 0.5);
vec4 color = vec4(texture2D(u_texture, texcoords).rgb, 1.0);
gl_FragColor = color;
vec4 color = vec4(texture2D(u_buffer, texcoords).rgb, 1.0);
vec4 prev_color = vec4(texture2D(u_prev_buffer, texcoords).rgb, 1.0);

/* (do stuff with color here) */
vec4 final_color = mix(color, prev_color, 0.01);

/* Blend final color with previous frame’s final color */
vec4 prev_final_color = vec4(texture2D(u_prev_final, texcoords).rgb, 1.0);
out_color = mix(final_color, prev_final_color, vec4(0.5) + 0.3 * (prev_final_color - final_color));
}


+ 1
- 0
src/lol-core.vcxproj View File

@@ -366,6 +366,7 @@
<LolFxCompile Include="easymesh\shinydebugwireframe.lolfx" />
<LolFxCompile Include="easymesh\shinyflat.lolfx" />
<LolFxCompile Include="easymesh\shiny_SK.lolfx" />
<LolFxCompile Include="gpu\blit.lolfx" />
<LolFxCompile Include="gpu\defaultmaterial.lolfx" />
<LolFxCompile Include="gpu\emptymaterial.lolfx" />
<LolFxCompile Include="gpu\line.lolfx" />


+ 65
- 17
src/scene.cpp View File

@@ -26,6 +26,8 @@
LOLFX_RESOURCE_DECLARE(tile);
LOLFX_RESOURCE_DECLARE(palette);
LOLFX_RESOURCE_DECLARE(line);

LOLFX_RESOURCE_DECLARE(blit);
LOLFX_RESOURCE_DECLARE(postprocess);

namespace lol
@@ -136,16 +138,16 @@ private:
* the default one created by the app will be used */
SceneDisplay* m_display = nullptr;

/** Back buffer: where to render to. */
Framebuffer *m_backbuffer = nullptr;
/** Render buffers: where to render to. */
Framebuffer *m_renderbuffer[4];

struct postprocess
{
Shader *m_shader = nullptr;
Shader *m_shader[2];
VertexBuffer *m_vbo = nullptr;
VertexDeclaration *m_vdecl = nullptr;
ShaderUniform m_texture;
ShaderAttrib m_coord;
ShaderUniform m_buffer_uni[2][3];
ShaderAttrib m_coord[2];
}
m_pp;

@@ -201,11 +203,19 @@ mutex SceneData::m_prim_mutex;
Scene::Scene(ivec2 size)
: data(new SceneData())
{
data->m_backbuffer = new Framebuffer(size);
data->m_pp.m_shader = Shader::Create(LOLFX_RESOURCE_NAME(postprocess));
data->m_pp.m_coord = data->m_pp.m_shader->GetAttribLocation(VertexUsage::Position, 0);
data->m_renderbuffer[0] = new Framebuffer(size);
data->m_renderbuffer[1] = new Framebuffer(size);
data->m_renderbuffer[2] = new Framebuffer(size);
data->m_renderbuffer[3] = new Framebuffer(size);
data->m_pp.m_shader[0] = Shader::Create(LOLFX_RESOURCE_NAME(blit));
data->m_pp.m_shader[1] = Shader::Create(LOLFX_RESOURCE_NAME(postprocess));
data->m_pp.m_coord[0] = data->m_pp.m_shader[0]->GetAttribLocation(VertexUsage::Position, 0);
data->m_pp.m_coord[1] = data->m_pp.m_shader[1]->GetAttribLocation(VertexUsage::Position, 0);
data->m_pp.m_vdecl = new VertexDeclaration(VertexStream<vec2>(VertexUsage::Position));
data->m_pp.m_texture = data->m_pp.m_shader->GetUniformLocation("u_texture");
data->m_pp.m_buffer_uni[0][0] = data->m_pp.m_shader[0]->GetUniformLocation("u_buffer");
data->m_pp.m_buffer_uni[1][0] = data->m_pp.m_shader[1]->GetUniformLocation("u_buffer");
data->m_pp.m_buffer_uni[1][1] = data->m_pp.m_shader[1]->GetUniformLocation("u_prev_buffer");
data->m_pp.m_buffer_uni[1][2] = data->m_pp.m_shader[1]->GetUniformLocation("u_prev_final");

array<vec2> quad { vec2( 1.0, 1.0), vec2(-1.0, -1.0), vec2( 1.0, -1.0),
vec2(-1.0, -1.0), vec2( 1.0, 1.0), vec2(-1.0, 1.0), };
@@ -621,7 +631,9 @@ void Scene::render(float seconds)

/* First render into the offline buffer */
if (do_pp)
data->m_backbuffer->Bind();
{
data->m_renderbuffer[0]->Bind();
}

{
RenderContext rc;
@@ -641,18 +653,55 @@ void Scene::render(float seconds)

if (do_pp)
{
data->m_backbuffer->Unbind();
data->m_renderbuffer[0]->Unbind();

gpu_marker("PostProcess");

/* Now blit the offline buffer */
data->m_pp.m_shader->Bind();
data->m_pp.m_shader->SetUniform(data->m_pp.m_texture, data->m_backbuffer->GetTextureUniform(), 0);
data->m_pp.m_vdecl->SetStream(data->m_pp.m_vbo, data->m_pp.m_coord);
data->m_renderbuffer[3]->Bind();

RenderContext rc;
rc.SetClearColor(vec4(0.f, 0.f, 0.f, 1.f));
rc.SetClearDepth(1.f);
Renderer::Get()->Clear(ClearMask::Color | ClearMask::Depth);

/* Execute post process */
data->m_pp.m_shader[1]->Bind();
data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][0], data->m_renderbuffer[0]->GetTextureUniform(), 0);
data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][1], data->m_renderbuffer[1]->GetTextureUniform(), 1);
data->m_pp.m_shader[1]->SetUniform(data->m_pp.m_buffer_uni[1][2], data->m_renderbuffer[2]->GetTextureUniform(), 2);
data->m_pp.m_vdecl->SetStream(data->m_pp.m_vbo, data->m_pp.m_coord[1]);
data->m_pp.m_vdecl->Bind();
data->m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6);
data->m_pp.m_vdecl->Unbind();
data->m_pp.m_shader[1]->Unbind();
data->m_renderbuffer[3]->Unbind();
}

if (do_pp)
{
gpu_marker("Blit frame");

data->m_pp.m_shader[0]->Bind();

RenderContext rc;
rc.SetClearColor(vec4(0.f, 0.f, 0.f, 1.f));
rc.SetClearDepth(1.f);
Renderer::Get()->Clear(ClearMask::Color | ClearMask::Depth);

/* Blit final image to screen */
data->m_pp.m_shader[0]->SetUniform(data->m_pp.m_buffer_uni[0][0], data->m_renderbuffer[3]->GetTextureUniform(), 3);
data->m_pp.m_vdecl->SetStream(data->m_pp.m_vbo, data->m_pp.m_coord[0]);
data->m_pp.m_vdecl->Bind();
data->m_pp.m_vdecl->DrawElements(MeshPrimitive::Triangles, 0, 6);
data->m_pp.m_vdecl->Unbind();
data->m_pp.m_shader->Unbind();
data->m_pp.m_shader[0]->Unbind();
}

if (do_pp)
{
/* Swap back buffers */
std::swap(data->m_renderbuffer[0], data->m_renderbuffer[1]);
std::swap(data->m_renderbuffer[2], data->m_renderbuffer[3]);
}

gpu_marker("End Render");
@@ -794,7 +843,6 @@ void Scene::render_tiles() // XXX: rename to Blit()
shader->Unbind();
}


#if (defined LOL_USE_GLEW || defined HAVE_GL_2X) && !defined HAVE_GLES_2X
glDisable(GL_TEXTURE_2D);
#endif


Loading…
Cancel
Save