mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-10 18:21:14 +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);
|
||||
}
|
||||
|
||||
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,6 +211,7 @@ void GL11_SubmitDraw(
|
||||
glLoadMatrixf(&modelViewMatrix[0][0]);
|
||||
glEnable(GL_NORMALIZE);
|
||||
|
||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||
glColor4ub(appearance.color.r, appearance.color.g, appearance.color.b, appearance.color.a);
|
||||
|
||||
if (appearance.shininess != 0.0f) {
|
||||
@ -220,8 +234,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 +291,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 +317,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,
|
||||
|
||||
@ -58,6 +58,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_OES_texture_npot");
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
auto texture = static_cast<Direct3DRMTextureImpl*>(iTexture);
|
||||
@ -118,28 +172,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 +189,20 @@ 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,
|
||||
static_cast<float>(surface->m_surface->w),
|
||||
static_cast<float>(surface->m_surface->h)}
|
||||
);
|
||||
AddTextureDestroyCallback((Uint32) (m_textures.size() - 1), texture);
|
||||
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 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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user