mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-11 10:31:16 +00:00
Add support for POT-only GPUs, fix VBO (#468)
This commit is contained in:
parent
12d4d6a89a
commit
7b06ee5ae6
@ -42,12 +42,26 @@ void GL11_DestroyTexture(GLuint texId)
|
|||||||
glDeleteTextures(1, &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;
|
GLuint texId;
|
||||||
glGenTextures(1, &texId);
|
glGenTextures(1, &texId);
|
||||||
glBindTexture(GL_TEXTURE_2D, 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);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||||
|
|
||||||
return texId;
|
return texId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +125,6 @@ void GL11_BeginFrame(const Matrix4x4* projection)
|
|||||||
glDepthMask(GL_TRUE);
|
glDepthMask(GL_TRUE);
|
||||||
glEnable(GL_LIGHTING);
|
glEnable(GL_LIGHTING);
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
|
||||||
|
|
||||||
// Disable all lights and reset global ambient
|
// Disable all lights and reset global ambient
|
||||||
for (int i = 0; i < 8; ++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
@ -198,6 +211,7 @@ void GL11_SubmitDraw(
|
|||||||
glLoadMatrixf(&modelViewMatrix[0][0]);
|
glLoadMatrixf(&modelViewMatrix[0][0]);
|
||||||
glEnable(GL_NORMALIZE);
|
glEnable(GL_NORMALIZE);
|
||||||
|
|
||||||
|
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||||
glColor4ub(appearance.color.r, appearance.color.g, appearance.color.b, appearance.color.a);
|
glColor4ub(appearance.color.r, appearance.color.g, appearance.color.b, appearance.color.a);
|
||||||
|
|
||||||
if (appearance.shininess != 0.0f) {
|
if (appearance.shininess != 0.0f) {
|
||||||
@ -220,8 +234,6 @@ void GL11_SubmitDraw(
|
|||||||
|
|
||||||
// Bind texture if present
|
// Bind texture if present
|
||||||
if (appearance.textureId != NO_TEXTURE_ID) {
|
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);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, texId);
|
glBindTexture(GL_TEXTURE_2D, texId);
|
||||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||||
@ -279,7 +291,7 @@ void GL11_Clear(float r, float g, float b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GL11_Draw2DImage(
|
void GL11_Draw2DImage(
|
||||||
GLuint texId,
|
GLTextureCacheEntry& cache,
|
||||||
const SDL_Rect& srcRect,
|
const SDL_Rect& srcRect,
|
||||||
const SDL_Rect& dstRect,
|
const SDL_Rect& dstRect,
|
||||||
float left,
|
float left,
|
||||||
@ -305,24 +317,17 @@ void GL11_Draw2DImage(
|
|||||||
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glBindTexture(GL_TEXTURE_2D, texId);
|
glBindTexture(GL_TEXTURE_2D, cache.glTextureId);
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
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;
|
GLint boundTexture = 0;
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &boundTexture);
|
||||||
|
|
||||||
GLfloat texW, texH;
|
float u1 = srcRect.x / cache.width;
|
||||||
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &texW);
|
float v1 = srcRect.y / cache.height;
|
||||||
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &texH);
|
float u2 = (srcRect.x + srcRect.w) / cache.width;
|
||||||
|
float v2 = (srcRect.y + srcRect.h) / cache.height;
|
||||||
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 x1 = (float) dstRect.x;
|
float x1 = (float) dstRect.x;
|
||||||
float y1 = (float) dstRect.y;
|
float y1 = (float) dstRect.y;
|
||||||
|
|||||||
@ -39,6 +39,8 @@ struct GLTextureCacheEntry {
|
|||||||
IDirect3DRMTexture* texture;
|
IDirect3DRMTexture* texture;
|
||||||
Uint32 version;
|
Uint32 version;
|
||||||
GLuint glTextureId;
|
GLuint glTextureId;
|
||||||
|
float width;
|
||||||
|
float height;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GLMeshCacheEntry {
|
struct GLMeshCacheEntry {
|
||||||
@ -62,7 +64,7 @@ struct GLMeshCacheEntry {
|
|||||||
void GL11_InitState();
|
void GL11_InitState();
|
||||||
void GL11_LoadExtensions();
|
void GL11_LoadExtensions();
|
||||||
void GL11_DestroyTexture(GLuint texId);
|
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_UploadMesh(GLMeshCacheEntry& cache, bool hasTexture);
|
||||||
void GL11_DestroyMesh(GLMeshCacheEntry& cache);
|
void GL11_DestroyMesh(GLMeshCacheEntry& cache);
|
||||||
void GL11_BeginFrame(const Matrix4x4* projection);
|
void GL11_BeginFrame(const Matrix4x4* projection);
|
||||||
@ -77,7 +79,7 @@ void GL11_SubmitDraw(
|
|||||||
void GL11_Resize(int width, int height);
|
void GL11_Resize(int width, int height);
|
||||||
void GL11_Clear(float r, float g, float b);
|
void GL11_Clear(float r, float g, float b);
|
||||||
void GL11_Draw2DImage(
|
void GL11_Draw2DImage(
|
||||||
GLuint texId,
|
GLTextureCacheEntry& cache,
|
||||||
const SDL_Rect& srcRect,
|
const SDL_Rect& srcRect,
|
||||||
const SDL_Rect& dstRect,
|
const SDL_Rect& dstRect,
|
||||||
float left,
|
float left,
|
||||||
|
|||||||
@ -58,6 +58,8 @@ OpenGL1Renderer::OpenGL1Renderer(DWORD width, DWORD height, SDL_GLContext contex
|
|||||||
m_virtualHeight = height;
|
m_virtualHeight = height;
|
||||||
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32);
|
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32);
|
||||||
GL11_LoadExtensions();
|
GL11_LoadExtensions();
|
||||||
|
m_useVBOs = SDL_GL_ExtensionSupported("GL_ARB_vertex_buffer_object");
|
||||||
|
m_useNPOT = SDL_GL_ExtensionSupported("GL_OES_texture_npot");
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGL1Renderer::~OpenGL1Renderer()
|
OpenGL1Renderer::~OpenGL1Renderer()
|
||||||
@ -108,6 +110,58 @@ 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;
|
||||||
|
|
||||||
|
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)
|
Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
|
||||||
{
|
{
|
||||||
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
|
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
|
||||||
@ -118,28 +172,16 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
|
|||||||
if (tex.texture == texture) {
|
if (tex.texture == texture) {
|
||||||
if (tex.version != texture->m_version) {
|
if (tex.version != texture->m_version) {
|
||||||
GL11_DestroyTexture(tex.glTextureId);
|
GL11_DestroyTexture(tex.glTextureId);
|
||||||
|
tex.glTextureId = UploadTextureData(surface->m_surface, m_useNPOT, isUi);
|
||||||
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.version = texture->m_version;
|
tex.version = texture->m_version;
|
||||||
|
tex.width = surface->m_surface->w;
|
||||||
|
tex.height = surface->m_surface->h;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLuint texId;
|
GLuint texId = UploadTextureData(surface->m_surface, m_useNPOT, isUi);
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
for (Uint32 i = 0; i < m_textures.size(); ++i) {
|
for (Uint32 i = 0; i < m_textures.size(); ++i) {
|
||||||
auto& tex = m_textures[i];
|
auto& tex = m_textures[i];
|
||||||
@ -147,12 +189,20 @@ Uint32 OpenGL1Renderer::GetTextureId(IDirect3DRMTexture* iTexture, bool isUi)
|
|||||||
tex.texture = texture;
|
tex.texture = texture;
|
||||||
tex.version = texture->m_version;
|
tex.version = texture->m_version;
|
||||||
tex.glTextureId = texId;
|
tex.glTextureId = texId;
|
||||||
|
tex.width = surface->m_surface->w;
|
||||||
|
tex.height = surface->m_surface->h;
|
||||||
AddTextureDestroyCallback(i, texture);
|
AddTextureDestroyCallback(i, texture);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_textures.push_back({texture, texture->m_version, texId});
|
m_textures.push_back(
|
||||||
|
{texture,
|
||||||
|
texture->m_version,
|
||||||
|
texId,
|
||||||
|
static_cast<float>(surface->m_surface->w),
|
||||||
|
static_cast<float>(surface->m_surface->h)}
|
||||||
|
);
|
||||||
AddTextureDestroyCallback((Uint32) (m_textures.size() - 1), texture);
|
AddTextureDestroyCallback((Uint32) (m_textures.size() - 1), texture);
|
||||||
return (Uint32) (m_textures.size() - 1);
|
return (Uint32) (m_textures.size() - 1);
|
||||||
}
|
}
|
||||||
@ -331,7 +381,7 @@ void OpenGL1Renderer::Draw2DImage(Uint32 textureId, const SDL_Rect& srcRect, con
|
|||||||
float top = -m_viewportTransform.offsetY / m_viewportTransform.scale;
|
float top = -m_viewportTransform.offsetY / m_viewportTransform.scale;
|
||||||
float bottom = (m_height - 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)
|
void OpenGL1Renderer::Download(SDL_Surface* target)
|
||||||
|
|||||||
@ -47,6 +47,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
|||||||
|
|
||||||
SDL_GLContext context = SDL_GL_CreateContext(DDWindow);
|
SDL_GLContext context = SDL_GL_CreateContext(DDWindow);
|
||||||
if (!context) {
|
if (!context) {
|
||||||
|
SDL_Log("SDL_GL_CreateContext: %s", SDL_GetError());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -46,6 +46,7 @@ class OpenGL1Renderer : public Direct3DRMRenderer {
|
|||||||
D3DRMMATRIX4D m_projection;
|
D3DRMMATRIX4D m_projection;
|
||||||
SDL_Surface* m_renderedImage;
|
SDL_Surface* m_renderedImage;
|
||||||
bool m_useVBOs;
|
bool m_useVBOs;
|
||||||
|
bool m_useNPOT;
|
||||||
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;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user