mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-02-02 20:11:15 +00:00
MSAA WIP
This commit is contained in:
parent
e86fd71560
commit
11316f5699
@ -14,7 +14,7 @@ endif()
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
add_compile_options(-pthread)
|
||||
add_link_options(-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sOFFSCREENCANVAS_SUPPORT=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1)
|
||||
add_link_options(-sUSE_WEBGL2=1 -sMIN_WEBGL_VERSION=2 -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sOFFSCREENCANVAS_SUPPORT=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1)
|
||||
set(SDL_PTHREADS ON CACHE BOOL "Enable SDL pthreads" FORCE)
|
||||
endif()
|
||||
|
||||
|
||||
@ -179,6 +179,7 @@ IsleApp::IsleApp()
|
||||
m_yRes = 480;
|
||||
m_frameRate = 100.0f;
|
||||
m_exclusiveFullScreen = FALSE;
|
||||
m_msaaSamples = 0;
|
||||
}
|
||||
|
||||
// FUNCTION: ISLE 0x4011a0
|
||||
@ -912,6 +913,11 @@ MxResult IsleApp::SetupWindow()
|
||||
|
||||
window = SDL_CreateWindowWithProperties(props);
|
||||
|
||||
SDL_SetPointerProperty(SDL_GetWindowProperties(window), ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM, &m_videoParam);
|
||||
MxVideoParam* p = (MxVideoParam*)
|
||||
SDL_GetPointerProperty(SDL_GetWindowProperties(window), ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM, nullptr);
|
||||
SDL_Log("MSAA WINDOW: %p %d", p, (p)->GetMSAASamples());
|
||||
|
||||
if (m_exclusiveFullScreen && m_fullScreen) {
|
||||
SDL_DisplayMode closestMode;
|
||||
SDL_DisplayID displayID = SDL_GetDisplayForWindow(window);
|
||||
@ -1172,6 +1178,7 @@ bool IsleApp::LoadConfig()
|
||||
}
|
||||
m_frameRate = (1000.0f / iniparser_getdouble(dict, "isle:Frame Delta", m_frameDelta));
|
||||
m_frameDelta = static_cast<int>(std::round(iniparser_getdouble(dict, "isle:Frame Delta", m_frameDelta)));
|
||||
m_videoParam.SetMSAASamples(iniparser_getint(dict, "isle:MSAA", m_msaaSamples));
|
||||
|
||||
const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL);
|
||||
if (deviceId != NULL) {
|
||||
|
||||
@ -111,6 +111,7 @@ class IsleApp {
|
||||
MxS32 m_yRes;
|
||||
MxFloat m_frameRate;
|
||||
MxBool m_exclusiveFullScreen;
|
||||
MxU32 m_msaaSamples;
|
||||
};
|
||||
|
||||
extern IsleApp* g_isle;
|
||||
|
||||
@ -148,7 +148,8 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM
|
||||
p_videoParam.GetRect().GetHeight(),
|
||||
bits,
|
||||
paletteEntries,
|
||||
sizeof(paletteEntries) / sizeof(paletteEntries[0])
|
||||
sizeof(paletteEntries) / sizeof(paletteEntries[0]),
|
||||
p_videoParam.GetMSAASamples()
|
||||
)) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDirect3D::Create failed");
|
||||
goto done;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include <SDL3/SDL.h> // for SDL_Log
|
||||
#include <assert.h>
|
||||
#include <miniwin/miniwind3d.h>
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxDirect3D, 0x894)
|
||||
|
||||
@ -40,10 +41,12 @@ BOOL MxDirect3D::Create(
|
||||
int height,
|
||||
int bpp,
|
||||
const PALETTEENTRY* pPaletteEntries,
|
||||
int paletteEntryCount
|
||||
int paletteEntryCount,
|
||||
DWORD msaaSamples
|
||||
)
|
||||
{
|
||||
BOOL success = FALSE;
|
||||
IDirect3DMiniwin* miniwind3d = nullptr;
|
||||
assert(m_currentDeviceInfo);
|
||||
|
||||
if (!MxDirectDraw::Create(
|
||||
@ -55,7 +58,8 @@ BOOL MxDirect3D::Create(
|
||||
height,
|
||||
bpp,
|
||||
pPaletteEntries,
|
||||
paletteEntryCount
|
||||
paletteEntryCount,
|
||||
msaaSamples
|
||||
)) {
|
||||
goto done;
|
||||
}
|
||||
@ -64,6 +68,10 @@ BOOL MxDirect3D::Create(
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (msaaSamples && m_pDirect3d->QueryInterface(IID_IDirect3DMiniwin, (void**) &miniwind3d) == S_OK) {
|
||||
miniwind3d->RequestMSAA(msaaSamples);
|
||||
}
|
||||
|
||||
if (!D3DSetMode()) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
@ -31,7 +31,8 @@ class MxDirect3D : public MxDirectDraw {
|
||||
int height,
|
||||
int bpp,
|
||||
const PALETTEENTRY* pPaletteEntries,
|
||||
int paletteEntryCount
|
||||
int paletteEntryCount,
|
||||
DWORD msaaSamples
|
||||
) override; // vtable+0x04
|
||||
void Destroy() override; // vtable+0x08
|
||||
void DestroyButNotDirectDraw() override; // vtable+0x0c
|
||||
|
||||
@ -91,7 +91,8 @@ BOOL MxDirectDraw::Create(
|
||||
int height,
|
||||
int bpp,
|
||||
const PALETTEENTRY* pPaletteEntries,
|
||||
int paletteEntryCount
|
||||
int paletteEntryCount,
|
||||
DWORD msaaSamples
|
||||
)
|
||||
{
|
||||
assert(m_currentDevInfo);
|
||||
|
||||
@ -33,7 +33,8 @@ class MxDirectDraw {
|
||||
int height,
|
||||
int bpp,
|
||||
const PALETTEENTRY* pPaletteEntries,
|
||||
int paletteEntryCount
|
||||
int paletteEntryCount,
|
||||
DWORD msaaSamples
|
||||
); // vtable+0x04
|
||||
virtual void Destroy(); // vtable+0x08
|
||||
virtual void DestroyButNotDirectDraw(); // vtable+0x0c
|
||||
|
||||
@ -1,7 +1,10 @@
|
||||
#include "mxdirectxinfo.h"
|
||||
|
||||
#include "mxvideoparam.h"
|
||||
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <assert.h>
|
||||
#include <miniwin/miniwind3d.h>
|
||||
#include <stdio.h> // for vsprintf
|
||||
|
||||
DECOMP_SIZE_ASSERT(MxAssignedDevice, 0xe4)
|
||||
@ -216,12 +219,24 @@ BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc
|
||||
LPDIRECTDRAW lpDD = NULL;
|
||||
MxDriver& newDevice = m_ddInfo.back();
|
||||
HRESULT result = DirectDrawCreate(newDevice.m_guid, &lpDD, NULL);
|
||||
IDirect3DMiniwin* miniwind3d = nullptr;
|
||||
|
||||
if (result != DD_OK) {
|
||||
BuildErrorString("DirectDraw Create failed: %s\n", EnumerateErrorToString(result));
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = lpDD->QueryInterface(IID_IDirect3DMiniwin, (void**) &miniwind3d);
|
||||
if (result == DD_OK) {
|
||||
MxVideoParam* videoParam = (MxVideoParam*) SDL_GetPointerProperty(
|
||||
SDL_GetWindowProperties(reinterpret_cast<SDL_Window*>(m_hWnd)),
|
||||
ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM,
|
||||
nullptr
|
||||
);
|
||||
assert(videoParam);
|
||||
miniwind3d->RequestMSAA(videoParam->GetMSAASamples());
|
||||
}
|
||||
|
||||
result = lpDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);
|
||||
if (result != DD_OK) {
|
||||
BuildErrorString("SetCooperativeLevel failed: %s\n", EnumerateErrorToString(result));
|
||||
@ -243,7 +258,7 @@ BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc
|
||||
goto done;
|
||||
}
|
||||
|
||||
result = lpDirect3d2->EnumDevices(DevicesEnumerateCallback, this);
|
||||
result = lpDirect3d2->EnumDevices(DevicesEnumerateCallback, miniwind3d);
|
||||
|
||||
if (result != DD_OK) {
|
||||
BuildErrorString("D3D enum devices failed: %s\n", EnumerateErrorToString(result));
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
|
||||
class MxPalette;
|
||||
|
||||
#define ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM "ISLE.window.create.videoParam"
|
||||
|
||||
// SIZE 0x24
|
||||
class MxVideoParam {
|
||||
public:
|
||||
@ -51,6 +53,9 @@ class MxVideoParam {
|
||||
// FUNCTION: BETA10 0x10141fe0
|
||||
void SetBackBuffers(MxU32 p_backBuffers) { m_backBuffers = p_backBuffers; }
|
||||
|
||||
void SetMSAASamples(MxU32 p_msaaSamples) { m_msaaSamples = p_msaaSamples; }
|
||||
MxU32 GetMSAASamples() { return m_msaaSamples; }
|
||||
|
||||
private:
|
||||
MxRect32 m_rect; // 0x00
|
||||
MxPalette* m_palette; // 0x10
|
||||
@ -58,6 +63,7 @@ class MxVideoParam {
|
||||
MxVideoParamFlags m_flags; // 0x18
|
||||
int m_unk0x1c; // 0x1c
|
||||
char* m_deviceId; // 0x20
|
||||
MxU32 m_msaaSamples;
|
||||
};
|
||||
|
||||
#endif // MXVIDEOPARAM_H
|
||||
|
||||
@ -28,6 +28,7 @@ MxVideoParam::MxVideoParam(MxRect32& p_rect, MxPalette* p_palette, MxULong p_bac
|
||||
m_flags = p_flags;
|
||||
m_unk0x1c = 0;
|
||||
m_deviceId = NULL;
|
||||
m_msaaSamples = 0;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100becf0
|
||||
@ -41,6 +42,7 @@ MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam)
|
||||
m_unk0x1c = p_videoParam.m_unk0x1c;
|
||||
m_deviceId = NULL;
|
||||
SetDeviceName(p_videoParam.m_deviceId);
|
||||
m_msaaSamples = p_videoParam.m_msaaSamples;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100bed50
|
||||
@ -82,6 +84,7 @@ MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
|
||||
m_flags = p_videoParam.m_flags;
|
||||
m_unk0x1c = p_videoParam.m_unk0x1c;
|
||||
SetDeviceName(p_videoParam.m_deviceId);
|
||||
m_msaaSamples = p_videoParam.m_msaaSamples;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
8
miniwin/include/miniwin/miniwind3d.h
Normal file
8
miniwin/include/miniwin/miniwind3d.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
DEFINE_GUID(IID_IDirect3DMiniwin, 0xf8a97f2d, 0x9b3a, 0x4f1c, 0x9e, 0x8d, 0x6a, 0x5b, 0x4c, 0x3d, 0x2e, 0x1f);
|
||||
|
||||
struct IDirect3DMiniwin : virtual public IUnknown {
|
||||
virtual HRESULT RequestMSAA(DWORD msaaSamples) = 0;
|
||||
virtual DWORD GetMSAASamples() const = 0;
|
||||
};
|
||||
@ -1,8 +1,8 @@
|
||||
#include "d3drmrenderer_opengles2.h"
|
||||
#include "meshutils.h"
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
#include <GLES3/gl3.h>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
@ -28,7 +28,7 @@ struct SceneLightGLES2 {
|
||||
float direction[4];
|
||||
};
|
||||
|
||||
Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
||||
Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height, DWORD msaaSamples)
|
||||
{
|
||||
// We have to reset the attributes here after having enumerated the
|
||||
// OpenGL ES 2.0 renderer, or else SDL gets very confused by SDL_GL_DEPTH_SIZE
|
||||
@ -37,9 +37,14 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
||||
// But ResetAttributes resets it to 16.
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
|
||||
if (msaaSamples > 1) {
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, msaaSamples);
|
||||
}
|
||||
|
||||
if (!DDWindow) {
|
||||
SDL_Log("No window handler");
|
||||
return nullptr;
|
||||
@ -168,7 +173,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
|
||||
return new OpenGLES2Renderer(width, height, context, shaderProgram);
|
||||
return new OpenGLES2Renderer(width, height, msaaSamples, context, shaderProgram);
|
||||
}
|
||||
|
||||
GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = false)
|
||||
@ -278,14 +283,25 @@ bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram)
|
||||
OpenGLES2Renderer::OpenGLES2Renderer(
|
||||
DWORD width,
|
||||
DWORD height,
|
||||
DWORD msaaSamples,
|
||||
SDL_GLContext context,
|
||||
GLuint shaderProgram
|
||||
)
|
||||
: m_context(context), m_shaderProgram(shaderProgram)
|
||||
{
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
|
||||
if (msaaSamples > 1) {
|
||||
glGenFramebuffers(1, &m_msaaFbo);
|
||||
}
|
||||
|
||||
m_virtualWidth = width;
|
||||
m_virtualHeight = height;
|
||||
m_requestedMsaaSamples = msaaSamples;
|
||||
SDL_Log("Requested MSAA %d", m_requestedMsaaSamples);
|
||||
ViewportTransform viewportTransform = {1.0f, 0.0f, 0.0f};
|
||||
Resize(width, height, viewportTransform);
|
||||
|
||||
@ -488,7 +504,7 @@ HRESULT OpenGLES2Renderer::BeginFrame()
|
||||
SDL_GL_MakeCurrent(DDWindow, m_context);
|
||||
m_dirty = true;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_useMsaa ? m_msaaFbo : m_fbo);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glDisable(GL_BLEND);
|
||||
@ -610,6 +626,52 @@ void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& v
|
||||
}
|
||||
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32);
|
||||
|
||||
if (m_colorTarget) {
|
||||
glDeleteTextures(1, &m_colorTarget);
|
||||
}
|
||||
if (m_depthTarget) {
|
||||
glDeleteRenderbuffers(1, &m_depthTarget);
|
||||
}
|
||||
if (m_msaaColorRbo) {
|
||||
glDeleteRenderbuffers(1, &m_msaaColorRbo);
|
||||
}
|
||||
if (m_msaaDepthRbo) {
|
||||
glDeleteRenderbuffers(1, &m_msaaDepthRbo);
|
||||
}
|
||||
m_colorTarget = m_depthTarget = m_msaaColorRbo = m_msaaDepthRbo = 0;
|
||||
|
||||
GLint samples;
|
||||
glGetIntegerv(GL_SAMPLES, &samples);
|
||||
m_useMsaa = samples > 1;
|
||||
|
||||
if (m_useMsaa) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_msaaFbo);
|
||||
|
||||
glGenRenderbuffers(1, &m_msaaColorRbo);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_msaaColorRbo);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_RGBA8, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, m_msaaColorRbo);
|
||||
|
||||
glGenRenderbuffers(1, &m_msaaDepthRbo);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_msaaDepthRbo);
|
||||
glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, GL_DEPTH24_STENCIL8, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_msaaDepthRbo);
|
||||
|
||||
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
|
||||
SDL_Log("MSAA Framebuffer is not complete! Disabling MSAA.");
|
||||
m_useMsaa = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_useMsaa) {
|
||||
GLint max_samples;
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &max_samples);
|
||||
SDL_Log("MSAA: ON! samples %d max samples %d", samples, max_samples);
|
||||
}
|
||||
else {
|
||||
SDL_Log("MSAA: OFF! %d %d", samples, m_requestedMsaaSamples);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
|
||||
// Create color texture
|
||||
@ -625,16 +687,7 @@ void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& v
|
||||
// Create depth renderbuffer
|
||||
glGenRenderbuffers(1, &m_depthTarget);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_depthTarget);
|
||||
|
||||
if (SDL_GL_ExtensionSupported("GL_OES_depth24")) {
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES, width, height);
|
||||
}
|
||||
else if (SDL_GL_ExtensionSupported("GL_OES_depth32")) {
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT32_OES, width, height);
|
||||
}
|
||||
else {
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
|
||||
}
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthTarget);
|
||||
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
@ -645,7 +698,7 @@ void OpenGLES2Renderer::Clear(float r, float g, float b)
|
||||
SDL_GL_MakeCurrent(DDWindow, m_context);
|
||||
m_dirty = true;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_useMsaa ? m_msaaFbo : m_fbo);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
@ -660,6 +713,12 @@ void OpenGLES2Renderer::Flip()
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_useMsaa) {
|
||||
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);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@ -722,7 +781,7 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c
|
||||
SDL_GL_MakeCurrent(DDWindow, m_context);
|
||||
m_dirty = true;
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_useMsaa ? m_msaaFbo : m_fbo);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_FALSE);
|
||||
@ -809,6 +868,12 @@ void OpenGLES2Renderer::Download(SDL_Surface* target)
|
||||
{
|
||||
glFinish();
|
||||
|
||||
if (m_useMsaa) {
|
||||
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);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_renderedImage->pixels);
|
||||
|
||||
|
||||
@ -132,7 +132,11 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface(
|
||||
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
|
||||
surface->GetSurfaceDesc(&DDSDesc);
|
||||
|
||||
DDRenderer = CreateDirect3DRMRenderer(DDSDesc, guid);
|
||||
IDirect3DMiniwin* miniwind3d = nullptr;
|
||||
miniwind3d->QueryInterface(IID_IDirect3DMiniwin, (void**) &miniwind3d);
|
||||
SDL_assert(miniwind3d);
|
||||
|
||||
DDRenderer = CreateDirect3DRMRenderer(miniwind3d, DDSDesc, guid);
|
||||
if (!DDRenderer) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized");
|
||||
return E_NOINTERFACE;
|
||||
|
||||
@ -18,7 +18,11 @@
|
||||
#include "d3drmrenderer_software.h"
|
||||
#endif
|
||||
|
||||
Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const GUID* guid)
|
||||
Direct3DRMRenderer* CreateDirect3DRMRenderer(
|
||||
const IDirect3DMiniwin* d3d,
|
||||
const DDSURFACEDESC& DDSDesc,
|
||||
const GUID* guid
|
||||
)
|
||||
{
|
||||
#ifdef USE_SDL_GPU
|
||||
if (SDL_memcmp(guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) {
|
||||
@ -32,7 +36,7 @@ Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const
|
||||
#endif
|
||||
#ifdef USE_OPENGLES2
|
||||
if (SDL_memcmp(guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) {
|
||||
return OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
|
||||
return OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight, d3d->GetMSAASamples());
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_OPENGL1
|
||||
|
||||
@ -29,6 +29,11 @@ HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject)
|
||||
*ppvObject = static_cast<IDirect3D2*>(this);
|
||||
return S_OK;
|
||||
}
|
||||
if (SDL_memcmp(&riid, &IID_IDirect3DMiniwin, sizeof(GUID)) == 0) {
|
||||
this->IUnknown::AddRef();
|
||||
*ppvObject = static_cast<IDirect3DMiniwin*>(this);
|
||||
return S_OK;
|
||||
}
|
||||
MINIWIN_NOT_IMPLEMENTED();
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
@ -317,7 +322,7 @@ HRESULT DirectDrawImpl::CreateDevice(
|
||||
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
|
||||
pBackBuffer->GetSurfaceDesc(&DDSDesc);
|
||||
|
||||
DDRenderer = CreateDirect3DRMRenderer(DDSDesc, &guid);
|
||||
DDRenderer = CreateDirect3DRMRenderer(this, DDSDesc, &guid);
|
||||
if (!DDRenderer) {
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized");
|
||||
return E_NOINTERFACE;
|
||||
@ -326,6 +331,17 @@ HRESULT DirectDrawImpl::CreateDevice(
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
HRESULT DirectDrawImpl::RequestMSAA(DWORD msaaSamples)
|
||||
{
|
||||
m_msaaSamples = msaaSamples;
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
DWORD DirectDrawImpl::GetMSAASamples() const
|
||||
{
|
||||
return m_msaaSamples;
|
||||
}
|
||||
|
||||
HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context)
|
||||
{
|
||||
const char* driverName = SDL_GetCurrentVideoDriver();
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "d3drmmesh_impl.h"
|
||||
#include "mathutils.h"
|
||||
#include "miniwin/d3drm.h"
|
||||
#include "miniwin/miniwind3d.h"
|
||||
#include "miniwin/miniwindevice.h"
|
||||
#include "structs.h"
|
||||
|
||||
@ -61,5 +62,9 @@ class Direct3DRMRenderer : public IDirect3DDevice2 {
|
||||
ViewportTransform m_viewportTransform;
|
||||
};
|
||||
|
||||
Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const GUID* guid);
|
||||
Direct3DRMRenderer* CreateDirect3DRMRenderer(
|
||||
const IDirect3DMiniwin* d3d,
|
||||
const DDSURFACEDESC& DDSDesc,
|
||||
const GUID* guid
|
||||
);
|
||||
void Direct3DRMRenderer_EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx);
|
||||
|
||||
@ -32,8 +32,8 @@ struct GLES2MeshCacheEntry {
|
||||
|
||||
class OpenGLES2Renderer : public Direct3DRMRenderer {
|
||||
public:
|
||||
static Direct3DRMRenderer* Create(DWORD width, DWORD height);
|
||||
OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram);
|
||||
static Direct3DRMRenderer* Create(DWORD width, DWORD height, DWORD msaaSamples);
|
||||
OpenGLES2Renderer(DWORD width, DWORD height, DWORD msaaSamples, SDL_GLContext context, GLuint shaderProgram);
|
||||
~OpenGLES2Renderer() override;
|
||||
|
||||
void PushLights(const SceneLight* lightsArray, size_t count) override;
|
||||
@ -72,7 +72,12 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
|
||||
bool m_dirty = false;
|
||||
std::vector<SceneLight> m_lights;
|
||||
SDL_GLContext m_context;
|
||||
uint32_t m_requestedMsaaSamples;
|
||||
bool m_useMsaa;
|
||||
GLuint m_fbo;
|
||||
GLuint m_msaaFbo;
|
||||
GLuint m_msaaColorRbo;
|
||||
GLuint m_msaaDepthRbo;
|
||||
GLuint m_colorTarget;
|
||||
GLuint m_depthTarget;
|
||||
GLuint m_shaderProgram;
|
||||
@ -94,7 +99,10 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
|
||||
|
||||
inline static void OpenGLES2Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
||||
{
|
||||
Direct3DRMRenderer* device = OpenGLES2Renderer::Create(640, 480);
|
||||
IDirect3DMiniwin* miniwind3d = reinterpret_cast<IDirect3DMiniwin*>(ctx);
|
||||
SDL_assert(miniwind3d);
|
||||
|
||||
Direct3DRMRenderer* device = OpenGLES2Renderer::Create(640, 480, miniwind3d->GetMSAASamples());
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "framebuffer_impl.h"
|
||||
#include "miniwin/d3d.h"
|
||||
#include "miniwin/ddraw.h"
|
||||
#include "miniwin/miniwind3d.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
@ -15,7 +16,7 @@ inline static SDL_Rect ConvertRect(const RECT* r)
|
||||
return {r->left, r->top, r->right - r->left, r->bottom - r->top};
|
||||
}
|
||||
|
||||
struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
|
||||
struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2, public IDirect3DMiniwin {
|
||||
// IUnknown interface
|
||||
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
|
||||
// IDirectDraw interface
|
||||
@ -45,11 +46,15 @@ struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
|
||||
HRESULT CreateDevice(const GUID& guid, IDirectDrawSurface* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice)
|
||||
override;
|
||||
HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) override;
|
||||
// IDirect3DMiniwin interface
|
||||
HRESULT RequestMSAA(DWORD msaaSamples) override;
|
||||
DWORD GetMSAASamples() const override;
|
||||
|
||||
private:
|
||||
FrameBufferImpl* m_frameBuffer;
|
||||
int m_virtualWidth = 0;
|
||||
int m_virtualHeight = 0;
|
||||
DWORD m_msaaSamples = 0;
|
||||
};
|
||||
|
||||
HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user