From 67af3b870f95265225db96ef043ab6bcd4b1bfbf Mon Sep 17 00:00:00 2001 From: XProger Date: Tue, 24 Apr 2018 03:15:22 +0300 Subject: [PATCH] platform and API defines, add GAPI namespace and basic Pipeline State Object structure --- src/cache.h | 168 ++-- src/camera.h | 2 +- src/core.h | 1001 +++++---------------- src/debug.h | 18 +- src/game.h | 4 +- src/gameflow.h | 4 +- src/gapi_gl.h | 555 ++++++++++++ src/gapi_gu.h | 215 +++++ src/gapi_gx.h | 6 + src/gapi_vk.h | 6 + src/inventory.h | 40 +- src/lara.h | 6 +- src/level.h | 66 +- src/mesh.h | 60 +- src/platform/psp/main.cpp | 8 +- src/platform/web/index.html | 6 +- src/platform/web/main.cpp | 7 + src/platform/win/OpenLara.vcxproj | 22 +- src/platform/win/OpenLara.vcxproj.filters | 4 + src/platform/win/main.cpp | 3 +- src/shader.h | 14 +- src/sound.h | 6 +- src/texture.h | 63 +- src/trigger.h | 10 +- src/ui.h | 16 +- src/utils.h | 14 +- 26 files changed, 1280 insertions(+), 1044 deletions(-) create mode 100644 src/gapi_gl.h create mode 100644 src/gapi_gu.h create mode 100644 src/gapi_gx.h create mode 100644 src/gapi_vk.h diff --git a/src/cache.h b/src/cache.h index 3927494..9c43ec7 100644 --- a/src/cache.h +++ b/src/cache.h @@ -12,28 +12,11 @@ //#define WATER_USE_GRID #define UNDERWATER_COLOR "#define UNDERWATER_COLOR vec3(0.6, 0.9, 0.9)\n" -#ifndef FFP -const char SHADER[] = - #include "shaders/shader.glsl" -; - -const char WATER[] = - #include "shaders/water.glsl" -; - -const char FILTER[] = - #include "shaders/filter.glsl" -; - -const char GUI[] = - #include "shaders/gui.glsl" -; -#endif - struct ShaderCache { enum Effect { FX_NONE = 0, FX_UNDERWATER = 1, FX_ALPHA_TEST = 2, FX_CLIP_PLANE = 4 }; Shader *shaders[Core::passMAX][Shader::MAX][(FX_UNDERWATER | FX_ALPHA_TEST | FX_CLIP_PLANE) + 1]; + PSO *pso[Core::passMAX][Shader::MAX][(FX_UNDERWATER | FX_ALPHA_TEST | FX_CLIP_PLANE) + 1][bmMAX]; ShaderCache() { memset(shaders, 0, sizeof(shaders)); @@ -64,64 +47,77 @@ struct ShaderCache { delete shaders[pass][type][fx]; } - void prepareCompose(int fx) { - compile(Core::passCompose, Shader::MIRROR, fx | FX_NONE); - compile(Core::passCompose, Shader::ROOM, fx | FX_NONE); - compile(Core::passCompose, Shader::ROOM, fx | FX_ALPHA_TEST); - compile(Core::passCompose, Shader::ROOM, fx | FX_UNDERWATER); - compile(Core::passCompose, Shader::ROOM, fx | FX_UNDERWATER | FX_ALPHA_TEST); + #define rsBase (RS_COLOR_WRITE | RS_DEPTH_TEST | RS_DEPTH_WRITE | RS_CULL_FRONT) + #define rsBlend (RS_BLEND_ALPHA | RS_BLEND_ADD) + #define rsFull (rsBase | rsBlend) + #define rsShadow (RS_DEPTH_TEST | RS_DEPTH_WRITE | RS_CULL_BACK) - compile(Core::passCompose, Shader::ENTITY, fx | FX_NONE); - compile(Core::passCompose, Shader::ENTITY, fx | FX_UNDERWATER); - compile(Core::passCompose, Shader::ENTITY, fx | FX_UNDERWATER | FX_ALPHA_TEST); - compile(Core::passCompose, Shader::ENTITY, fx | FX_ALPHA_TEST); - compile(Core::passCompose, Shader::SPRITE, fx | FX_ALPHA_TEST); - compile(Core::passCompose, Shader::SPRITE, fx | FX_UNDERWATER | FX_ALPHA_TEST); - compile(Core::passCompose, Shader::FLASH, fx | FX_NONE); - compile(Core::passCompose, Shader::FLASH, fx | FX_ALPHA_TEST); + void prepareCompose(int fx) { + compile(Core::passCompose, Shader::MIRROR, fx, rsBase); + compile(Core::passCompose, Shader::ROOM, fx, rsFull); + compile(Core::passCompose, Shader::ROOM, fx, rsFull | RS_DISCARD); + compile(Core::passCompose, Shader::ROOM, fx | FX_UNDERWATER, rsFull); + compile(Core::passCompose, Shader::ROOM, fx | FX_UNDERWATER, rsFull | RS_DISCARD); + + compile(Core::passCompose, Shader::ENTITY, fx, rsFull); + compile(Core::passCompose, Shader::ENTITY, fx | FX_UNDERWATER, rsFull); + compile(Core::passCompose, Shader::ENTITY, fx | FX_UNDERWATER, rsFull | RS_DISCARD); + compile(Core::passCompose, Shader::ENTITY, fx, rsFull | RS_DISCARD); + compile(Core::passCompose, Shader::SPRITE, fx, rsFull | RS_DISCARD); + compile(Core::passCompose, Shader::SPRITE, fx | FX_UNDERWATER, rsFull | RS_DISCARD); + compile(Core::passCompose, Shader::FLASH, fx, rsFull | RS_BLEND_MULT); + compile(Core::passCompose, Shader::FLASH, fx, rsFull | RS_BLEND_MULT | RS_DISCARD); } void prepareAmbient(int fx) { - compile(Core::passAmbient, Shader::ROOM, fx | FX_NONE); - compile(Core::passAmbient, Shader::ROOM, fx | FX_ALPHA_TEST); - compile(Core::passAmbient, Shader::ROOM, fx | FX_UNDERWATER); - compile(Core::passAmbient, Shader::ROOM, fx | FX_UNDERWATER | FX_ALPHA_TEST); - compile(Core::passAmbient, Shader::SPRITE, fx | FX_ALPHA_TEST); - compile(Core::passAmbient, Shader::SPRITE, fx | FX_UNDERWATER | FX_ALPHA_TEST); + compile(Core::passAmbient, Shader::ROOM, fx, rsFull); + compile(Core::passAmbient, Shader::ROOM, fx, rsFull | RS_DISCARD); + compile(Core::passAmbient, Shader::ROOM, fx | FX_UNDERWATER, rsFull); + compile(Core::passAmbient, Shader::ROOM, fx | FX_UNDERWATER, rsFull | RS_DISCARD); + compile(Core::passAmbient, Shader::SPRITE, fx, rsFull | RS_DISCARD); + compile(Core::passAmbient, Shader::SPRITE, fx | FX_UNDERWATER, rsFull | RS_DISCARD); } void prepareShadows(int fx) { - compile(Core::passShadow, Shader::ENTITY, fx | FX_NONE); - compile(Core::passShadow, Shader::ENTITY, fx | FX_ALPHA_TEST); + compile(Core::passShadow, Shader::ENTITY, fx, rsShadow); + compile(Core::passShadow, Shader::ENTITY, fx, rsShadow | RS_DISCARD); } void prepareWater(int fx) { - compile(Core::passWater, Shader::WATER_MASK, fx | FX_NONE); - compile(Core::passWater, Shader::WATER_STEP, fx | FX_NONE); - compile(Core::passWater, Shader::WATER_CAUSTICS, fx | FX_NONE); - compile(Core::passWater, Shader::WATER_COMPOSE, fx | FX_NONE); - compile(Core::passWater, Shader::WATER_DROP, fx | FX_NONE); + compile(Core::passWater, Shader::WATER_MASK, fx, RS_COLOR_WRITE_A | RS_DEPTH_TEST); + compile(Core::passWater, Shader::WATER_STEP, fx, RS_COLOR_WRITE); + compile(Core::passWater, Shader::WATER_DROP, fx, RS_COLOR_WRITE); + compile(Core::passWater, Shader::WATER_CAUSTICS, fx, RS_COLOR_WRITE); + compile(Core::passWater, Shader::WATER_COMPOSE, fx, RS_COLOR_WRITE | RS_DEPTH_TEST); } void prepareFilter(int fx) { - compile(Core::passFilter, Shader::DEFAULT, fx | FX_NONE); - compile(Core::passFilter, Shader::FILTER_DOWNSAMPLE, fx | FX_NONE); - compile(Core::passFilter, Shader::FILTER_GRAYSCALE, fx | FX_NONE); - compile(Core::passFilter, Shader::FILTER_BLUR, fx | FX_NONE); - compile(Core::passFilter, Shader::FILTER_MIXER, fx | FX_NONE); + compile(Core::passFilter, Shader::DEFAULT, fx, RS_COLOR_WRITE); + compile(Core::passFilter, Shader::FILTER_DOWNSAMPLE, fx, RS_COLOR_WRITE); + compile(Core::passFilter, Shader::FILTER_GRAYSCALE, fx, RS_COLOR_WRITE); + compile(Core::passFilter, Shader::FILTER_BLUR, fx, RS_COLOR_WRITE); + compile(Core::passFilter, Shader::FILTER_MIXER, fx, RS_COLOR_WRITE); } void prepareGUI(int fx) { - compile(Core::passGUI, Shader::DEFAULT, fx | FX_NONE); + compile(Core::passGUI, Shader::DEFAULT, fx, RS_COLOR_WRITE | RS_BLEND_ALPHA); } - Shader* compile(Core::Pass pass, Shader::Type type, int fx) { + #undef rsBase + #undef rsBlend + #undef rsFull + #undef rsShadow + + Shader* compile(Core::Pass pass, Shader::Type type, int fx, uint32 rs) { + if (rs & RS_DISCARD) + fx |= FX_ALPHA_TEST; + #ifndef FFP char def[1024], ext[255]; ext[0] = 0; if (Core::settings.detail.shadows) { if (Core::support.shadowSampler) { - #ifdef MOBILE + #ifdef _GAPI_GLES strcat(ext, "#extension GL_EXT_shadow_samplers : require\n"); #endif strcat(ext, "#define SHADOW_SAMPLER\n"); @@ -142,7 +138,7 @@ struct ShaderCache { case Core::passAmbient : { static const char *typeNames[] = { "SPRITE", "FLASH", "ROOM", "ENTITY", "MIRROR" }; - src = SHADER; + src = GAPI::SHADER_BASE; typ = typeNames[type]; sprintf(def, "%s#define PASS_%s\n#define TYPE_%s\n#define MAX_LIGHTS %d\n#define MAX_CONTACTS %d\n#define WATER_FOG_DIST (1.0/%d.0)\n", ext, passNames[pass], typ, MAX_LIGHTS, MAX_CONTACTS, WATER_FOG_DIST); #ifdef MERGE_SPRITES @@ -177,7 +173,7 @@ struct ShaderCache { } case Core::passWater : { static const char *typeNames[] = { "DROP", "STEP", "CAUSTICS", "MASK", "COMPOSE" }; - src = WATER; + src = GAPI::SHADER_WATER; typ = typeNames[type]; sprintf(def, "%s#define PASS_%s\n#define WATER_%s\n#define WATER_FOG_DIST (1.0/%d.0)\n" UNDERWATER_COLOR, ext, passNames[pass], typ, WATER_FOG_DIST); #ifdef WATER_USE_GRID @@ -187,14 +183,14 @@ struct ShaderCache { } case Core::passFilter : { static const char *typeNames[] = { "DEFAULT", "DOWNSAMPLE", "GRAYSCALE", "BLUR", "MIXER", "EQUIRECTANGULAR" }; - src = FILTER; + src = GAPI::SHADER_FILTER; typ = typeNames[type]; sprintf(def, "%s#define PASS_%s\n#define FILTER_%s\n", ext, passNames[pass], typ); break; } case Core::passGUI : { static const char *typeNames[] = { "DEFAULT" }; - src = GUI; + src = GAPI::SHADER_GUI; typ = typeNames[type]; sprintf(def, "%s#define PASS_%s\n", ext, passNames[pass]); break; @@ -208,25 +204,20 @@ struct ShaderCache { #endif } - void bind(Core::Pass pass, Shader::Type type, int fx, IGame *game) { - Core::pass = pass; - #ifndef FFP + Shader *getShader(Core::Pass pass, Shader::Type type, int fx) { Shader *shader = shaders[pass][type][fx]; - if (!shader) - shader = compile(pass, type, fx); ASSERT(shader != NULL); - shader->bind(); - // TODO: bindable uniform block - shader->setParam(uViewProj, Core::mViewProj); - shader->setParam(uLightProj, Core::mLightProj[0], Core::settings.detail.shadows > Core::Settings::Quality::MEDIUM ? SHADOW_OBJ_MAX : 1); - shader->setParam(uViewPos, Core::viewPos); - shader->setParam(uParam, Core::params); - shader->setParam(uFogParams, Core::fogParams); - #else - Core::setAlphaTest((fx & FX_ALPHA_TEST) != 0); - #endif + return shader; } + void bind(Core::Pass pass, Shader::Type type, int fx) { + Core::pass = pass; + + Shader *shader = getShader(pass, type, fx); + + shader->bind(); + Core::setAlphaTest((fx & FX_ALPHA_TEST) != 0); + } }; struct AmbientCache { @@ -266,7 +257,7 @@ struct AmbientCache { // init downsample textures for (int j = 0; j < 6; j++) for (int i = 0; i < 4; i++) - textures[j * 4 + i] = new Texture(64 >> (i << 1), 64 >> (i << 1), Texture::RGBA, false); + textures[j * 4 + i] = new Texture(64 >> (i << 1), 64 >> (i << 1), FMT_RGBA, false); } ~AmbientCache() { @@ -472,7 +463,7 @@ struct WaterCache { m[(x - minX) + w * (z - minZ)] = hasWater ? 0xF800 : 0; } - mask = new Texture(w, h, Texture::RGB16, Texture::NEAREST, m); + mask = new Texture(w, h, FMT_RGB16, Texture::NEAREST, m); delete[] m; size = vec3(float((maxX - minX) * 512), 1.0f, float((maxZ - minZ) * 512)); // half size @@ -480,11 +471,11 @@ struct WaterCache { int *mf = new int[4 * w * 64 * h * 64]; memset(mf, 0, sizeof(int) * 4 * w * 64 * h * 64); - data[0] = new Texture(w * 64, h * 64, Texture::RGBA_HALF, 0, mf); - data[1] = new Texture(w * 64, h * 64, Texture::RGBA_HALF); + data[0] = new Texture(w * 64, h * 64, FMT_RGBA_HALF, 0, mf); + data[1] = new Texture(w * 64, h * 64, FMT_RGBA_HALF); delete[] mf; - caustics = Core::settings.detail.water > Core::Settings::MEDIUM ? new Texture(512, 512, Texture::RGBA) : NULL; + caustics = Core::settings.detail.water > Core::Settings::MEDIUM ? new Texture(512, 512, FMT_RGBA) : NULL; #ifdef BLUR_CAUSTICS caustics_tmp = Core::settings.detail.water > Core::Settings::MEDIUM ? new Texture(512, 512, Texture::RGBA) : NULL; #endif @@ -516,7 +507,7 @@ struct WaterCache { } drops[MAX_DROPS]; WaterCache(IGame *game) : game(game), level(game->getLevel()), refract(NULL), count(0), dropCount(0) { - reflect = new Texture(512, 512, Texture::RGB16); + reflect = new Texture(512, 512, FMT_RGBA); } ~WaterCache() { @@ -710,7 +701,7 @@ struct WaterCache { Core::setColorWrite(false, false, false, true); Core::setDepthWrite(false); - Core::setCulling(cfNone); + Core::setCullMode(cmNone); for (int i = 0; i < count; i++) { Item &item = items[i]; @@ -723,7 +714,7 @@ struct WaterCache { Core::setColorWrite(true, true, true, true); Core::setDepthWrite(true); - Core::setCulling(cfFront); + Core::setCullMode(cmFront); } void getTargetSize(int &w, int &h) { @@ -744,7 +735,12 @@ struct WaterCache { // get refraction texture if (!refract || w != refract->origWidth || h != refract->origHeight) { delete refract; - refract = new Texture(w, h, Texture::RGBA); + refract = new Texture(w, h, FMT_RGBA); + + Core::setTarget(refract, RT_CLEAR_COLOR | RT_STORE_COLOR); + Core::validateRenderState(); + Core::setTarget(NULL, RT_STORE_COLOR); + Core::validateRenderState(); } Core::copyTarget(refract, 0, 0, int(Core::viewportDef.x), int(Core::viewportDef.y), w, h); // copy framebuffer into refraction texture } @@ -753,7 +749,7 @@ struct WaterCache { PROFILE_MARKER("WATER_SIMULATE"); // simulate water Core::setDepthTest(false); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); for (int i = 0; i < count; i++) { Item &item = items[i]; if (!item.visible) continue; @@ -865,8 +861,8 @@ struct WaterCache { reflect->bind(sReflect); item.mask->bind(sMask); item.data[0]->bind(sNormal); - Core::setCulling(cfNone); - Core::setBlending(bmAlpha); + Core::setCullMode(cmNone); + Core::setBlendMode(bmAlpha); #ifdef WATER_USE_GRID vec3 rPosScale[2] = { item.pos, item.size * vec3(1.0f / PLANE_DETAIL, 512.0f, 1.0f / PLANE_DETAIL) }; Core::active.shader->setParam(uPosScale, rPosScale[0], 2); @@ -875,8 +871,8 @@ struct WaterCache { Core::active.shader->setParam(uPosScale, item.pos, 2); game->getMesh()->renderQuad(); #endif - Core::setCulling(cfFront); - Core::setBlending(bmNone); + Core::setCullMode(cmFront); + Core::setBlendMode(bmNone); } dropCount = 0; } diff --git a/src/camera.h b/src/camera.h index a4280ce..b0a4410 100644 --- a/src/camera.h +++ b/src/camera.h @@ -531,7 +531,7 @@ struct Camera : ICamera { fov = firstPerson ? 90.0f : 65.0f; znear = firstPerson ? 8.0f : 32.0f; - #ifdef _PSP + #ifdef _OS_PSP znear = 256.0f; #endif zfar = 45.0f * 1024.0f; diff --git a/src/core.h b/src/core.h index fc266ef..13917ee 100644 --- a/src/core.h +++ b/src/core.h @@ -1,10 +1,6 @@ #ifndef H_CORE #define H_CORE -#ifndef _PSP - #define USE_INFLATE -#endif - #ifdef _DEBUG #define PROFILE #endif @@ -15,57 +11,69 @@ #define OS_PTHREAD_MT #ifdef WIN32 + #define _OS_WINDOWS + #define _GAPI_GL + //#define _GAPI_VULKAN + #include - #include - #include + + #ifdef _GAPI_GL + #include + #include + #endif #undef OS_PTHREAD_MT #elif ANDROID - #define MOBILE - #define RENDER_TBR + #define _OS_ANDROID + #define _GAPI_GL + #define _GAPI_GLES + //#define _GAPI_VULKAN - #include - #include #include - #define GL_CLAMP_TO_BORDER 0x812D - #define GL_TEXTURE_BORDER_COLOR 0x1004 + #ifdef _GAPI_GL + #include + #include + #define GL_CLAMP_TO_BORDER 0x812D + #define GL_TEXTURE_BORDER_COLOR 0x1004 - #define GL_TEXTURE_COMPARE_MODE 0x884C - #define GL_TEXTURE_COMPARE_FUNC 0x884D - #define GL_COMPARE_REF_TO_TEXTURE 0x884E + #define GL_TEXTURE_COMPARE_MODE 0x884C + #define GL_TEXTURE_COMPARE_FUNC 0x884D + #define GL_COMPARE_REF_TO_TEXTURE 0x884E - #define GL_RGBA16F 0x881A - #define GL_RGBA32F 0x8814 - #define GL_HALF_FLOAT 0x140B + #define GL_RGBA16F 0x881A + #define GL_RGBA32F 0x8814 + #define GL_HALF_FLOAT 0x140B - #define GL_DEPTH_STENCIL GL_DEPTH_STENCIL_OES - #define GL_UNSIGNED_INT_24_8 GL_UNSIGNED_INT_24_8_OES + #define GL_DEPTH_STENCIL GL_DEPTH_STENCIL_OES + #define GL_UNSIGNED_INT_24_8 GL_UNSIGNED_INT_24_8_OES - #define PFNGLGENVERTEXARRAYSPROC PFNGLGENVERTEXARRAYSOESPROC - #define PFNGLDELETEVERTEXARRAYSPROC PFNGLDELETEVERTEXARRAYSOESPROC - #define PFNGLBINDVERTEXARRAYPROC PFNGLBINDVERTEXARRAYOESPROC - #define glGenVertexArrays glGenVertexArraysOES - #define glDeleteVertexArrays glDeleteVertexArraysOES - #define glBindVertexArray glBindVertexArrayOES + #define PFNGLGENVERTEXARRAYSPROC PFNGLGENVERTEXARRAYSOESPROC + #define PFNGLDELETEVERTEXARRAYSPROC PFNGLDELETEVERTEXARRAYSOESPROC + #define PFNGLBINDVERTEXARRAYPROC PFNGLBINDVERTEXARRAYOESPROC + #define glGenVertexArrays glGenVertexArraysOES + #define glDeleteVertexArrays glDeleteVertexArraysOES + #define glBindVertexArray glBindVertexArrayOES - #define PFNGLGETPROGRAMBINARYPROC PFNGLGETPROGRAMBINARYOESPROC - #define PFNGLPROGRAMBINARYPROC PFNGLPROGRAMBINARYOESPROC - #define glGetProgramBinary glGetProgramBinaryOES - #define glProgramBinary glProgramBinaryOES + #define PFNGLGETPROGRAMBINARYPROC PFNGLGETPROGRAMBINARYOESPROC + #define PFNGLPROGRAMBINARYPROC PFNGLPROGRAMBINARYOESPROC + #define glGetProgramBinary glGetProgramBinaryOES + #define glProgramBinary glProgramBinaryOES - #define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES + #define GL_PROGRAM_BINARY_LENGTH GL_PROGRAM_BINARY_LENGTH_OES + #endif extern void osToggleVR(bool enable); #elif __RPI__ - #define MOBILE - #define RENDER_TBR + #define _OS_RPI + #define _GAPI_GL + #define _GAPI_GLES #include #include #include #include - + #define GL_CLAMP_TO_BORDER 0x812D #define GL_TEXTURE_BORDER_COLOR 0x1004 @@ -96,16 +104,21 @@ #define DYNGEOM_NO_VBO #elif __linux__ - #define LINUX 1 - #include - #include - #include + #define _OS_LINUX + #define _GAPI_GL + + #ifdef _GAPI_GL + #include + #include + #include + #endif #elif __APPLE__ + #define _GAPI_GL #include "TargetConditionals.h" #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR - #define MOBILE - #define RENDER_TBR + #define _OS_IOS + #define _GAPI_GLES #include #include @@ -125,6 +138,8 @@ #define GL_TEXTURE_COMPARE_FUNC GL_TEXTURE_COMPARE_FUNC_EXT #define GL_COMPARE_REF_TO_TEXTURE GL_COMPARE_REF_TO_TEXTURE_EXT #else + #define _OS_MACOS + #include #include #include @@ -150,7 +165,10 @@ #define glProgramBinary(...) 0 #endif #elif __EMSCRIPTEN__ - #define MOBILE + #define _OS_WEB + #define _GAPI_GL + #define _GAPI_GLES + #include #include #include @@ -164,6 +182,8 @@ #undef OS_FILEIO_CACHE #elif _PSP + #define _OS_PSP + #define _GAPI_SCEGU #include #include @@ -175,13 +195,17 @@ #undef OS_PTHREAD_MT #endif +#ifndef _OS_PSP + #define USE_INFLATE +#endif + #ifdef USE_INFLATE #include "libs/tinf/tinf.h" #endif #ifdef FFP #define SPLIT_BY_TILE - #ifdef _PSP + #ifdef _OS_PSP #define SPLIT_BY_CLUT #endif #else @@ -206,10 +230,10 @@ extern void osMutexFree (void *obj); extern void osMutexLock (void *obj); extern void osMutexUnlock (void *obj); -extern int osGetTime (); +extern int osGetTime (); -extern bool osJoyReady (int index); -extern void osJoyVibrate (int index, float L, float R); +extern bool osJoyReady (int index); +extern void osJoyVibrate (int index, float L, float R); struct Mutex { void *obj; @@ -410,104 +434,7 @@ namespace Core { #include "input.h" #include "sound.h" -#if defined(WIN32) || (defined(LINUX) && !defined(__RPI__)) || defined(ANDROID) - #ifdef ANDROID - #define GetProc(x) dlsym(libGL, x); - #else - void* GetProc(const char *name) { - #ifdef WIN32 - return (void*)wglGetProcAddress(name); - #elif __RPI__ - return (void*)eglGetProcAddress(name); - #elif LINUX - return (void*)glXGetProcAddress((GLubyte*)name); - #endif - } - #endif - - #define GetProcOGL(x) x=(decltype(x))GetProc(#x); - -// Texture - #ifdef WIN32 - PFNGLACTIVETEXTUREPROC glActiveTexture; - #endif - -// VSync - #ifdef WIN32 - typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); - PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; - #elif LINUX - typedef int (*PFNGLXSWAPINTERVALSGIPROC) (int interval); - PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI; - #endif - - #if defined(WIN32) || defined(LINUX) - PFNGLGENERATEMIPMAPPROC glGenerateMipmap; - // Profiling - #ifdef PROFILE - PFNGLOBJECTLABELPROC glObjectLabel; - PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup; - PFNGLPOPDEBUGGROUPPROC glPopDebugGroup; - PFNGLGENQUERIESPROC glGenQueries; - PFNGLDELETEQUERIESPROC glDeleteQueries; - PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv; - PFNGLBEGINQUERYPROC glBeginQuery; - PFNGLENDQUERYPROC glEndQuery; - #endif - // Shader - PFNGLCREATEPROGRAMPROC glCreateProgram; - PFNGLDELETEPROGRAMPROC glDeleteProgram; - PFNGLLINKPROGRAMPROC glLinkProgram; - PFNGLUSEPROGRAMPROC glUseProgram; - PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; - PFNGLCREATESHADERPROC glCreateShader; - PFNGLDELETESHADERPROC glDeleteShader; - PFNGLSHADERSOURCEPROC glShaderSource; - PFNGLATTACHSHADERPROC glAttachShader; - PFNGLCOMPILESHADERPROC glCompileShader; - PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; - PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; - PFNGLUNIFORM1IVPROC glUniform1iv; - PFNGLUNIFORM1FVPROC glUniform1fv; - PFNGLUNIFORM2FVPROC glUniform2fv; - PFNGLUNIFORM3FVPROC glUniform3fv; - PFNGLUNIFORM4FVPROC glUniform4fv; - PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; - PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; - PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; - PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; - PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; - PFNGLGETPROGRAMIVPROC glGetProgramiv; - // Render to texture - PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; - PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; - PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; - PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; - PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; - PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; - PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; - PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; - PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; - PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; - // Mesh - PFNGLGENBUFFERSARBPROC glGenBuffers; - PFNGLDELETEBUFFERSARBPROC glDeleteBuffers; - PFNGLBINDBUFFERARBPROC glBindBuffer; - PFNGLBUFFERDATAARBPROC glBufferData; - PFNGLBUFFERSUBDATAARBPROC glBufferSubData; - #endif - - PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; - PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; - PFNGLBINDVERTEXARRAYPROC glBindVertexArray; - PFNGLGETPROGRAMBINARYPROC glGetProgramBinary; - PFNGLPROGRAMBINARYPROC glProgramBinary; -#endif - -#if defined(ANDROID) || defined(__EMSCRIPTEN__) - PFNGLDISCARDFRAMEBUFFEREXTPROC glDiscardFramebufferEXT; -#endif #define MAX_LIGHTS 4 #define MAX_RENDER_BUFFERS 32 @@ -533,14 +460,32 @@ enum RenderState { RS_BLEND_ADD = 1 << 11, RS_BLEND_MULT = 1 << 12, RS_BLEND_PREMULT = 1 << 13, - RS_BLEND = RS_BLEND_ADD | RS_BLEND_ALPHA | RS_BLEND_MULT | RS_BLEND_PREMULT, - RS_ALPHA_TEST = 1 << 14, + RS_BLEND = RS_BLEND_ALPHA | RS_BLEND_ADD | RS_BLEND_MULT | RS_BLEND_PREMULT, + RS_DISCARD = 1 << 14, }; -enum ClearMode { - CLEAR_COLOR = 1, - CLEAR_DEPTH = 2, - CLEAR_ALL = CLEAR_COLOR | CLEAR_DEPTH, +// Texture image format +enum Format { + FMT_LUMINANCE, + FMT_RGBA, + FMT_RGB16, + FMT_RGBA16, + FMT_RGBA_FLOAT, + FMT_RGBA_HALF, + FMT_DEPTH, + FMT_DEPTH_STENCIL, + FMT_SHADOW, + FMT_MAX, +}; + +// Pipeline State Object +struct PSO { + void *data; + void *shader; + vec4 clearColor; + Format colorFormat; + Format depthFormat; + uint32 renderState; }; typedef uint16 Index; @@ -553,89 +498,8 @@ struct Vertex { ubyte4 light; // xyz - color, w - use premultiplied alpha }; -#ifdef _PSP - struct VertexGPU { - short2 texCoord; - ubyte4 color; - short3 normal; - short3 coord; - }; -#else - typedef Vertex VertexGPU; -#endif - -#ifdef PROFILE - //#define USE_CV_MARKERS - - #ifdef USE_CV_MARKERS - #include - using namespace Concurrency::diagnostic; - - marker_series *series[256]; - int seriesIndex; - #endif - - struct Marker { - #ifdef USE_CV_MARKERS - span *cvSpan; - #endif - - Marker(const char *title) { - if (Core::support.profMarker) glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, title); - #ifdef USE_CV_MARKERS - marker_series *&s = series[seriesIndex]; - if (s == NULL) { - char seriesTitle[64]; - sprintf(seriesTitle, "events - %d", seriesIndex); - s = new marker_series(seriesTitle); - } - cvSpan = new span(*s, normal_importance, _T(title)); - seriesIndex++; - #endif - } - - ~Marker() { - if (Core::support.profMarker) glPopDebugGroup(); - #ifdef USE_CV_MARKERS - delete cvSpan; - seriesIndex--; - #endif - } - - static void setLabel(GLenum id, GLuint name, const char *label) { - if (Core::support.profMarker) glObjectLabel(id, name, -1, label); - } - }; - - struct Timing { - GLuint ID; - int &result; - - Timing(int &result) : result(result) { - if (!Core::support.profTiming) return; - glGenQueries(1, &ID); - glBeginQuery(GL_TIME_ELAPSED, ID); - } - - ~Timing() { - if (!Core::support.profTiming) return; - glEndQuery(GL_TIME_ELAPSED); - glGetQueryObjectiv(ID, GL_QUERY_RESULT, (GLint*)&result); - glDeleteQueries(1, &ID); - } - }; - - #define PROFILE_MARKER(title) Marker marker(title) - #define PROFILE_LABEL(id, name, label) Marker::setLabel(GL_##id, name, label) - #define PROFILE_TIMING(result) Timing timing(result) -#else - #define PROFILE_MARKER(title) - #define PROFILE_LABEL(id, name, label) - #define PROFILE_TIMING(time) -#endif - -enum CullFace { cfNone, cfBack, cfFront }; -enum BlendMode { bmNone, bmAlpha, bmAdd, bmMult, bmPremult }; +enum CullMode { cmNone, cmBack, cmFront }; +enum BlendMode { bmNone, bmAlpha, bmAdd, bmMult, bmPremult, bmMAX }; namespace Core { float eye; @@ -654,7 +518,7 @@ namespace Core { enum Pass { passCompose, passShadow, passAmbient, passWater, passFilter, passGUI, passMAX } pass; - #ifdef _PSP + #ifdef _OS_PSP void *curBackBuffer; #else GLuint FBO, defaultFBO; @@ -673,22 +537,24 @@ namespace Core { int32 renderState; struct Active { + const PSO *pso; Shader *shader; + int32 renderState; + Texture *textures[8]; Texture *target; uint32 targetFace; uint32 targetOp; vec4 viewport; vec4 material; - #ifdef _PSP + #ifdef _OS_PSP Index *iBuffer; - VertexGPU *vBuffer; + GAPI::Vertex *vBuffer; #else GLuint VAO; GLuint iBuffer; GLuint vBuffer; #endif - int32 renderState; int32 basisCount; Basis *basis; @@ -725,58 +591,23 @@ namespace Core { frame++; } } stats; - -#ifdef _PSP - uint32 *cmdBuf = NULL; - - static int EDRAM_OFFSET; - static int EDRAM_SIZE; - - void* allocEDRAM(int size) { - LOG("EDRAM ALLOC: offset: %d size %d (free %d)\n", Core::EDRAM_OFFSET, size, EDRAM_SIZE - (Core::EDRAM_OFFSET + size)); - if (Core::EDRAM_OFFSET + size > EDRAM_SIZE) - LOG("! EDRAM overflow !\n"); - - void *ptr = ((char*)sceGeEdramGetAddr()) + EDRAM_OFFSET; - EDRAM_OFFSET += (size + 15) / 16 * 16; - return ptr; - } - - void freeEDRAM() { - EDRAM_OFFSET = (512 * 272 * 2 * 2) + (512 * 272 * 2); - LOG("EDRAM FREE: offset: %d\n", EDRAM_OFFSET); - } -#endif - - void beginCmdBuf() { - #ifdef _PSP - if (!cmdBuf) - cmdBuf = new uint32[262144]; - - sceGuStart(GU_DIRECT, cmdBuf); - #endif - } - - void submitCmdBuf() { - #ifdef _PSP - ASSERT(cmdBuf); - sceGuFinish(); - sceGuSync(GU_SYNC_WAIT, GU_SYNC_FINISH); - #endif - } } +#ifdef _GAPI_GL + #include "gapi_gl.h" +#elif _GAPI_GX + #include "gapi_gx.h" +#elif _GAPI_SCEGU + #include "gapi_gu.h" +#elif _GAPI_VULKAN + #include "gapi_vk.h" +#endif + #include "texture.h" #include "shader.h" namespace Core { - Texture *eyeTex[2]; - - bool extSupport(const char *str, const char *ext) { - return strstr(str, ext) != NULL; - } - void init() { x = y = 0; #ifdef USE_INFLATE @@ -786,173 +617,11 @@ namespace Core { isQuit = false; Input::init(); - #ifdef ANDROID - void *libGL = dlopen("libGLESv2.so", RTLD_LAZY); - #endif + Sound::init(); - #if defined(WIN32) || (defined(LINUX) && !defined(__RPI__)) || defined(ANDROID) - #ifdef WIN32 - GetProcOGL(glActiveTexture); - #endif + GAPI::init(); - #ifdef WIN32 - GetProcOGL(wglSwapIntervalEXT); - #elif LINUX - GetProcOGL(glXSwapIntervalSGI); - #endif - - #if defined(WIN32) || defined(LINUX) - GetProcOGL(glGenerateMipmap); - - #ifdef PROFILE - GetProcOGL(glObjectLabel); - GetProcOGL(glPushDebugGroup); - GetProcOGL(glPopDebugGroup); - GetProcOGL(glGenQueries); - GetProcOGL(glDeleteQueries); - GetProcOGL(glGetQueryObjectiv); - GetProcOGL(glBeginQuery); - GetProcOGL(glEndQuery); - #endif - - GetProcOGL(glCreateProgram); - GetProcOGL(glDeleteProgram); - GetProcOGL(glLinkProgram); - GetProcOGL(glUseProgram); - GetProcOGL(glGetProgramInfoLog); - GetProcOGL(glCreateShader); - GetProcOGL(glDeleteShader); - GetProcOGL(glShaderSource); - GetProcOGL(glAttachShader); - GetProcOGL(glCompileShader); - GetProcOGL(glGetShaderInfoLog); - GetProcOGL(glGetUniformLocation); - GetProcOGL(glUniform1iv); - GetProcOGL(glUniform1fv); - GetProcOGL(glUniform2fv); - GetProcOGL(glUniform3fv); - GetProcOGL(glUniform4fv); - GetProcOGL(glUniformMatrix4fv); - GetProcOGL(glBindAttribLocation); - GetProcOGL(glEnableVertexAttribArray); - GetProcOGL(glDisableVertexAttribArray); - GetProcOGL(glVertexAttribPointer); - GetProcOGL(glGetProgramiv); - - GetProcOGL(glGenFramebuffers); - GetProcOGL(glBindFramebuffer); - GetProcOGL(glGenRenderbuffers); - GetProcOGL(glBindRenderbuffer); - GetProcOGL(glFramebufferTexture2D); - GetProcOGL(glFramebufferRenderbuffer); - GetProcOGL(glRenderbufferStorage); - GetProcOGL(glCheckFramebufferStatus); - GetProcOGL(glDeleteFramebuffers); - GetProcOGL(glDeleteRenderbuffers); - - GetProcOGL(glGenBuffers); - GetProcOGL(glDeleteBuffers); - GetProcOGL(glBindBuffer); - GetProcOGL(glBufferData); - GetProcOGL(glBufferSubData); - #endif - - #if defined(ANDROID) || defined(__EMSCRIPTEN__) - GetProcOGL(glDiscardFramebufferEXT); - #endif - - GetProcOGL(glGenVertexArrays); - GetProcOGL(glDeleteVertexArrays); - GetProcOGL(glBindVertexArray); - GetProcOGL(glGetProgramBinary); - GetProcOGL(glProgramBinary); - #endif - - const char *vendor, *renderer, *version; - - #ifdef _PSP - vendor = "Sony"; - renderer = "SCE GU"; - version = "1.0"; - #else - vendor = (char*)glGetString(GL_VENDOR); - renderer = (char*)glGetString(GL_RENDERER); - version = (char*)glGetString(GL_VERSION); - - char *ext = (char*)glGetString(GL_EXTENSIONS); -/* - if (ext != NULL) { - char buf[255]; - int len = strlen(ext); - int start = 0; - for (int i = 0; i < len; i++) - if (ext[i] == ' ' || (i == len - 1)) { - memcpy(buf, &ext[start], i - start); - buf[i - start] = 0; - LOG("%s\n", buf); - start = i + 1; - } - } -*/ - #endif - - #ifdef FFP - support.maxAniso = 1; - support.maxVectors = 0; - support.shaderBinary = false; - support.VAO = false; - support.depthTexture = false; - support.shadowSampler = false; - support.discardFrame = false; - support.texNPOT = false; - support.texRG = false; - support.texBorder = false; - support.maxAniso = false; - support.colorFloat = false; - support.colorHalf = false; - support.texFloatLinear = false; - support.texFloat = false; - support.texHalfLinear = false; - support.texHalf = false; - #else - support.shaderBinary = extSupport(ext, "_program_binary"); - support.VAO = extSupport(ext, "_vertex_array_object"); - support.depthTexture = extSupport(ext, "_depth_texture"); - support.shadowSampler = support.depthTexture && (extSupport(ext, "_shadow_samplers") || extSupport(ext, "GL_ARB_shadow")); - support.discardFrame = extSupport(ext, "_discard_framebuffer"); - support.texNPOT = extSupport(ext, "_texture_npot") || extSupport(ext, "_texture_non_power_of_two"); - support.texRG = extSupport(ext, "_texture_rg "); // hope that isn't last extension in string ;) - support.texBorder = extSupport(ext, "_texture_border_clamp"); - support.maxAniso = extSupport(ext, "_texture_filter_anisotropic"); - support.colorFloat = extSupport(ext, "_color_buffer_float"); - support.colorHalf = extSupport(ext, "_color_buffer_half_float") || extSupport(ext, "GL_ARB_half_float_pixel"); - support.texFloatLinear = support.colorFloat || extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_float_linear"); - support.texFloat = support.texFloatLinear || extSupport(ext, "_texture_float"); - support.texHalfLinear = support.colorHalf || extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_half_float_linear") || extSupport(ext, "_color_buffer_half_float"); - support.texHalf = support.texHalfLinear || extSupport(ext, "_texture_half_float"); - - if (support.maxAniso) - glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &support.maxAniso); - #ifdef MOBILE - glGetIntegerv(GL_MAX_VARYING_VECTORS, &support.maxVectors); - #else - support.maxVectors = 16; - #endif - #endif - - #ifdef PROFILE - support.profMarker = extSupport(ext, "_KHR_debug"); - support.profTiming = extSupport(ext, "_timer_query"); - #endif - - LOG("Vendor : %s\n", vendor); - LOG("Renderer : %s\n", renderer); - LOG("Version : %s\n", version); LOG("cache : %s\n", Stream::cacheDir); - #ifdef _PSP - EDRAM_SIZE = sceGeEdramGetSize(); - LOG("VRAM : %d\n", EDRAM_SIZE); - #endif LOG("supports :\n"); LOG(" variyngs count : %d\n", support.maxVectors); LOG(" binary shaders : %s\n", support.shaderBinary ? "true" : "false"); @@ -969,87 +638,8 @@ namespace Core { support.colorHalf ? "full" : (support.texHalf ? (support.texHalfLinear ? "linear" : "nearest") : "false")); LOG("\n"); - #ifndef _PSP - glEnable(GL_SCISSOR_TEST); - #endif - - #ifdef FFP - #ifdef _PSP - Core::width = 480; - Core::height = 272; - - sceGuDepthFunc(GU_LEQUAL); - sceGuDepthRange(0x0000, 0xFFFF); - sceGuClearDepth(0xFFFF); - - sceGuShadeModel(GU_SMOOTH); - sceGuAlphaFunc(GU_GREATER, 127, 255); - - int swizzle = GU_FALSE; - #ifdef TEX_SWIZZLE - swizzle = GU_TRUE; - #endif - - sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0); - sceGuTexMode(GU_PSM_T4, 0, 0, swizzle); - sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); - sceGuTexScale(1.0f, 1.0f); - sceGuTexOffset(0.0f, 0.0f); - sceGuTexFilter(GU_LINEAR, GU_LINEAR); - //sceGuTexFilter(GU_NEAREST, GU_NEAREST); - sceGuEnable(GU_CLIP_PLANES); - - const ScePspIMatrix4 dith = - { {-4, 0, -3, 1}, - { 2, -2, 3, -1}, - {-3, 1, -4, 0}, - { 3, -1, 2, -2} }; - sceGuSetDither(&dith); - sceGuEnable(GU_DITHER); - - sceGuAmbientColor(0xFFFFFFFF); - sceGuColor(0xFFFFFFFF); - sceGuClearColor(0x00000000); - sceGuColorMaterial(GU_AMBIENT | GU_DIFFUSE); - - freeEDRAM(); - #else - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_COLOR_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glEnableClientState(GL_VERTEX_ARRAY); - - glAlphaFunc(GL_GREATER, 0.5f); - - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glScalef(1.0f / 32767.0f, 1.0f / 32767.0f, 1.0f / 32767.0f); - - glClearColor(0, 0, 0, 0); - #endif - #endif - - #ifndef _PSP - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - - glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&defaultFBO); - glGenFramebuffers(1, &FBO); - glDepthFunc(GL_LEQUAL); - - memset(rtCache, 0, sizeof(rtCache)); - #endif - - #if defined(FFP) && defined(SPLIT_BY_TILE) - #ifdef _PSP - sceGuEnable(GU_TEXTURE_2D); - #else - glEnable(GL_TEXTURE_2D); - #endif - #endif - defaultTarget = NULL; - - Sound::init(); + memset(rtCache, 0, sizeof(rtCache)); for (int i = 0; i < MAX_LIGHTS; i++) { lightPos[i] = vec3(0.0); @@ -1058,10 +648,10 @@ namespace Core { eye = 0.0f; uint32 data = 0xFFFFFFFF; - whiteTex = new Texture(1, 1, Texture::RGBA, Texture::NEAREST, &data); - whiteCube = new Texture(1, 1, Texture::RGBA, Texture::CUBEMAP, &data); + whiteTex = new Texture(1, 1, FMT_RGBA, Texture::NEAREST, &data); + whiteCube = new Texture(1, 1, FMT_RGBA, Texture::CUBEMAP, &data); data = 0; - blackTex = new Texture(1, 1, Texture::RGBA, Texture::NEAREST, &data); + blackTex = new Texture(1, 1, FMT_RGBA, Texture::NEAREST, &data); // init settings settings.version = SETTINGS_VERSION; @@ -1070,11 +660,11 @@ namespace Core { settings.detail.setLighting (Core::Settings::HIGH); settings.detail.setShadows (Core::Settings::HIGH); settings.detail.setWater (Core::Settings::HIGH); - settings.detail.vsync = true; - settings.detail.stereo = Settings::STEREO_OFF; - settings.audio.music = 14; - settings.audio.sound = 14; - settings.audio.reverb = true; + settings.detail.vsync = true; + settings.detail.stereo = Settings::STEREO_OFF; + settings.audio.music = 14; + settings.audio.sound = 14; + settings.audio.reverb = true; // player 1 { @@ -1125,19 +715,19 @@ namespace Core { } // use S key for action on Mac because Ctrl + Left/Right used by system (default) - #ifdef __APPLE__ + #ifdef _OS_MACOS settings.controls[0].keys[ cAction ].key = ikS; #endif // use D key for jump in browsers - #ifdef __EMSCRIPTEN__ + #ifdef _OS_WEB settings.controls[0].keys[ cJump ].key = ikD; settings.controls[0].keys[ cInventory ].key = ikTab; #endif - #ifdef __RPI__ - settings.detail.setShadows(Core::Settings::LOW); - settings.detail.setLighting(Core::Settings::MEDIUM); + #ifdef _OS_RPI + settings.detail.setShadows (Core::Settings::LOW); + settings.detail.setLighting (Core::Settings::MEDIUM); #endif #ifdef FFP @@ -1145,10 +735,11 @@ namespace Core { settings.detail.setLighting (Core::Settings::LOW); settings.detail.setShadows (Core::Settings::LOW); settings.detail.setWater (Core::Settings::LOW); - settings.audio.reverb = false; #endif - eyeTex[0] = eyeTex[1] = NULL; + #ifdef _OS_PSP + settings.audio.reverb = false; + #endif memset(&active, 0, sizeof(active)); renderState = 0; @@ -1157,33 +748,25 @@ namespace Core { } void deinit() { - delete eyeTex[0]; - delete eyeTex[1]; delete whiteTex; delete whiteCube; delete blackTex; - #ifdef _PSP - delete[] cmdBuf; - #else - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glDeleteFramebuffers(1, &FBO); - glBindRenderbuffer(GL_RENDERBUFFER, 0); - for (int b = 0; b < 2; b++) - for (int i = 0; i < rtCache[b].count; i++) - glDeleteRenderbuffers(1, &rtCache[b].items[i].ID); - #endif + GAPI::deinit(); + Sound::deinit(); } -#ifdef VR_SUPPORT - void initVR(int width, int height) { - eyeTex[0] = new Texture(width, height, Texture::RGBA); - eyeTex[1] = new Texture(width, height, Texture::RGBA); + void setVSync(bool enable) { + GAPI::setVSync(Core::settings.detail.vsync = enable); } -#endif -#ifndef _PSP + void waitVBlank() { + if (Core::settings.detail.vsync) + GAPI::waitVBlank(); + } + +#ifndef _OS_PSP int cacheRenderTarget(bool depth, int width, int height) { RenderTargetCache &cache = rtCache[depth]; @@ -1220,22 +803,13 @@ namespace Core { if (!mask) return; if (mask & RS_TARGET) { - #ifdef MOBILE - if (support.discardFrame) { - int count = 0; - GLenum discard[2]; - if (!(active.targetOp & RT_STORE_COLOR)) discard[count++] = active.target ? GL_COLOR_ATTACHMENT0 : GL_COLOR_EXT; - if (!(active.targetOp & RT_STORE_DEPTH)) discard[count++] = active.target ? GL_DEPTH_ATTACHMENT : GL_DEPTH_EXT; - if (count) - glDiscardFramebufferEXT(GL_FRAMEBUFFER, count, discard); - } - #endif + GAPI::discardTarget(!(active.targetOp & RT_STORE_COLOR), !(active.targetOp & RT_STORE_DEPTH)); Texture *target = reqTarget.texture; uint32 face = reqTarget.face; if (target != active.target || face != active.targetFace) { - #ifdef _PSP + #ifdef _OS_PSP /* if (!target) sceGuDrawBufferList(GU_PSM_5650, curBackBuffer, 512); @@ -1253,7 +827,7 @@ namespace Core { if (target->opt & Texture::CUBEMAP) texTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face; - depth = target->format == Texture::DEPTH || target->format == Texture::SHADOW; + depth = target->format == FMT_DEPTH || target->format == FMT_SHADOW; int rtIndex = cacheRenderTarget(depth, target->width, target->height); @@ -1263,10 +837,10 @@ namespace Core { } #endif - #ifdef RENDER_TBR - if (!(reqTarget.op & RT_LOAD_COLOR) && !depth) reqTarget.op |= RT_CLEAR_COLOR; - if (!(reqTarget.op & RT_LOAD_DEPTH) && depth) reqTarget.op |= RT_CLEAR_DEPTH; - #endif + if (support.discardFrame) { + if (!(reqTarget.op & RT_LOAD_COLOR) && !depth) reqTarget.op |= RT_CLEAR_COLOR; + if (!(reqTarget.op & RT_LOAD_DEPTH) && depth) reqTarget.op |= RT_CLEAR_DEPTH; + } active.target = target; active.targetOp = reqTarget.op; @@ -1277,122 +851,31 @@ namespace Core { if (mask & RS_VIEWPORT) { if (viewport != active.viewport) { active.viewport = viewport; - #ifdef _PSP - sceGuOffset(2048 - int(viewport.z) / 2, 2048 - int(viewport.w) / 2); - sceGuViewport(2048 + int(viewport.x), 2048 + int(viewport.y), int(viewport.z), int(viewport.w)); - #else - glViewport(int(viewport.x), int(viewport.y), int(viewport.z), int(viewport.w)); - glScissor(int(viewport.x), int(viewport.y), int(viewport.z), int(viewport.w)); - #endif + GAPI::setViewport(int(viewport.x), int(viewport.y), int(viewport.z), int(viewport.w)); } renderState &= ~RS_VIEWPORT; } - if (mask & RS_DEPTH_TEST) { - #ifdef _PSP - if (renderState & RS_DEPTH_TEST) - sceGuEnable(GU_DEPTH_TEST); - else - sceGuDisable(GU_DEPTH_TEST); - #else - if (renderState & RS_DEPTH_TEST) - glEnable(GL_DEPTH_TEST); - else - glDisable(GL_DEPTH_TEST); - #endif - } + if (mask & RS_DEPTH_TEST) + GAPI::setDepthTest((renderState & RS_DEPTH_TEST) != 0); - if (mask & RS_DEPTH_WRITE) { - #ifdef _PSP - sceGuDepthMask((renderState & RS_DEPTH_WRITE) != 0 ? GU_FALSE : GU_TRUE); - #else - glDepthMask((renderState & RS_DEPTH_WRITE) != 0 ? GL_TRUE : GL_FALSE); - #endif - } + if (mask & RS_DEPTH_WRITE) + GAPI::setDepthWrite((renderState & RS_DEPTH_WRITE) != 0); - if (mask & RS_COLOR_WRITE) { - #ifdef _PSP - sceGuPixelMask(~(((renderState & RS_COLOR_WRITE_R) != 0 ? 0x000000FF : 0) | - ((renderState & RS_COLOR_WRITE_G) != 0 ? 0x0000FF00 : 0) | - ((renderState & RS_COLOR_WRITE_B) != 0 ? 0x00FF0000 : 0) | - ((renderState & RS_COLOR_WRITE_A) != 0 ? 0xFF000000 : 0))); - #else - glColorMask((renderState & RS_COLOR_WRITE_R) != 0, - (renderState & RS_COLOR_WRITE_G) != 0, - (renderState & RS_COLOR_WRITE_B) != 0, - (renderState & RS_COLOR_WRITE_A) != 0); - #endif - } + if (mask & RS_COLOR_WRITE) + GAPI::setColorWrite((renderState & RS_COLOR_WRITE_R) != 0, (renderState & RS_COLOR_WRITE_G) != 0, (renderState & RS_COLOR_WRITE_B) != 0, (renderState & RS_COLOR_WRITE_A) != 0); - if (mask & RS_CULL) { - #ifdef _PSP - if (!(active.renderState & RS_CULL)) - sceGuEnable(GU_CULL_FACE); - switch (renderState & RS_CULL) { - case RS_CULL_BACK : sceGuFrontFace(GU_CCW); break; - case RS_CULL_FRONT : sceGuFrontFace(GU_CW); break; - default : sceGuDisable(GU_CULL_FACE); - } - #else - if (!(active.renderState & RS_CULL)) - glEnable(GL_CULL_FACE); - switch (renderState & RS_CULL) { - case RS_CULL_BACK : glCullFace(GL_BACK); break; - case RS_CULL_FRONT : glCullFace(GL_FRONT); break; - default : glDisable(GL_CULL_FACE); - } - #endif - } + if (mask & RS_CULL) + GAPI::setCullMode(renderState & RS_CULL); + + if (mask & RS_BLEND) + GAPI::setBlendMode(renderState & RS_BLEND); + + if (mask & RS_DISCARD) + GAPI::setAlphaTest((renderState & RS_DISCARD) != 0); - if (mask & RS_BLEND) { - #ifdef _PSP - if (!(active.renderState & RS_BLEND)) - sceGuEnable(GU_BLEND); - switch (renderState & RS_BLEND) { - case RS_BLEND_ALPHA : sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); break; - case RS_BLEND_ADD : sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xffffffff, 0xffffffff); break; - case RS_BLEND_MULT : sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_FIX, 0, 0); break; - case RS_BLEND_PREMULT : sceGuBlendFunc(GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_ALPHA, 0xffffffff, 0); break; - default : sceGuDisable(GU_BLEND); - } - #else - if (!(active.renderState & RS_BLEND)) - glEnable(GL_BLEND); - switch (renderState & RS_BLEND) { - case RS_BLEND_ALPHA : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; - case RS_BLEND_ADD : glBlendFunc(GL_ONE, GL_ONE); break; - case RS_BLEND_MULT : glBlendFunc(GL_DST_COLOR, GL_ZERO); break; - case RS_BLEND_PREMULT : glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); break; - default : glDisable(GL_BLEND); - } - #endif - } - #ifdef FFP - if (mask & RS_ALPHA_TEST) { - #ifdef _PSP - if (renderState & RS_ALPHA_TEST) - sceGuEnable(GU_ALPHA_TEST); - else - sceGuDisable(GU_ALPHA_TEST); - #else - if (renderState & RS_ALPHA_TEST) - glEnable(GL_ALPHA_TEST); - else - glDisable(GL_ALPHA_TEST); - #endif - } - #endif if (mask & RS_TARGET) { - int clear = 0; - #ifdef _PSP - if (reqTarget.op & RT_CLEAR_COLOR) clear |= GU_COLOR_BUFFER_BIT; - if (reqTarget.op & RT_CLEAR_DEPTH) clear |= GU_DEPTH_BUFFER_BIT; - if (clear) sceGuClear(clear | GU_FAST_CLEAR_BIT); - #else - if (reqTarget.op & RT_CLEAR_COLOR) clear |= GL_COLOR_BUFFER_BIT; - if (reqTarget.op & RT_CLEAR_DEPTH) clear |= GL_DEPTH_BUFFER_BIT; - if (clear) glClear(clear); - #endif + GAPI::clear((reqTarget.op & RT_CLEAR_COLOR) != 0, (reqTarget.op & RT_CLEAR_DEPTH) != 0); renderState &= ~RS_TARGET; } @@ -1400,15 +883,7 @@ namespace Core { } void setClearColor(const vec4 &color) { - #ifdef _PSP - ubyte4 c(clamp(int(color.x * 255), 0, 255), - clamp(int(color.y * 255), 0, 255), - clamp(int(color.z * 255), 0, 255), - clamp(int(color.w * 255), 0, 255)); - sceGuClearColor(*((uint32*)&c)); - #else - glClearColor(color.x, color.y, color.z, color.w); - #endif + GAPI::setClearColor(color); } void setViewport(int x, int y, int width, int height) { @@ -1420,16 +895,16 @@ namespace Core { setViewport(int(vp.x), int(vp.y), int(vp.z), int(vp.w)); } - void setCulling(CullFace mode) { + void setCullMode(CullMode mode) { renderState &= ~RS_CULL; switch (mode) { - case cfNone : break; - case cfBack : renderState |= RS_CULL_BACK; break; - case cfFront : renderState |= RS_CULL_FRONT; break; + case cmNone : break; + case cmBack : renderState |= RS_CULL_BACK; break; + case cmFront : renderState |= RS_CULL_FRONT; break; } } - void setBlending(BlendMode mode) { + void setBlendMode(BlendMode mode) { renderState &= ~RS_BLEND; switch (mode) { case bmNone : break; @@ -1440,10 +915,10 @@ namespace Core { } } - void setAlphaTest(bool value) { - renderState &= ~RS_ALPHA_TEST; - if (value) - renderState |= RS_ALPHA_TEST; + void setAlphaTest(bool enable) { + renderState &= ~RS_DISCARD; + if (enable) + renderState |= RS_DISCARD; } void setColorWrite(bool r, bool g, bool b, bool a) { @@ -1454,15 +929,15 @@ namespace Core { if (a) renderState |= RS_COLOR_WRITE_A; } - void setDepthWrite(bool write) { - if (write) + void setDepthWrite(bool enable) { + if (enable) renderState |= RS_DEPTH_WRITE; else renderState &= ~RS_DEPTH_WRITE; } - void setDepthTest(bool test) { - if (test) + void setDepthTest(bool enable) { + if (enable) renderState |= RS_DEPTH_TEST; else renderState &= ~RS_DEPTH_TEST; @@ -1472,7 +947,7 @@ namespace Core { if (!target) target = defaultTarget; - bool color = !target || (target->format != Texture::DEPTH && target->format != Texture::SHADOW); + bool color = !target || (target->format != FMT_DEPTH && target->format != FMT_SHADOW); setColorWrite(color, color, color, color); if (target == defaultTarget) // backbuffer @@ -1501,33 +976,20 @@ namespace Core { void copyTarget(Texture *dst, int xOffset, int yOffset, int x, int y, int width, int height) { validateRenderState(); + // GAPI::copyTarget(dst, xOffset, yOffset, x, y, width, height); TODO dst->bind(sDiffuse); - #ifdef _PSP - - #else + #ifdef _GAPI_GL glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height); // TODO: too bad for iOS devices! #endif } vec4 copyPixel(int x, int y) { // GPU sync! validateRenderState(); - #ifdef _PSP - return vec4(0.0f); - #else - ubyte4 c; - glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &c); - return vec4(float(c.x), float(c.y), float(c.z), float(c.w)) * (1.0f / 255.0f); - #endif + return GAPI::copyPixel(x, y); } void reset() { - #ifndef _PSP - if (Core::support.VAO) - glBindVertexArray(0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glUseProgram(0); - #endif + GAPI::resetState(); memset(&active, 0, sizeof(active)); renderState = 0; @@ -1535,8 +997,8 @@ namespace Core { setViewport(Core::x, Core::y, Core::width, Core::height); viewportDef = viewport; - setCulling(cfFront); - setBlending(bmAlpha); + setCullMode(cmFront); + setBlendMode(bmAlpha); setDepthTest(true); setDepthWrite(true); setColorWrite(true, true, true, true); @@ -1548,78 +1010,51 @@ namespace Core { } void endFrame() { - #ifdef __EMSCRIPTEN__ - glColorMask(false, false, false, true); - glClearColor(0.0f, 0.0f, 0.0f, 1.0f); - glClear(GL_COLOR_BUFFER_BIT); - glColorMask(true, true, true, true); - #endif Core::stats.stop(); } - void waitVBlank() { - if (Core::settings.detail.vsync) { - #ifdef WIN32 - if (wglSwapIntervalEXT) wglSwapIntervalEXT(1); - #elif LINUX - if (glXSwapIntervalSGI) glXSwapIntervalSGI(1); - #elif __RPI__ - eglSwapInterval(display, 1); - #elif _PSP - sceDisplayWaitVblankStart(); - #endif - } else { - #ifdef WIN32 - if (wglSwapIntervalEXT) wglSwapIntervalEXT(0); - #elif LINUX - if (glXSwapIntervalSGI) glXSwapIntervalSGI(0); - #elif __RPI__ - eglSwapInterval(display, 0); - #endif - } - } - void setViewProj(const mat4 &mView, const mat4 &mProj) { Core::mProj = mProj; Core::mView = mView; Core::mViewProj = mProj * mView; - #ifdef FFP - #ifdef _PSP - sceGumMatrixMode(GU_PROJECTION); - sceGumLoadMatrix((ScePspFMatrix4*)&mProj); - sceGumMatrixMode(GU_VIEW); - sceGumLoadMatrix((ScePspFMatrix4*)&mView); - #else - glMatrixMode(GL_PROJECTION); - glLoadMatrixf((float*)&mProj); - #endif - #endif + + GAPI::setViewProj(mView, mProj); } - void DIP(int iStart, int iCount, void *iBuffer) { - validateRenderState(); - - #ifdef FFP - #ifdef _PSP - mat4 m = mModel; - m.scale(vec3(32767.0f)); - sceGumMatrixMode(GU_MODEL); - sceGumLoadMatrix((ScePspFMatrix4*)&m); - #else - mat4 m = mView * mModel; - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf((GLfloat*)&m); - #endif - #endif - - #ifdef _PSP - sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_16BIT | GU_COLOR_8888 | GU_NORMAL_16BIT | GU_VERTEX_16BIT | GU_INDEX_16BIT | GU_TRANSFORM_3D, iCount, active.iBuffer + iStart, active.vBuffer); - #else - glDrawElements(GL_TRIANGLES, iCount, GL_UNSIGNED_SHORT, (Index*)iBuffer + iStart); - #endif - + void DIP(int iStart, int iCount, Index *iBuffer) { stats.dips++; stats.tris += iCount / 3; + + validateRenderState(); + + GAPI::DIP(iStart, iCount, iBuffer); + } + + PSO* psoCreate(Shader *shader, uint32 renderState, Format colorFormat = FMT_RGBA, Format depthFormat = FMT_DEPTH, const vec4 &clearColor = vec4(0.0f)) { + PSO *pso = new PSO(); + pso->data = NULL; + pso->shader = shader; + pso->renderState = renderState; + pso->colorFormat = colorFormat; + pso->depthFormat = depthFormat; + pso->clearColor = clearColor; + GAPI::initPSO(pso); + return pso; + } + + void psoDestroy(PSO *pso) { + GAPI::deinitPSO(pso); + delete pso; + } + + void psoBind(PSO *pso) { + ASSERT(pso); + ASSERT(pso->data); + ASSERT(pso->shader); + ((Shader*)pso->shader)->bind(); + GAPI::bindPSO(pso); + + Core::active.pso = pso; } } diff --git a/src/debug.h b/src/debug.h index 277989a..70fc07f 100644 --- a/src/debug.h +++ b/src/debug.h @@ -11,7 +11,7 @@ namespace Debug { static GLuint font; void init() { - #ifdef WIN32 + #ifdef _OS_WINDOWS font = glGenLists(256); HDC hdc = GetDC(0); HFONT hfont = CreateFontA(-MulDiv(10, GetDeviceCaps(hdc, LOGPIXELSY), 72), 0, @@ -21,7 +21,7 @@ namespace Debug { SelectObject(hdc, hfont); wglUseFontBitmaps(hdc, 0, 256, font); DeleteObject(hfont); - #elif LINUX + #elif _OS_LINUX XFontStruct *fontInfo; Font id; unsigned int first, last; @@ -182,7 +182,7 @@ namespace Debug { glOrtho(0, Core::width, Core::height, 0, 0, 1); Core::setDepthTest(false); - Core::setCulling(cfNone); + Core::setCullMode(cmNone); Core::validateRenderState(); glColor4fv((GLfloat*)&color); @@ -190,7 +190,7 @@ namespace Debug { glListBase(font); glCallLists(strlen(str), GL_UNSIGNED_BYTE, str); Core::setDepthTest(true); - Core::setCulling(cfFront); + Core::setCullMode(cmFront); glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -400,7 +400,7 @@ namespace Debug { sprintf(str, "%d", boxIndex); Draw::text(vec3((b.maxX + b.minX) * 0.5f, b.floor, (b.maxZ + b.minZ) * 0.5f), vec4(0, 1, 0, 1), str); glColor4f(0.0f, 1.0f, 0.0f, 0.25f); - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); debugBox(b); TR::Overlap *o = &level.overlaps[level.boxes[boxIndex].overlap.index]; @@ -409,7 +409,7 @@ namespace Debug { sprintf(str, "%d", o->boxIndex); Draw::text(vec3((b.maxX + b.minX) * 0.5f, b.floor, (b.maxZ + b.minZ) * 0.5f), vec4(0, 0, 1, 1), str); glColor4f(0.0f, 0.0f, 1.0f, 0.25f); - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); debugBox(b); } while (!(o++)->end); } @@ -418,7 +418,7 @@ namespace Debug { if (!boxes) return; glColor4f(0.0f, 1.0f, 0.0f, 0.25f); - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); Core::setDepthTest(false); Core::validateRenderState(); for (int i = 0; i < count; i++) @@ -455,7 +455,7 @@ namespace Debug { } void portals(const TR::Level &level) { - Core::setBlending(bmAdd); + Core::setBlendMode(bmAdd); glColor3f(0, 0.25f, 0.25f); glDepthMask(GL_FALSE); @@ -473,7 +473,7 @@ namespace Debug { glEnd(); glDepthMask(GL_TRUE); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); } void entities(const TR::Level &level) { diff --git a/src/game.h b/src/game.h index 9b4ee23..3828ea7 100644 --- a/src/game.h +++ b/src/game.h @@ -39,12 +39,14 @@ void loadSettings(Stream *stream, void *userData) { delete stream; } - #ifdef ANDROID + #ifdef _OS_ANDROID if (Core::settings.detail.stereo == Core::Settings::STEREO_VR) osToggleVR(true); #endif Core::settings.version = SETTINGS_VERSION; + Core::setVSync(Core::settings.detail.vsync != 0); + shaderCache = new ShaderCache(); Game::startLevel((Stream*)userData); UI::init(Game::level); diff --git a/src/gameflow.h b/src/gameflow.h index f0aecd3..bc30b73 100644 --- a/src/gameflow.h +++ b/src/gameflow.h @@ -555,7 +555,7 @@ namespace TR { if (version & VER_TR3) strcat(dst, "3/"); strcat(dst, LEVEL_INFO[id].name); - #ifdef __EMSCRIPTEN__ + #ifdef _OS_WEB strcat(dst, ".PSX"); #else switch (version) { @@ -692,7 +692,7 @@ namespace TR { break; case VER_TR3_PC : case VER_TR3_PSX : - #ifndef __EMSCRIPTEN__ + #ifndef _OS_WEB callback(Sound::openCDAudioWAD("audio/3/cdaudio.wad", track), userData); return; #else diff --git a/src/gapi_gl.h b/src/gapi_gl.h new file mode 100644 index 0000000..31a8e7f --- /dev/null +++ b/src/gapi_gl.h @@ -0,0 +1,555 @@ +#ifndef H_GAPI_GL +#define H_GAPI_GL + +#include "core.h" + +#if defined(_OS_WINDOWS) || (defined(_OS_LINUX) && !defined(_OS_RPI)) || defined(_OS_ANDROID) + + #ifdef _OS_ANDROID + #define GetProc(x) dlsym(libGL, x); + #else + void* GetProc(const char *name) { + #ifdef _OS_WINDOWS + return (void*)wglGetProcAddress(name); + #elif _OS_LINUX + return (void*)glXGetProcAddress((GLubyte*)name); + #elif _OS_RPI + return (void*)eglGetProcAddress(name); + #endif + } + #endif + + #define GetProcOGL(x) x=(decltype(x))GetProc(#x); + +// Texture + #ifdef _OS_WINDOWS + PFNGLACTIVETEXTUREPROC glActiveTexture; + #endif + +// VSync + #ifdef _OS_WINDOWS + typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; + #elif _OS_LINUX + typedef int (*PFNGLXSWAPINTERVALSGIPROC) (int interval); + PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI; + #endif + + #if defined(_OS_WINDOWS) || defined(_OS_LINUX) + PFNGLGENERATEMIPMAPPROC glGenerateMipmap; + // Profiling + #ifdef PROFILE + PFNGLOBJECTLABELPROC glObjectLabel; + PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup; + PFNGLPOPDEBUGGROUPPROC glPopDebugGroup; + PFNGLGENQUERIESPROC glGenQueries; + PFNGLDELETEQUERIESPROC glDeleteQueries; + PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv; + PFNGLBEGINQUERYPROC glBeginQuery; + PFNGLENDQUERYPROC glEndQuery; + #endif + // Shader + PFNGLCREATEPROGRAMPROC glCreateProgram; + PFNGLDELETEPROGRAMPROC glDeleteProgram; + PFNGLLINKPROGRAMPROC glLinkProgram; + PFNGLUSEPROGRAMPROC glUseProgram; + PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; + PFNGLCREATESHADERPROC glCreateShader; + PFNGLDELETESHADERPROC glDeleteShader; + PFNGLSHADERSOURCEPROC glShaderSource; + PFNGLATTACHSHADERPROC glAttachShader; + PFNGLCOMPILESHADERPROC glCompileShader; + PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; + PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; + PFNGLUNIFORM1IVPROC glUniform1iv; + PFNGLUNIFORM1FVPROC glUniform1fv; + PFNGLUNIFORM2FVPROC glUniform2fv; + PFNGLUNIFORM3FVPROC glUniform3fv; + PFNGLUNIFORM4FVPROC glUniform4fv; + PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; + PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; + PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; + PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; + PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; + PFNGLGETPROGRAMIVPROC glGetProgramiv; + // Render to texture + PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; + PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; + PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; + PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; + PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; + PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; + PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; + PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; + PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; + PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; + // Mesh + PFNGLGENBUFFERSARBPROC glGenBuffers; + PFNGLDELETEBUFFERSARBPROC glDeleteBuffers; + PFNGLBINDBUFFERARBPROC glBindBuffer; + PFNGLBUFFERDATAARBPROC glBufferData; + PFNGLBUFFERSUBDATAARBPROC glBufferSubData; + #endif + + PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; + PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; + PFNGLBINDVERTEXARRAYPROC glBindVertexArray; + PFNGLGETPROGRAMBINARYPROC glGetProgramBinary; + PFNGLPROGRAMBINARYPROC glProgramBinary; +#endif + +#if defined(_GAPI_GLES) + PFNGLDISCARDFRAMEBUFFEREXTPROC glDiscardFramebufferEXT; +#endif + + +#ifdef PROFILE + //#define USE_CV_MARKERS + + #ifdef USE_CV_MARKERS + #include + using namespace Concurrency::diagnostic; + + marker_series *series[256]; + int seriesIndex; + #endif + + struct Marker { + #ifdef USE_CV_MARKERS + span *cvSpan; + #endif + + Marker(const char *title) { + if (Core::support.profMarker) glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, title); + #ifdef USE_CV_MARKERS + marker_series *&s = series[seriesIndex]; + if (s == NULL) { + char seriesTitle[64]; + sprintf(seriesTitle, "events - %d", seriesIndex); + s = new marker_series(seriesTitle); + } + cvSpan = new span(*s, normal_importance, _T(title)); + seriesIndex++; + #endif + } + + ~Marker() { + if (Core::support.profMarker) glPopDebugGroup(); + #ifdef USE_CV_MARKERS + delete cvSpan; + seriesIndex--; + #endif + } + + static void setLabel(GLenum id, GLuint name, const char *label) { + if (Core::support.profMarker) glObjectLabel(id, name, -1, label); + } + }; + + struct Timing { + GLuint ID; + int &result; + + Timing(int &result) : result(result) { + if (!Core::support.profTiming) return; + glGenQueries(1, &ID); + glBeginQuery(GL_TIME_ELAPSED, ID); + } + + ~Timing() { + if (!Core::support.profTiming) return; + glEndQuery(GL_TIME_ELAPSED); + glGetQueryObjectiv(ID, GL_QUERY_RESULT, (GLint*)&result); + glDeleteQueries(1, &ID); + } + }; + + #define PROFILE_MARKER(title) Marker marker(title) + #define PROFILE_LABEL(id, name, label) Marker::setLabel(GL_##id, name, label) + #define PROFILE_TIMING(result) Timing timing(result) +#else + #define PROFILE_MARKER(title) + #define PROFILE_LABEL(id, name, label) + #define PROFILE_TIMING(time) +#endif + + +namespace GAPI { + +#ifndef FFP + const char SHADER_BASE[] = + #include "shaders/shader.glsl" + ; + + const char SHADER_WATER[] = + #include "shaders/water.glsl" + ; + + const char SHADER_FILTER[] = + #include "shaders/filter.glsl" + ; + + const char SHADER_GUI[] = + #include "shaders/gui.glsl" + ; +#endif + + using namespace Core; + + typedef ::Vertex Vertex; + + int cullMode, blendMode; + + bool extSupport(const char *str, const char *ext) { + return strstr(str, ext) != NULL; + } + + void init() { + #ifdef _OS_ANDROID + void *libGL = dlopen("libGLESv2.so", RTLD_LAZY); + #endif + + #if defined(_OS_WINDOWS) || (defined(_OS_LINUX) && !defined(_OS_RPI)) || defined(_OS_ANDROID) + #ifdef _OS_WINDOWS + GetProcOGL(glActiveTexture); + #endif + + #ifdef _OS_WINDOWS + GetProcOGL(wglSwapIntervalEXT); + #elif _OS_LINUX + GetProcOGL(glXSwapIntervalSGI); + #endif + + #if defined(_OS_WINDOWS) || defined(_OS_LINUX) + GetProcOGL(glGenerateMipmap); + + #ifdef PROFILE + GetProcOGL(glObjectLabel); + GetProcOGL(glPushDebugGroup); + GetProcOGL(glPopDebugGroup); + GetProcOGL(glGenQueries); + GetProcOGL(glDeleteQueries); + GetProcOGL(glGetQueryObjectiv); + GetProcOGL(glBeginQuery); + GetProcOGL(glEndQuery); + #endif + + GetProcOGL(glCreateProgram); + GetProcOGL(glDeleteProgram); + GetProcOGL(glLinkProgram); + GetProcOGL(glUseProgram); + GetProcOGL(glGetProgramInfoLog); + GetProcOGL(glCreateShader); + GetProcOGL(glDeleteShader); + GetProcOGL(glShaderSource); + GetProcOGL(glAttachShader); + GetProcOGL(glCompileShader); + GetProcOGL(glGetShaderInfoLog); + GetProcOGL(glGetUniformLocation); + GetProcOGL(glUniform1iv); + GetProcOGL(glUniform1fv); + GetProcOGL(glUniform2fv); + GetProcOGL(glUniform3fv); + GetProcOGL(glUniform4fv); + GetProcOGL(glUniformMatrix4fv); + GetProcOGL(glBindAttribLocation); + GetProcOGL(glEnableVertexAttribArray); + GetProcOGL(glDisableVertexAttribArray); + GetProcOGL(glVertexAttribPointer); + GetProcOGL(glGetProgramiv); + + GetProcOGL(glGenFramebuffers); + GetProcOGL(glBindFramebuffer); + GetProcOGL(glGenRenderbuffers); + GetProcOGL(glBindRenderbuffer); + GetProcOGL(glFramebufferTexture2D); + GetProcOGL(glFramebufferRenderbuffer); + GetProcOGL(glRenderbufferStorage); + GetProcOGL(glCheckFramebufferStatus); + GetProcOGL(glDeleteFramebuffers); + GetProcOGL(glDeleteRenderbuffers); + + GetProcOGL(glGenBuffers); + GetProcOGL(glDeleteBuffers); + GetProcOGL(glBindBuffer); + GetProcOGL(glBufferData); + GetProcOGL(glBufferSubData); + #endif + + #ifdef _GAPI_GLES + GetProcOGL(glDiscardFramebufferEXT); + #endif + + GetProcOGL(glGenVertexArrays); + GetProcOGL(glDeleteVertexArrays); + GetProcOGL(glBindVertexArray); + GetProcOGL(glGetProgramBinary); + GetProcOGL(glProgramBinary); + #endif + + LOG("Vendor : %s\n", (char*)glGetString(GL_VENDOR)); + LOG("Renderer : %s\n", (char*)glGetString(GL_RENDERER)); + LOG("Version : %s\n", (char*)glGetString(GL_VERSION)); + + char *ext = (char*)glGetString(GL_EXTENSIONS); +/* + if (ext != NULL) { + char buf[255]; + int len = strlen(ext); + int start = 0; + for (int i = 0; i < len; i++) + if (ext[i] == ' ' || (i == len - 1)) { + memcpy(buf, &ext[start], i - start); + buf[i - start] = 0; + LOG("%s\n", buf); + start = i + 1; + } + } +*/ + + #ifdef FFP + support.maxAniso = 1; + support.maxVectors = 0; + support.shaderBinary = false; + support.VAO = false; + support.depthTexture = false; + support.shadowSampler = false; + support.discardFrame = false; + support.texNPOT = false; + support.texRG = false; + support.texBorder = false; + support.maxAniso = false; + support.colorFloat = false; + support.colorHalf = false; + support.texFloatLinear = false; + support.texFloat = false; + support.texHalfLinear = false; + support.texHalf = false; + #else + support.shaderBinary = extSupport(ext, "_program_binary"); + support.VAO = extSupport(ext, "_vertex_array_object"); + support.depthTexture = extSupport(ext, "_depth_texture"); + support.shadowSampler = support.depthTexture && (extSupport(ext, "_shadow_samplers") || extSupport(ext, "GL_ARB_shadow")); + support.discardFrame = extSupport(ext, "_discard_framebuffer"); + support.texNPOT = extSupport(ext, "_texture_npot") || extSupport(ext, "_texture_non_power_of_two"); + support.texRG = extSupport(ext, "_texture_rg "); // hope that isn't last extension in string ;) + support.texBorder = extSupport(ext, "_texture_border_clamp"); + support.maxAniso = extSupport(ext, "_texture_filter_anisotropic"); + support.colorFloat = extSupport(ext, "_color_buffer_float"); + support.colorHalf = extSupport(ext, "_color_buffer_half_float") || extSupport(ext, "GL_ARB_half_float_pixel"); + support.texFloatLinear = support.colorFloat || extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_float_linear"); + support.texFloat = support.texFloatLinear || extSupport(ext, "_texture_float"); + support.texHalfLinear = support.colorHalf || extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_half_float_linear") || extSupport(ext, "_color_buffer_half_float"); + support.texHalf = support.texHalfLinear || extSupport(ext, "_texture_half_float"); + + #ifdef PROFILE + support.profMarker = extSupport(ext, "_KHR_debug"); + support.profTiming = extSupport(ext, "_timer_query"); + #endif + + if (support.maxAniso) + glGetIntegerv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &support.maxAniso); + #ifdef _GAPI_GLES + glGetIntegerv(GL_MAX_VARYING_VECTORS, &support.maxVectors); + #else + support.maxVectors = 16; + #endif + #endif + + glEnable(GL_SCISSOR_TEST); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&defaultFBO); + glGenFramebuffers(1, &FBO); + glDepthFunc(GL_LEQUAL); + + #ifdef FFP + glEnable(GL_TEXTURE_2D); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + glEnableClientState(GL_NORMAL_ARRAY); + glEnableClientState(GL_VERTEX_ARRAY); + + glAlphaFunc(GL_GREATER, 0.5f); + + glMatrixMode(GL_TEXTURE); + glLoadIdentity(); + glScalef(1.0f / 32767.0f, 1.0f / 32767.0f, 1.0f / 32767.0f); + + glClearColor(0, 0, 0, 0); + #endif + } + + void deinit() { + glBindFramebuffer(GL_FRAMEBUFFER, 0); + glDeleteFramebuffers(1, &FBO); + + glBindRenderbuffer(GL_RENDERBUFFER, 0); + for (int b = 0; b < 2; b++) + for (int i = 0; i < rtCache[b].count; i++) + glDeleteRenderbuffers(1, &rtCache[b].items[i].ID); + } + + void resetState() { + if (glBindVertexArray) + glBindVertexArray(0); + glActiveTexture(GL_TEXTURE0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glUseProgram(0); + } + + void discardTarget(bool color, bool depth) { + #ifdef _GAPI_GLES + if (Core::support.discardFrame) { + int count = 0; + GLenum discard[2]; + if (color) discard[count++] = Core::active.target ? GL_COLOR_ATTACHMENT0 : GL_COLOR_EXT; + if (depth) discard[count++] = Core::active.target ? GL_DEPTH_ATTACHMENT : GL_DEPTH_EXT; + if (count) + glDiscardFramebufferEXT(GL_FRAMEBUFFER, count, discard); + } + #endif + } + + void setVSync(bool enable) { + #ifdef _OS_WINDOWS + if (wglSwapIntervalEXT) wglSwapIntervalEXT(enable ? 1 : 0); + #elif _OS_LINUX + if (glXSwapIntervalSGI) glXSwapIntervalSGI(enable ? 1 : 0); + #elif _OS_RPI + eglSwapInterval(display, enable ? 1 : 0); + #endif + } + + void waitVBlank() {} + + void clear(bool color, bool depth) { + uint32 mask = (color ? GL_COLOR_BUFFER_BIT : 0) | (depth ? GL_DEPTH_BUFFER_BIT : 0); + if (mask) glClear(mask); + } + + void setClearColor(const vec4 &color) { + glClearColor(color.x, color.y, color.z, color.w); + } + + void setViewport(int x, int y, int w, int h) { + glViewport(x, y, w, h); + glScissor(int(viewport.x), int(viewport.y), int(viewport.z), int(viewport.w)); + } + + void setDepthTest(bool enable) { + if (enable) + glEnable(GL_DEPTH_TEST); + else + glDisable(GL_DEPTH_TEST); + } + + void setDepthWrite(bool enable) { + glDepthMask(enable ? GL_TRUE : GL_FALSE); + } + + void setColorWrite(bool r, bool g, bool b, bool a) { + glColorMask(r, g, b, a); + } + + void setAlphaTest(bool enable) { + if (enable) + glEnable(GL_ALPHA_TEST); + else + glDisable(GL_ALPHA_TEST); + } + + void setCullMode(int rsMask) { + cullMode = rsMask; + switch (rsMask) { + case RS_CULL_BACK : glCullFace(GL_BACK); break; + case RS_CULL_FRONT : glCullFace(GL_FRONT); break; + default : glDisable(GL_CULL_FACE); return; + } + glEnable(GL_CULL_FACE); + } + + void setBlendMode(int rsMask) { + blendMode = rsMask; + switch (rsMask) { + case RS_BLEND_ALPHA : glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); break; + case RS_BLEND_ADD : glBlendFunc(GL_ONE, GL_ONE); break; + case RS_BLEND_MULT : glBlendFunc(GL_DST_COLOR, GL_ZERO); break; + case RS_BLEND_PREMULT : glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); break; + default : glDisable(GL_BLEND); return; + } + glEnable(GL_BLEND); + } + + void setViewProj(const mat4 &mView, const mat4 &mProj) { + #ifdef FFP + glMatrixMode(GL_PROJECTION); + glLoadMatrixf((float*)&mProj); + #endif + } + + void DIP(int iStart, int iCount, Index *iBuffer) { + #ifdef FFP + mat4 m = mView * mModel; + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf((GLfloat*)&m); + #endif + + glDrawElements(GL_TRIANGLES, iCount, GL_UNSIGNED_SHORT, iBuffer + iStart); + } + + vec4 copyPixel(int x, int y) { + ubyte4 c; + glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &c); + return vec4(float(c.x), float(c.y), float(c.z), float(c.w)) * (1.0f / 255.0f); + } + + void initPSO(PSO *pso) { + ASSERT(pso); + ASSERT(pso && pso->data == NULL); + pso->data = &pso; + } + + void deinitPSO(PSO *pso) { + ASSERT(pso); + ASSERT(pso->data != NULL); + pso->data = NULL; + } + + void bindPSO(const PSO *pso) { + ASSERT(pso); + ASSERT(pso->data != NULL); + + uint32 state = pso->renderState; + uint32 mask = mask; + + if (Core::active.pso) + mask ^= Core::active.pso->renderState; + + if (!Core::active.pso || Core::active.pso->clearColor != pso->clearColor) + setClearColor(pso->clearColor); + + if (mask & RS_DEPTH_TEST) + setDepthTest((state & RS_DEPTH_TEST) != 0); + + if (mask & RS_DEPTH_WRITE) + setDepthWrite((state & RS_DEPTH_WRITE) != 0); + + if (mask & RS_COLOR_WRITE) + setColorWrite((state & RS_COLOR_WRITE_R) != 0, (state & RS_COLOR_WRITE_G) != 0, (state & RS_COLOR_WRITE_B) != 0, (state & RS_COLOR_WRITE_A) != 0); + + if (mask & RS_CULL) + setCullMode(state & RS_CULL); + + if (mask & RS_BLEND) + setBlendMode(state & RS_BLEND); + + #ifdef FFP + if (mask & RS_DISCARD) + setAlphaTest((state & RS_DISCARD) != 0); + #endif + } +} + +#endif \ No newline at end of file diff --git a/src/gapi_gu.h b/src/gapi_gu.h new file mode 100644 index 0000000..8652ffd --- /dev/null +++ b/src/gapi_gu.h @@ -0,0 +1,215 @@ +#ifndef H_GAPI_GU +#define H_GAPI_GU + +#include "core.h" + +namespace GAPI { + + using namespace Core; + + struct Vertex { + short2 texCoord; + ubyte4 color; + short3 normal; + short3 coord; + }; + + int cullMode, blendMode; + + uint32 *cmdBuf = NULL; + + static int EDRAM_OFFSET; + static int EDRAM_SIZE; + + void* allocEDRAM(int size) { + LOG("EDRAM ALLOC: offset: %d size %d (free %d)\n", Core::EDRAM_OFFSET, size, EDRAM_SIZE - (Core::EDRAM_OFFSET + size)); + if (Core::EDRAM_OFFSET + size > EDRAM_SIZE) + LOG("! EDRAM overflow !\n"); + + void *ptr = ((char*)sceGeEdramGetAddr()) + EDRAM_OFFSET; + EDRAM_OFFSET += (size + 15) / 16 * 16; + return ptr; + } + + void freeEDRAM() { + EDRAM_OFFSET = (512 * 272 * 2 * 2) + (512 * 272 * 2); + LOG("EDRAM FREE: offset: %d\n", EDRAM_OFFSET); + } + + void beginCmdBuf() { + if (!cmdBuf) + cmdBuf = new uint32[262144]; + sceGuStart(GU_DIRECT, cmdBuf); + } + + void submitCmdBuf() { + ASSERT(cmdBuf); + sceGuFinish(); + sceGuSync(GU_SYNC_WAIT, GU_SYNC_FINISH); + } + + void init() { + LOG("Vendor : %s\n", "Sony"); + LOG("Renderer : %s\n", "SCE GU"); + LOG("Version : %s\n", "1.0"); + + EDRAM_SIZE = sceGeEdramGetSize(); + LOG("VRAM : %d\n", EDRAM_SIZE); + freeEDRAM(); + + + support.maxAniso = 1; + support.maxVectors = 0; + support.shaderBinary = false; + support.VAO = false; + support.depthTexture = false; + support.shadowSampler = false; + support.discardFrame = false; + support.texNPOT = false; + support.texRG = false; + support.texBorder = false; + support.maxAniso = false; + support.colorFloat = false; + support.colorHalf = false; + support.texFloatLinear = false; + support.texFloat = false; + support.texHalfLinear = false; + support.texHalf = false; + + Core::width = 480; + Core::height = 272; + + sceGuEnable(GU_TEXTURE_2D); + sceGuDepthFunc(GU_LEQUAL); + sceGuDepthRange(0x0000, 0xFFFF); + sceGuClearDepth(0xFFFF); + + sceGuShadeModel(GU_SMOOTH); + sceGuAlphaFunc(GU_GREATER, 127, 255); + + int swizzle = GU_FALSE; + #ifdef TEX_SWIZZLE + swizzle = GU_TRUE; + #endif + + sceGuClutMode(GU_PSM_5551, 0, 0xFF, 0); + sceGuTexMode(GU_PSM_T4, 0, 0, swizzle); + sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA); + sceGuTexScale(1.0f, 1.0f); + sceGuTexOffset(0.0f, 0.0f); + sceGuTexFilter(GU_LINEAR, GU_LINEAR); + //sceGuTexFilter(GU_NEAREST, GU_NEAREST); + sceGuEnable(GU_CLIP_PLANES); + + const ScePspIMatrix4 dith = + { {-4, 0, -3, 1}, + { 2, -2, 3, -1}, + {-3, 1, -4, 0}, + { 3, -1, 2, -2} }; + sceGuSetDither(&dith); + sceGuEnable(GU_DITHER); + + sceGuAmbientColor(0xFFFFFFFF); + sceGuColor(0xFFFFFFFF); + sceGuClearColor(0x00000000); + sceGuColorMaterial(GU_AMBIENT | GU_DIFFUSE); + } + + void deinit() { + delete[] cmdBuf; + } + + void resetState() {} + + void discardTarget(bool color, bool depth) {} + + void setVSync(bool enable) {} + + void waitVBlank() { + sceDisplayWaitVblankStart(); + } + + void clear(bool color, bool depth) { + uint32 mask = (color ? GU_COLOR_BUFFER_BIT : 0) | (depth ? GU_DEPTH_BUFFER_BIT : 0); + if (mask) sceGuClear(mask | GU_FAST_CLEAR_BIT); + } + + void setClearColor(const vec4 &color) { + ubyte4 c(clamp(int(color.x * 255), 0, 255), + clamp(int(color.y * 255), 0, 255), + clamp(int(color.z * 255), 0, 255), + clamp(int(color.w * 255), 0, 255)); + sceGuClearColor(*((uint32*)&c)); + } + + void setViewport(int x, int y, int w, int h) { + sceGuOffset(2048 - w / 2, 2048 - h / 2); + sceGuViewport(2048 + x, 2048 + y, w, h); + } + + void setDepthTest(bool enable) { + if (enable) + sceGuEnable(GU_DEPTH_TEST); + else + sceGuDisable(GU_DEPTH_TEST); + } + + void setDepthWrite(bool enable) { + sceGuDepthMask(enable ? GU_FALSE : GU_TRUE); + } + + void setColorWrite(bool r, bool g, bool b, bool a) { + sceGuPixelMask(~((r ? 0x000000FF : 0) | (g ? 0x0000FF00 : 0) | (b ? 0x00FF0000 : 0) | (a ? 0xFF000000 : 0))); + } + + void setAlphaTest(bool enable) { + if (enable) + sceGuEnable(GU_ALPHA_TEST); + else + sceGuDisable(GU_ALPHA_TEST); + } + + void setCullMode(int rsMask) { + cullMode = rsMask; + switch (rsMask) { + case RS_CULL_BACK : sceGuFrontFace(GU_CCW); break; + case RS_CULL_FRONT : sceGuFrontFace(GU_CW); break; + default : sceGuDisable(GU_CULL_FACE); return; + } + sceGuEnable(GU_CULL_FACE); + } + + void setBlendMode(int rsMask) { + blendMode = rsMask; + switch (rsMask) { + case RS_BLEND_ALPHA : sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0); break; + case RS_BLEND_ADD : sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xffffffff, 0xffffffff); break; + case RS_BLEND_MULT : sceGuBlendFunc(GU_ADD, GU_DST_COLOR, GU_FIX, 0, 0); break; + case RS_BLEND_PREMULT : sceGuBlendFunc(GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_ALPHA, 0xffffffff, 0); break; + default : sceGuDisable(GU_BLEND); return; + } + sceGuEnable(GU_BLEND); + } + + void setViewProj(const mat4 &mView, const mat4 &mProj) { + sceGumMatrixMode(GU_PROJECTION); + sceGumLoadMatrix((ScePspFMatrix4*)&mProj); + sceGumMatrixMode(GU_VIEW); + sceGumLoadMatrix((ScePspFMatrix4*)&mView); + } + + void DIP(int iStart, int iCount, Index *iBuffer) { + mat4 m = mModel; + m.scale(vec3(32767.0f)); + sceGumMatrixMode(GU_MODEL); + sceGumLoadMatrix((ScePspFMatrix4*)&m); + + sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_16BIT | GU_COLOR_8888 | GU_NORMAL_16BIT | GU_VERTEX_16BIT | GU_INDEX_16BIT | GU_TRANSFORM_3D, iCount, active.iBuffer + iStart, active.vBuffer); + } + + vec4 copyPixel(int x, int y) { + return vec4(0.0f); // TODO: read from framebuffer + } +} + +#endif \ No newline at end of file diff --git a/src/gapi_gx.h b/src/gapi_gx.h new file mode 100644 index 0000000..efbc3e8 --- /dev/null +++ b/src/gapi_gx.h @@ -0,0 +1,6 @@ +#ifndef H_GAPI_GX +#define H_GAPI_GX + +// TODO + +#endif \ No newline at end of file diff --git a/src/gapi_vk.h b/src/gapi_vk.h new file mode 100644 index 0000000..369439e --- /dev/null +++ b/src/gapi_vk.h @@ -0,0 +1,6 @@ +#ifndef H_GAPI_VK +#define H_GAPI_VK + +// TODO + +#endif \ No newline at end of file diff --git a/src/inventory.h b/src/inventory.h index 4847bb8..ed4fda5 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -7,7 +7,7 @@ #define INVENTORY_MAX_ITEMS 32 #define INVENTORY_MAX_RADIUS 688.0f -#ifdef _PSP +#ifdef _OS_PSP #define INVENTORY_BG_SIZE 256 #else #define INVENTORY_BG_SIZE 512 @@ -125,12 +125,12 @@ static const OptionItem optDetail[] = { OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_LIGHTING, SETTINGS( detail.lighting ), STR_QUALITY_LOW, 0, 2 ), OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_SHADOWS, SETTINGS( detail.shadows ), STR_QUALITY_LOW, 0, 2 ), OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_WATER, SETTINGS( detail.water ), STR_QUALITY_LOW, 0, 2 ), -#if defined(WIN32) || defined(LINUX) || defined(_PSP) || defined(__RPI__) +#if defined(_OS_WINDOWS) || defined(_OS_LINUX) || defined(_OS_PSP) || defined(_OS_RPI) OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_VSYNC, SETTINGS( detail.vsync ), STR_OFF, 0, 1 ), #endif -#ifndef _PSP +#ifndef _OS_PSP OptionItem( OptionItem::TYPE_PARAM, STR_OPT_DETAIL_STEREO, SETTINGS( detail.stereo ), STR_OFF, 0, -#if /*defined(_WIN32) ||*/ defined(ANDROID) +#if /*defined(_OS_WINDOWS) ||*/ defined(_OS_ANDROID) 3 /* with VR option */ #else 2 /* without VR support */ @@ -154,7 +154,7 @@ static const OptionItem optControls[] = { OptionItem( ), OptionItem( OptionItem::TYPE_PARAM, STR_NOT_IMPLEMENTED , SETTINGS( playerIndex ), STR_PLAYER_1, 0, 1 ), OptionItem( OptionItem::TYPE_PARAM, STR_OPT_CONTROLS_GAMEPAD , SETTINGS( controls[0].joyIndex ), STR_GAMEPAD_1, 0, 3 ), -#ifdef WIN32 +#ifdef _OS_WINDOWS OptionItem( OptionItem::TYPE_PARAM, STR_OPT_CONTROLS_VIBRATION , SETTINGS( controls[0].vibration ), STR_OFF, 0, 1 ), #endif OptionItem( OptionItem::TYPE_PARAM, STR_OPT_CONTROLS_RETARGET , SETTINGS( controls[0].retarget ), STR_OFF, 0, 1 ), @@ -431,18 +431,18 @@ struct Inventory { Core::setBasis(joints, m.mCount); - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); mesh->transparent = 0; mesh->renderModel(desc.model); mesh->transparent = 1; mesh->renderModel(desc.model); - Core::setBlending(bmAdd); + Core::setBlendMode(bmAdd); Core::setDepthWrite(false); mesh->transparent = 2; mesh->renderModel(desc.model); Core::setDepthWrite(true); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); } void choose() { @@ -760,7 +760,7 @@ struct Inventory { switch (level->version & TR::VER_VERSION) { case TR::VER_TR1 : - #ifdef __EMSCRIPTEN__ + #ifdef _OS_WEB passportSlotCount = 2; passportSlots[0] = TR::LVL_TR1_1; passportSlots[1] = TR::LVL_TR1_2; @@ -773,7 +773,7 @@ struct Inventory { #endif break; case TR::VER_TR2 : - #ifdef __EMSCRIPTEN__ + #ifdef _OS_WEB passportSlotCount = 2; passportSlots[0] = TR::LVL_TR2_WALL; passportSlots[1] = TR::LVL_TR2_BOAT; @@ -786,7 +786,7 @@ struct Inventory { #endif break; case TR::VER_TR3 : - #ifdef __EMSCRIPTEN__ + #ifdef _OS_WEB passportSlotCount = 1; passportSlots[0] = TR::LVL_TR3_JUNGLE; #else @@ -1107,7 +1107,7 @@ struct Inventory { for (int i = 0; i < COUNT(background); i++) if (!background[i]) - background[i] = new Texture(INVENTORY_BG_SIZE, INVENTORY_BG_SIZE, Texture::RGBA); + background[i] = new Texture(INVENTORY_BG_SIZE, INVENTORY_BG_SIZE, FMT_RGBA); return background[0]; } @@ -1116,7 +1116,7 @@ struct Inventory { if (Core::settings.detail.stereo == Core::Settings::STEREO_VR) return; - #ifdef _PSP + #ifdef _OS_PSP return; #endif Core::defaultTarget = getBackgroundTarget(); @@ -1124,7 +1124,7 @@ struct Inventory { Core::defaultTarget = NULL; Core::setDepthTest(false); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); #ifdef FFP mat4 m; @@ -1133,7 +1133,7 @@ struct Inventory { Core::mModel.identity(); #endif - #ifdef _PSP + #ifdef _OS_PSP // #else // vertical blur @@ -1331,10 +1331,10 @@ struct Inventory { uint8 alpha; if (!isActive() && titleTimer > 0.0f && titleTimer < 1.0f) { - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); alpha = uint8(titleTimer * 255); } else { - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); alpha = 255; } @@ -1417,7 +1417,7 @@ struct Inventory { } void renderGameBG() { - #ifdef _PSP + #ifdef _OS_PSP return; #endif Index indices[6] = { 0, 1, 2, 0, 2, 3 }; @@ -1443,7 +1443,7 @@ struct Inventory { } else background[0]->bind(sDiffuse); // blured grayscale image - Core::setBlending(phaseRing < 1.0f ? bmAlpha : bmNone); + Core::setBlendMode(phaseRing < 1.0f ? bmAlpha : bmNone); game->getMesh()->renderBuffer(indices, COUNT(indices), vertices, COUNT(vertices)); } @@ -1465,7 +1465,7 @@ struct Inventory { renderTitleBG(); } - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); Core::setDepthTest(true); } diff --git a/src/lara.h b/src/lara.h index 3f1aacb..353bc55 100644 --- a/src/lara.h +++ b/src/lara.h @@ -1443,7 +1443,7 @@ struct Lara : Character { void bakeEnvironment() { flags.invisible = true; if (!environment) - environment = new Texture(256, 256, Texture::RGBA, Texture::CUBEMAP | Texture::MIPMAPS); + environment = new Texture(256, 256, FMT_RGBA, Texture::CUBEMAP | Texture::MIPMAPS); game->renderEnvironment(getRoomIndex(), pos - vec3(0.0f, 384.0f, 0.0f), &environment, 0, Core::passCompose); environment->generateMipMap(); flags.invisible = false; @@ -3282,11 +3282,11 @@ struct Lara : Character { Core::active.shader->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS); */ environment->bind(sEnvironment); - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); visibleMask ^= 0xFFFFFFFF; Controller::render(frustum, mesh, type, caustics); visibleMask ^= 0xFFFFFFFF; - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); } } }; diff --git a/src/level.h b/src/level.h index 0fc6f43..a906258 100644 --- a/src/level.h +++ b/src/level.h @@ -70,7 +70,7 @@ struct Level : IGame { } virtual void loadNextLevel() { - #ifdef __EMSCRIPTEN__ + #ifdef _OS_WEB if (level.id == TR::LVL_TR1_2 && level.version != TR::VER_TR1_PC) { loadLevel(TR::LVL_TR1_TITLE); return; @@ -226,9 +226,9 @@ struct Level : IGame { void initShadow() { delete shadow; if (Core::settings.detail.shadows > Core::Settings::MEDIUM) - shadow = new Texture(SHADOW_TEX_WIDTH, SHADOW_TEX_HEIGHT, Texture::SHADOW); + shadow = new Texture(SHADOW_TEX_WIDTH, SHADOW_TEX_HEIGHT, FMT_SHADOW); else if (Core::settings.detail.shadows > Core::Settings::LOW) - shadow = new Texture(SHADOW_TEX_BIG_WIDTH, SHADOW_TEX_BIG_HEIGHT, Texture::SHADOW); + shadow = new Texture(SHADOW_TEX_BIG_WIDTH, SHADOW_TEX_BIG_HEIGHT, FMT_SHADOW); else shadow = NULL; } @@ -245,13 +245,15 @@ struct Level : IGame { bool redraw = settings.detail.stereo != Core::settings.detail.stereo; - #ifdef ANDROID + #ifdef _OS_ANDROID if ((settings.detail.stereo == Core::Settings::STEREO_VR) ^ (Core::settings.detail.stereo == Core::Settings::STEREO_VR)) osToggleVR(settings.detail.stereo == Core::Settings::STEREO_VR); #endif Core::settings = settings; + Core::setVSync(Core::settings.detail.vsync != 0); + Stream::cacheWrite("settings", (char*)&settings, sizeof(settings)); if (rebuildShaders) { @@ -366,7 +368,7 @@ struct Level : IGame { } virtual void setShader(Core::Pass pass, Shader::Type type, bool underwater = false, bool alphaTest = false) { - shaderCache->bind(pass, type, (underwater ? ShaderCache::FX_UNDERWATER : 0) | (alphaTest ? ShaderCache::FX_ALPHA_TEST : 0) | ((params->clipHeight != NO_CLIP_PLANE && pass == Core::passCompose) ? ShaderCache::FX_CLIP_PLANE : 0), this); + shaderCache->bind(pass, type, (underwater ? ShaderCache::FX_UNDERWATER : 0) | (alphaTest ? ShaderCache::FX_ALPHA_TEST : 0) | ((params->clipHeight != NO_CLIP_PLANE && pass == Core::passCompose) ? ShaderCache::FX_CLIP_PLANE : 0)); } virtual void setRoomParams(int roomIndex, Shader::Type type, float diffuse, float ambient, float specular, float alpha, bool alphaTest = false) { @@ -657,7 +659,7 @@ struct Level : IGame { //============================== Level(Stream &stream) : level(stream), inventory(this), waitTrack(false), isEnded(false), cutsceneWaitTimer(0.0f), animTexTimer(0.0f) { - #ifdef _PSP + #ifdef _OS_PSP Core::freeEDRAM(); #endif params = (Params*)&Core::params; @@ -1080,7 +1082,7 @@ struct Level : IGame { #ifndef SPLIT_BY_TILE - #ifdef _PSP + #ifdef _OS_PSP #error atlas packing is not allowed for this platform #endif @@ -1137,7 +1139,7 @@ struct Level : IGame { delete[] level.tiles; level.tiles = NULL; #else - #ifdef _PSP + #ifdef _OS_PSP atlas = new Texture(level.tiles4, level.tilesCount, level.cluts, level.clutsCount); #else level.initTiles(); @@ -1257,7 +1259,7 @@ struct Level : IGame { else b = Basis(quat(0, 0, 0, 1), vec3(0)); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); Core::setDepthTest(false); setShader(Core::pass, Shader::FLASH, false, false); Core::active.shader->setParam(uMaterial, vec4(0.5f, 0.0f, 0.0f, 0.0f)); @@ -1315,9 +1317,9 @@ struct Level : IGame { Core::mModel.identity(); switch (transp) { - case 0 : Core::setBlending(bmNone); break; - case 1 : Core::setBlending(bmAlpha); break; - case 2 : Core::setBlending(bmAdd); Core::setDepthWrite(false); break; + case 0 : Core::setBlendMode(bmNone); break; + case 1 : Core::setBlendMode(bmAlpha); break; + case 2 : Core::setBlendMode(bmAdd); Core::setDepthWrite(false); break; } int i = 0; @@ -1362,7 +1364,7 @@ struct Level : IGame { Core::setDepthWrite(true); if (transp == 1) { - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); #ifdef MERGE_SPRITES basis.rot = Core::mViewInv.getRot(); @@ -1393,7 +1395,7 @@ struct Level : IGame { } endLighting(); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); } void renderEntity(const TR::Entity &entity) { @@ -1583,7 +1585,7 @@ struct Level : IGame { void updateLighting() { #ifdef FFP - #ifdef _PSP + #ifdef _OS_PSP ubyte4 ambient; ambient.x = ambient.y = ambient.z = clamp(int(Core::active.material.y * 255), 0, 255); ambient.w = 255; @@ -1627,7 +1629,7 @@ struct Level : IGame { void beginLighting(bool room) { #ifdef FFP Core::mModel.identity(); - #ifdef _PSP + #ifdef _OS_PSP sceGuEnable(GU_LIGHTING); if (room) sceGuDisable(GU_LIGHT0); @@ -1648,7 +1650,7 @@ struct Level : IGame { void endLighting() { #ifdef FFP - #ifdef _PSP + #ifdef _OS_PSP sceGuDisable(GU_LIGHTING); #else glDisable(GL_COLOR_MATERIAL); @@ -1680,27 +1682,27 @@ struct Level : IGame { beginLighting(false); if (transp == 0) { - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); renderEntitiesTransp(transp); } if (transp == 1) { - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); renderEntitiesTransp(transp); - Core::setBlending(bmMult); + Core::setBlendMode(bmMult); for (int i = 0; i < level.entitiesCount; i++) { TR::Entity &entity = level.entities[i]; Controller *controller = (Controller*)entity.controller; if (controller && controller->flags.rendered && controller->getEntity().castShadow()) controller->renderShadow(mesh); } - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); } if (transp == 2) { Core::setDepthWrite(false); - Core::setBlending(bmAdd); + Core::setBlendMode(bmAdd); renderEntitiesTransp(transp); Core::setDepthWrite(true); } @@ -1900,7 +1902,7 @@ struct Level : IGame { if (camera->isUnderwater()) renderAdditive(roomsList, roomsCount); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); if (water && waterCache && waterCache->visible) { Core::Pass pass = Core::pass; waterCache->renderMask(); @@ -1914,7 +1916,7 @@ struct Level : IGame { if (!camera->isUnderwater()) renderAdditive(roomsList, roomsCount); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); if (showUI) { Core::Pass pass = Core::pass; @@ -1995,7 +1997,7 @@ struct Level : IGame { bias.e00 = bias.e11 = bias.e22 = bias.e03 = bias.e13 = bias.e23 = 0.5f; Core::mLightProj[index] = bias * (Core::mProj * Core::mView); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); mesh->transparent = 0; if (mesh->models[controller->getEntity().modelIndex - 1].geometry[mesh->transparent].count) { @@ -2076,13 +2078,13 @@ struct Level : IGame { Core::pass = Core::passShadow; shadow->unbind(sShadow); - bool colorShadow = shadow->format == Texture::RGBA ? true : false; + bool colorShadow = shadow->format == FMT_RGBA ? true : false; if (colorShadow) Core::setClearColor(vec4(1.0f)); Core::setTarget(shadow, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH)); Core::validateRenderState(); - Core::setCulling(cfBack); + Core::setCullMode(cmBack); if (Core::settings.detail.shadows > Core::Settings::Quality::MEDIUM) { // per-object shadow map (atlas) NearObj nearObj[SHADOW_OBJ_MAX]; @@ -2098,7 +2100,7 @@ struct Level : IGame { } else // all-in-one shadow map renderShadowView(roomIndex); - Core::setCulling(cfFront); + Core::setCullMode(cmFront); if (colorShadow) Core::setClearColor(vec4(0.0f)); @@ -2165,9 +2167,9 @@ struct Level : IGame { else atlas->bind(sDiffuse); glEnable(GL_TEXTURE_2D); - Core::setCulling(cfNone); + Core::setCullMode(cmNone); Core::setDepthTest(false); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); Core::validateRenderState(); glColor3f(10, 10, 10); @@ -2203,7 +2205,7 @@ struct Level : IGame { // Box bbox = lara->getBoundingBox(); // Debug::Draw::box(bbox.min, bbox.max, vec4(1, 0, 1, 1)); - Core::setBlending(bmAlpha); + Core::setBlendMode(bmAlpha); Core::setDepthTest(false); Core::validateRenderState(); // Debug::Level::rooms(level, lara->pos, lara->getEntity().room); @@ -2220,7 +2222,7 @@ struct Level : IGame { // Debug::Level::debugOverlaps(level, lara->box); // Debug::Level::debugBoxes(level, lara->dbgBoxes, lara->dbgBoxesCount); Core::setDepthTest(true); - Core::setBlending(bmNone); + Core::setBlendMode(bmNone); /* Core::validateRenderState(); diff --git a/src/mesh.h b/src/mesh.h index 6e4ae0f..8a702a6 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -19,13 +19,13 @@ struct MeshRange { MeshRange() : iStart(0), iCount(0), vStart(0), aIndex(-1), tile(0), clut(0) {} #ifdef FFP - #ifdef _PSP + #ifdef _OS_PSP void setup() const { Core::active.vBuffer += vStart; } #else void setup() const { - VertexGPU *v = (VertexGPU*)NULL + vStart; + GAPI::Vertex *v = (GAPI::Vertex*)NULL + vStart; glTexCoordPointer (2, GL_SHORT, sizeof(*v), &v->texCoord); glColorPointer (4, GL_UNSIGNED_BYTE, sizeof(*v), &v->light); glNormalPointer ( GL_SHORT, sizeof(*v), &v->normal); @@ -42,7 +42,7 @@ struct MeshRange { glEnableVertexAttribArray(aColor); glEnableVertexAttribArray(aLight); - VertexGPU *v = (VertexGPU*)vBuffer + vStart; + GAPI::Vertex *v = (GAPI::Vertex*)vBuffer + vStart; glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(*v), &v->coord); glVertexAttribPointer(aNormal, 4, GL_SHORT, true, sizeof(*v), &v->normal); glVertexAttribPointer(aTexCoord, 4, GL_SHORT, true, sizeof(*v), &v->texCoord); @@ -66,9 +66,9 @@ struct MeshRange { #define MAX_ROOM_DYN_FACES 512 struct Mesh { - Index *iBuffer; - VertexGPU *vBuffer; -#ifndef _PSP + Index *iBuffer; + GAPI::Vertex *vBuffer; +#ifndef _OS_PSP GLuint ID[2]; GLuint *VAO; #endif @@ -79,21 +79,21 @@ struct Mesh { int aIndex; bool cmdBufAlloc; -#ifdef _PSP +#ifdef _OS_PSP Mesh(int iCount, int vCount, bool dynamic) : iCount(iCount), vCount(vCount), aCount(0), aIndex(-1), cmdBufAlloc(true) { iBuffer = (Index*)sceGuGetMemory(iCount * sizeof(Index)); - vBuffer = (VertexGPU*)sceGuGetMemory(vCount * sizeof(VertexGPU)); + vBuffer = (GAPI::Vertex*)sceGuGetMemory(vCount * sizeof(GAPI::Vertex)); } #endif Mesh(Index *indices, int iCount, Vertex *vertices, int vCount, int aCount) : iCount(iCount), vCount(vCount), aCount(aCount), aIndex(0), cmdBufAlloc(false) { - #ifdef _PSP + #ifdef _OS_PSP #ifdef EDRAM_MESH iBuffer = (Index*)Core::allocEDRAM(iCount * sizeof(Index)); - vBuffer = (VertexGPU*)Core::allocEDRAM(vCount * sizeof(VertexGPU)); + vBuffer = (GAPI::Vertex*)Core::allocEDRAM(vCount * sizeof(GAPI::Vertex)); #else iBuffer = new Index[iCount]; - vBuffer = new VertexGPU[vCount]; + vBuffer = new GAPI::Vertex[vCount]; #endif update(indices, iCount, vertices, vCount); @@ -106,7 +106,7 @@ struct Mesh { if (!vertices && !indices) { ID[0] = ID[1] = 0; iBuffer = new Index[iCount]; - vBuffer = new VertexGPU[vCount]; + vBuffer = new GAPI::Vertex[vCount]; return; } #endif @@ -114,7 +114,7 @@ struct Mesh { glGenBuffers(2, ID); bind(true); glBufferData(GL_ELEMENT_ARRAY_BUFFER, iCount * sizeof(Index), indices, GL_STATIC_DRAW); - glBufferData(GL_ARRAY_BUFFER, vCount * sizeof(VertexGPU), vertices, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vCount * sizeof(GAPI::Vertex), vertices, GL_STATIC_DRAW); if (Core::support.VAO && aCount) { VAO = new GLuint[aCount]; @@ -126,13 +126,13 @@ struct Mesh { } void update(Index *indices, int iCount, Vertex *vertices, int vCount) { - #ifdef _PSP + #ifdef _OS_PSP if (indices) memcpy(iBuffer, indices, iCount * sizeof(indices[0])); if (vertices) { Vertex *src = vertices; - VertexGPU *dst = vBuffer; + GAPI::Vertex *dst = vBuffer; for (int i = 0; i < vCount; i++) { dst->texCoord = short2(src->texCoord.x, src->texCoord.y); @@ -145,8 +145,8 @@ struct Mesh { } } #else - // !!! typeof vertices[0] == Vertex == VertexGPU - ASSERT(sizeof(VertexGPU) == sizeof(Vertex)); + // !!! typeof vertices[0] == Vertex == GAPI::Vertex + ASSERT(sizeof(GAPI::Vertex) == sizeof(Vertex)); if (Core::support.VAO) glBindVertexArray(Core::active.VAO = 0); @@ -161,17 +161,17 @@ struct Mesh { } if (vertices && vCount) { if (vBuffer) { - memcpy(vBuffer, vertices, vCount * sizeof(VertexGPU)); + memcpy(vBuffer, vertices, vCount * sizeof(GAPI::Vertex)); } else { glBindBuffer(GL_ARRAY_BUFFER, Core::active.vBuffer = ID[1]); - glBufferSubData(GL_ARRAY_BUFFER, 0, vCount * sizeof(VertexGPU), vertices); + glBufferSubData(GL_ARRAY_BUFFER, 0, vCount * sizeof(GAPI::Vertex), vertices); } } #endif } virtual ~Mesh() { - #ifdef _PSP + #ifdef _OS_PSP #ifndef EDRAM_MESH if (!cmdBufAlloc) { delete[] iBuffer; @@ -193,7 +193,7 @@ struct Mesh { } void initRange(MeshRange &range) { - #ifndef _PSP + #ifndef _OS_PSP if (Core::support.VAO && VAO) { ASSERT(aIndex < aCount); range.aIndex = aIndex++; @@ -207,7 +207,7 @@ struct Mesh { } void bind(bool force = false) { - #ifdef _PSP + #ifdef _OS_PSP Core::active.iBuffer = iBuffer; Core::active.vBuffer = vBuffer; #else @@ -229,7 +229,7 @@ struct Mesh { if (range.aIndex == -1) bind(); - #ifndef _PSP + #ifndef _OS_PSP range.bind(VAO); #endif @@ -277,7 +277,7 @@ uint8 intensity(int lighting) { } struct MeshBuilder { -#ifndef _PSP +#ifndef _OS_PSP MeshRange dynRange; Mesh *dynMesh; #endif @@ -374,7 +374,7 @@ struct MeshBuilder { }; MeshBuilder(TR::Level &level, Texture *atlas) : atlas(atlas), level(&level) { - #ifndef _PSP + #ifndef _OS_PSP dynMesh = new Mesh(NULL, DYN_MESH_QUADS * 6, NULL, DYN_MESH_QUADS * 4, 1); dynRange.vStart = 0; dynRange.iStart = 0; @@ -739,7 +739,7 @@ struct MeshBuilder { plane.iCount = 0; #endif - LOG("MegaMesh (i:%d v:%d a:%d, size:%d)\n", iCount, vCount, aCount, int(iCount * sizeof(Index) + vCount * sizeof(VertexGPU))); + LOG("MegaMesh (i:%d v:%d a:%d, size:%d)\n", iCount, vCount, aCount, int(iCount * sizeof(Index) + vCount * sizeof(GAPI::Vertex))); // compile buffer and ranges mesh = new Mesh(indices, iCount, vertices, vCount, aCount); @@ -805,7 +805,7 @@ struct MeshBuilder { delete[] models; delete[] sequences; delete mesh; - #ifndef _PSP + #ifndef _OS_PSP delete dynMesh; #endif } @@ -1235,7 +1235,7 @@ struct MeshBuilder { if (!iCount) return; ASSERT(vCount > 0); - #ifdef _PSP + #ifdef _OS_PSP MeshRange dynRange; Mesh cmdBufMesh(iCount, vCount); Mesh *dynMesh = &cmdBufMesh; @@ -1427,13 +1427,13 @@ struct MeshBuilder { } void renderShadowBlob() { - #ifdef _PSP + #ifdef _OS_PSP sceGuDisable(GU_TEXTURE_2D); #endif mesh->render(shadowBlob); - #ifdef _PSP + #ifdef _OS_PSP sceGuEnable(GU_TEXTURE_2D); #endif } diff --git a/src/platform/psp/main.cpp b/src/platform/psp/main.cpp index 352bb6b..1548e62 100644 --- a/src/platform/psp/main.cpp +++ b/src/platform/psp/main.cpp @@ -148,7 +148,7 @@ int main() { sceGuInit(); - Core::beginCmdBuf(); + GAPI::beginCmdBuf(); sceGuDrawBuffer(GU_PSM_5650, (void*)0, BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, (void*)(BUF_WIDTH * SCR_HEIGHT * 2), BUF_WIDTH); @@ -165,7 +165,7 @@ int main() { Game::init(); - Core::submitCmdBuf(); + GAPI::submitCmdBuf(); sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); @@ -173,12 +173,12 @@ int main() { Core::curBackBuffer = 0; while (!Core::isQuit) { - Core::beginCmdBuf(); + GAPI::beginCmdBuf(); joyUpdate(); Game::update(); Game::render(); - Core::submitCmdBuf(); + GAPI::submitCmdBuf(); Core::waitVBlank(); Core::curBackBuffer = sceGuSwapBuffers(); } diff --git a/src/platform/web/index.html b/src/platform/web/index.html index 9b3b586..5988e87 100644 --- a/src/platform/web/index.html +++ b/src/platform/web/index.html @@ -22,10 +22,10 @@ - + -
+
Starting...