diff --git a/CONFIG/res/maindialog.ui b/CONFIG/res/maindialog.ui
index 12739f27..66e2b52e 100644
--- a/CONFIG/res/maindialog.ui
+++ b/CONFIG/res/maindialog.ui
@@ -455,11 +455,6 @@
Unknown - Broken
- -
-
- Fake Mosaic
-
-
-
diff --git a/LEGO1/lego/legoomni/include/mxtransitionmanager.h b/LEGO1/lego/legoomni/include/mxtransitionmanager.h
index 7c31daf7..dd9dc9ed 100644
--- a/LEGO1/lego/legoomni/include/mxtransitionmanager.h
+++ b/LEGO1/lego/legoomni/include/mxtransitionmanager.h
@@ -48,8 +48,7 @@ class MxTransitionManager : public MxCore {
e_mosaic,
e_wipeDown,
e_windows,
- e_broken, // Unknown what this is supposed to be, it locks the game up
- e_fakeMosaic
+ e_broken // Unknown what this is supposed to be, it locks the game up
};
MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim);
@@ -69,7 +68,6 @@ class MxTransitionManager : public MxCore {
void WipeDownTransition();
void WindowsTransition();
void BrokenTransition();
- void FakeMosaicTransition();
void SubmitCopyRect(LPDDSURFACEDESC p_ddsc);
void SetupCopyRect(LPDDSURFACEDESC p_ddsc);
diff --git a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp
index 04805092..7431033e 100644
--- a/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp
+++ b/LEGO1/lego/legoomni/src/common/mxtransitionmanager.cpp
@@ -84,9 +84,6 @@ MxResult MxTransitionManager::Tickle()
case e_broken:
BrokenTransition();
break;
- case e_fakeMosaic:
- FakeMosaicTransition();
- break;
}
return SUCCESS;
}
@@ -664,166 +661,3 @@ void MxTransitionManager::configureMxTransitionManager(TransitionType p_transiti
{
g_transitionManagerConfig = p_transitionManagerConfig;
}
-
-int g_colorOffset;
-int GetColorIndexWithLocality(int p_col, int p_row)
-{
- int islandX = p_col / 8;
- int islandY = p_row / 8; // Dvide screen in 8x6 tiles
-
- int island = islandY * 8 + islandX; // tile id
-
- if (SDL_rand(3) > island / 8) {
- return 6 + SDL_rand(2); // emulate sky
- }
-
- if (SDL_rand(16) > 2) {
- island += SDL_rand(3) - 1 + (SDL_rand(3) - 1) * 8; // blure tiles
- }
-
- int hash = (island + g_colorOffset) * 2654435761u;
- int scrambled = (hash >> 16) % 32;
-
- int finalIndex = scrambled + SDL_rand(3) - 1;
- return abs(finalIndex) % 32;
-}
-
-void MxTransitionManager::FakeMosaicTransition()
-{
- static LPDIRECTDRAWSURFACE g_fakeTranstionSurface = nullptr;
-
- if (m_animationTimer == 16) {
- m_animationTimer = 0;
- if (g_fakeTranstionSurface) {
- g_fakeTranstionSurface->Release();
- g_fakeTranstionSurface = nullptr;
- }
- EndTransition(TRUE);
- return;
- }
- else {
- if (m_animationTimer == 0) {
- g_colorOffset = SDL_rand(32);
-
- // Same init/shuffle steps as the dissolve transition, except that
- // we are using big blocky pixels and only need 64 columns.
- MxS32 i;
- for (i = 0; i < 64; i++) {
- m_columnOrder[i] = i;
- }
-
- for (i = 0; i < 64; i++) {
- MxS32 swap = SDL_rand(64);
- MxU16 t = m_columnOrder[i];
- m_columnOrder[i] = m_columnOrder[swap];
- m_columnOrder[swap] = t;
- }
-
- // The same is true here. We only need 48 rows.
- for (i = 0; i < 48; i++) {
- m_randomShift[i] = SDL_rand(64);
- }
- DDSURFACEDESC mainDesc = {};
- mainDesc.dwSize = sizeof(mainDesc);
- if (m_ddSurface->GetSurfaceDesc(&mainDesc) != DD_OK) {
- return;
- }
-
- DDSURFACEDESC tempDesc = {};
- tempDesc.dwSize = sizeof(tempDesc);
- tempDesc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS;
- tempDesc.dwWidth = 64;
- tempDesc.dwHeight = 48;
- tempDesc.ddpfPixelFormat = mainDesc.ddpfPixelFormat;
- tempDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
-
- if (MVideoManager()->GetDirectDraw()->CreateSurface(&tempDesc, &g_fakeTranstionSurface, nullptr) != DD_OK) {
- return;
- }
-
- DWORD fillColor = 0x00000000;
- switch (mainDesc.ddpfPixelFormat.dwRGBBitCount) {
- case 8:
- fillColor = 0x10;
- break;
- case 16:
- fillColor = RGB555_CREATE(0x1f, 0, 0x1f);
- break;
- }
-
- DDBLTFX bltFx = {};
- bltFx.dwSize = sizeof(bltFx);
- bltFx.dwFillColor = fillColor;
- g_fakeTranstionSurface->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &bltFx);
-
- DDCOLORKEY key = {};
- key.dwColorSpaceLowValue = key.dwColorSpaceHighValue = fillColor;
- g_fakeTranstionSurface->SetColorKey(DDCKEY_SRCBLT, &key);
- }
-
- // Run one tick of the animation
- DDSURFACEDESC ddsd;
- memset(&ddsd, 0, sizeof(ddsd));
- ddsd.dwSize = sizeof(ddsd);
-
- HRESULT res = g_fakeTranstionSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
- if (res == DDERR_SURFACELOST) {
- g_fakeTranstionSurface->Restore();
- res = g_fakeTranstionSurface->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_WRITEONLY, NULL);
- }
-
- if (res == DD_OK) {
- SubmitCopyRect(&ddsd);
-
- static const MxU8 g_palette[32][3] = {
- {0x00, 0x00, 0x00}, {0x12, 0x1e, 0x50}, {0x00, 0x22, 0x6c}, {0x14, 0x2d, 0x9f}, {0x0e, 0x36, 0xb0},
- {0x0e, 0x39, 0xd0}, {0x47, 0x96, 0xe2}, {0x79, 0xaa, 0xca}, {0xff, 0xff, 0xff}, {0xc9, 0xcd, 0xcb},
- {0xad, 0xad, 0xab}, {0xa6, 0x91, 0x8e}, {0xaf, 0x59, 0x49}, {0xc0, 0x00, 0x00}, {0xab, 0x18, 0x18},
- {0x61, 0x0c, 0x0c}, {0x04, 0x38, 0x12}, {0x2c, 0x67, 0x28}, {0x4a, 0xb4, 0x6b}, {0x94, 0xb7, 0x7c},
- {0xb6, 0xb9, 0x87}, {0x52, 0x4a, 0x67}, {0x87, 0x8d, 0x8a}, {0xa6, 0x91, 0x8e}, {0xf8, 0xee, 0xdc},
- {0xf4, 0xe2, 0xc3}, {0x87, 0x8d, 0x8a}, {0xba, 0x9f, 0x12}, {0xb5, 0x83, 0x00}, {0x6a, 0x44, 0x27},
- {0x36, 0x37, 0x34}, {0x2b, 0x23, 0x0f}
- };
-
- MxS32 bytesPerPixel = ddsd.ddpfPixelFormat.dwRGBBitCount / 8;
-
- for (MxS32 col = 0; col < 64; col++) {
- // Select 4 columns on each tick
- if (m_animationTimer * 4 > m_columnOrder[col]) {
- continue;
- }
-
- if (m_animationTimer * 4 + 3 < m_columnOrder[col]) {
- continue;
- }
-
- for (MxS32 row = 0; row < 48; row++) {
- MxS32 x = (m_randomShift[row] + col) % 64;
- MxU8* dest = (MxU8*) ddsd.lpSurface + row * ddsd.lPitch + x * bytesPerPixel;
-
- const MxU8 paletteIndex = GetColorIndexWithLocality(col, row);
- const MxU8* color = g_palette[paletteIndex];
- switch (bytesPerPixel) {
- case 1:
- *dest = paletteIndex;
- break;
- case 2:
- *((MxU16*) dest) = RGB555_CREATE(color[2], color[1], color[0]);
- break;
- default:
- *((MxU32*) dest) = RGB8888_CREATE(color[2], color[1], color[0], 255);
- break;
- }
- }
- }
-
- SetupCopyRect(&ddsd);
- g_fakeTranstionSurface->Unlock(ddsd.lpSurface);
-
- RECT srcRect = {0, 0, 64, 48};
- m_ddSurface->Blt(&g_fullScreenRect, g_fakeTranstionSurface, &srcRect, DDBLT_WAIT | DDBLT_KEYSRC, NULL);
-
- m_animationTimer++;
- }
- }
-}
diff --git a/miniwin/src/d3drm/backends/opengles2/renderer.cpp b/miniwin/src/d3drm/backends/opengles2/renderer.cpp
index ebcb38e6..50e43d02 100644
--- a/miniwin/src/d3drm/backends/opengles2/renderer.cpp
+++ b/miniwin/src/d3drm/backends/opengles2/renderer.cpp
@@ -237,14 +237,79 @@ GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = f
return cache;
}
+bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
+{
+ SDL_Surface* surf = source;
+ if (source->format != SDL_PIXELFORMAT_RGBA32) {
+ surf = SDL_ConvertSurface(source, SDL_PIXELFORMAT_RGBA32);
+ if (!surf) {
+ return false;
+ }
+ }
+
+ glGenTextures(1, &outTexId);
+ glBindTexture(GL_TEXTURE_2D, outTexId);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);
+
+ if (isUI) {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ }
+ else {
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if (strstr((const char*) glGetString(GL_EXTENSIONS), "GL_EXT_texture_filter_anisotropic")) {
+ GLfloat maxAniso = 0.0f;
+ glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
+ GLfloat desiredAniso = fminf(8.0f, maxAniso);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, desiredAniso);
+ }
+ glGenerateMipmap(GL_TEXTURE_2D);
+ }
+
+ if (surf != source) {
+ SDL_DestroySurface(surf);
+ }
+
+ return true;
+}
+
OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram)
: m_context(context), m_shaderProgram(shaderProgram)
{
+ glGenFramebuffers(1, &m_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+
m_virtualWidth = width;
m_virtualHeight = height;
ViewportTransform viewportTransform = {1.0f, 0.0f, 0.0f};
Resize(width, height, viewportTransform);
+ SDL_Surface* dummySurface = SDL_CreateSurface(1, 1, SDL_PIXELFORMAT_RGBA32);
+ if (!dummySurface) {
+ SDL_Log("Failed to create surface: %s", SDL_GetError());
+ return;
+ }
+ if (!SDL_LockSurface(dummySurface)) {
+ SDL_Log("Failed to lock surface: %s", SDL_GetError());
+ SDL_DestroySurface(dummySurface);
+ return;
+ }
+ ((Uint32*) dummySurface->pixels)[0] = 0xFFFFFFFF;
+ SDL_UnlockSurface(dummySurface);
+
+ UploadTexture(dummySurface, m_dummyTexture, false);
+ if (!m_dummyTexture) {
+ SDL_DestroySurface(dummySurface);
+ SDL_Log("Failed to create surface: %s", SDL_GetError());
+ return;
+ }
+ SDL_DestroySurface(dummySurface);
+
m_uiMesh.vertices = {
{{0.0f, 0.0f, 0.0f}, {0, 0, -1}, {0.0f, 0.0f}},
{{1.0f, 0.0f, 0.0f}, {0, 0, -1}, {1.0f, 0.0f}},
@@ -270,6 +335,8 @@ OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext co
m_modelViewMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_modelViewMatrix");
m_normalMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_normalMatrix");
m_projectionMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_projectionMatrix");
+
+ glUseProgram(m_shaderProgram);
}
OpenGLES2Renderer::~OpenGLES2Renderer()
@@ -321,47 +388,6 @@ void OpenGLES2Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture*
);
}
-bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
-{
- SDL_Surface* surf = source;
- if (source->format != SDL_PIXELFORMAT_RGBA32) {
- surf = SDL_ConvertSurface(source, SDL_PIXELFORMAT_RGBA32);
- if (!surf) {
- return false;
- }
- }
-
- glGenTextures(1, &outTexId);
- glBindTexture(GL_TEXTURE_2D, outTexId);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surf->w, surf->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surf->pixels);
-
- if (isUI) {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- }
- else {
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- if (strstr((const char*) glGetString(GL_EXTENSIONS), "GL_EXT_texture_filter_anisotropic")) {
- GLfloat maxAniso = 0.0f;
- glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
- GLfloat desiredAniso = fminf(8.0f, maxAniso);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, desiredAniso);
- }
- glGenerateMipmap(GL_TEXTURE_2D);
- }
-
- if (surf != source) {
- SDL_DestroySurface(surf);
- }
-
- return true;
-}
-
Uint32 OpenGLES2Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY)
{
auto texture = static_cast(iTexture);
@@ -460,13 +486,13 @@ HRESULT OpenGLES2Renderer::BeginFrame()
{
m_dirty = true;
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+
glEnable(GL_CULL_FACE);
glDisable(GL_BLEND);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
- glUseProgram(m_shaderProgram);
-
SceneLightGLES2 lightData[3];
int lightCount = std::min(static_cast(m_lights.size()), 3);
@@ -537,6 +563,9 @@ void OpenGLES2Renderer::SubmitDraw(
}
else {
glUniform1i(m_useTextureLoc, 0);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_dummyTexture);
+ glUniform1i(m_textureLoc, 0);
}
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboPositions);
@@ -564,7 +593,6 @@ HRESULT OpenGLES2Renderer::FinalizeFrame()
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- glUseProgram(0);
return DD_OK;
}
@@ -578,12 +606,43 @@ void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& v
SDL_DestroySurface(m_renderedImage);
}
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32);
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+
+ // Create color texture
+ glGenTextures(1, &m_colorTarget);
+ glBindTexture(GL_TEXTURE_2D, m_colorTarget);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_colorTarget, 0);
+
+ // 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);
+ }
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthTarget);
+
glViewport(0, 0, m_width, m_height);
}
void OpenGLES2Renderer::Clear(float r, float g, float b)
{
m_dirty = true;
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glClearColor(r, g, b, 1.0f);
@@ -592,21 +651,76 @@ void OpenGLES2Renderer::Clear(float r, float g, float b)
void OpenGLES2Renderer::Flip()
{
- if (m_dirty) {
- SDL_GL_SwapWindow(DDWindow);
- m_dirty = false;
+ if (!m_dirty) {
+ return;
}
+
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ glDisable(GL_DEPTH_TEST);
+ glFrontFace(GL_CCW);
+ glDepthMask(GL_FALSE);
+
+ glUniform4f(m_colorLoc, 1.0f, 1.0f, 1.0f, 1.0f);
+ glUniform1f(m_shinLoc, 0.0f);
+
+ float ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ float blank[] = {0.0f, 0.0f, 0.0f, 0.0f};
+ glUniform4fv(u_lightLocs[0][0], 1, ambient);
+ glUniform4fv(u_lightLocs[0][1], 1, blank);
+ glUniform4fv(u_lightLocs[0][2], 1, blank);
+ glUniform1i(m_lightCountLoc, 1);
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_colorTarget);
+ glUniform1i(m_textureLoc, 0);
+ glUniform1i(m_useTextureLoc, 1);
+
+ D3DRMMATRIX4D projection;
+ D3DRMMATRIX4D modelViewMatrix = {
+ {(float) m_width, 0.0f, 0.0f, 0.0f},
+ {0.0f, (float) -m_height, 0.0f, 0.0f},
+ {0.0f, 0.0f, 1.0f, 0.0f},
+ {0.0f, (float) m_height, 0.0f, 1.0f}
+ };
+ glUniformMatrix4fv(m_modelViewMatrixLoc, 1, GL_FALSE, &modelViewMatrix[0][0]);
+ Matrix3x3 identity = {{1.f, 0.f, 0.f}, {0.f, 1.f, 0.f}, {0.f, 0.f, 1.f}};
+ glUniformMatrix3fv(m_normalMatrixLoc, 1, GL_FALSE, &identity[0][0]);
+ CreateOrthographicProjection((float) m_width, (float) m_height, projection);
+ glUniformMatrix4fv(m_projectionMatrixLoc, 1, GL_FALSE, &projection[0][0]);
+
+ glDisable(GL_SCISSOR_TEST);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_uiMeshCache.vboPositions);
+ glEnableVertexAttribArray(m_posLoc);
+ glVertexAttribPointer(m_posLoc, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
+
+ glBindBuffer(GL_ARRAY_BUFFER, m_uiMeshCache.vboTexcoords);
+ glEnableVertexAttribArray(m_texLoc);
+ glVertexAttribPointer(m_texLoc, 2, GL_FLOAT, GL_FALSE, 0, nullptr);
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_uiMeshCache.ibo);
+ glDrawElements(GL_TRIANGLES, static_cast(m_uiMeshCache.indices.size()), GL_UNSIGNED_SHORT, nullptr);
+
+ glDisableVertexAttribArray(m_texLoc);
+
+ SDL_GL_SwapWindow(DDWindow);
+ glFrontFace(GL_CW);
+ m_dirty = false;
}
void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color)
{
m_dirty = true;
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
+
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
- glUseProgram(m_shaderProgram);
-
float ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
float blank[] = {0.0f, 0.0f, 0.0f, 0.0f};
glUniform4fv(u_lightLocs[0][0], 1, ambient);
@@ -629,14 +743,17 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c
static_cast(std::round(texture.height * scaleY))
};
- glActiveTexture(GL_TEXTURE0);
glUniform1i(m_useTextureLoc, 1);
+ glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture.glTextureId);
glUniform1i(m_textureLoc, 0);
}
else {
expandedDstRect = dstRect;
glUniform1i(m_useTextureLoc, 0);
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, m_dummyTexture);
+ glUniform1i(m_textureLoc, 0);
}
D3DRMMATRIX4D modelView, projection;
@@ -685,6 +802,8 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c
void OpenGLES2Renderer::Download(SDL_Surface* target)
{
glFinish();
+
+ glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_renderedImage->pixels);
SDL_Rect srcRect = {
diff --git a/miniwin/src/internal/d3drmrenderer_opengles2.h b/miniwin/src/internal/d3drmrenderer_opengles2.h
index 0472ff80..d4985f32 100644
--- a/miniwin/src/internal/d3drmrenderer_opengles2.h
+++ b/miniwin/src/internal/d3drmrenderer_opengles2.h
@@ -72,7 +72,11 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
bool m_dirty = false;
std::vector m_lights;
SDL_GLContext m_context;
+ GLuint m_fbo;
+ GLuint m_colorTarget;
+ GLuint m_depthTarget;
GLuint m_shaderProgram;
+ GLuint m_dummyTexture;
GLint m_posLoc;
GLint m_normLoc;
GLint m_texLoc;