mirror of
https://github.com/blawar/GLideN64.git
synced 2024-07-02 09:03:37 +00:00
Implement PostProcessor class for image post processing effects.
This commit is contained in:
parent
9674adcb71
commit
4f1a636c20
|
@ -35,6 +35,7 @@ set(GLideN64_SOURCES
|
|||
ZSort.cpp
|
||||
Textures.cpp
|
||||
TextDrawer.cpp
|
||||
PostProcessor.cpp
|
||||
VI.cpp
|
||||
common/CommonAPIImpl_common.cpp
|
||||
)
|
||||
|
@ -42,7 +43,7 @@ set(GLideN64_SOURCES
|
|||
if(MUPENPLUSAPI)
|
||||
add_definitions(
|
||||
-DMUPENPLUSAPI
|
||||
-DTXFILTER_LIB
|
||||
-DTXFILTER_LIB
|
||||
)
|
||||
include_directories( inc )
|
||||
set(GLideN64_SOURCES_UNIX
|
||||
|
@ -98,14 +99,14 @@ if(UNIX)
|
|||
)
|
||||
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
if( NOT MUPENPLUSAPI)
|
||||
add_definitions(
|
||||
add_definitions(
|
||||
-D_DEBUG
|
||||
)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||
include_directories(${GLIB_INCLUDE_DIRS})
|
||||
find_package(GTK2 REQUIRED)
|
||||
include_directories(${GTK2_INCLUDE_DIRS})
|
||||
)
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(GLIB REQUIRED glib-2.0)
|
||||
include_directories(${GLIB_INCLUDE_DIRS})
|
||||
find_package(GTK2 REQUIRED)
|
||||
include_directories(${GTK2_INCLUDE_DIRS})
|
||||
endif( NOT MUPENPLUSAPI)
|
||||
endif(UNIX)
|
||||
|
||||
|
@ -166,43 +167,43 @@ if(NOT OPENGL_FOUND)
|
|||
endif(NOT OPENGL_FOUND)
|
||||
|
||||
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
SET(GCC_CPP11_COMPILE_FLAGS "-std=c++0x -static-libgcc -static-libstdc++")
|
||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS}" )
|
||||
SET(GCC_STATIC_LINK_FLAGS "-static-libgcc -static-libstdc++")
|
||||
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_STATIC_LINK_FLAGS}" )
|
||||
SET(GCC_CPP11_COMPILE_FLAGS "-std=c++0x -static-libgcc -static-libstdc++")
|
||||
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_CPP11_COMPILE_FLAGS}" )
|
||||
SET(GCC_STATIC_LINK_FLAGS "-static-libgcc -static-libstdc++")
|
||||
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_STATIC_LINK_FLAGS}" )
|
||||
endif()
|
||||
|
||||
add_library( ${GLideN64_DLL_NAME} SHARED ${GLideN64_SOURCES})
|
||||
|
||||
if( CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
SET_TARGET_PROPERTIES(
|
||||
${GLideN64_DLL_NAME}
|
||||
PROPERTIES
|
||||
LINKER_LANGUAGE CXX # Or else we get an error message, because cmake can't figure out from the ".o"-suffix that it is a C-linker we need.
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin/debug
|
||||
${GLideN64_DLL_NAME}
|
||||
PROPERTIES
|
||||
LINKER_LANGUAGE CXX # Or else we get an error message, because cmake can't figure out from the ".o"-suffix that it is a C-linker we need.
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin/debug
|
||||
)
|
||||
|
||||
if(SDL)
|
||||
target_link_libraries(${GLideN64_DLL_NAME} PRIVATE ${OPENGL_LIBRARIES} ${SDL_LIBRARIES} ${FREETYPE_LIBRARIES} GLideNHQd )
|
||||
target_link_libraries(${GLideN64_DLL_NAME} PRIVATE ${OPENGL_LIBRARIES} ${SDL_LIBRARIES} ${FREETYPE_LIBRARIES} GLideNHQd )
|
||||
else(SDL)
|
||||
target_link_libraries(${GLideN64_DLL_NAME} PRIVATE ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES} GLideNHQd )
|
||||
target_link_libraries(${GLideN64_DLL_NAME} PRIVATE ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES} GLideNHQd )
|
||||
endif(SDL)
|
||||
endif( CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
|
||||
if( CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
SET_TARGET_PROPERTIES(
|
||||
${GLideN64_DLL_NAME}
|
||||
PROPERTIES
|
||||
LINKER_LANGUAGE CXX # Or else we get an error message, because cmake can't figure out from the ".o"-suffix that it is a C-linker we need.
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin/release
|
||||
${GLideN64_DLL_NAME}
|
||||
PROPERTIES
|
||||
LINKER_LANGUAGE CXX # Or else we get an error message, because cmake can't figure out from the ".o"-suffix that it is a C-linker we need.
|
||||
PREFIX ""
|
||||
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/plugin/release
|
||||
)
|
||||
|
||||
if(SDL)
|
||||
target_link_libraries(${GLideN64_DLL_NAME} ${OPENGL_LIBRARIES} ${SDL_LIBRARIES} ${FREETYPE_LIBRARIES} GLideNHQ )
|
||||
target_link_libraries(${GLideN64_DLL_NAME} ${OPENGL_LIBRARIES} ${SDL_LIBRARIES} ${FREETYPE_LIBRARIES} GLideNHQ )
|
||||
else(SDL)
|
||||
target_link_libraries(${GLideN64_DLL_NAME} PRIVATE ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES} GLideNHQ )
|
||||
target_link_libraries(${GLideN64_DLL_NAME} PRIVATE ${OPENGL_LIBRARIES} ${FREETYPE_LIBRARIES} GLideNHQ )
|
||||
endif(SDL)
|
||||
endif( CMAKE_BUILD_TYPE STREQUAL "Release")
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "Types.h"
|
||||
#include "Config.h"
|
||||
#include "Debug.h"
|
||||
#include "PostProcessor.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -403,6 +404,9 @@ void FrameBufferList::renderBuffer(u32 _address)
|
|||
srcY1 = srcY0 + VI.real_height;
|
||||
}
|
||||
|
||||
#if 1
|
||||
PostProcessor::get().processTexture(pBuffer->m_pTexture);
|
||||
#endif
|
||||
// glDisable(GL_SCISSOR_TEST) does not affect glBlitFramebuffer, at least on AMD
|
||||
glScissor(0, 0, ogl.getScreenWidth(), ogl.getScreenHeight());
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
|
|
|
@ -293,6 +293,7 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="N64.cpp" />
|
||||
<ClCompile Include="OpenGL.cpp" />
|
||||
<ClCompile Include="PostProcessor.cpp" />
|
||||
<ClCompile Include="RDP.CPP" />
|
||||
<ClCompile Include="RSP.cpp" />
|
||||
<ClCompile Include="TextDrawer.cpp" />
|
||||
|
@ -372,6 +373,7 @@
|
|||
<ClInclude Include="Noise_shader.h" />
|
||||
<ClInclude Include="OpenGL.h" />
|
||||
<ClInclude Include="PluginAPI.h" />
|
||||
<ClInclude Include="PostProcessor.h" />
|
||||
<ClInclude Include="RDP.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="RSP.h" />
|
||||
|
|
|
@ -192,6 +192,9 @@
|
|||
<ClCompile Include="TextDrawer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PostProcessor.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="3DMath.h">
|
||||
|
@ -335,6 +338,9 @@
|
|||
<ClInclude Include="TextDrawer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="PostProcessor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="Resource.rc">
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "Config.h"
|
||||
#include "Log.h"
|
||||
#include "TextDrawer.h"
|
||||
#include "PostProcessor.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -1275,6 +1276,7 @@ void OGLRender::_initData()
|
|||
Combiner_Init();
|
||||
TextDrawer::get().init();
|
||||
TFH.init();
|
||||
PostProcessor::get().init();
|
||||
m_renderState = rsNone;
|
||||
|
||||
gSP.changed = gDP.changed = 0xFFFFFFFF;
|
||||
|
@ -1293,6 +1295,7 @@ void OGLRender::_initData()
|
|||
void OGLRender::_destroyData()
|
||||
{
|
||||
m_renderState = rsNone;
|
||||
PostProcessor::get().destroy();
|
||||
TextDrawer::get().destroy();
|
||||
Combiner_Destroy();
|
||||
FrameBuffer_Destroy();
|
||||
|
|
2
OpenGL.h
2
OpenGL.h
|
@ -80,6 +80,8 @@ public:
|
|||
};
|
||||
RENDER_STATE getRenderState() const {return m_renderState;}
|
||||
|
||||
void dropRenderState() {m_renderState = rsNone;}
|
||||
|
||||
#ifdef __TRIBUFFER_OPT
|
||||
u32 getIndexmap(u32 _v) const {return triangles.indexmap[_v];}
|
||||
u32 getIndexmapNew(u32 _index, u32 _num);
|
||||
|
|
197
PostProcessor.cpp
Normal file
197
PostProcessor.cpp
Normal file
|
@ -0,0 +1,197 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "N64.h"
|
||||
#include "gSP.h"
|
||||
#include "PostProcessor.h"
|
||||
#include "GLSLCombiner.h"
|
||||
|
||||
const char * vertexShader =
|
||||
"#version 330 core \n"
|
||||
"in highp vec2 aPosition; \n"
|
||||
"in highp vec2 aTexCoord; \n"
|
||||
"out mediump vec2 vTexCoord; \n"
|
||||
"void main(){ \n"
|
||||
"gl_Position = vec4(aPosition.x, aPosition.y, 0.0, 1.0);\n"
|
||||
"vTexCoord = aTexCoord; \n"
|
||||
"} \n"
|
||||
;
|
||||
|
||||
static const char* bloomShader =
|
||||
"#version 330 core \n"
|
||||
"in mediump vec2 vTexCoord; \n"
|
||||
"layout(binding = 0) uniform sampler2D bgl_RenderedTexture; \n"
|
||||
"out lowp vec4 fragColor; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" vec4 sum = vec4(0); \n"
|
||||
" vec2 texcoord = vTexCoord; \n"
|
||||
" int j; \n"
|
||||
" int i; \n"
|
||||
" \n"
|
||||
" for( i= -4 ; i < 4; i++) \n"
|
||||
" { \n"
|
||||
" for (j = -3; j < 3; j++) \n"
|
||||
" { \n"
|
||||
" sum += texture2D(bgl_RenderedTexture, texcoord + vec2(j, i)*0.004) * 0.25; \n"
|
||||
" } \n"
|
||||
" } \n"
|
||||
" if (texture2D(bgl_RenderedTexture, texcoord).r < 0.3) \n"
|
||||
" { \n"
|
||||
" fragColor = sum*sum*0.012 + texture2D(bgl_RenderedTexture, texcoord); \n"
|
||||
" } \n"
|
||||
" else \n"
|
||||
" { \n"
|
||||
" if (texture2D(bgl_RenderedTexture, texcoord).r < 0.5) \n"
|
||||
" { \n"
|
||||
" fragColor = sum*sum*0.009 + texture2D(bgl_RenderedTexture, texcoord); \n"
|
||||
" } \n"
|
||||
" else \n"
|
||||
" { \n"
|
||||
" fragColor = sum*sum*0.0075 + texture2D(bgl_RenderedTexture, texcoord); \n"
|
||||
" } \n"
|
||||
" } \n"
|
||||
"} \n"
|
||||
;
|
||||
|
||||
static const char* copyShader =
|
||||
"#version 330 core \n"
|
||||
"in mediump vec2 vTexCoord; \n"
|
||||
"layout(binding = 0) uniform sampler2D bgl_RenderedTexture; \n"
|
||||
"out lowp vec4 fragColor; \n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" fragColor = texture2D(bgl_RenderedTexture, vTexCoord); \n"
|
||||
"} \n"
|
||||
;
|
||||
|
||||
static
|
||||
GLuint _createShaderProgram(const char * _strVertex, const char * _strFragment)
|
||||
{
|
||||
GLuint vertex_shader_object = glCreateShader(GL_VERTEX_SHADER);
|
||||
glShaderSource(vertex_shader_object, 1, &_strVertex, NULL);
|
||||
glCompileShader(vertex_shader_object);
|
||||
|
||||
GLuint fragment_shader_object = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
glShaderSource(fragment_shader_object, 1, &_strFragment, NULL);
|
||||
glCompileShader(fragment_shader_object);
|
||||
|
||||
GLuint program = glCreateProgram();
|
||||
glBindAttribLocation(program, SC_POSITION, "aPosition");
|
||||
glBindAttribLocation(program, SC_TEXCOORD0, "aTexCoord");
|
||||
glAttachShader(program, vertex_shader_object);
|
||||
glAttachShader(program, fragment_shader_object);
|
||||
glLinkProgram(program);
|
||||
glDeleteShader(vertex_shader_object);
|
||||
glDeleteShader(fragment_shader_object);
|
||||
return program;
|
||||
}
|
||||
|
||||
|
||||
void PostProcessor::init()
|
||||
{
|
||||
m_bloomProgram = _createShaderProgram(vertexShader, bloomShader);
|
||||
m_copyProgram = _createShaderProgram(vertexShader, copyShader);
|
||||
|
||||
m_pTexture = textureCache().addFrameBufferTexture();
|
||||
m_pTexture->format = G_IM_FMT_RGBA;
|
||||
m_pTexture->clampS = 1;
|
||||
m_pTexture->clampT = 1;
|
||||
m_pTexture->frameBufferTexture = TRUE;
|
||||
m_pTexture->maskS = 0;
|
||||
m_pTexture->maskT = 0;
|
||||
m_pTexture->mirrorS = 0;
|
||||
m_pTexture->mirrorT = 0;
|
||||
m_pTexture->realWidth = video().getWidth();
|
||||
m_pTexture->realHeight = video().getHeight();
|
||||
m_pTexture->textureBytes = m_pTexture->realWidth * m_pTexture->realHeight * 4;
|
||||
textureCache().addFrameBufferTextureSize(m_pTexture->textureBytes);
|
||||
glBindTexture(GL_TEXTURE_2D, m_pTexture->glName);
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_pTexture->realWidth, m_pTexture->realHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glGenFramebuffers(1, &m_FBO);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_pTexture->glName, 0);
|
||||
GLuint attachments[1] = { GL_COLOR_ATTACHMENT0 };
|
||||
glDrawBuffers(1, attachments);
|
||||
// check if everything is OK
|
||||
assert(checkFBO());
|
||||
assert(!isGLError());
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
|
||||
}
|
||||
|
||||
void PostProcessor::destroy()
|
||||
{
|
||||
if (m_bloomProgram != 0)
|
||||
glDeleteProgram(m_bloomProgram);
|
||||
|
||||
if (m_copyProgram != 0)
|
||||
glDeleteProgram(m_copyProgram);
|
||||
|
||||
if (m_FBO != 0)
|
||||
glDeleteFramebuffers(1, &m_FBO);
|
||||
|
||||
if (m_pTexture != NULL)
|
||||
textureCache().removeFrameBufferTexture(m_pTexture);
|
||||
}
|
||||
|
||||
PostProcessor & PostProcessor::get()
|
||||
{
|
||||
static PostProcessor processor;
|
||||
return processor;
|
||||
}
|
||||
|
||||
void _setGLState() {
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
static const float vert[] =
|
||||
{
|
||||
-1.0, -1.0, +0.0, +0.0,
|
||||
+1.0, -1.0, +1.0, +0.0,
|
||||
-1.0, +1.0, +0.0, +1.0,
|
||||
+1.0, +1.0, +1.0, +1.0
|
||||
};
|
||||
|
||||
glEnableVertexAttribArray(SC_POSITION);
|
||||
glVertexAttribPointer(SC_POSITION, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (float*)vert);
|
||||
glEnableVertexAttribArray(SC_TEXCOORD0);
|
||||
glVertexAttribPointer(SC_TEXCOORD0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(float), (float*)vert + 2);
|
||||
glDisableVertexAttribArray(SC_COLOR);
|
||||
glDisableVertexAttribArray(SC_TEXCOORD1);
|
||||
glDisableVertexAttribArray(SC_NUMLIGHTS);
|
||||
glViewport(0, 0, video().getWidth(), video().getHeight());
|
||||
}
|
||||
|
||||
void PostProcessor::processTexture(CachedTexture * _pTexture)
|
||||
{
|
||||
_setGLState();
|
||||
|
||||
textureCache().activateTexture(0, _pTexture);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO);
|
||||
glUseProgram(m_bloomProgram);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
textureCache().activateTexture(0, m_pTexture);
|
||||
GLuint copyFBO = 0;
|
||||
glGenFramebuffers(1, ©FBO);
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, copyFBO);
|
||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _pTexture->glName, 0);
|
||||
assert(checkFBO());
|
||||
glUseProgram(m_copyProgram);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
||||
glDeleteFramebuffers(1, ©FBO);
|
||||
video().getRender().dropRenderState();
|
||||
glUseProgram(0);
|
||||
gSP.changed = CHANGED_VIEWPORT | CHANGED_TEXTURE;
|
||||
}
|
28
PostProcessor.h
Normal file
28
PostProcessor.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#ifndef POST_PROCESSOR_H
|
||||
#define POST_PROCESSOR_H
|
||||
|
||||
#include "Types.h"
|
||||
#include "OpenGL.h"
|
||||
#include "Textures.h"
|
||||
|
||||
class PostProcessor {
|
||||
public:
|
||||
void init();
|
||||
void destroy();
|
||||
|
||||
void processTexture(CachedTexture * _pTexture);
|
||||
|
||||
static PostProcessor & get();
|
||||
|
||||
private:
|
||||
PostProcessor() : m_bloomProgram(0), m_copyProgram(0), m_FBO(0), m_pTexture(NULL) {};
|
||||
PostProcessor(const PostProcessor & _other);
|
||||
|
||||
GLuint m_bloomProgram;
|
||||
GLuint m_copyProgram;
|
||||
|
||||
GLuint m_FBO;
|
||||
CachedTexture * m_pTexture;
|
||||
};
|
||||
|
||||
#endif // POST_PROCESSOR_H
|
Loading…
Reference in New Issue
Block a user