From 4ac67e5df87da7d94725789cedad2b69e8687007 Mon Sep 17 00:00:00 2001 From: aap Date: Wed, 18 Nov 2020 10:02:14 +0100 Subject: [PATCH] made GLES runtime option; also broke opengl txd format again --- src/gl/gl3device.cpp | 121 +++++++++++++--------- src/gl/gl3immed.cpp | 18 +--- src/gl/gl3matfx.cpp | 6 +- src/gl/gl3raster.cpp | 167 ++++++++++++++++++++----------- src/gl/gl3shader.cpp | 24 ++--- src/gl/gl3skin.cpp | 9 +- src/gl/rwgl3.h | 14 ++- src/gl/shaders/Makefile | 26 ++--- src/gl/shaders/default.vert | 11 +- src/gl/shaders/default_vs_gl.inc | 25 +++++ src/gl/shaders/header.frag | 4 + src/gl/shaders/header.vert | 17 ++++ src/gl/shaders/header_fs.inc | 4 + src/gl/shaders/header_vs.inc | 17 ++++ src/gl/shaders/im2d.vert | 10 +- src/gl/shaders/im2d_gl.inc | 21 ++++ src/gl/shaders/im3d.vert | 10 +- src/gl/shaders/im3d_gl.inc | 18 ++++ src/gl/shaders/matfx_env.frag | 13 +-- src/gl/shaders/matfx_env.vert | 13 +-- src/gl/shaders/matfx_gl.inc | 66 ++++++++++++ src/gl/shaders/simple.frag | 11 +- src/gl/shaders/simple_fs_gl.inc | 17 ++++ src/gl/shaders/skin.vert | 13 +-- src/gl/shaders/skin_gl.inc | 34 +++++++ 25 files changed, 476 insertions(+), 213 deletions(-) create mode 100644 src/gl/shaders/default_vs_gl.inc create mode 100644 src/gl/shaders/im2d_gl.inc create mode 100644 src/gl/shaders/im3d_gl.inc create mode 100644 src/gl/shaders/matfx_gl.inc create mode 100644 src/gl/shaders/simple_fs_gl.inc create mode 100644 src/gl/shaders/skin_gl.inc diff --git a/src/gl/gl3device.cpp b/src/gl/gl3device.cpp index 21b162c..3a8062a 100644 --- a/src/gl/gl3device.cpp +++ b/src/gl/gl3device.cpp @@ -60,6 +60,8 @@ struct GlGlobals } glGlobals; Gl3Caps gl3Caps; +// terrible hack for GLES +bool32 needToReadBackTextures; int32 alphaFunc; float32 alphaRef; @@ -107,30 +109,37 @@ struct GLShaderState SurfaceProperties surfProps; }; -const char *shaderDecl330 = "#version 330\n"; +const char *shaderDecl330 = +"#version 330\n" +"#define VSIN(index) layout(location = index) in\n" +"#define VSOUT out\n" +"#define FSIN in\n" +"#define FRAGCOLOR(c) (fragColor = c)\n"; const char *shaderDecl100es = -"#version 100\n"\ -"precision highp float;\n"\ +"#version 100\n" +"#define GL2\n" +"#define texture texture2D\n" +"#define VSIN(index) attribute\n" +"#define VSOUT varying\n" +"#define FSIN varying\n" +"#define FRAGCOLOR(c) (gl_FragColor = c)\n" +"precision highp float;\n" "precision highp int;\n"; const char *shaderDecl310es = -"#version 310 es\n"\ -"precision highp float;\n"\ +"#version 310 es\n" +"#define VSIN(index) layout(location = index) in\n" +"#define VSOUT out\n" +"#define FSIN in\n" +"#define FRAGCOLOR(c) (fragColor = c)\n" +"precision highp float;\n" "precision highp int;\n"; -#ifdef RW_GLES3 -const char *shaderDecl = shaderDecl310es; -#elif defined RW_GLES2 -const char *shaderDecl = shaderDecl100es; -#else -const char *shaderDecl = shaderDecl330; -#endif +const char *shaderDecl; // this needs a define in the shaders as well! //#define RW_GL_USE_UBOS -#ifndef RW_GLES2 static GLuint vao; -#endif #ifdef RW_GL_USE_UBOS static GLuint ubo_state, ubo_scene, ubo_object; #endif @@ -1082,8 +1091,12 @@ setFrameBuffer(Camera *cam) } natfb->fboMate = zbuf; natzb->fboMate = fbuf; - if(natfb->fbo) - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, natzb->texid, 0); + if(natfb->fbo){ + if(gl3Caps.gles) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, natzb->texid); + else + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, natzb->texid, 0); + } } }else{ // remove z-buffer @@ -1399,27 +1412,14 @@ openGLFW(EngineOpenParams *openparams) glGlobals.winTitle = openparams->windowtitle; glGlobals.pWindow = openparams->window; + memset(&gl3Caps, 0, sizeof(gl3Caps)); + /* Init GLFW */ if(!glfwInit()){ RWERROR((ERR_GENERAL, "glfwInit() failed")); return 0; } glfwWindowHint(GLFW_SAMPLES, 0); -#ifdef RW_GLES3 - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1); -#elif defined RW_GLES2 - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 0); -#else - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); -#endif glGlobals.monitor = glfwGetMonitors(&glGlobals.numMonitors)[0]; @@ -1441,6 +1441,17 @@ glfwerr(int error, const char *desc) fprintf(stderr, "GLFW Error: %s\n", desc); } +static struct { + int gl; + int major, minor; +} profiles[] = { + { GLFW_OPENGL_API, 3, 3 }, + { GLFW_OPENGL_API, 2, 1 }, + { GLFW_OPENGL_ES_API, 3, 1 }, + { GLFW_OPENGL_ES_API, 2, 0 }, + { 0, 0, 0 }, +}; + static int startGLFW(void) { @@ -1456,16 +1467,28 @@ startGLFW(void) glfwWindowHint(GLFW_BLUE_BITS, mode->mode.blueBits); glfwWindowHint(GLFW_REFRESH_RATE, mode->mode.refreshRate); - if(mode->flags & VIDEOMODEEXCLUSIVE) - win = glfwCreateWindow(mode->mode.width, mode->mode.height, glGlobals.winTitle, glGlobals.monitor, nil); - else - win = glfwCreateWindow(glGlobals.winWidth, glGlobals.winHeight, glGlobals.winTitle, nil, nil); + int i; + for(i = 0; profiles[i].gl; i++){ + glfwWindowHint(GLFW_CLIENT_API, profiles[i].gl); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, profiles[i].major); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, profiles[i].minor); + + if(mode->flags & VIDEOMODEEXCLUSIVE) + win = glfwCreateWindow(mode->mode.width, mode->mode.height, glGlobals.winTitle, glGlobals.monitor, nil); + else + win = glfwCreateWindow(glGlobals.winWidth, glGlobals.winHeight, glGlobals.winTitle, nil, nil); + if(win){ + gl3Caps.gles = profiles[i].gl == GLFW_OPENGL_ES_API; + gl3Caps.glversion = profiles[i].major*10 + profiles[i].minor; + break; + } + } if(win == nil){ RWERROR((ERR_GENERAL, "glfwCreateWindow() failed")); return 0; } glfwMakeContextCurrent(win); -printf("version %s\n", glGetString(GL_VERSION)); + printf("OpenGL version: %s\n", glGetString(GL_VERSION)); /* Init GLEW */ glewExperimental = GL_TRUE; @@ -1500,7 +1523,6 @@ stopGLFW(void) static int initOpenGL(void) { - memset(&gl3Caps, 0, sizeof(gl3Caps)); int numExt; glGetIntegerv(GL_NUM_EXTENSIONS, &numExt); for(int i = 0; i < numExt; i++){ @@ -1512,6 +1534,14 @@ initOpenGL(void) // printf("%d %s\n", i, ext); } + if(gl3Caps.gles){ + if(gl3Caps.glversion >= 30) + shaderDecl = shaderDecl310es; + else + shaderDecl = shaderDecl100es; + }else + shaderDecl = shaderDecl330; + #ifndef RW_GL_USE_UBOS u_alphaRef = registerUniform("u_alphaRef"); u_fogData = registerUniform("u_fogData"); @@ -1553,10 +1583,10 @@ initOpenGL(void) glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); -#ifndef RW_GLES2 - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); -#endif + if(gl3Caps.glversion >= 30){ + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + } #ifdef RW_GL_USE_UBOS glGenBuffers(1, &ubo_state); @@ -1581,13 +1611,8 @@ initOpenGL(void) glBindBuffer(GL_UNIFORM_BUFFER, 0); #endif -#ifdef RW_GLES2 -#include "gl2_shaders/default_vs_gl2.inc" -#include "gl2_shaders/simple_fs_gl2.inc" -#else -#include "shaders/default_vs_gl3.inc" -#include "shaders/simple_fs_gl3.inc" -#endif +#include "shaders/default_vs_gl.inc" +#include "shaders/simple_fs_gl.inc" const char *vs[] = { shaderDecl, header_vert_src, default_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; defaultShader = Shader::create(vs, fs); diff --git a/src/gl/gl3immed.cpp b/src/gl/gl3immed.cpp index a1bed63..e7678e2 100644 --- a/src/gl/gl3immed.cpp +++ b/src/gl/gl3immed.cpp @@ -56,13 +56,8 @@ openIm2D(void) { u_xform = registerUniform("u_xform"); -#ifdef RW_GLES2 -#include "gl2_shaders/im2d_gl2.inc" -#include "gl2_shaders/simple_fs_gl2.inc" -#else -#include "shaders/im2d_gl3.inc" -#include "shaders/simple_fs_gl3.inc" -#endif +#include "shaders/im2d_gl.inc" +#include "shaders/simple_fs_gl.inc" const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; im2dShader = Shader::create(vs, fs); @@ -216,13 +211,8 @@ static int32 num3DVertices; // not actually needed here void openIm3D(void) { -#ifdef RW_GLES2 -#include "gl2_shaders/im3d_gl2.inc" -#include "gl2_shaders/simple_fs_gl2.inc" -#else -#include "shaders/im3d_gl3.inc" -#include "shaders/simple_fs_gl3.inc" -#endif +#include "shaders/im3d_gl.inc" +#include "shaders/simple_fs_gl.inc" const char *vs[] = { shaderDecl, header_vert_src, im3d_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; im3dShader = Shader::create(vs, fs); diff --git a/src/gl/gl3matfx.cpp b/src/gl/gl3matfx.cpp index 98f67da..acd3121 100644 --- a/src/gl/gl3matfx.cpp +++ b/src/gl/gl3matfx.cpp @@ -176,11 +176,7 @@ matfxOpen(void *o, int32, int32) { matFXGlobals.pipelines[PLATFORM_GL3] = makeMatFXPipeline(); -#ifdef RW_GLES2 -#include "gl2_shaders/matfx_gl2.inc" -#else -#include "shaders/matfx_gl3.inc" -#endif +#include "shaders/matfx_gl.inc" const char *vs[] = { shaderDecl, header_vert_src, matfx_env_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, matfx_env_frag_src, nil }; envShader = Shader::create(vs, fs); diff --git a/src/gl/gl3raster.cpp b/src/gl/gl3raster.cpp index 5088cc6..a7437ed 100644 --- a/src/gl/gl3raster.cpp +++ b/src/gl/gl3raster.cpp @@ -97,13 +97,13 @@ rasterCreateTexture(Raster *raster) return nil; } -#ifdef RW_GLES - // glReadPixels only supports GL_RGBA - natras->internalFormat = GL_RGBA8; - natras->format = GL_RGBA; - natras->type = GL_UNSIGNED_BYTE; - natras->bpp = 4; -#endif + if(gl3Caps.gles){ + // glReadPixels only supports GL_RGBA + natras->internalFormat = GL_RGBA8; + natras->format = GL_RGBA; + natras->type = GL_UNSIGNED_BYTE; + natras->bpp = 4; + } raster->stride = raster->width*natras->bpp; @@ -174,13 +174,14 @@ rasterCreateCameraTexture(Raster *raster) break; } -#ifdef RW_GLES - // glReadPixels only supports GL_RGBA -// natras->internalFormat = GL_RGBA8; -// natras->format = GL_RGBA; -// natras->type = GL_UNSIGNED_BYTE; -// natras->bpp = 4; -#endif + // i don't remember why this was once here... + if(gl3Caps.gles){ + // glReadPixels only supports GL_RGBA +// natras->internalFormat = GL_RGBA8; +// natras->format = GL_RGBA; +// natras->type = GL_UNSIGNED_BYTE; +// natras->bpp = 4; + } raster->stride = raster->width*natras->bpp; @@ -228,25 +229,30 @@ rasterCreateZbuffer(Raster *raster) { Gl3Raster *natras = GETGL3RASTEREXT(raster); - // TODO: set/check width, height, depth, format? + if(gl3Caps.gles){ + // have to use RBO on GLES!! + glGenRenderbuffers(1, &natras->texid); + glBindRenderbuffer(GL_RENDERBUFFER, natras->texid); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, raster->width, raster->height); + }else{ + // TODO: set/check width, height, depth, format? + natras->internalFormat = GL_DEPTH_COMPONENT; + natras->format = GL_DEPTH_COMPONENT; + natras->type = GL_UNSIGNED_BYTE; - natras->internalFormat = GL_DEPTH_COMPONENT; - natras->format = GL_DEPTH_COMPONENT; - natras->type = GL_UNSIGNED_BYTE; + natras->autogenMipmap = 0; - natras->autogenMipmap = 0; - - glGenTextures(1, &natras->texid); - uint32 prev = bindTexture(natras->texid); - glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat, - raster->width, raster->height, - 0, natras->format, natras->type, nil); - natras->filterMode = 0; - natras->addressU = 0; - natras->addressV = 0; - - bindTexture(prev); + glGenTextures(1, &natras->texid); + uint32 prev = bindTexture(natras->texid); + glTexImage2D(GL_TEXTURE_2D, 0, natras->internalFormat, + raster->width, raster->height, + 0, natras->format, natras->type, nil); + natras->filterMode = 0; + natras->addressU = 0; + natras->addressV = 0; + bindTexture(prev); + } natras->fbo = 0; natras->fboMate = nil; @@ -318,6 +324,29 @@ allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha) bindTexture(prev); raster->originalStride = raster->stride; + + if(gl3Caps.gles && needToReadBackTextures){ + // Uh oh, need to keep a copy in cpu memory + int32 i; + int32 size = 0; + for(i = 0; i < natras->numLevels; i++) + size += getLevelSize(raster, i); + uint8 *data = (uint8*)rwNew(sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(natras->numLevels-1)+size, + MEMDUR_EVENT | ID_DRIVER); + RasterLevels *levels = (RasterLevels*)data; + data += sizeof(RasterLevels)+sizeof(RasterLevels::Level)*(natras->numLevels-1); + levels->numlevels = natras->numLevels; + levels->format = 0; // not needed + for(i = 0; i < natras->numLevels; i++){ + levels->levels[i].data = data; + levels->levels[i].size = getLevelSize(raster, i); + levels->levels[i].width = 0; // we don't need those here, maybe later... + levels->levels[i].height = 0; + data += levels->levels[i].size; + } + natras->backingStore = levels; + } + raster->flags &= ~Raster::DONTALLOCATE; #endif } @@ -403,6 +432,7 @@ rasterLock(Raster *raster, int32 level, int32 lockMode) #ifdef RW_OPENGL Gl3Raster *natras GETGL3RASTEREXT(raster); uint8 *px; + uint32 allocSz; int i; assert(raster->privateFlags == 0); @@ -420,34 +450,39 @@ rasterLock(Raster *raster, int32 level, int32 lockMode) raster->height /= 2; } - px = (uint8*)rwMalloc(getLevelSize(raster, level), MEMDUR_EVENT | ID_DRIVER); + allocSz = getLevelSize(raster, level); + px = (uint8*)rwMalloc(allocSz, MEMDUR_EVENT | ID_DRIVER); assert(raster->pixels == nil); raster->pixels = px; if(lockMode & Raster::LOCKREAD || !(lockMode & Raster::LOCKNOFETCH)){ if(natras->isCompressed){ - uint32 prev = bindTexture(natras->texid); - glGetCompressedTexImage(GL_TEXTURE_2D, level, px); - bindTexture(prev); - }else{ -#ifdef RW_GLES + if(natras->backingStore){ + assert(level < natras->backingStore->numlevels); + assert(allocSz >= natras->backingStore->levels[level].size); + memcpy(px, natras->backingStore->levels[level].data, allocSz); + }else{ + // GLES is losing here + uint32 prev = bindTexture(natras->texid); + glGetCompressedTexImage(GL_TEXTURE_2D, level, px); + bindTexture(prev); + } + }else if(gl3Caps.gles){ GLuint fbo; -GLenum e; glGenFramebuffers(1, &fbo); bindFramebuffer(fbo); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, natras->texid, 0); - e = glCheckFramebufferStatus(GL_FRAMEBUFFER); + GLenum e = glCheckFramebufferStatus(GL_FRAMEBUFFER); assert(natras->format == GL_RGBA); glReadPixels(0, 0, raster->width, raster->height, natras->format, natras->type, px); //e = glGetError(); printf("GL err4 %x (%x)\n", e, natras->format); bindFramebuffer(0); glDeleteFramebuffers(1, &fbo); -#else + }else{ uint32 prev = bindTexture(natras->texid); glPixelStorei(GL_PACK_ALIGNMENT, 1); glGetTexImage(GL_TEXTURE_2D, level, natras->format, natras->type, px); bindTexture(prev); -#endif } } @@ -475,12 +510,17 @@ rasterUnlock(Raster *raster, int32 level) if(raster->privateFlags & Raster::LOCKWRITE){ uint32 prev = bindTexture(natras->texid); - if(natras->isCompressed) + if(natras->isCompressed){ glCompressedTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat, raster->width, raster->height, 0, getLevelSize(raster, level), raster->pixels); - else{ + if(natras->backingStore){ + assert(level < natras->backingStore->numlevels); + memcpy(natras->backingStore->levels[level].data, raster->pixels, + natras->backingStore->levels[level].size); + } + }else{ glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat, raster->width, raster->height, @@ -584,38 +624,32 @@ rasterFromImage(Raster *raster, Image *image) assert(!natras->isCompressed); switch(image->depth){ case 32: -#ifdef RW_GLES - conv = conv_RGBA8888_from_RGBA8888; -#else - if(format == Raster::C8888) + if(gl3Caps.gles) + conv = conv_RGBA8888_from_RGBA8888; + else if(format == Raster::C8888) conv = conv_RGBA8888_from_RGBA8888; else if(format == Raster::C888) conv = conv_RGB888_from_RGB888; else goto err; -#endif break; case 24: -#ifdef RW_GLES - conv = conv_RGBA8888_from_RGB888; -#else - if(format == Raster::C8888) + if(gl3Caps.gles) + conv = conv_RGBA8888_from_RGB888; + else if(format == Raster::C8888) conv = conv_RGBA8888_from_RGB888; else if(format == Raster::C888) conv = conv_RGB888_from_RGB888; else goto err; -#endif break; case 16: -#ifdef RW_GLES - conv = conv_RGBA8888_from_ARGB1555; -#else - if(format == Raster::C1555) + if(gl3Caps.gles) + conv = conv_RGBA8888_from_ARGB1555; + else if(format == Raster::C1555) conv = conv_RGBA5551_from_ARGB1555; else goto err; -#endif break; case 8: @@ -668,6 +702,7 @@ createNativeRaster(void *object, int32 offset, int32) ras->texid = 0; ras->fbo = 0; ras->fboMate = nil; + ras->backingStore = nil; return object; } @@ -704,7 +739,10 @@ destroyNativeRaster(void *object, int32 offset, int32) } oldfb->fboMate = nil; } - glDeleteTextures(1, &natras->texid); + if(gl3Caps.gles) + glDeleteRenderbuffers(1, &natras->texid); + else + glDeleteTextures(1, &natras->texid); break; case Raster::CAMERA: @@ -719,6 +757,8 @@ destroyNativeRaster(void *object, int32 offset, int32) natras->texid = 0; natras->fbo = 0; + free(natras->backingStore); + #endif return object; } @@ -730,6 +770,7 @@ copyNativeRaster(void *dst, void *, int32 offset, int32) d->texid = 0; d->fbo = 0; d->fboMate = nil; + d->backingStore = nil; return dst; } @@ -763,9 +804,16 @@ readNativeTexture(Stream *stream) int32 numLevels = stream->readI32(); // Native raster + int32 subplatform = stream->readI32(); int32 flags = stream->readI32(); int32 compression = stream->readI32(); + if(subplatform != gl3Caps.gles){ + tex->destroy(); + RWERROR((ERR_PLATFORM, platform)); + return nil; + } + Raster *raster; Gl3Raster *natras; if(flags & 2){ @@ -841,6 +889,7 @@ writeNativeTexture(Texture *tex, Stream *stream) assert(0 && "unknown compression"); } } + stream->writeI32(gl3Caps.gles); stream->writeI32(flags); stream->writeI32(compression); // TODO: auto mipmaps? @@ -859,7 +908,7 @@ writeNativeTexture(Texture *tex, Stream *stream) uint32 getSizeNativeTexture(Texture *tex) { - uint32 size = 12 + 72 + 28; + uint32 size = 12 + 72 + 32; int32 levels = tex->raster->getNumLevels(); for(int32 i = 0; i < levels; i++) size += 4 + getLevelSize(tex->raster, i); diff --git a/src/gl/gl3shader.cpp b/src/gl/gl3shader.cpp index f46e5a0..0dc4a57 100644 --- a/src/gl/gl3shader.cpp +++ b/src/gl/gl3shader.cpp @@ -17,13 +17,8 @@ namespace rw { namespace gl3 { -#ifdef RW_GLES2 -#include "gl2_shaders/header_vs.inc" -#include "gl2_shaders/header_fs.inc" -#else #include "shaders/header_vs.inc" #include "shaders/header_fs.inc" -#endif UniformRegistry uniformRegistry; @@ -137,15 +132,16 @@ linkprogram(GLint vs, GLint fs, GLuint *program) prog = glCreateProgram(); -#ifdef RW_GLES2 - // TODO: perhaps just do this always and get rid of the layout stuff? - glBindAttribLocation(prog, ATTRIB_POS, "in_pos"); - glBindAttribLocation(prog, ATTRIB_NORMAL, "in_normal"); - glBindAttribLocation(prog, ATTRIB_COLOR, "in_color"); - glBindAttribLocation(prog, ATTRIB_TEXCOORDS0, "in_tex0"); - glBindAttribLocation(prog, ATTRIB_WEIGHTS, "in_weights"); - glBindAttribLocation(prog, ATTRIB_INDICES, "in_indices"); -#endif + if(gl3Caps.glversion < 30){ + // TODO: perhaps just do this always and get rid of the layout stuff? + glBindAttribLocation(prog, ATTRIB_POS, "in_pos"); + glBindAttribLocation(prog, ATTRIB_NORMAL, "in_normal"); + glBindAttribLocation(prog, ATTRIB_COLOR, "in_color"); + glBindAttribLocation(prog, ATTRIB_WEIGHTS, "in_weights"); + glBindAttribLocation(prog, ATTRIB_INDICES, "in_indices"); + glBindAttribLocation(prog, ATTRIB_TEXCOORDS0, "in_tex0"); + glBindAttribLocation(prog, ATTRIB_TEXCOORDS1, "in_tex1"); + } glAttachShader(prog, vs); glAttachShader(prog, fs); diff --git a/src/gl/gl3skin.cpp b/src/gl/gl3skin.cpp index fd103aa..aa5d527 100644 --- a/src/gl/gl3skin.cpp +++ b/src/gl/gl3skin.cpp @@ -297,13 +297,8 @@ skinOpen(void *o, int32, int32) { skinGlobals.pipelines[PLATFORM_GL3] = makeSkinPipeline(); -#ifdef RW_GLES2 -#include "gl2_shaders/simple_fs_gl2.inc" -#include "gl2_shaders/skin_gl2.inc" -#else -#include "shaders/simple_fs_gl3.inc" -#include "shaders/skin_gl3.inc" -#endif +#include "shaders/simple_fs_gl.inc" +#include "shaders/skin_gl.inc" const char *vs[] = { shaderDecl, header_vert_src, skin_vert_src, nil }; const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil }; skinShader = Shader::create(vs, fs); diff --git a/src/gl/rwgl3.h b/src/gl/rwgl3.h index f55d237..633c792 100644 --- a/src/gl/rwgl3.h +++ b/src/gl/rwgl3.h @@ -45,18 +45,16 @@ enum AttribIndices ATTRIB_POS = 0, ATTRIB_NORMAL, ATTRIB_COLOR, + ATTRIB_WEIGHTS, + ATTRIB_INDICES, ATTRIB_TEXCOORDS0, ATTRIB_TEXCOORDS1, -#ifndef RW_GLES2 ATTRIB_TEXCOORDS2, ATTRIB_TEXCOORDS3, ATTRIB_TEXCOORDS4, ATTRIB_TEXCOORDS5, ATTRIB_TEXCOORDS6, ATTRIB_TEXCOORDS7, -#endif - ATTRIB_WEIGHTS, - ATTRIB_INDICES }; // default uniform indices @@ -244,15 +242,21 @@ struct Gl3Raster uint32 fbo; // used for camera texture only! Raster *fboMate; // color or zbuffer raster mate of this one + RasterLevels *backingStore; // if we can't read back GPU memory but have to }; struct Gl3Caps { - // TODO: put more stuff into this + int gles; + int glversion; bool dxtSupported; bool astcSupported; // not used yet }; extern Gl3Caps gl3Caps; +// GLES can't read back textures very nicely. +// In most cases that's not an issue, but when it is, +// this has to be set before the texture is filled: +extern bool32 needToReadBackTextures; void allocateDXT(Raster *raster, int32 dxt, int32 numLevels, bool32 hasAlpha); diff --git a/src/gl/shaders/Makefile b/src/gl/shaders/Makefile index 2301a95..6471f17 100644 --- a/src/gl/shaders/Makefile +++ b/src/gl/shaders/Makefile @@ -1,4 +1,4 @@ -all: header_vs.inc header_fs.inc im2d_gl3.inc im3d_gl3.inc default_vs_gl3.inc simple_fs_gl3.inc matfx_gl3.inc skin_gl3.inc +all: header_vs.inc header_fs.inc im2d_gl.inc im3d_gl.inc default_vs_gl.inc simple_fs_gl.inc matfx_gl.inc skin_gl.inc header_vs.inc: header.vert (echo 'const char *header_vert_src =';\ @@ -10,36 +10,36 @@ header_fs.inc: header.frag sed 's/..*/"&\\n"/' header.frag;\ echo ';') >header_fs.inc -im2d_gl3.inc: im2d.vert +im2d_gl.inc: im2d.vert (echo 'const char *im2d_vert_src =';\ sed 's/..*/"&\\n"/' im2d.vert;\ - echo ';') >im2d_gl3.inc + echo ';') >im2d_gl.inc -im3d_gl3.inc: im3d.vert +im3d_gl.inc: im3d.vert (echo 'const char *im3d_vert_src =';\ sed 's/..*/"&\\n"/' im3d.vert;\ - echo ';') >im3d_gl3.inc + echo ';') >im3d_gl.inc -default_vs_gl3.inc: default.vert +default_vs_gl.inc: default.vert (echo 'const char *default_vert_src =';\ sed 's/..*/"&\\n"/' default.vert;\ - echo ';') >default_vs_gl3.inc + echo ';') >default_vs_gl.inc -simple_fs_gl3.inc: simple.frag +simple_fs_gl.inc: simple.frag (echo 'const char *simple_frag_src =';\ sed 's/..*/"&\\n"/' simple.frag;\ - echo ';') >simple_fs_gl3.inc + echo ';') >simple_fs_gl.inc -matfx_gl3.inc: matfx_env.frag matfx_env.vert +matfx_gl.inc: matfx_env.frag matfx_env.vert (echo 'const char *matfx_env_vert_src =';\ sed 's/..*/"&\\n"/' matfx_env.vert;\ echo ';';\ echo 'const char *matfx_env_frag_src =';\ sed 's/..*/"&\\n"/' matfx_env.frag;\ - echo ';') >matfx_gl3.inc + echo ';') >matfx_gl.inc -skin_gl3.inc: skin.vert +skin_gl.inc: skin.vert (echo 'const char *skin_vert_src =';\ sed 's/..*/"&\\n"/' skin.vert;\ - echo ';') >skin_gl3.inc + echo ';') >skin_gl.inc diff --git a/src/gl/shaders/default.vert b/src/gl/shaders/default.vert index edd3ac6..8e3fad7 100644 --- a/src/gl/shaders/default.vert +++ b/src/gl/shaders/default.vert @@ -1,11 +1,8 @@ -layout(location = 0) in vec3 in_pos; -layout(location = 1) in vec3 in_normal; -layout(location = 2) in vec4 in_color; -layout(location = 3) in vec2 in_tex0; +VSIN(ATTRIB_POS) vec3 in_pos; -out vec4 v_color; -out vec2 v_tex0; -out float v_fog; +VSOUT vec4 v_color; +VSOUT vec2 v_tex0; +VSOUT float v_fog; void main(void) diff --git a/src/gl/shaders/default_vs_gl.inc b/src/gl/shaders/default_vs_gl.inc new file mode 100644 index 0000000..6e3d6c4 --- /dev/null +++ b/src/gl/shaders/default_vs_gl.inc @@ -0,0 +1,25 @@ +const char *default_vert_src = +"VSIN(ATTRIB_POS) vec3 in_pos;\n" + +"VSOUT vec4 v_color;\n" +"VSOUT vec2 v_tex0;\n" +"VSOUT float v_fog;\n" + +"void\n" +"main(void)\n" +"{\n" +" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n" +" gl_Position = u_proj * u_view * Vertex;\n" +" vec3 Normal = mat3(u_world) * in_normal;\n" + +" v_tex0 = in_tex0;\n" + +" v_color = in_color;\n" +" v_color.rgb += u_ambLight.rgb*surfAmbient;\n" +" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n" +" v_color = clamp(v_color, 0.0, 1.0);\n" +" v_color *= u_matColor;\n" + +" v_fog = DoFog(gl_Position.w);\n" +"}\n" +; diff --git a/src/gl/shaders/header.frag b/src/gl/shaders/header.frag index 98b424b..ffe26e3 100644 --- a/src/gl/shaders/header.frag +++ b/src/gl/shaders/header.frag @@ -17,6 +17,10 @@ uniform vec4 u_fogColor; #define u_fogRange (u_fogData.z) #define u_fogDisable (u_fogData.w) +#ifndef GL2 +out vec4 fragColor; +#endif + void DoAlphaTest(float a) { if(a < u_alphaRef.x || a >= u_alphaRef.y) diff --git a/src/gl/shaders/header.vert b/src/gl/shaders/header.vert index 61b711a..81f86bd 100644 --- a/src/gl/shaders/header.vert +++ b/src/gl/shaders/header.vert @@ -3,6 +3,23 @@ //#define POINTLIGHTS //#define SPOTLIGHTS +#define ATTRIB_POS 0 +#define ATTRIB_NORMAL 1 +#define ATTRIB_COLOR 2 +#define ATTRIB_WEIGHTS 3 +#define ATTRIB_INDICES 4 +#define ATTRIB_TEXCOORDS0 5 +#define ATTRIB_TEXCOORDS1 6 + + +VSIN(ATTRIB_NORMAL) vec3 in_normal; +VSIN(ATTRIB_COLOR) vec4 in_color; +VSIN(ATTRIB_WEIGHTS) vec4 in_weights; +VSIN(ATTRIB_INDICES) vec4 in_indices; +VSIN(ATTRIB_TEXCOORDS0) vec2 in_tex0; +VSIN(ATTRIB_TEXCOORDS1) vec2 in_tex1; + + #ifdef USE_UBOS layout(std140) uniform State { diff --git a/src/gl/shaders/header_fs.inc b/src/gl/shaders/header_fs.inc index fc106a7..62ef8f2 100644 --- a/src/gl/shaders/header_fs.inc +++ b/src/gl/shaders/header_fs.inc @@ -18,6 +18,10 @@ const char *header_frag_src = "#define u_fogRange (u_fogData.z)\n" "#define u_fogDisable (u_fogData.w)\n" +"#ifndef GL2\n" +"out vec4 fragColor;\n" +"#endif\n" + "void DoAlphaTest(float a)\n" "{\n" " if(a < u_alphaRef.x || a >= u_alphaRef.y)\n" diff --git a/src/gl/shaders/header_vs.inc b/src/gl/shaders/header_vs.inc index a0ca752..cd37b25 100644 --- a/src/gl/shaders/header_vs.inc +++ b/src/gl/shaders/header_vs.inc @@ -4,6 +4,23 @@ const char *header_vert_src = "//#define POINTLIGHTS\n" "//#define SPOTLIGHTS\n" +"#define ATTRIB_POS 0\n" +"#define ATTRIB_NORMAL 1\n" +"#define ATTRIB_COLOR 2\n" +"#define ATTRIB_WEIGHTS 3\n" +"#define ATTRIB_INDICES 4\n" +"#define ATTRIB_TEXCOORDS0 5\n" +"#define ATTRIB_TEXCOORDS1 6\n" + + +"VSIN(ATTRIB_NORMAL) vec3 in_normal;\n" +"VSIN(ATTRIB_COLOR) vec4 in_color;\n" +"VSIN(ATTRIB_WEIGHTS) vec4 in_weights;\n" +"VSIN(ATTRIB_INDICES) vec4 in_indices;\n" +"VSIN(ATTRIB_TEXCOORDS0) vec2 in_tex0;\n" +"VSIN(ATTRIB_TEXCOORDS1) vec2 in_tex1;\n" + + "#ifdef USE_UBOS\n" "layout(std140) uniform State\n" "{\n" diff --git a/src/gl/shaders/im2d.vert b/src/gl/shaders/im2d.vert index 241593b..fcd81c2 100644 --- a/src/gl/shaders/im2d.vert +++ b/src/gl/shaders/im2d.vert @@ -1,12 +1,10 @@ uniform vec4 u_xform; -layout(location = 0) in vec4 in_pos; -layout(location = 2) in vec4 in_color; -layout(location = 3) in vec2 in_tex0; +VSIN(ATTRIB_POS) vec4 in_pos; -out vec4 v_color; -out vec2 v_tex0; -out float v_fog; +VSOUT vec4 v_color; +VSOUT vec2 v_tex0; +VSOUT float v_fog; void main(void) diff --git a/src/gl/shaders/im2d_gl.inc b/src/gl/shaders/im2d_gl.inc new file mode 100644 index 0000000..d11f5d3 --- /dev/null +++ b/src/gl/shaders/im2d_gl.inc @@ -0,0 +1,21 @@ +const char *im2d_vert_src = +"uniform vec4 u_xform;\n" + +"VSIN(ATTRIB_POS) vec4 in_pos;\n" + +"VSOUT vec4 v_color;\n" +"VSOUT vec2 v_tex0;\n" +"VSOUT float v_fog;\n" + +"void\n" +"main(void)\n" +"{\n" +" gl_Position = in_pos;\n" +" gl_Position.w = 1.0;\n" +" gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;\n" +" v_fog = DoFog(gl_Position.z);\n" +" gl_Position.xyz *= gl_Position.w;\n" +" v_color = in_color;\n" +" v_tex0 = in_tex0;\n" +"}\n" +; diff --git a/src/gl/shaders/im3d.vert b/src/gl/shaders/im3d.vert index 162d4f9..7088352 100644 --- a/src/gl/shaders/im3d.vert +++ b/src/gl/shaders/im3d.vert @@ -1,10 +1,8 @@ -layout(location = 0) in vec3 in_pos; -layout(location = 2) in vec4 in_color; -layout(location = 3) in vec2 in_tex0; +VSIN(ATTRIB_POS) vec3 in_pos; -out vec4 v_color; -out vec2 v_tex0; -out float v_fog; +VSOUT vec4 v_color; +VSOUT vec2 v_tex0; +VSOUT float v_fog; void main(void) diff --git a/src/gl/shaders/im3d_gl.inc b/src/gl/shaders/im3d_gl.inc new file mode 100644 index 0000000..389589b --- /dev/null +++ b/src/gl/shaders/im3d_gl.inc @@ -0,0 +1,18 @@ +const char *im3d_vert_src = +"VSIN(ATTRIB_POS) vec3 in_pos;\n" + +"VSOUT vec4 v_color;\n" +"VSOUT vec2 v_tex0;\n" +"VSOUT float v_fog;\n" + +"void\n" +"main(void)\n" +"{\n" +" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n" +" vec4 CamVertex = u_view * Vertex;\n" +" gl_Position = u_proj * CamVertex;\n" +" v_color = in_color;\n" +" v_tex0 = in_tex0;\n" +" v_fog = DoFog(gl_Position.w);\n" +"}\n" +; diff --git a/src/gl/shaders/matfx_env.frag b/src/gl/shaders/matfx_env.frag index 0d11871..4164ed1 100644 --- a/src/gl/shaders/matfx_env.frag +++ b/src/gl/shaders/matfx_env.frag @@ -7,12 +7,10 @@ uniform vec4 u_colorClamp; #define shininess (u_fxparams.x) #define disableFBA (u_fxparams.y) -in vec4 v_color; -in vec2 v_tex0; -in vec2 v_tex1; -in float v_fog; - -out vec4 color; +FSIN vec4 v_color; +FSIN vec2 v_tex0; +FSIN vec2 v_tex1; +FSIN float v_fog; void main(void) @@ -27,8 +25,11 @@ main(void) pass2.rgb = mix(vec3(0.0, 0.0, 0.0), pass2.rgb, v_fog); float fba = max(pass1.a, disableFBA); + vec4 color; color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba; color.a = pass1.a; DoAlphaTest(color.a); + + FRAGCOLOR(color); } diff --git a/src/gl/shaders/matfx_env.vert b/src/gl/shaders/matfx_env.vert index b19ae0f..b93c7ea 100644 --- a/src/gl/shaders/matfx_env.vert +++ b/src/gl/shaders/matfx_env.vert @@ -1,14 +1,11 @@ uniform mat4 u_texMatrix; -layout(location = 0) in vec3 in_pos; -layout(location = 1) in vec3 in_normal; -layout(location = 2) in vec4 in_color; -layout(location = 3) in vec2 in_tex0; +VSIN(ATTRIB_POS) vec3 in_pos; -out vec4 v_color; -out vec2 v_tex0; -out vec2 v_tex1; -out float v_fog; +VSOUT vec4 v_color; +VSOUT vec2 v_tex0; +VSOUT vec2 v_tex1; +VSOUT float v_fog; void main(void) diff --git a/src/gl/shaders/matfx_gl.inc b/src/gl/shaders/matfx_gl.inc new file mode 100644 index 0000000..f7296a8 --- /dev/null +++ b/src/gl/shaders/matfx_gl.inc @@ -0,0 +1,66 @@ +const char *matfx_env_vert_src = +"uniform mat4 u_texMatrix;\n" + +"VSIN(ATTRIB_POS) vec3 in_pos;\n" + +"VSOUT vec4 v_color;\n" +"VSOUT vec2 v_tex0;\n" +"VSOUT vec2 v_tex1;\n" +"VSOUT float v_fog;\n" + +"void\n" +"main(void)\n" +"{\n" +" vec4 Vertex = u_world * vec4(in_pos, 1.0);\n" +" gl_Position = u_proj * u_view * Vertex;\n" +" vec3 Normal = mat3(u_world) * in_normal;\n" + +" v_tex0 = in_tex0;\n" +" v_tex1 = (u_texMatrix * vec4(Normal, 1.0)).xy;\n" + +" v_color = in_color;\n" +" v_color.rgb += u_ambLight.rgb*surfAmbient;\n" +" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n" +" v_color = clamp(v_color, 0.0, 1.0);\n" +" v_color *= u_matColor;\n" + +" v_fog = DoFog(gl_Position.w);\n" +"}\n" +; +const char *matfx_env_frag_src = +"uniform sampler2D tex0;\n" +"uniform sampler2D tex1;\n" + +"uniform vec2 u_fxparams;\n" +"uniform vec4 u_colorClamp;\n" + +"#define shininess (u_fxparams.x)\n" +"#define disableFBA (u_fxparams.y)\n" + +"FSIN vec4 v_color;\n" +"FSIN vec2 v_tex0;\n" +"FSIN vec2 v_tex1;\n" +"FSIN float v_fog;\n" + +"void\n" +"main(void)\n" +"{\n" +" vec4 pass1 = v_color;\n" +" vec4 envColor = max(pass1, u_colorClamp);\n" +" pass1 *= texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n" + +" vec4 pass2 = envColor*shininess*texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));\n" + +" pass1.rgb = mix(u_fogColor.rgb, pass1.rgb, v_fog);\n" +" pass2.rgb = mix(vec3(0.0, 0.0, 0.0), pass2.rgb, v_fog);\n" + +" float fba = max(pass1.a, disableFBA);\n" +" vec4 color;\n" +" color.rgb = pass1.rgb*pass1.a + pass2.rgb*fba;\n" +" color.a = pass1.a;\n" + +" DoAlphaTest(color.a);\n" + +" FRAGCOLOR(color);\n" +"}\n" +; diff --git a/src/gl/shaders/simple.frag b/src/gl/shaders/simple.frag index 87157be..32b2afb 100644 --- a/src/gl/shaders/simple.frag +++ b/src/gl/shaders/simple.frag @@ -1,16 +1,15 @@ uniform sampler2D tex0; -in vec4 v_color; -in vec2 v_tex0; -in float v_fog; - -out vec4 color; +FSIN vec4 v_color; +FSIN vec2 v_tex0; +FSIN float v_fog; void main(void) { - color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y)); + vec4 color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y)); color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog); DoAlphaTest(color.a); + FRAGCOLOR(color); } diff --git a/src/gl/shaders/simple_fs_gl.inc b/src/gl/shaders/simple_fs_gl.inc new file mode 100644 index 0000000..a9216ca --- /dev/null +++ b/src/gl/shaders/simple_fs_gl.inc @@ -0,0 +1,17 @@ +const char *simple_frag_src = +"uniform sampler2D tex0;\n" + +"FSIN vec4 v_color;\n" +"FSIN vec2 v_tex0;\n" +"FSIN float v_fog;\n" + +"void\n" +"main(void)\n" +"{\n" +" vec4 color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n" +" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n" +" DoAlphaTest(color.a);\n" +" FRAGCOLOR(color);\n" +"}\n" + +; diff --git a/src/gl/shaders/skin.vert b/src/gl/shaders/skin.vert index ff198b1..7408542 100644 --- a/src/gl/shaders/skin.vert +++ b/src/gl/shaders/skin.vert @@ -1,15 +1,10 @@ uniform mat4 u_boneMatrices[64]; -layout(location = 0) in vec3 in_pos; -layout(location = 1) in vec3 in_normal; -layout(location = 2) in vec4 in_color; -layout(location = 3) in vec2 in_tex0; -layout(location = 11) in vec4 in_weights; -layout(location = 12) in vec4 in_indices; +VSIN(ATTRIB_POS) vec3 in_pos; -out vec4 v_color; -out vec2 v_tex0; -out float v_fog; +VSOUT vec4 v_color; +VSOUT vec2 v_tex0; +VSOUT float v_fog; void main(void) diff --git a/src/gl/shaders/skin_gl.inc b/src/gl/shaders/skin_gl.inc new file mode 100644 index 0000000..7d1268e --- /dev/null +++ b/src/gl/shaders/skin_gl.inc @@ -0,0 +1,34 @@ +const char *skin_vert_src = +"uniform mat4 u_boneMatrices[64];\n" + +"VSIN(ATTRIB_POS) vec3 in_pos;\n" + +"VSOUT vec4 v_color;\n" +"VSOUT vec2 v_tex0;\n" +"VSOUT float v_fog;\n" + +"void\n" +"main(void)\n" +"{\n" +" vec3 SkinVertex = vec3(0.0, 0.0, 0.0);\n" +" vec3 SkinNormal = vec3(0.0, 0.0, 0.0);\n" +" for(int i = 0; i < 4; i++){\n" +" SkinVertex += (u_boneMatrices[int(in_indices[i])] * vec4(in_pos, 1.0)).xyz * in_weights[i];\n" +" SkinNormal += (mat3(u_boneMatrices[int(in_indices[i])]) * in_normal) * in_weights[i];\n" +" }\n" + +" vec4 Vertex = u_world * vec4(SkinVertex, 1.0);\n" +" gl_Position = u_proj * u_view * Vertex;\n" +" vec3 Normal = mat3(u_world) * SkinNormal;\n" + +" v_tex0 = in_tex0;\n" + +" v_color = in_color;\n" +" v_color.rgb += u_ambLight.rgb*surfAmbient;\n" +" v_color.rgb += DoDynamicLight(Vertex.xyz, Normal)*surfDiffuse;\n" +" v_color = clamp(v_color, 0.0, 1.0);\n" +" v_color *= u_matColor;\n" + +" v_fog = DoFog(gl_Position.z);\n" +"}\n" +;