mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-12 18:51:15 +00:00
Make OpenGL 1.1 renderer work under PSP
This commit is contained in:
parent
87072cc230
commit
6668d185d4
@ -665,7 +665,9 @@ MxResult IsleApp::SetupWindow()
|
||||
#if defined(MINIWIN) && !defined(__3DS__)
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
#ifndef __PSP__
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindowWithProperties(props);
|
||||
|
||||
@ -42,12 +42,26 @@ void GL11_DestroyTexture(GLuint texId)
|
||||
glDeleteTextures(1, &texId);
|
||||
}
|
||||
|
||||
GLuint GL11_UploadTextureData(void* pixels, int width, int height)
|
||||
GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUi)
|
||||
{
|
||||
GLuint texId;
|
||||
glGenTextures(1, &texId);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
if (isUi) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
else {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
return texId;
|
||||
}
|
||||
|
||||
@ -111,7 +125,6 @@ void GL11_BeginFrame(const Matrix4x4* projection)
|
||||
glDepthMask(GL_TRUE);
|
||||
glEnable(GL_LIGHTING);
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||
|
||||
// Disable all lights and reset global ambient
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
@ -198,7 +211,18 @@ void GL11_SubmitDraw(
|
||||
glLoadMatrixf(&modelViewMatrix[0][0]);
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
#ifndef __PSP__
|
||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||
glColor4ub(appearance.color.r, appearance.color.g, appearance.color.b, appearance.color.a);
|
||||
#else
|
||||
GLfloat color[4] = {
|
||||
appearance.color.r / 255.0f,
|
||||
appearance.color.g / 255.0f,
|
||||
appearance.color.b / 255.0f,
|
||||
appearance.color.a / 255.0f
|
||||
};
|
||||
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color);
|
||||
#endif
|
||||
|
||||
if (appearance.shininess != 0.0f) {
|
||||
GLfloat whiteSpec[] = {1.f, 1.f, 1.f, 1.f};
|
||||
@ -220,8 +244,6 @@ void GL11_SubmitDraw(
|
||||
|
||||
// Bind texture if present
|
||||
if (appearance.textureId != NO_TEXTURE_ID) {
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
@ -279,7 +301,7 @@ void GL11_Clear(float r, float g, float b)
|
||||
}
|
||||
|
||||
void GL11_Draw2DImage(
|
||||
GLuint texId,
|
||||
GLTextureCacheEntry& cache,
|
||||
const SDL_Rect& srcRect,
|
||||
const SDL_Rect& dstRect,
|
||||
float left,
|
||||
@ -305,24 +327,17 @@ void GL11_Draw2DImage(
|
||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texId);
|
||||
glBindTexture(GL_TEXTURE_2D, cache.glTextureId);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
GLint boundTexture = 0;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
|
||||
|
||||
GLfloat texW, texH;
|
||||
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texW);
|
||||
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texH);
|
||||
|
||||
float u1 = srcRect.x / texW;
|
||||
float v1 = srcRect.y / texH;
|
||||
float u2 = (srcRect.x + srcRect.w) / texW;
|
||||
float v2 = (srcRect.y + srcRect.h) / texH;
|
||||
float u1 = srcRect.x / cache.width;
|
||||
float v1 = srcRect.y / cache.height;
|
||||
float u2 = (srcRect.x + srcRect.w) / cache.width;
|
||||
float v2 = (srcRect.y + srcRect.h) / cache.height;
|
||||
|
||||
float x1 = (float) dstRect.x;
|
||||
float y1 = (float) dstRect.y;
|
||||
|
||||
@ -39,6 +39,8 @@ struct GLTextureCacheEntry {
|
||||
IDirect3DRMTexture* texture;
|
||||
Uint32 version;
|
||||
GLuint glTextureId;
|
||||
float width;
|
||||
float height;
|
||||
};
|
||||
|
||||
struct GLMeshCacheEntry {
|
||||
@ -62,7 +64,7 @@ struct GLMeshCacheEntry {
|
||||
void GL11_InitState();
|
||||
void GL11_LoadExtensions();
|
||||
void GL11_DestroyTexture(GLuint texId);
|
||||
GLuint GL11_UploadTextureData(void* pixels, int width, int height);
|
||||
GLuint GL11_UploadTextureData(void* pixels, int width, int height, bool isUI);
|
||||
void GL11_UploadMesh(GLMeshCacheEntry& cache, bool hasTexture);
|
||||
void GL11_DestroyMesh(GLMeshCacheEntry& cache);
|
||||
void GL11_BeginFrame(const Matrix4x4* projection);
|
||||
@ -77,7 +79,7 @@ void GL11_SubmitDraw(
|
||||
void GL11_Resize(int width, int height);
|
||||
void GL11_Clear(float r, float g, float b);
|
||||
void GL11_Draw2DImage(
|
||||
GLuint texId,
|
||||
GLTextureCacheEntry& cache,
|
||||
const SDL_Rect& srcRect,
|
||||
const SDL_Rect& dstRect,
|
||||
float left,
|
||||
|
||||
@ -23,7 +23,9 @@ Direct3DRMRenderer* OpenGL1Renderer::Create(DWORD width, DWORD height)
|
||||
// call below when on an EGL-based backend, and crashes with EGL_BAD_MATCH.
|
||||
SDL_GL_ResetAttributes();
|
||||
// But ResetAttributes resets it to 16.
|
||||
#ifndef __PSP__
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
#endif
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
@ -58,6 +60,8 @@ OpenGL1Renderer::OpenGL1Renderer(DWORD width, DWORD height, SDL_GLContext contex
|
||||
m_virtualHeight = height;
|
||||
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32);
|
||||
GL11_LoadExtensions();
|
||||
m_useVBOs = SDL_GL_ExtensionSupported("GL_ARB_vertex_buffer_object");
|
||||
m_useNPOT = SDL_GL_ExtensionSupported("GL_ARB_vertex_buffer_object");
|
||||
}
|
||||
|
||||
OpenGL1Renderer::~OpenGL1Renderer()
|
||||
@ -108,6 +112,59 @@ void OpenGL1Renderer::AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* t
|
||||
);
|
||||
}
|
||||
|
||||
static int NextPowerOfTwo(int v)
|
||||
{
|
||||
int power = 1;
|
||||
while (power < v) {
|
||||
power <<= 1;
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
static Uint32 UploadTextureData(SDL_Surface* src, bool useNPOT, bool isUi)
|
||||
{
|
||||
SDL_Surface* working = src;
|
||||
if (src->format != SDL_PIXELFORMAT_RGBA32) {
|
||||
working = SDL_ConvertSurface(src, SDL_PIXELFORMAT_RGBA32);
|
||||
if (!working) {
|
||||
SDL_Log("SDL_ConvertSurface failed: %s", SDL_GetError());
|
||||
return NO_TEXTURE_ID;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_Surface* finalSurface = working;
|
||||
|
||||
// Resize to next power-of-two if needed and NPOT isn't supported
|
||||
int newW = NextPowerOfTwo(working->w);
|
||||
int newH = NextPowerOfTwo(working->h);
|
||||
|
||||
if (!useNPOT && (newW != working->w || newH != working->h)) {
|
||||
SDL_Surface* resized = SDL_CreateSurface(newW, newH, working->format);
|
||||
if (!resized) {
|
||||
SDL_Log("SDL_CreateSurface (resize) failed: %s", SDL_GetError());
|
||||
if (working != src) {
|
||||
SDL_DestroySurface(working);
|
||||
}
|
||||
return NO_TEXTURE_ID;
|
||||
}
|
||||
|
||||
SDL_Rect srcRect = {0, 0, working->w, working->h};
|
||||
SDL_Rect dstRect = {0, 0, newW, newH};
|
||||
SDL_BlitSurfaceScaled(working, &srcRect, resized, &dstRect, SDL_SCALEMODE_NEAREST);
|
||||
|
||||
if (working != src) {
|
||||
SDL_DestroySurface(working);
|
||||
}
|
||||
finalSurface = resized;
|
||||
}
|
||||
|
||||
Uint32 texId = GL11_UploadTextureData(finalSurface->pixels, finalSurface->w, finalSurface->h, isUi);
|
||||
if (finalSurface != src) {
|
||||
SDL_DestroySurface(finalSurface);
|
||||
}
|
||||
return texId;
|
||||
}
|
||||
|
||||
Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
|
||||
{
|
||||
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
|
||||
@ -118,28 +175,16 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
|
||||
if (tex.texture == texture) {
|
||||
if (tex.version != texture->m_version) {
|
||||
GL11_DestroyTexture(tex.glTextureId);
|
||||
|
||||
SDL_Surface* surf = SDL_ConvertSurface(surface->m_surface, SDL_PIXELFORMAT_RGBA32);
|
||||
if (!surf) {
|
||||
return NO_TEXTURE_ID;
|
||||
}
|
||||
tex.glTextureId = GL11_UploadTextureData(surf->pixels, surf->w, surf->h);
|
||||
SDL_DestroySurface(surf);
|
||||
|
||||
tex.glTextureId = UploadTextureData(surface->m_surface, m_useNPOT, isUi);
|
||||
tex.version = texture->m_version;
|
||||
tex.width = surface->m_surface->w;
|
||||
tex.height = surface->m_surface->h;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
GLuint texId;
|
||||
|
||||
SDL_Surface* surf = SDL_ConvertSurface(surface->m_surface, SDL_PIXELFORMAT_RGBA32);
|
||||
if (!surf) {
|
||||
return NO_TEXTURE_ID;
|
||||
}
|
||||
texId = GL11_UploadTextureData(surf->pixels, surf->w, surf->h);
|
||||
SDL_DestroySurface(surf);
|
||||
GLuint texId = UploadTextureData(surface->m_surface, m_useNPOT, isUi);
|
||||
|
||||
for (Uint32 i = 0; i < m_textures.size(); ++i) {
|
||||
auto& tex = m_textures[i];
|
||||
@ -147,12 +192,14 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
|
||||
tex.texture = texture;
|
||||
tex.version = texture->m_version;
|
||||
tex.glTextureId = texId;
|
||||
tex.width = surface->m_surface->w;
|
||||
tex.height = surface->m_surface->h;
|
||||
AddTextureDestroyCallback(i, texture);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
m_textures.push_back({texture, texture->m_version, texId});
|
||||
m_textures.push_back({texture, texture->m_version, texId, surface->m_surface->w, surface->m_surface->h});
|
||||
AddTextureDestroyCallback((Uint32) (m_textures.size() - 1), texture);
|
||||
return (Uint32) (m_textures.size() - 1);
|
||||
}
|
||||
@ -331,7 +378,7 @@ void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con
|
||||
float top = -m_viewportTransform.offsetY / m_viewportTransform.scale;
|
||||
float bottom = (m_height - m_viewportTransform.offsetY) / m_viewportTransform.scale;
|
||||
|
||||
GL11_Draw2DImage(m_textures[textureId].glTextureId, srcRect, dstRect, left, right, bottom, top);
|
||||
GL11_Draw2DImage(m_textures[textureId], srcRect, dstRect, left, right, bottom, top);
|
||||
}
|
||||
|
||||
void OpenGL1Renderer::Download(SDL_Surface* target)
|
||||
|
||||
@ -47,6 +47,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
||||
|
||||
SDL_GLContext context = SDL_GL_CreateContext(DDWindow);
|
||||
if (!context) {
|
||||
SDL_Log("SDL_GL_CreateContext: %s", SDL_GetError());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@ class OpenGL1Renderer : public Direct3DRMRenderer {
|
||||
D3DRMMATRIX4D m_projection;
|
||||
SDL_Surface* m_renderedImage;
|
||||
bool m_useVBOs;
|
||||
bool m_useNPOT;
|
||||
bool m_dirty = false;
|
||||
std::vector<SceneLight> m_lights;
|
||||
SDL_GLContext m_context;
|
||||
@ -54,11 +55,13 @@ class OpenGL1Renderer : public Direct3DRMRenderer {
|
||||
|
||||
inline static void OpenGL1Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
||||
{
|
||||
#ifndef __PSP__
|
||||
Direct3DRMRenderer* device = OpenGL1Renderer::Create(640, 480);
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
delete device;
|
||||
#endif
|
||||
|
||||
D3DDEVICEDESC halDesc = {};
|
||||
halDesc.dcmColorModel = D3DCOLORMODEL::RGB;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user