mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-02-03 12:31:15 +00:00
MSAA
This commit is contained in:
parent
5be9b09b40
commit
9ef35c3dc5
@ -6,12 +6,13 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
Direct3DRMRenderer* OpenGL15Renderer::Create(DWORD width, DWORD height)
|
Direct3DRMRenderer* OpenGL15Renderer::Create(DWORD width, DWORD height)
|
||||||
{
|
{
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 5);
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 8);
|
||||||
|
|
||||||
SDL_Window* window = DDWindow;
|
SDL_Window* window = DDWindow;
|
||||||
bool testWindow = false;
|
bool testWindow = false;
|
||||||
@ -37,55 +38,82 @@ Direct3DRMRenderer* OpenGL15Renderer::Create(DWORD width, DWORD height)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!GLEW_EXT_framebuffer_object) {
|
||||||
|
SDL_Log("FBOs are not supported (missing GL_EXT_framebuffer_object)");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!GLEW_EXT_framebuffer_multisample || !GLEW_EXT_framebuffer_blit) {
|
||||||
|
SDL_Log("MSAA not supported (missing GL_EXT_framebuffer_multisample or GL_EXT_framebuffer_blit)");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
glFrontFace(GL_CCW);
|
glFrontFace(GL_CCW);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
|
||||||
// Setup FBO
|
// Create color texture for resolved FBO
|
||||||
GLuint fbo;
|
|
||||||
glGenFramebuffers(1, &fbo);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
|
||||||
|
|
||||||
// Create color texture
|
|
||||||
GLuint colorTex;
|
GLuint colorTex;
|
||||||
glGenTextures(1, &colorTex);
|
glGenTextures(1, &colorTex);
|
||||||
glBindTexture(GL_TEXTURE_2D, colorTex);
|
glBindTexture(GL_TEXTURE_2D, colorTex);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
|
|
||||||
|
|
||||||
// Create depth renderbuffer
|
// Create multisample renderbuffers
|
||||||
GLuint depthRb;
|
GLuint msaaColorRb, msaaDepthRb;
|
||||||
glGenRenderbuffers(1, &depthRb);
|
glGenRenderbuffers(1, &msaaColorRb);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, depthRb);
|
glBindRenderbuffer(GL_RENDERBUFFER, msaaColorRb);
|
||||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_RGBA8, width, height);
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, depthRb);
|
|
||||||
|
glGenRenderbuffers(1, &msaaDepthRb);
|
||||||
|
glBindRenderbuffer(GL_RENDERBUFFER, msaaDepthRb);
|
||||||
|
glRenderbufferStorageMultisample(GL_RENDERBUFFER, 8, GL_DEPTH_COMPONENT24, width, height);
|
||||||
|
|
||||||
|
// Create FBO for resolved (non-MSAA) rendering target
|
||||||
|
GLuint fbo;
|
||||||
|
glGenFramebuffers(1, &fbo);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
|
||||||
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
|
||||||
|
// No depth buffer needed here for resolve FBO
|
||||||
|
|
||||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
if (testWindow) {
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create MSAA FBO for actual rendering
|
||||||
|
GLuint msaaFBO;
|
||||||
|
glGenFramebuffers(1, &msaaFBO);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, msaaFBO);
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, msaaColorRb);
|
||||||
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, msaaDepthRb);
|
||||||
|
|
||||||
|
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||||
|
if (testWindow) {
|
||||||
|
SDL_DestroyWindow(window);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind FBO
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
if (testWindow) {
|
if (testWindow) {
|
||||||
SDL_DestroyWindow(window);
|
SDL_DestroyWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new OpenGL15Renderer(width, height, context, fbo, colorTex, depthRb);
|
return new OpenGL15Renderer(width, height, context, fbo, msaaFBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGL15Renderer::OpenGL15Renderer(
|
OpenGL15Renderer::OpenGL15Renderer(int width, int height, SDL_GLContext context, GLuint fbo, GLuint msaaFBO)
|
||||||
int width,
|
: m_width(width), m_height(height), m_context(context), m_fbo(fbo), m_msaaFBO(msaaFBO)
|
||||||
int height,
|
|
||||||
SDL_GLContext context,
|
|
||||||
GLuint fbo,
|
|
||||||
GLuint colorTex,
|
|
||||||
GLuint depthRb
|
|
||||||
)
|
|
||||||
: m_width(width), m_height(height), m_context(context), m_fbo(fbo), m_colorTex(colorTex), m_depthRb(depthRb)
|
|
||||||
{
|
{
|
||||||
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_ABGR8888);
|
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_ABGR8888);
|
||||||
}
|
}
|
||||||
@ -95,6 +123,14 @@ OpenGL15Renderer::~OpenGL15Renderer()
|
|||||||
if (m_renderedImage) {
|
if (m_renderedImage) {
|
||||||
SDL_DestroySurface(m_renderedImage);
|
SDL_DestroySurface(m_renderedImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_fbo) {
|
||||||
|
glDeleteFramebuffers(1, &m_fbo);
|
||||||
|
}
|
||||||
|
if (m_msaaFBO) {
|
||||||
|
glDeleteFramebuffers(1, &m_msaaFBO);
|
||||||
|
}
|
||||||
|
// You may also want to delete textures and renderbuffers similarly if you keep references to them.
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGL15Renderer::PushLights(const SceneLight* lightsArray, size_t count)
|
void OpenGL15Renderer::PushLights(const SceneLight* lightsArray, size_t count)
|
||||||
@ -227,7 +263,7 @@ HRESULT OpenGL15Renderer::BeginFrame(const D3DRMMATRIX4D& viewMatrix)
|
|||||||
memcpy(m_viewMatrix, viewMatrix, sizeof(D3DRMMATRIX4D));
|
memcpy(m_viewMatrix, viewMatrix, sizeof(D3DRMMATRIX4D));
|
||||||
|
|
||||||
SDL_GL_MakeCurrent(DDWindow, m_context);
|
SDL_GL_MakeCurrent(DDWindow, m_context);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_msaaFBO);
|
||||||
glViewport(0, 0, m_width, m_height);
|
glViewport(0, 0, m_width, m_height);
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
@ -365,10 +401,19 @@ void OpenGL15Renderer::SubmitDraw(
|
|||||||
|
|
||||||
HRESULT OpenGL15Renderer::FinalizeFrame()
|
HRESULT OpenGL15Renderer::FinalizeFrame()
|
||||||
{
|
{
|
||||||
|
// Resolve multisampled FBO into resolved FBO (texture)
|
||||||
|
glBindFramebuffer(GL_READ_FRAMEBUFFER, m_msaaFBO);
|
||||||
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo);
|
||||||
|
glBlitFramebuffer(0, 0, m_width, m_height, 0, 0, m_width, m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||||
|
|
||||||
|
// Read pixels from resolved FBO (texture)
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_renderedImage->pixels);
|
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_renderedImage->pixels);
|
||||||
|
|
||||||
|
// Unbind framebuffer to avoid side effects
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
// Composite onto SDL backbuffer
|
// Copy the pixels to SDL backbuffer surface
|
||||||
SDL_BlitSurface(m_renderedImage, nullptr, DDBackBuffer, nullptr);
|
SDL_BlitSurface(m_renderedImage, nullptr, DDBackBuffer, nullptr);
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
|
|||||||
@ -19,7 +19,7 @@ struct GLTextureCacheEntry {
|
|||||||
class OpenGL15Renderer : public Direct3DRMRenderer {
|
class OpenGL15Renderer : public Direct3DRMRenderer {
|
||||||
public:
|
public:
|
||||||
static Direct3DRMRenderer* Create(DWORD width, DWORD height);
|
static Direct3DRMRenderer* Create(DWORD width, DWORD height);
|
||||||
OpenGL15Renderer(int width, int height, SDL_GLContext context, GLuint fbo, GLuint colorTex, GLuint depthRb);
|
OpenGL15Renderer(int width, int height, SDL_GLContext context, GLuint fbo, GLuint msaaFBO);
|
||||||
~OpenGL15Renderer() override;
|
~OpenGL15Renderer() override;
|
||||||
void PushLights(const SceneLight* lightsArray, size_t count) override;
|
void PushLights(const SceneLight* lightsArray, size_t count) override;
|
||||||
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
|
void SetProjection(const D3DRMMATRIX4D& projection, D3DVALUE front, D3DVALUE back) override;
|
||||||
@ -48,8 +48,7 @@ class OpenGL15Renderer : public Direct3DRMRenderer {
|
|||||||
std::vector<SceneLight> m_lights;
|
std::vector<SceneLight> m_lights;
|
||||||
SDL_GLContext m_context;
|
SDL_GLContext m_context;
|
||||||
GLuint m_fbo = 0;
|
GLuint m_fbo = 0;
|
||||||
GLuint m_colorTex = 0;
|
GLuint m_msaaFBO = 0;
|
||||||
GLuint m_depthRb = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline static void OpenGL15Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
inline static void OpenGL15Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user