This commit is contained in:
Christian Semmler 2025-07-22 16:19:35 -07:00
parent e86fd71560
commit 11316f5699
No known key found for this signature in database
GPG Key ID: 086DAA1360BEEE5C
19 changed files with 195 additions and 36 deletions

View File

@ -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()

View File

@ -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) {

View File

@ -111,6 +111,7 @@ class IsleApp {
MxS32 m_yRes;
MxFloat m_frameRate;
MxBool m_exclusiveFullScreen;
MxU32 m_msaaSamples;
};
extern IsleApp* g_isle;

View File

@ -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;

View File

@ -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;
}

View File

@ -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

View File

@ -91,7 +91,8 @@ BOOL MxDirectDraw::Create(
int height,
int bpp,
const PALETTEENTRY* pPaletteEntries,
int paletteEntryCount
int paletteEntryCount,
DWORD msaaSamples
)
{
assert(m_currentDevInfo);

View File

@ -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

View File

@ -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));

View File

@ -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

View File

@ -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;
}

View 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;
};

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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);