mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-12 02:41:14 +00:00
Update OpenGL ES 2.0 renderer
This commit is contained in:
parent
d32c815de4
commit
f8e32ce052
@ -15,8 +15,17 @@ static GLuint CompileShader(GLenum type, const char* source)
|
||||
GLint success;
|
||||
glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
|
||||
if (!success) {
|
||||
GLint logLength = 0;
|
||||
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength);
|
||||
if (logLength > 0) {
|
||||
std::vector<char> log(logLength);
|
||||
glGetShaderInfoLog(shader, logLength, nullptr, log.data());
|
||||
SDL_Log("Shader compile error: %s", log.data());
|
||||
}
|
||||
else {
|
||||
SDL_Log("CompileShader (%s)", SDL_GetError());
|
||||
}
|
||||
glDeleteShader(shader);
|
||||
SDL_Log("CompileShader (%s)", SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
return shader;
|
||||
@ -28,7 +37,7 @@ struct SceneLightGLES2 {
|
||||
float direction[4];
|
||||
};
|
||||
|
||||
Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
||||
Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height, float anisotropic)
|
||||
{
|
||||
// We have to reset the attributes here after having enumerated the
|
||||
// OpenGL ES 2.0 renderer, or else SDL gets very confused by SDL_GL_DEPTH_SIZE
|
||||
@ -134,7 +143,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
||||
|
||||
// Specular
|
||||
if (u_shininess > 0.0 && u_lights[i].direction.w == 1.0) {
|
||||
vec3 viewVec = normalize(-v_viewPos); // Assuming camera at origin
|
||||
vec3 viewVec = normalize(-v_viewPos);
|
||||
vec3 H = normalize(lightVec + viewVec);
|
||||
float dotNH = max(dot(v_normal, H), 0.0);
|
||||
float spec = pow(dotNH, u_shininess);
|
||||
@ -168,7 +177,7 @@ Direct3DRMRenderer* OpenGLES2Renderer::Create(DWORD width, DWORD height)
|
||||
glDeleteShader(vs);
|
||||
glDeleteShader(fs);
|
||||
|
||||
return new OpenGLES2Renderer(width, height, context, shaderProgram);
|
||||
return new OpenGLES2Renderer(width, height, anisotropic, context, shaderProgram);
|
||||
}
|
||||
|
||||
GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = false)
|
||||
@ -237,7 +246,7 @@ GLES2MeshCacheEntry GLES2UploadMesh(const MeshGroup& meshGroup, bool forceUV = f
|
||||
return cache;
|
||||
}
|
||||
|
||||
bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
|
||||
bool OpenGLES2Renderer::UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
|
||||
{
|
||||
SDL_Surface* surf = source;
|
||||
if (source->format != SDL_PIXELFORMAT_RGBA32) {
|
||||
@ -262,11 +271,8 @@ bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
|
||||
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);
|
||||
if (m_anisotropic > 1.0f) {
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_anisotropic);
|
||||
}
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
}
|
||||
@ -278,12 +284,34 @@ bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI)
|
||||
return true;
|
||||
}
|
||||
|
||||
OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram)
|
||||
: m_context(context), m_shaderProgram(shaderProgram)
|
||||
OpenGLES2Renderer::OpenGLES2Renderer(
|
||||
DWORD width,
|
||||
DWORD height,
|
||||
float anisotropic,
|
||||
SDL_GLContext context,
|
||||
GLuint shaderProgram
|
||||
)
|
||||
: m_context(context), m_shaderProgram(shaderProgram), m_anisotropic(anisotropic)
|
||||
{
|
||||
glGenFramebuffers(1, &m_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
|
||||
bool anisoAvailable = SDL_GL_ExtensionSupported("GL_EXT_texture_filter_anisotropic");
|
||||
GLfloat maxAniso = 0.0f;
|
||||
if (anisoAvailable) {
|
||||
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAniso);
|
||||
}
|
||||
if (m_anisotropic > maxAniso) {
|
||||
m_anisotropic = maxAniso;
|
||||
}
|
||||
SDL_Log(
|
||||
"Anisotropic is %s. Requested: %f, active: %f, max aniso: %f",
|
||||
m_anisotropic > 1.0f ? "on" : "off",
|
||||
anisotropic,
|
||||
m_anisotropic,
|
||||
maxAniso
|
||||
);
|
||||
|
||||
m_virtualWidth = width;
|
||||
m_virtualHeight = height;
|
||||
ViewportTransform viewportTransform = {1.0f, 0.0f, 0.0f};
|
||||
@ -310,14 +338,6 @@ OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext co
|
||||
}
|
||||
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}},
|
||||
{{1.0f, 1.0f, 0.0f}, {0, 0, -1}, {1.0f, 1.0f}},
|
||||
{{0.0f, 1.0f, 0.0f}, {0, 0, -1}, {0.0f, 1.0f}}
|
||||
};
|
||||
m_uiMesh.indices = {0, 1, 2, 0, 2, 3};
|
||||
m_uiMeshCache = GLES2UploadMesh(m_uiMesh, true);
|
||||
m_posLoc = glGetAttribLocation(m_shaderProgram, "a_position");
|
||||
m_normLoc = glGetAttribLocation(m_shaderProgram, "a_normal");
|
||||
m_texLoc = glGetAttribLocation(m_shaderProgram, "a_texCoord");
|
||||
@ -336,13 +356,26 @@ OpenGLES2Renderer::OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext co
|
||||
m_normalMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_normalMatrix");
|
||||
m_projectionMatrixLoc = glGetUniformLocation(m_shaderProgram, "u_projectionMatrix");
|
||||
|
||||
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}},
|
||||
{{1.0f, 1.0f, 0.0f}, {0, 0, -1}, {1.0f, 1.0f}},
|
||||
{{0.0f, 1.0f, 0.0f}, {0, 0, -1}, {0.0f, 1.0f}}
|
||||
};
|
||||
m_uiMesh.indices = {0, 1, 2, 0, 2, 3};
|
||||
m_uiMeshCache = GLES2UploadMesh(m_uiMesh, true);
|
||||
|
||||
glUseProgram(m_shaderProgram);
|
||||
}
|
||||
|
||||
OpenGLES2Renderer::~OpenGLES2Renderer()
|
||||
{
|
||||
SDL_DestroySurface(m_renderedImage);
|
||||
glDeleteTextures(1, &m_dummyTexture);
|
||||
glDeleteProgram(m_shaderProgram);
|
||||
glDeleteTextures(1, &m_colorTarget);
|
||||
glDeleteRenderbuffers(1, &m_depthTarget);
|
||||
glDeleteFramebuffers(1, &m_fbo);
|
||||
SDL_GL_DestroyContext(m_context);
|
||||
}
|
||||
|
||||
@ -610,6 +643,15 @@ void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& v
|
||||
}
|
||||
m_renderedImage = SDL_CreateSurface(m_width, m_height, SDL_PIXELFORMAT_RGBA32);
|
||||
|
||||
if (m_colorTarget) {
|
||||
glDeleteTextures(1, &m_colorTarget);
|
||||
m_colorTarget = 0;
|
||||
}
|
||||
if (m_depthTarget) {
|
||||
glDeleteRenderbuffers(1, &m_depthTarget);
|
||||
m_depthTarget = 0;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
|
||||
// Create color texture
|
||||
@ -636,6 +678,12 @@ void OpenGLES2Renderer::Resize(int width, int height, const ViewportTransform& v
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
|
||||
}
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, m_depthTarget);
|
||||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
if (status != GL_FRAMEBUFFER_COMPLETE) {
|
||||
SDL_Log("FBO incomplete: 0x%X", status);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_fbo);
|
||||
|
||||
glViewport(0, 0, m_width, m_height);
|
||||
}
|
||||
|
||||
@ -49,7 +49,7 @@ Direct3DRMRenderer* CreateDirect3DRMRenderer(
|
||||
#endif
|
||||
#ifdef USE_OPENGLES2
|
||||
if (SDL_memcmp(guid, &OpenGLES2_GUID, sizeof(GUID)) == 0) {
|
||||
return OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight);
|
||||
return OpenGLES2Renderer::Create(DDSDesc.dwWidth, DDSDesc.dwHeight, d3d->GetAnisotropic());
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_OPENGL1
|
||||
@ -79,7 +79,7 @@ void Direct3DRMRenderer_EnumDevices(const IDirect3DMiniwin* d3d, LPD3DENUMDEVICE
|
||||
OpenGLES3Renderer_EnumDevice(d3d, cb, ctx);
|
||||
#endif
|
||||
#ifdef USE_OPENGLES2
|
||||
OpenGLES2Renderer_EnumDevice(cb, ctx);
|
||||
OpenGLES2Renderer_EnumDevice(d3d, cb, ctx);
|
||||
#endif
|
||||
#ifdef USE_OPENGL1
|
||||
OpenGL1Renderer_EnumDevice(d3d, cb, ctx);
|
||||
|
||||
@ -32,8 +32,8 @@ struct GLES2MeshCacheEntry {
|
||||
|
||||
class OpenGLES2Renderer : public Direct3DRMRenderer {
|
||||
public:
|
||||
static Direct3DRMRenderer* Create(DWORD width, DWORD height);
|
||||
OpenGLES2Renderer(DWORD width, DWORD height, SDL_GLContext context, GLuint shaderProgram);
|
||||
static Direct3DRMRenderer* Create(DWORD width, DWORD height, float anisotropic);
|
||||
OpenGLES2Renderer(DWORD width, DWORD height, float anisotropic, SDL_GLContext context, GLuint shaderProgram);
|
||||
~OpenGLES2Renderer() override;
|
||||
|
||||
void PushLights(const SceneLight* lightsArray, size_t count) override;
|
||||
@ -62,6 +62,7 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
|
||||
private:
|
||||
void AddTextureDestroyCallback(Uint32 id, IDirect3DRMTexture* texture);
|
||||
void AddMeshDestroyCallback(Uint32 id, IDirect3DRMMesh* mesh);
|
||||
bool UploadTexture(SDL_Surface* source, GLuint& outTexId, bool isUI);
|
||||
|
||||
MeshGroup m_uiMesh;
|
||||
GLES2MeshCacheEntry m_uiMeshCache;
|
||||
@ -72,6 +73,7 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
|
||||
bool m_dirty = false;
|
||||
std::vector<SceneLight> m_lights;
|
||||
SDL_GLContext m_context;
|
||||
float m_anisotropic;
|
||||
GLuint m_fbo;
|
||||
GLuint m_colorTarget;
|
||||
GLuint m_depthTarget;
|
||||
@ -92,9 +94,9 @@ class OpenGLES2Renderer : public Direct3DRMRenderer {
|
||||
ViewportTransform m_viewportTransform;
|
||||
};
|
||||
|
||||
inline static void OpenGLES2Renderer_EnumDevice(LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
||||
inline static void OpenGLES2Renderer_EnumDevice(const IDirect3DMiniwin* d3d, LPD3DENUMDEVICESCALLBACK cb, void* ctx)
|
||||
{
|
||||
Direct3DRMRenderer* device = OpenGLES2Renderer::Create(640, 480);
|
||||
Direct3DRMRenderer* device = OpenGLES2Renderer::Create(640, 480, d3d->GetAnisotropic());
|
||||
if (!device) {
|
||||
return;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user