1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-02-24 15:32:30 +01:00

#23 mutual shader cache

This commit is contained in:
XProger 2017-09-13 06:30:33 +03:00
parent 0213d91175
commit 0cf58dac36
4 changed files with 26 additions and 20 deletions

View File

@ -34,10 +34,9 @@ const char GUI[] =
struct ShaderCache {
enum Effect { FX_NONE = 0, FX_UNDERWATER = 1, FX_ALPHA_TEST = 2, FX_CLIP_PLANE = 4 };
MeshBuilder *mesh;
Shader *shaders[Core::passMAX][Shader::MAX][(FX_UNDERWATER | FX_ALPHA_TEST | FX_CLIP_PLANE) + 1];
ShaderCache(MeshBuilder *mesh) : mesh(mesh) {
ShaderCache() {
memset(shaders, 0, sizeof(shaders));
LOG("shader: cache warm up...\n");
@ -128,10 +127,8 @@ struct ShaderCache {
static const char *typeNames[] = { "SPRITE", "FLASH", "ROOM", "ENTITY", "MIRROR" };
src = SHADER;
typ = typeNames[type];
int animTexRangesCount = mesh->animTexRangesCount;
int animTexOffsetsCount = mesh->animTexOffsetsCount;
sprintf(def, "%s#define PASS_%s\n#define TYPE_%s\n#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define MAX_CONTACTS %d\n#define FOG_DIST (1.0/%d.0)\n#define WATER_FOG_DIST (1.0/%d.0)\n#define SHADOW_TEX_SIZE %d.0\n", ext, passNames[pass], typ, MAX_LIGHTS, animTexRangesCount, animTexOffsetsCount, MAX_CONTACTS, FOG_DIST, WATER_FOG_DIST, SHADOW_TEX_SIZE);
typ = typeNames[type];
sprintf(def, "%s#define PASS_%s\n#define TYPE_%s\n#define MAX_LIGHTS %d\n#define MAX_RANGES %d\n#define MAX_OFFSETS %d\n#define MAX_CONTACTS %d\n#define FOG_DIST (1.0/%d.0)\n#define WATER_FOG_DIST (1.0/%d.0)\n#define SHADOW_TEX_SIZE %d.0\n", ext, passNames[pass], typ, MAX_LIGHTS, MAX_ANIM_TEX_RANGES, MAX_ANIM_TEX_OFFSETS, MAX_CONTACTS, FOG_DIST, WATER_FOG_DIST, SHADOW_TEX_SIZE);
if (fx & FX_UNDERWATER) strcat(def, "#define UNDERWATER\n" UNDERWATER_COLOR);
if (fx & FX_ALPHA_TEST) strcat(def, "#define ALPHA_TEST\n");
if (fx & FX_CLIP_PLANE) strcat(def, "#define CLIP_PLANE\n");
@ -172,7 +169,7 @@ struct ShaderCache {
return shaders[pass][type][fx] = new Shader(src, def);
}
void bind(Core::Pass pass, Shader::Type type, int fx) {
void bind(Core::Pass pass, Shader::Type type, int fx, IGame *game) {
Core::pass = pass;
Shader *shader = shaders[pass][type][fx];
if (!shader)
@ -184,6 +181,9 @@ struct ShaderCache {
shader->setParam(uLightProj, Core::mLightProj);
shader->setParam(uViewPos, Core::viewPos);
shader->setParam(uParam, Core::params);
MeshBuilder *mesh = game->getMesh();
ASSERT(mesh->animTexRangesCount <= MAX_ANIM_TEX_RANGES);
ASSERT(mesh->animTexOffsetsCount <= MAX_ANIM_TEX_OFFSETS);
shader->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount);
shader->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount);
}

View File

@ -253,10 +253,12 @@ namespace Core {
PFNGLDISCARDFRAMEBUFFEREXTPROC glDiscardFramebufferEXT;
#endif
#define MAX_LIGHTS 4
#define MAX_CACHED_LIGHTS 3
#define MAX_RENDER_BUFFERS 32
#define MAX_CONTACTS 15
#define MAX_LIGHTS 4
#define MAX_CACHED_LIGHTS 3
#define MAX_RENDER_BUFFERS 32
#define MAX_CONTACTS 15
#define MAX_ANIM_TEX_RANGES 16
#define MAX_ANIM_TEX_OFFSETS 32
struct Shader;
struct Texture;

View File

@ -3,11 +3,14 @@
#include "core.h"
#include "format.h"
#include "cache.h"
#include "level.h"
#include "ui.h"
ShaderCache *shaderCache;
namespace Game {
Level *level;
Level *level;
Stream *nextLevel;
}
@ -35,9 +38,6 @@ namespace Game {
nextLevel = NULL;
Core::init();
UI::init(level);
Sound::callback = stopChannel;
Core::settings.detail.ambient = true;
Core::settings.detail.lighting = true;
@ -51,6 +51,12 @@ namespace Game {
Core::settings.controls.retarget = true;
Core::settings.audio.reverb = true;
shaderCache = new ShaderCache();
UI::init(level);
Sound::callback = stopChannel;
level = NULL;
startLevel(lvl);
}
@ -63,6 +69,7 @@ namespace Game {
void free() {
delete level;
UI::free();
delete shaderCache;
Core::free();
}

View File

@ -15,6 +15,7 @@
#include "debug.h"
#endif
extern ShaderCache *shaderCache;
extern void loadAsync(Stream *stream, void *userData);
struct Level : IGame {
@ -35,7 +36,6 @@ struct Level : IGame {
float clipHeight;
} *params = (Params*)&Core::params;
ShaderCache *shaderCache;
AmbientCache *ambientCache;
WaterCache *waterCache;
ZoneCache *zoneCache;
@ -115,7 +115,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));
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);
}
virtual void setupBinding() {
@ -259,7 +259,6 @@ struct Level : IGame {
initTextures();
mesh = new MeshBuilder(level);
shaderCache = new ShaderCache(mesh);
initOverrides();
for (int i = 0; i < level.entitiesBaseCount; i++) {
@ -438,8 +437,6 @@ struct Level : IGame {
for (int i = 0; i < level.entitiesCount; i++)
delete (Controller*)level.entities[i].controller;
delete shaderCache;
delete shadow;
delete ambientCache;
delete waterCache;