1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-02-24 23:42:49 +01:00

#15 mutex & cache code refactoring; #23 colored fog closes #92

This commit is contained in:
XProger 2018-03-06 09:44:37 +03:00
parent 06e0eb560c
commit 317dad4347
15 changed files with 173 additions and 547 deletions

View File

@ -10,7 +10,6 @@
#define SHADOW_TEX_SIZE 1024
#define FOG_DIST (18 * 1024)
#define WATER_FOG_DIST (6 * 1024)
//#define WATER_USE_GRID
#define UNDERWATER_COLOR "#define UNDERWATER_COLOR vec3(0.6, 0.9, 0.9)\n"
@ -76,7 +75,6 @@ struct ShaderCache {
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 | FX_CLIP_PLANE);
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);
@ -146,7 +144,7 @@ struct ShaderCache {
src = SHADER;
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);
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 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, WATER_FOG_DIST, SHADOW_TEX_SIZE);
#ifdef MERGE_SPRITES
if (type == Shader::SPRITE)
strcat(def, "#define ALIGN_SPRITES 1\n");
@ -216,6 +214,7 @@ struct ShaderCache {
shader->setParam(uLightProj, Core::mLightProj);
shader->setParam(uViewPos, Core::viewPos);
shader->setParam(uParam, Core::params);
shader->setParam(uFogParams, Core::fogParams);
#else
Core::setAlphaTest((fx & FX_ALPHA_TEST) != 0);
#endif

View File

@ -6,10 +6,16 @@
#endif
#include <stdio.h>
#define OS_FILEIO_CACHE
#define OS_PTHREAD_MT
#ifdef WIN32
#include <windows.h>
#include <gl/GL.h>
#include <gl/glext.h>
#undef OS_PTHREAD_MT
#elif ANDROID
#define MOBILE
#include <GLES2/gl2.h>
@ -143,6 +149,8 @@
#define glGetProgramBinary(...)
#define glProgramBinary(...)
#undef OS_FILEIO_CACHE
#elif _PSP
#include <pspgu.h>
#include <pspgum.h>
@ -151,6 +159,8 @@
#define TEX_SWIZZLE
//#define EDRAM_MESH
#define EDRAM_TEX
#undef OS_PTHREAD_MT
#endif
#ifdef USE_INFLATE
@ -614,6 +624,7 @@ namespace Core {
vec4 lightPos[MAX_LIGHTS];
vec4 lightColor[MAX_LIGHTS];
vec4 params;
vec4 fogParams;
vec4 contacts[MAX_CONTACTS];
Texture *whiteTex;

View File

@ -827,6 +827,41 @@ namespace TR {
return NULL;
}
#define FOG_DIST (1.0f / (18 * 1024))
#define FOG_BLACK vec4(0.0f, 0.0f, 0.0f, FOG_DIST)
#define FOG_SANDY vec4(0.2f, 0.1f, 0.0f, FOG_DIST)
#define FOG_GREEN vec4(0.0f, 0.1f, 0.0f, FOG_DIST)
#define FOG_RED vec4(0.2f, 0.0f, 0.0f, FOG_DIST)
vec4 getFogParams(LevelID id) {
switch (id) {
case LVL_TR1_1 :
case LVL_TR1_2 :
case LVL_TR1_3A :
case LVL_TR1_3B :
case LVL_TR1_CUT_1 : return FOG_BLACK;
case LVL_TR1_4 :
case LVL_TR1_5 :
case LVL_TR1_6 : return FOG_SANDY;
case LVL_TR1_7A :
case LVL_TR1_7B :
case LVL_TR1_CUT_2 : return FOG_GREEN;
case LVL_TR1_8A :
case LVL_TR1_8B :
case LVL_TR1_8C : return FOG_SANDY;
case LVL_TR1_10A : return FOG_BLACK;
case LVL_TR1_CUT_3 :
case LVL_TR1_10B :
case LVL_TR1_CUT_4 :
case LVL_TR1_10C : return FOG_RED;
case LVL_TR1_EGYPT :
case LVL_TR1_CAT :
case LVL_TR1_END :
case LVL_TR1_END2 : return FOG_SANDY;
}
return FOG_BLACK;
}
}
#undef CHECK_FILE

View File

@ -2600,6 +2600,9 @@ struct Lara : Character {
case TR::LVL_TR1_6 :
reset(73, vec3(73372, 122, 51687), PI * 0.5f); // level 6 (midas hand)
break;
case TR::LVL_TR1_7A :
reset(99, vec3(45562, -3328, 63366), 225 * DEG2RAD); // level 7a (flipmap)
break;
case TR::LVL_TR1_7B :
reset(77, vec3(36943, -4096, 62821), 270 * DEG2RAD); // level 7b (heavy trigger)
break;

View File

@ -612,6 +612,8 @@ struct Level : IGame {
memset(players, 0, sizeof(players));
player = NULL;
Core::fogParams = TR::getFogParams(level.id);
initTextures();
mesh = new MeshBuilder(level, atlas);
initOverrides();
@ -1815,10 +1817,19 @@ struct Level : IGame {
prepareRooms(roomsList, roomsCount);
updateLighting();
for (int transp = 0; transp < 3; transp++) {
renderRooms(roomsList, roomsCount, transp);
renderEntities(transp);
}
// opaque pass
renderRooms(roomsList, roomsCount, 0);
renderEntities(0);
// alpha blending pass
renderRooms(roomsList, roomsCount, 1);
renderEntities(1);
// additive blending pass
vec4 oldFog = Core::fogParams;
Core::fogParams = FOG_BLACK; // don't apply fog for additive
renderRooms(roomsList, roomsCount, 2);
renderEntities(2);
Core::fogParams = oldFog;
Core::setBlending(bmNone);
if (water && waterCache && waterCache->visible) {

View File

@ -11,54 +11,6 @@
JNIEXPORT return_type JNICALL \
Java_org_xproger_openlara_Wrapper_##method_name
// multi-threading
void* osMutexInit() {
pthread_mutex_t *mutex = new pthread_mutex_t();
pthread_mutex_init(mutex, NULL);
return mutex;
}
void osMutexFree(void *obj) {
pthread_mutex_destroy((pthread_mutex_t*)obj);
delete (pthread_mutex_t*)obj;
}
void osMutexLock(void *obj) {
pthread_mutex_lock((pthread_mutex_t*)obj);
}
void osMutexUnlock(void *obj) {
pthread_mutex_unlock((pthread_mutex_t*)obj);
}
void* osRWLockInit() {
pthread_rwlock_t *lock = new pthread_rwlock_t();
pthread_rwlock_init(lock, NULL);
return lock;
}
void osRWLockFree(void *obj) {
pthread_rwlock_destroy((pthread_rwlock_t*)obj);
delete (pthread_rwlock_t*)obj;
}
void osRWLockRead(void *obj) {
pthread_rwlock_rdlock((pthread_rwlock_t*)obj);
}
void osRWUnlockRead(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
void osRWLockWrite(void *obj) {
pthread_rwlock_wrlock((pthread_rwlock_t*)obj);
}
void osRWUnlockWrite(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
// timing
time_t startTime;
@ -68,7 +20,6 @@ int osGetTime() {
return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000);
}
// joystick
bool osJoyReady(int index) {
return index == 0;
@ -78,55 +29,6 @@ void osJoyVibrate(int index, float L, float R) {
//
}
// storage
void osCacheWrite(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "wb");
if (f) {
fwrite(stream->data, 1, stream->size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, NULL, 0), stream->userData);
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osCacheRead(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
int size = ftell(f);
fseek(f, 0, SEEK_SET);
char *data = new char[size];
fread(data, 1, size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, data, size), stream->userData);
delete[] data;
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osSaveGame(Stream *stream) {
return osCacheWrite(stream);
}
void osLoadGame(Stream *stream) {
return osCacheRead(stream);
}
extern "C" {
char Stream::cacheDir[255];

View File

@ -15,54 +15,6 @@
#define WND_TITLE "OpenLara"
// multi-threading
void* osMutexInit() {
pthread_mutex_t *mutex = new pthread_mutex_t();
pthread_mutex_init(mutex, NULL);
return mutex;
}
void osMutexFree(void *obj) {
pthread_mutex_destroy((pthread_mutex_t*)obj);
delete (pthread_mutex_t*)obj;
}
void osMutexLock(void *obj) {
pthread_mutex_lock((pthread_mutex_t*)obj);
}
void osMutexUnlock(void *obj) {
pthread_mutex_unlock((pthread_mutex_t*)obj);
}
void* osRWLockInit() {
pthread_rwlock_t *lock = new pthread_rwlock_t();
pthread_rwlock_init(lock, NULL);
return lock;
}
void osRWLockFree(void *obj) {
pthread_rwlock_destroy((pthread_rwlock_t*)obj);
delete (pthread_rwlock_t*)obj;
}
void osRWLockRead(void *obj) {
pthread_rwlock_rdlock((pthread_rwlock_t*)obj);
}
void osRWUnlockRead(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
void osRWLockWrite(void *obj) {
pthread_rwlock_wrlock((pthread_rwlock_t*)obj);
}
void osRWUnlockWrite(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
// timing
unsigned int startTime;
@ -72,56 +24,7 @@ int osGetTime() {
return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000);
}
// storage
void osCacheWrite(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "wb");
if (f) {
fwrite(stream->data, 1, stream->size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, NULL, 0), stream->userData);
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osCacheRead(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
int size = ftell(f);
fseek(f, 0, SEEK_SET);
char *data = new char[size];
fread(data, 1, size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, data, size), stream->userData);
delete[] data;
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osSaveGame(Stream *stream) {
return osCacheWrite(stream);
}
void osLoadGame(Stream *stream) {
return osCacheRead(stream);
}
// Sound
// sound
#define SND_FRAME_SIZE 4
#define SND_DATA_SIZE (1024 * SND_FRAME_SIZE)

View File

@ -4,54 +4,7 @@
WindowRef window;
AGLContext context;
// multi-threading
void* osMutexInit() {
pthread_mutex_t *mutex = new pthread_mutex_t();
pthread_mutex_init(mutex, NULL);
return mutex;
}
void osMutexFree(void *obj) {
pthread_mutex_destroy((pthread_mutex_t*)obj);
delete (pthread_mutex_t*)obj;
}
void osMutexLock(void *obj) {
pthread_mutex_lock((pthread_mutex_t*)obj);
}
void osMutexUnlock(void *obj) {
pthread_mutex_unlock((pthread_mutex_t*)obj);
}
void* osRWLockInit() {
pthread_rwlock_t *lock = new pthread_rwlock_t();
pthread_rwlock_init(lock, NULL);
return lock;
}
void osRWLockFree(void *obj) {
pthread_rwlock_destroy((pthread_rwlock_t*)obj);
delete (pthread_rwlock_t*)obj;
}
void osRWLockRead(void *obj) {
pthread_rwlock_rdlock((pthread_rwlock_t*)obj);
}
void osRWUnlockRead(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
void osRWLockWrite(void *obj) {
pthread_rwlock_wrlock((pthread_rwlock_t*)obj);
}
void osRWUnlockWrite(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
// Sound
// sound
#define SND_SIZE 8192
static AudioQueueRef audioQueue;
@ -193,7 +146,6 @@ OSStatus eventHandler(EventHandlerCallRef handler, EventRef event, void* userDat
return CallNextEventHandler(handler, event);
}
// timing
int osGetTime() {
UInt64 t;
@ -201,53 +153,6 @@ int osGetTime() {
return int(t / 1000);
}
// storage
void osCacheWrite(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "wb");
if (f) {
fwrite(stream->data, 1, stream->size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, NULL, 0), stream->userData);
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osCacheRead(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
int size = ftell(f);
fseek(f, 0, SEEK_SET);
char *data = new char[size];
fread(data, 1, size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, data, size), stream->userData);
delete[] data;
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osSaveGame(Stream *stream) {
return osCacheWrite(stream);
}
void osLoadGame(Stream *stream) {
return osCacheRead(stream);
}
char Stream::contentDir[255];
char Stream::cacheDir[255];

View File

@ -83,7 +83,6 @@ void osRWUnlockWrite(void *obj) {
osMutexUnlock(obj);
}
// timing
int osStartTime = 0;
int osTimerFreq;
@ -94,55 +93,6 @@ int osGetTime() {
return int(time * 1000 / osTimerFreq - osStartTime);
}
// storage
void osCacheWrite(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "wb");
if (f) {
fwrite(stream->data, 1, stream->size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, NULL, 0), stream->userData);
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osCacheRead(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
int size = ftell(f);
fseek(f, 0, SEEK_SET);
char *data = new char[size];
fread(data, 1, size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, data, size), stream->userData);
delete[] data;
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osSaveGame(Stream *stream) {
return osCacheWrite(stream);
}
void osLoadGame(Stream *stream) {
return osCacheRead(stream);
}
// input
bool osJoyReady(int index) {
return index == 0;

View File

@ -15,54 +15,6 @@
#define WND_TITLE "OpenLara"
// multi-threading
void* osMutexInit() {
pthread_mutex_t *mutex = new pthread_mutex_t();
pthread_mutex_init(mutex, NULL);
return mutex;
}
void osMutexFree(void *obj) {
pthread_mutex_destroy((pthread_mutex_t*)obj);
delete (pthread_mutex_t*)obj;
}
void osMutexLock(void *obj) {
pthread_mutex_lock((pthread_mutex_t*)obj);
}
void osMutexUnlock(void *obj) {
pthread_mutex_unlock((pthread_mutex_t*)obj);
}
void* osRWLockInit() {
pthread_rwlock_t *lock = new pthread_rwlock_t();
pthread_rwlock_init(lock, NULL);
return lock;
}
void osRWLockFree(void *obj) {
pthread_rwlock_destroy((pthread_rwlock_t*)obj);
delete (pthread_rwlock_t*)obj;
}
void osRWLockRead(void *obj) {
pthread_rwlock_rdlock((pthread_rwlock_t*)obj);
}
void osRWUnlockRead(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
void osRWLockWrite(void *obj) {
pthread_rwlock_wrlock((pthread_rwlock_t*)obj);
}
void osRWUnlockWrite(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
// timing
unsigned int startTime;
@ -72,56 +24,7 @@ int osGetTime() {
return int((t.tv_sec - startTime) * 1000 + t.tv_usec / 1000);
}
// storage
void osCacheWrite(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "wb");
if (f) {
fwrite(stream->data, 1, stream->size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, NULL, 0), stream->userData);
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osCacheRead(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
int size = ftell(f);
fseek(f, 0, SEEK_SET);
char *data = new char[size];
fread(data, 1, size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, data, size), stream->userData);
delete[] data;
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osSaveGame(Stream *stream) {
return osCacheWrite(stream);
}
void osLoadGame(Stream *stream) {
return osCacheRead(stream);
}
// Sound
// sound
snd_pcm_uframes_t SND_FRAMES = 512;
snd_pcm_t *sndOut;
Sound::Frame *sndData;

View File

@ -10,61 +10,12 @@ EGLDisplay display;
EGLSurface surface;
EGLContext context;
// multi-threading
void* osMutexInit() {
pthread_mutex_t *mutex = new pthread_mutex_t();
pthread_mutex_init(mutex, NULL);
return mutex;
}
void osMutexFree(void *obj) {
pthread_mutex_destroy((pthread_mutex_t*)obj);
delete (pthread_mutex_t*)obj;
}
void osMutexLock(void *obj) {
pthread_mutex_lock((pthread_mutex_t*)obj);
}
void osMutexUnlock(void *obj) {
pthread_mutex_unlock((pthread_mutex_t*)obj);
}
void* osRWLockInit() {
pthread_rwlock_t *lock = new pthread_rwlock_t();
pthread_rwlock_init(lock, NULL);
return lock;
}
void osRWLockFree(void *obj) {
pthread_rwlock_destroy((pthread_rwlock_t*)obj);
delete (pthread_rwlock_t*)obj;
}
void osRWLockRead(void *obj) {
pthread_rwlock_rdlock((pthread_rwlock_t*)obj);
}
void osRWUnlockRead(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
void osRWLockWrite(void *obj) {
pthread_rwlock_wrlock((pthread_rwlock_t*)obj);
}
void osRWUnlockWrite(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
// timing
int osGetTime() {
return (int)emscripten_get_now();
}
// cache & data
// storage and data downloading
const char *IDB = "db";
void onError(void *arg) {

View File

@ -112,54 +112,6 @@ int osGetTime() {
#endif
}
// storage
void osCacheWrite(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "wb");
if (f) {
fwrite(stream->data, 1, stream->size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, NULL, 0), stream->userData);
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osCacheRead(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
int size = ftell(f);
fseek(f, 0, SEEK_SET);
char *data = new char[size];
fread(data, 1, size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, data, size), stream->userData);
delete[] data;
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osSaveGame(Stream *stream) {
return osCacheWrite(stream);
}
void osLoadGame(Stream *stream) {
return osCacheRead(stream);
}
// common input functions
InputKey keyToInputKey(int code) {
static const int codes[] = {

View File

@ -26,6 +26,7 @@
E( uLightProj ) \
E( uMaterial ) \
E( uAmbient ) \
E( uFogParams ) \
E( uViewPos ) \
E( uLightPos ) \
E( uLightColor ) \

View File

@ -21,6 +21,7 @@ uniform vec3 uViewPos;
uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height
uniform vec4 uLightPos[MAX_LIGHTS];
uniform vec4 uLightColor[MAX_LIGHTS]; // xyz - color, w - radius * intensity
uniform vec4 uFogParams;
uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
@ -100,7 +101,7 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
#endif
#ifndef PASS_SHADOW
vViewVec = vec4((uViewPos - coord.xyz) * FOG_DIST, coord.y);
vViewVec = vec4((uViewPos - coord.xyz) * uFogParams.w, coord.y);
#endif
#ifdef PASS_AMBIENT
@ -471,7 +472,7 @@ uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
#ifdef UNDERWATER
color.xyz = mix(UNDERWATER_COLOR * 0.2, color.xyz, vLightVec.w);
#else
color.xyz = mix(vec3(0.0), color.xyz, vLightVec.w);
color.xyz = mix(uFogParams.xyz, color.xyz, vLightVec.w);
#endif
#endif
/* catsuit test

View File

@ -1299,6 +1299,105 @@ struct Stream {
};
#ifdef OS_FILEIO_CACHE
void osCacheWrite(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "wb");
if (f) {
fwrite(stream->data, 1, stream->size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, NULL, 0), stream->userData);
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osCacheRead(Stream *stream) {
char path[255];
strcpy(path, Stream::cacheDir);
strcat(path, stream->name);
FILE *f = fopen(path, "rb");
if (f) {
fseek(f, 0, SEEK_END);
int size = ftell(f);
fseek(f, 0, SEEK_SET);
char *data = new char[size];
fread(data, 1, size, f);
fclose(f);
if (stream->callback)
stream->callback(new Stream(stream->name, data, size), stream->userData);
delete[] data;
} else
if (stream->callback)
stream->callback(NULL, stream->userData);
delete stream;
}
void osSaveGame(Stream *stream) {
return osCacheWrite(stream);
}
void osLoadGame(Stream *stream) {
return osCacheRead(stream);
}
#endif
#ifdef OS_PTHREAD_MT
// multi-threading
void* osMutexInit() {
pthread_mutex_t *mutex = new pthread_mutex_t();
pthread_mutex_init(mutex, NULL);
return mutex;
}
void osMutexFree(void *obj) {
pthread_mutex_destroy((pthread_mutex_t*)obj);
delete (pthread_mutex_t*)obj;
}
void osMutexLock(void *obj) {
pthread_mutex_lock((pthread_mutex_t*)obj);
}
void osMutexUnlock(void *obj) {
pthread_mutex_unlock((pthread_mutex_t*)obj);
}
void* osRWLockInit() {
pthread_rwlock_t *lock = new pthread_rwlock_t();
pthread_rwlock_init(lock, NULL);
return lock;
}
void osRWLockFree(void *obj) {
pthread_rwlock_destroy((pthread_rwlock_t*)obj);
delete (pthread_rwlock_t*)obj;
}
void osRWLockRead(void *obj) {
pthread_rwlock_rdlock((pthread_rwlock_t*)obj);
}
void osRWUnlockRead(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
void osRWLockWrite(void *obj) {
pthread_rwlock_wrlock((pthread_rwlock_t*)obj);
}
void osRWUnlockWrite(void *obj) {
pthread_rwlock_unlock((pthread_rwlock_t*)obj);
}
#endif
struct BitStream {
uint8 *data;
uint8 *end;