mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-02-02 20:11:15 +00:00
Merge branch 'master' into master
This commit is contained in:
commit
b995b238d4
@ -455,11 +455,6 @@
|
|||||||
<string>Unknown - Broken</string>
|
<string>Unknown - Broken</string>
|
||||||
</property>
|
</property>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Fake Mosaic</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|||||||
@ -48,8 +48,7 @@ class MxTransitionManager : public MxCore {
|
|||||||
e_mosaic,
|
e_mosaic,
|
||||||
e_wipeDown,
|
e_wipeDown,
|
||||||
e_windows,
|
e_windows,
|
||||||
e_broken, // Unknown what this is supposed to be, it locks the game up
|
e_broken // Unknown what this is supposed to be, it locks the game up
|
||||||
e_fakeMosaic
|
|
||||||
};
|
};
|
||||||
|
|
||||||
MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim);
|
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 WipeDownTransition();
|
||||||
void WindowsTransition();
|
void WindowsTransition();
|
||||||
void BrokenTransition();
|
void BrokenTransition();
|
||||||
void FakeMosaicTransition();
|
|
||||||
|
|
||||||
void SubmitCopyRect(LPDDSURFACEDESC p_ddsc);
|
void SubmitCopyRect(LPDDSURFACEDESC p_ddsc);
|
||||||
void SetupCopyRect(LPDDSURFACEDESC p_ddsc);
|
void SetupCopyRect(LPDDSURFACEDESC p_ddsc);
|
||||||
|
|||||||
@ -84,9 +84,6 @@ MxResult MxTransitionManager::Tickle()
|
|||||||
case e_broken:
|
case e_broken:
|
||||||
BrokenTransition();
|
BrokenTransition();
|
||||||
break;
|
break;
|
||||||
case e_fakeMosaic:
|
|
||||||
FakeMosaicTransition();
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
@ -664,166 +661,3 @@ void MxTransitionManager::configureMxTransitionManager(TransitionType p_transiti
|
|||||||
{
|
{
|
||||||
g_transitionManagerConfig = p_transitionManagerConfig;
|
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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -237,14 +237,79 @@ GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = f
|
|||||||
return cache;
|
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)
|
OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram)
|
||||||
: m_context(context), m_shaderProgram(shaderProgram)
|
: m_context(context), m_shaderProgram(shaderProgram)
|
||||||
{
|
{
|
||||||
|
glGenFramebuffers(1, &m_fbo);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
|
|
||||||
m_virtualWidth = width;
|
m_virtualWidth = width;
|
||||||
m_virtualHeight = height;
|
m_virtualHeight = height;
|
||||||
ViewportTransform viewportTransform = {1.0f, 0.0f, 0.0f};
|
ViewportTransform viewportTransform = {1.0f, 0.0f, 0.0f};
|
||||||
Resize(width, height, viewportTransform);
|
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 = {
|
m_uiMesh.vertices = {
|
||||||
{{0.0f, 0.0f, 0.0f}, {0, 0, -1}, {0.0f, 0.0f}},
|
{{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}},
|
{{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_modelViewMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_modelViewMatrix");
|
||||||
m_normalMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_normalMatrix");
|
m_normalMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_normalMatrix");
|
||||||
m_projectionMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_projectionMatrix");
|
m_projectionMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_projectionMatrix");
|
||||||
|
|
||||||
|
glUseProgram(m_shaderProgram);
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLES2Renderer::~OpenGLES2Renderer()
|
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)
|
Uint32 OpenGLES2Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUI, float scaleX, float scaleY)
|
||||||
{
|
{
|
||||||
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
|
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
|
||||||
@ -460,13 +486,13 @@ HRESULT OpenGLES2Renderer::BeginFrame()
|
|||||||
{
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
|
|
||||||
glEnable(GL_CULL_FACE);
|
glEnable(GL_CULL_FACE);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
|
|
||||||
glUseProgram(m_shaderProgram);
|
|
||||||
|
|
||||||
SceneLightGLES2 lightData[3];
|
SceneLightGLES2 lightData[3];
|
||||||
int lightCount = std::min(static_cast<int>(m_lights.size()), 3);
|
int lightCount = std::min(static_cast<int>(m_lights.size()), 3);
|
||||||
|
|
||||||
@ -537,6 +563,9 @@ void OpenGLES2Renderer::SubmitDraw(
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
glUniform1i(m_useTextureLoc, 0);
|
glUniform1i(m_useTextureLoc, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_dummyTexture);
|
||||||
|
glUniform1i(m_textureLoc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboPositions);
|
glBindBuffer(GL_ARRAY_BUFFER, mesh.vboPositions);
|
||||||
@ -564,7 +593,6 @@ HRESULT OpenGLES2Renderer::FinalizeFrame()
|
|||||||
{
|
{
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
glUseProgram(0);
|
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
@ -578,12 +606,43 @@ void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& v
|
|||||||
SDL_DestroySurface(m_renderedImage);
|
SDL_DestroySurface(m_renderedImage);
|
||||||
}
|
}
|
||||||
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32);
|
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);
|
glViewport(0, 0, m_width, m_height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLES2Renderer::Clear(float r, float g, float b)
|
void OpenGLES2Renderer::Clear(float r, float g, float b)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
|
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glClearColor(r, g, b, 1.0f);
|
glClearColor(r, g, b, 1.0f);
|
||||||
@ -592,21 +651,76 @@ void OpenGLES2Renderer::Clear(float r, float g, float b)
|
|||||||
|
|
||||||
void OpenGLES2Renderer::Flip()
|
void OpenGLES2Renderer::Flip()
|
||||||
{
|
{
|
||||||
if (m_dirty) {
|
if (!m_dirty) {
|
||||||
SDL_GL_SwapWindow(DDWindow);
|
return;
|
||||||
m_dirty = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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<GLsizei>(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)
|
void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, const SDL_Rect& dstRect, FColor color)
|
||||||
{
|
{
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
|
|
||||||
glUseProgram(m_shaderProgram);
|
|
||||||
|
|
||||||
float ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
float ambient[] = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||||
float blank[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
float blank[] = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||||
glUniform4fv(u_lightLocs[0][0], 1, ambient);
|
glUniform4fv(u_lightLocs[0][0], 1, ambient);
|
||||||
@ -629,14 +743,17 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c
|
|||||||
static_cast<int>(std::round(texture.height * scaleY))
|
static_cast<int>(std::round(texture.height * scaleY))
|
||||||
};
|
};
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glUniform1i(m_useTextureLoc, 1);
|
glUniform1i(m_useTextureLoc, 1);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture.glTextureId);
|
glBindTexture(GL_TEXTURE_2D, texture.glTextureId);
|
||||||
glUniform1i(m_textureLoc, 0);
|
glUniform1i(m_textureLoc, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
expandedDstRect = dstRect;
|
expandedDstRect = dstRect;
|
||||||
glUniform1i(m_useTextureLoc, 0);
|
glUniform1i(m_useTextureLoc, 0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, m_dummyTexture);
|
||||||
|
glUniform1i(m_textureLoc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
D3DRMMATRIX4D modelView, projection;
|
D3DRMMATRIX4D modelView, projection;
|
||||||
@ -685,6 +802,8 @@ void OpenGLES2Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, c
|
|||||||
void OpenGLES2Renderer::Download(SDL_Surface* target)
|
void OpenGLES2Renderer::Download(SDL_Surface* target)
|
||||||
{
|
{
|
||||||
glFinish();
|
glFinish();
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
SDL_Rect srcRect = {
|
SDL_Rect srcRect = {
|
||||||
|
|||||||
@ -72,7 +72,11 @@ 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;
|
||||||
|
GLuint m_fbo;
|
||||||
|
GLuint m_colorTarget;
|
||||||
|
GLuint m_depthTarget;
|
||||||
GLuint m_shaderProgram;
|
GLuint m_shaderProgram;
|
||||||
|
GLuint m_dummyTexture;
|
||||||
GLint m_posLoc;
|
GLint m_posLoc;
|
||||||
GLint m_normLoc;
|
GLint m_normLoc;
|
||||||
GLint m_texLoc;
|
GLint m_texLoc;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user