mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-02-03 12:31:15 +00:00
MSAA WIP
This commit is contained in:
parent
e86fd71560
commit
11316f5699
@ -14,7 +14,7 @@ endif()
|
|||||||
|
|
||||||
if (EMSCRIPTEN)
|
if (EMSCRIPTEN)
|
||||||
add_compile_options(-pthread)
|
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)
|
set(SDL_PTHREADS ON CACHE BOOL "Enable SDL pthreads" FORCE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@ -179,6 +179,7 @@ IsleApp::IsleApp()
|
|||||||
m_yRes = 480;
|
m_yRes = 480;
|
||||||
m_frameRate = 100.0f;
|
m_frameRate = 100.0f;
|
||||||
m_exclusiveFullScreen = FALSE;
|
m_exclusiveFullScreen = FALSE;
|
||||||
|
m_msaaSamples = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: ISLE 0x4011a0
|
// FUNCTION: ISLE 0x4011a0
|
||||||
@ -912,6 +913,11 @@ MxResult IsleApp::SetupWindow()
|
|||||||
|
|
||||||
window = SDL_CreateWindowWithProperties(props);
|
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) {
|
if (m_exclusiveFullScreen && m_fullScreen) {
|
||||||
SDL_DisplayMode closestMode;
|
SDL_DisplayMode closestMode;
|
||||||
SDL_DisplayID displayID = SDL_GetDisplayForWindow(window);
|
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_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_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);
|
const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL);
|
||||||
if (deviceId != NULL) {
|
if (deviceId != NULL) {
|
||||||
|
|||||||
@ -111,6 +111,7 @@ class IsleApp {
|
|||||||
MxS32 m_yRes;
|
MxS32 m_yRes;
|
||||||
MxFloat m_frameRate;
|
MxFloat m_frameRate;
|
||||||
MxBool m_exclusiveFullScreen;
|
MxBool m_exclusiveFullScreen;
|
||||||
|
MxU32 m_msaaSamples;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern IsleApp* g_isle;
|
extern IsleApp* g_isle;
|
||||||
|
|||||||
@ -148,7 +148,8 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM
|
|||||||
p_videoParam.GetRect().GetHeight(),
|
p_videoParam.GetRect().GetHeight(),
|
||||||
bits,
|
bits,
|
||||||
paletteEntries,
|
paletteEntries,
|
||||||
sizeof(paletteEntries) / sizeof(paletteEntries[0])
|
sizeof(paletteEntries) / sizeof(paletteEntries[0]),
|
||||||
|
p_videoParam.GetMSAASamples()
|
||||||
)) {
|
)) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDirect3D::Create failed");
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "MxDirect3D::Create failed");
|
||||||
goto done;
|
goto done;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <SDL3/SDL.h> // for SDL_Log
|
#include <SDL3/SDL.h> // for SDL_Log
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <miniwin/miniwind3d.h>
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(MxDirect3D, 0x894)
|
DECOMP_SIZE_ASSERT(MxDirect3D, 0x894)
|
||||||
|
|
||||||
@ -40,10 +41,12 @@ BOOL MxDirect3D::Create(
|
|||||||
int height,
|
int height,
|
||||||
int bpp,
|
int bpp,
|
||||||
const PALETTEENTRY* pPaletteEntries,
|
const PALETTEENTRY* pPaletteEntries,
|
||||||
int paletteEntryCount
|
int paletteEntryCount,
|
||||||
|
DWORD msaaSamples
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
BOOL success = FALSE;
|
BOOL success = FALSE;
|
||||||
|
IDirect3DMiniwin* miniwind3d = nullptr;
|
||||||
assert(m_currentDeviceInfo);
|
assert(m_currentDeviceInfo);
|
||||||
|
|
||||||
if (!MxDirectDraw::Create(
|
if (!MxDirectDraw::Create(
|
||||||
@ -55,7 +58,8 @@ BOOL MxDirect3D::Create(
|
|||||||
height,
|
height,
|
||||||
bpp,
|
bpp,
|
||||||
pPaletteEntries,
|
pPaletteEntries,
|
||||||
paletteEntryCount
|
paletteEntryCount,
|
||||||
|
msaaSamples
|
||||||
)) {
|
)) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@ -64,6 +68,10 @@ BOOL MxDirect3D::Create(
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msaaSamples && m_pDirect3d->QueryInterface(IID_IDirect3DMiniwin, (void**) &miniwind3d) == S_OK) {
|
||||||
|
miniwind3d->RequestMSAA(msaaSamples);
|
||||||
|
}
|
||||||
|
|
||||||
if (!D3DSetMode()) {
|
if (!D3DSetMode()) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,8 @@ class MxDirect3D : public MxDirectDraw {
|
|||||||
int height,
|
int height,
|
||||||
int bpp,
|
int bpp,
|
||||||
const PALETTEENTRY* pPaletteEntries,
|
const PALETTEENTRY* pPaletteEntries,
|
||||||
int paletteEntryCount
|
int paletteEntryCount,
|
||||||
|
DWORD msaaSamples
|
||||||
) override; // vtable+0x04
|
) override; // vtable+0x04
|
||||||
void Destroy() override; // vtable+0x08
|
void Destroy() override; // vtable+0x08
|
||||||
void DestroyButNotDirectDraw() override; // vtable+0x0c
|
void DestroyButNotDirectDraw() override; // vtable+0x0c
|
||||||
|
|||||||
@ -91,7 +91,8 @@ BOOL MxDirectDraw::Create(
|
|||||||
int height,
|
int height,
|
||||||
int bpp,
|
int bpp,
|
||||||
const PALETTEENTRY* pPaletteEntries,
|
const PALETTEENTRY* pPaletteEntries,
|
||||||
int paletteEntryCount
|
int paletteEntryCount,
|
||||||
|
DWORD msaaSamples
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
assert(m_currentDevInfo);
|
assert(m_currentDevInfo);
|
||||||
|
|||||||
@ -33,7 +33,8 @@ class MxDirectDraw {
|
|||||||
int height,
|
int height,
|
||||||
int bpp,
|
int bpp,
|
||||||
const PALETTEENTRY* pPaletteEntries,
|
const PALETTEENTRY* pPaletteEntries,
|
||||||
int paletteEntryCount
|
int paletteEntryCount,
|
||||||
|
DWORD msaaSamples
|
||||||
); // vtable+0x04
|
); // vtable+0x04
|
||||||
virtual void Destroy(); // vtable+0x08
|
virtual void Destroy(); // vtable+0x08
|
||||||
virtual void DestroyButNotDirectDraw(); // vtable+0x0c
|
virtual void DestroyButNotDirectDraw(); // vtable+0x0c
|
||||||
|
|||||||
@ -1,7 +1,10 @@
|
|||||||
#include "mxdirectxinfo.h"
|
#include "mxdirectxinfo.h"
|
||||||
|
|
||||||
|
#include "mxvideoparam.h"
|
||||||
|
|
||||||
#include <SDL3/SDL_log.h>
|
#include <SDL3/SDL_log.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <miniwin/miniwind3d.h>
|
||||||
#include <stdio.h> // for vsprintf
|
#include <stdio.h> // for vsprintf
|
||||||
|
|
||||||
DECOMP_SIZE_ASSERT(MxAssignedDevice, 0xe4)
|
DECOMP_SIZE_ASSERT(MxAssignedDevice, 0xe4)
|
||||||
@ -216,12 +219,24 @@ BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc
|
|||||||
LPDIRECTDRAW lpDD = NULL;
|
LPDIRECTDRAW lpDD = NULL;
|
||||||
MxDriver& newDevice = m_ddInfo.back();
|
MxDriver& newDevice = m_ddInfo.back();
|
||||||
HRESULT result = DirectDrawCreate(newDevice.m_guid, &lpDD, NULL);
|
HRESULT result = DirectDrawCreate(newDevice.m_guid, &lpDD, NULL);
|
||||||
|
IDirect3DMiniwin* miniwind3d = nullptr;
|
||||||
|
|
||||||
if (result != DD_OK) {
|
if (result != DD_OK) {
|
||||||
BuildErrorString("DirectDraw Create failed: %s\n", EnumerateErrorToString(result));
|
BuildErrorString("DirectDraw Create failed: %s\n", EnumerateErrorToString(result));
|
||||||
goto done;
|
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);
|
result = lpDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);
|
||||||
if (result != DD_OK) {
|
if (result != DD_OK) {
|
||||||
BuildErrorString("SetCooperativeLevel failed: %s\n", EnumerateErrorToString(result));
|
BuildErrorString("SetCooperativeLevel failed: %s\n", EnumerateErrorToString(result));
|
||||||
@ -243,7 +258,7 @@ BOOL MxDeviceEnumerate::EnumDirectDrawCallback(LPGUID p_guid, LPSTR p_driverDesc
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = lpDirect3d2->EnumDevices(DevicesEnumerateCallback, this);
|
result = lpDirect3d2->EnumDevices(DevicesEnumerateCallback, miniwind3d);
|
||||||
|
|
||||||
if (result != DD_OK) {
|
if (result != DD_OK) {
|
||||||
BuildErrorString("D3D enum devices failed: %s\n", EnumerateErrorToString(result));
|
BuildErrorString("D3D enum devices failed: %s\n", EnumerateErrorToString(result));
|
||||||
|
|||||||
@ -15,6 +15,8 @@
|
|||||||
|
|
||||||
class MxPalette;
|
class MxPalette;
|
||||||
|
|
||||||
|
#define ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM "ISLE.window.create.videoParam"
|
||||||
|
|
||||||
// SIZE 0x24
|
// SIZE 0x24
|
||||||
class MxVideoParam {
|
class MxVideoParam {
|
||||||
public:
|
public:
|
||||||
@ -51,6 +53,9 @@ class MxVideoParam {
|
|||||||
// FUNCTION: BETA10 0x10141fe0
|
// FUNCTION: BETA10 0x10141fe0
|
||||||
void SetBackBuffers(MxU32 p_backBuffers) { m_backBuffers = p_backBuffers; }
|
void SetBackBuffers(MxU32 p_backBuffers) { m_backBuffers = p_backBuffers; }
|
||||||
|
|
||||||
|
void SetMSAASamples(MxU32 p_msaaSamples) { m_msaaSamples = p_msaaSamples; }
|
||||||
|
MxU32 GetMSAASamples() { return m_msaaSamples; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MxRect32 m_rect; // 0x00
|
MxRect32 m_rect; // 0x00
|
||||||
MxPalette* m_palette; // 0x10
|
MxPalette* m_palette; // 0x10
|
||||||
@ -58,6 +63,7 @@ class MxVideoParam {
|
|||||||
MxVideoParamFlags m_flags; // 0x18
|
MxVideoParamFlags m_flags; // 0x18
|
||||||
int m_unk0x1c; // 0x1c
|
int m_unk0x1c; // 0x1c
|
||||||
char* m_deviceId; // 0x20
|
char* m_deviceId; // 0x20
|
||||||
|
MxU32 m_msaaSamples;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // MXVIDEOPARAM_H
|
#endif // MXVIDEOPARAM_H
|
||||||
|
|||||||
@ -28,6 +28,7 @@ MxVideoParam::MxVideoParam(MxRect32& p_rect, MxPalette* p_palette, MxULong p_bac
|
|||||||
m_flags = p_flags;
|
m_flags = p_flags;
|
||||||
m_unk0x1c = 0;
|
m_unk0x1c = 0;
|
||||||
m_deviceId = NULL;
|
m_deviceId = NULL;
|
||||||
|
m_msaaSamples = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x100becf0
|
// FUNCTION: LEGO1 0x100becf0
|
||||||
@ -41,6 +42,7 @@ MxVideoParam::MxVideoParam(MxVideoParam& p_videoParam)
|
|||||||
m_unk0x1c = p_videoParam.m_unk0x1c;
|
m_unk0x1c = p_videoParam.m_unk0x1c;
|
||||||
m_deviceId = NULL;
|
m_deviceId = NULL;
|
||||||
SetDeviceName(p_videoParam.m_deviceId);
|
SetDeviceName(p_videoParam.m_deviceId);
|
||||||
|
m_msaaSamples = p_videoParam.m_msaaSamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FUNCTION: LEGO1 0x100bed50
|
// FUNCTION: LEGO1 0x100bed50
|
||||||
@ -82,6 +84,7 @@ MxVideoParam& MxVideoParam::operator=(const MxVideoParam& p_videoParam)
|
|||||||
m_flags = p_videoParam.m_flags;
|
m_flags = p_videoParam.m_flags;
|
||||||
m_unk0x1c = p_videoParam.m_unk0x1c;
|
m_unk0x1c = p_videoParam.m_unk0x1c;
|
||||||
SetDeviceName(p_videoParam.m_deviceId);
|
SetDeviceName(p_videoParam.m_deviceId);
|
||||||
|
m_msaaSamples = p_videoParam.m_msaaSamples;
|
||||||
|
|
||||||
return *this;
|
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 "d3drmrenderer_opengles2.h"
|
||||||
#include "meshutils.h"
|
#include "meshutils.h"
|
||||||
|
|
||||||
#include <GLES2/gl2.h>
|
|
||||||
#include <GLES2/gl2ext.h>
|
#include <GLES2/gl2ext.h>
|
||||||
|
#include <GLES3/gl3.h>
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -28,7 +28,7 @@ struct SceneLightGLES2 {
|
|||||||
float direction[4];
|
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
|
// 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
|
// 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.
|
// But ResetAttributes resets it to 16.
|
||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
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_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);
|
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) {
|
if (!DDWindow) {
|
||||||
SDL_Log("No window handler");
|
SDL_Log("No window handler");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -168,7 +173,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
|||||||
glDeleteShader(vs);
|
glDeleteShader(vs);
|
||||||
glDeleteShader(fs);
|
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)
|
GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = false)
|
||||||
@ -278,14 +283,25 @@ bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
|
|||||||
return true;
|
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)
|
: m_context(context), m_shaderProgram(shaderProgram)
|
||||||
{
|
{
|
||||||
glGenFramebuffers(1, &m_fbo);
|
glGenFramebuffers(1, &m_fbo);
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
|
||||||
|
if (msaaSamples > 1) {
|
||||||
|
glGenFramebuffers(1, &m_msaaFbo);
|
||||||
|
}
|
||||||
|
|
||||||
m_virtualWidth = width;
|
m_virtualWidth = width;
|
||||||
m_virtualHeight = height;
|
m_virtualHeight = height;
|
||||||
|
m_requestedMsaaSamples = msaaSamples;
|
||||||
|
SDL_Log("Requested MSAA %d", m_requestedMsaaSamples);
|
||||||
ViewportTransform viewportTransform = {1.0f, 0.0f, 0.0f};
|
ViewportTransform viewportTransform = {1.0f, 0.0f, 0.0f};
|
||||||
Resize(width, height, viewportTransform);
|
Resize(width, height, viewportTransform);
|
||||||
|
|
||||||
@ -488,7 +504,7 @@ HRESULT OpenGLES2Renderer::BeginFrame()
|
|||||||
SDL_GL_MakeCurrent(DDWindow, m_context);
|
SDL_GL_MakeCurrent(DDWindow, m_context);
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_useMsaa ? m_msaaFbo : m_fbo);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glDisable(GL_BLEND);
|
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);
|
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);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
|
|
||||||
// Create color texture
|
// Create color texture
|
||||||
@ -625,16 +687,7 @@ void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& v
|
|||||||
// Create depth renderbuffer
|
// Create depth renderbuffer
|
||||||
glGenRenderbuffers(1, &m_depthTarget);
|
glGenRenderbuffers(1, &m_depthTarget);
|
||||||
glBindRenderbuffer(GL_RENDERBUFFER, m_depthTarget);
|
glBindRenderbuffer(GL_RENDERBUFFER, m_depthTarget);
|
||||||
|
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, width, height);
|
||||||
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);
|
|
||||||
}
|
|
||||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthTarget);
|
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthTarget);
|
||||||
|
|
||||||
glViewport(0, 0, m_width, m_height);
|
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);
|
SDL_GL_MakeCurrent(DDWindow, m_context);
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_useMsaa ? m_msaaFbo : m_fbo);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
@ -660,6 +713,12 @@ void OpenGLES2Renderer::Flip()
|
|||||||
return;
|
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);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
@ -722,7 +781,7 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c
|
|||||||
SDL_GL_MakeCurrent(DDWindow, m_context);
|
SDL_GL_MakeCurrent(DDWindow, m_context);
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
glBindFramebuffer(GL_FRAMEBUFFER, m_useMsaa ? m_msaaFbo : m_fbo);
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
@ -809,6 +868,12 @@ void OpenGLES2Renderer::Download(SDL_Surface* target)
|
|||||||
{
|
{
|
||||||
glFinish();
|
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);
|
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);
|
||||||
|
|
||||||
|
|||||||
@ -132,7 +132,11 @@ HRESULT Direct3DRMImpl::CreateDeviceFromSurface(
|
|||||||
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
|
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
|
||||||
surface->GetSurfaceDesc(&DDSDesc);
|
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) {
|
if (!DDRenderer) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized");
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized");
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
|
|||||||
@ -18,7 +18,11 @@
|
|||||||
#include "d3drmrenderer_software.h"
|
#include "d3drmrenderer_software.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const GUID* guid)
|
Direct3DRMRenderer* CreateDirect3DRMRenderer(
|
||||||
|
const IDirect3DMiniwin* d3d,
|
||||||
|
const DDSURFACEDESC& DDSDesc,
|
||||||
|
const GUID* guid
|
||||||
|
)
|
||||||
{
|
{
|
||||||
#ifdef USE_SDL_GPU
|
#ifdef USE_SDL_GPU
|
||||||
if (SDL_memcmp(guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) {
|
if (SDL_memcmp(guid, &SDL3_GPU_GUID, sizeof(GUID)) == 0) {
|
||||||
@ -32,7 +36,7 @@ Direct3DRMRenderer* CreateDirect3DRMRenderer(const DDSURFACEDESC& DDSDesc, const
|
|||||||
#endif
|
#endif
|
||||||
#ifdef USE_OPENGLES2
|
#ifdef USE_OPENGLES2
|
||||||
if (SDL_memcmp(guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) {
|
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
|
#endif
|
||||||
#ifdef USE_OPENGL1
|
#ifdef USE_OPENGL1
|
||||||
|
|||||||
@ -29,6 +29,11 @@ HRESULT DirectDrawImpl::QueryInterface(const GUID& riid, void** ppvObject)
|
|||||||
*ppvObject = static_cast<IDirect3D2*>(this);
|
*ppvObject = static_cast<IDirect3D2*>(this);
|
||||||
return S_OK;
|
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();
|
MINIWIN_NOT_IMPLEMENTED();
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
@ -317,7 +322,7 @@ HRESULT DirectDrawImpl::CreateDevice(
|
|||||||
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
|
DDSDesc.dwSize = sizeof(DDSURFACEDESC);
|
||||||
pBackBuffer->GetSurfaceDesc(&DDSDesc);
|
pBackBuffer->GetSurfaceDesc(&DDSDesc);
|
||||||
|
|
||||||
DDRenderer = CreateDirect3DRMRenderer(DDSDesc, &guid);
|
DDRenderer = CreateDirect3DRMRenderer(this, DDSDesc, &guid);
|
||||||
if (!DDRenderer) {
|
if (!DDRenderer) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized");
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Device GUID not recognized");
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
@ -326,6 +331,17 @@ HRESULT DirectDrawImpl::CreateDevice(
|
|||||||
return DD_OK;
|
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)
|
HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context)
|
||||||
{
|
{
|
||||||
const char* driverName = SDL_GetCurrentVideoDriver();
|
const char* driverName = SDL_GetCurrentVideoDriver();
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include "d3drmmesh_impl.h"
|
#include "d3drmmesh_impl.h"
|
||||||
#include "mathutils.h"
|
#include "mathutils.h"
|
||||||
#include "miniwin/d3drm.h"
|
#include "miniwin/d3drm.h"
|
||||||
|
#include "miniwin/miniwind3d.h"
|
||||||
#include "miniwin/miniwindevice.h"
|
#include "miniwin/miniwindevice.h"
|
||||||
#include "structs.h"
|
#include "structs.h"
|
||||||
|
|
||||||
@ -61,5 +62,9 @@ class Direct3DRMRenderer : public IDirect3DDevice2 {
|
|||||||
ViewportTransform m_viewportTransform;
|
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);
|
void Direct3DRMRenderer_EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx);
|
||||||
|
|||||||
@ -32,8 +32,8 @@ struct GLES2MeshCacheEntry {
|
|||||||
|
|
||||||
class OpenGLES2Renderer : public Direct3DRMRenderer {
|
class OpenGLES2Renderer : public Direct3DRMRenderer {
|
||||||
public:
|
public:
|
||||||
static Direct3DRMRenderer* Create(DWORD width, DWORD height);
|
static Direct3DRMRenderer* Create(DWORD width, DWORD height, DWORD msaaSamples);
|
||||||
OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram);
|
OpenGLES2Renderer(DWORD width, DWORD height, DWORD msaaSamples, SDL_GLContext context, GLuint shaderProgram);
|
||||||
~OpenGLES2Renderer() override;
|
~OpenGLES2Renderer() override;
|
||||||
|
|
||||||
void PushLights(const SceneLight* lightsArray, size_t count) override;
|
void PushLights(const SceneLight* lightsArray, size_t count) override;
|
||||||
@ -72,7 +72,12 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
|
|||||||
bool m_dirty = false;
|
bool m_dirty = false;
|
||||||
std::vector<SceneLight> m_lights;
|
std::vector<SceneLight> m_lights;
|
||||||
SDL_GLContext m_context;
|
SDL_GLContext m_context;
|
||||||
|
uint32_t m_requestedMsaaSamples;
|
||||||
|
bool m_useMsaa;
|
||||||
GLuint m_fbo;
|
GLuint m_fbo;
|
||||||
|
GLuint m_msaaFbo;
|
||||||
|
GLuint m_msaaColorRbo;
|
||||||
|
GLuint m_msaaDepthRbo;
|
||||||
GLuint m_colorTarget;
|
GLuint m_colorTarget;
|
||||||
GLuint m_depthTarget;
|
GLuint m_depthTarget;
|
||||||
GLuint m_shaderProgram;
|
GLuint m_shaderProgram;
|
||||||
@ -94,7 +99,10 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
|
|||||||
|
|
||||||
inline static void OpenGLES2Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
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) {
|
if (!device) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "framebuffer_impl.h"
|
#include "framebuffer_impl.h"
|
||||||
#include "miniwin/d3d.h"
|
#include "miniwin/d3d.h"
|
||||||
#include "miniwin/ddraw.h"
|
#include "miniwin/ddraw.h"
|
||||||
|
#include "miniwin/miniwind3d.h"
|
||||||
|
|
||||||
#include <SDL3/SDL.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};
|
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
|
// IUnknown interface
|
||||||
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
|
HRESULT QueryInterface(const GUID& riid, void** ppvObject) override;
|
||||||
// IDirectDraw interface
|
// IDirectDraw interface
|
||||||
@ -45,11 +46,15 @@ struct DirectDrawImpl : public IDirectDraw2, public IDirect3D2 {
|
|||||||
HRESULT CreateDevice(const GUID& guid, IDirectDrawSurface* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice)
|
HRESULT CreateDevice(const GUID& guid, IDirectDrawSurface* pBackBuffer, IDirect3DDevice2** ppDirect3DDevice)
|
||||||
override;
|
override;
|
||||||
HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) override;
|
HRESULT EnumDevices(LPD3DENUMDEVICESCALLBACK cb, void* ctx) override;
|
||||||
|
// IDirect3DMiniwin interface
|
||||||
|
HRESULT RequestMSAA(DWORD msaaSamples) override;
|
||||||
|
DWORD GetMSAASamples() const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FrameBufferImpl* m_frameBuffer;
|
FrameBufferImpl* m_frameBuffer;
|
||||||
int m_virtualWidth = 0;
|
int m_virtualWidth = 0;
|
||||||
int m_virtualHeight = 0;
|
int m_virtualHeight = 0;
|
||||||
|
DWORD m_msaaSamples = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context);
|
HRESULT DirectDrawEnumerate(LPDDENUMCALLBACKA cb, void* context);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user