mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-15 01:24:35 +02:00
remove atlas shadows; add D3D9 shadows; fix water rat and crocodile bug
This commit is contained in:
10
src/cache.h
10
src/cache.h
@@ -33,6 +33,7 @@ struct ShaderCache {
|
||||
prepareFilter(FX_NONE);
|
||||
prepareGUI(FX_NONE);
|
||||
|
||||
Core::resetTime();
|
||||
LOG("shader: cache is ready\n");
|
||||
}
|
||||
|
||||
@@ -148,12 +149,8 @@ struct ShaderCache {
|
||||
SD_ADD(CLIP_PLANE);
|
||||
if (Core::settings.detail.lighting > Core::Settings::MEDIUM && (type == Shader::ENTITY))
|
||||
SD_ADD(OPT_AMBIENT);
|
||||
if (Core::settings.detail.shadows > Core::Settings::LOW && (type == Shader::ENTITY || type == Shader::ROOM)) {
|
||||
if (Core::settings.detail.shadows > Core::Settings::LOW && (type == Shader::ENTITY || type == Shader::ROOM))
|
||||
SD_ADD(OPT_SHADOW);
|
||||
|
||||
if (Core::settings.detail.shadows > Core::Settings::MEDIUM)
|
||||
SD_ADD(OPT_SHADOW_HIGH);
|
||||
}
|
||||
if (Core::settings.detail.shadows > Core::Settings::MEDIUM && (type == Shader::ROOM))
|
||||
SD_ADD(OPT_CONTACT);
|
||||
if (Core::settings.detail.water > Core::Settings::MEDIUM && (type == Shader::ENTITY || type == Shader::ROOM) && (fx & FX_UNDERWATER))
|
||||
@@ -715,11 +712,12 @@ struct WaterCache {
|
||||
if (!refract || w != refract->origWidth || h != refract->origHeight) {
|
||||
delete refract;
|
||||
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
|
||||
}
|
||||
|
@@ -506,7 +506,7 @@ struct Camera : ICamera {
|
||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_VR)
|
||||
Core::mProj = Input::hmd.proj[Core::eye == -1.0f ? 0 : 1];
|
||||
else
|
||||
Core::mProj = mat4(fov, aspect, znear, zfar);
|
||||
Core::mProj = GAPI::perspective(fov, aspect, znear, zfar);
|
||||
}
|
||||
|
||||
Core::setViewProj(Core::mView, Core::mProj);
|
||||
@@ -531,9 +531,6 @@ struct Camera : ICamera {
|
||||
|
||||
fov = firstPerson ? 90.0f : 65.0f;
|
||||
znear = firstPerson ? 8.0f : 32.0f;
|
||||
#ifdef _OS_PSP
|
||||
znear = 256.0f;
|
||||
#endif
|
||||
zfar = 45.0f * 1024.0f;
|
||||
}
|
||||
};
|
||||
|
15
src/core.h
15
src/core.h
@@ -85,14 +85,8 @@
|
||||
#include "utils.h"
|
||||
|
||||
// muse be equal with base shader
|
||||
#define SHADOW_OBJ_COLS 4
|
||||
#define SHADOW_OBJ_ROWS 2
|
||||
#define SHADOW_TEX_TILE 128
|
||||
#define SHADOW_TEX_BIG_WIDTH 1024
|
||||
#define SHADOW_TEX_BIG_HEIGHT 1024
|
||||
#define SHADOW_TEX_WIDTH (SHADOW_OBJ_COLS * SHADOW_TEX_TILE)
|
||||
#define SHADOW_TEX_HEIGHT (SHADOW_OBJ_ROWS * SHADOW_TEX_TILE)
|
||||
#define SHADOW_OBJ_MAX (SHADOW_OBJ_COLS * SHADOW_OBJ_ROWS)
|
||||
#define SHADOW_TEX_WIDTH 1024
|
||||
#define SHADOW_TEX_HEIGHT 1024
|
||||
|
||||
extern void* osMutexInit ();
|
||||
extern void osMutexFree (void *obj);
|
||||
@@ -340,14 +334,12 @@ enum RenderState {
|
||||
|
||||
// Texture image format
|
||||
enum TexFormat {
|
||||
FMT_LUMINANCE,
|
||||
FMT_RGBA,
|
||||
FMT_RGB16,
|
||||
FMT_RGBA16,
|
||||
FMT_RGBA_FLOAT,
|
||||
FMT_RGBA_HALF,
|
||||
FMT_DEPTH,
|
||||
FMT_DEPTH_STENCIL,
|
||||
FMT_SHADOW,
|
||||
FMT_MAX,
|
||||
};
|
||||
@@ -453,7 +445,6 @@ struct MeshRange {
|
||||
E( CLIP_PLANE ) \
|
||||
E( OPT_AMBIENT ) \
|
||||
E( OPT_SHADOW ) \
|
||||
E( OPT_SHADOW_HIGH ) \
|
||||
E( OPT_CONTACT ) \
|
||||
E( OPT_CAUSTICS )
|
||||
|
||||
@@ -490,7 +481,7 @@ namespace Core {
|
||||
float eye;
|
||||
Viewport viewport, viewportDef;
|
||||
mat4 mModel, mView, mProj, mViewProj, mViewInv;
|
||||
mat4 mLightProj[SHADOW_OBJ_MAX];
|
||||
mat4 mLightProj;
|
||||
Basis basis;
|
||||
vec4 viewPos;
|
||||
vec4 lightPos[MAX_LIGHTS];
|
||||
|
10
src/enemy.h
10
src/enemy.h
@@ -794,6 +794,11 @@ struct Rat : Enemy {
|
||||
bool water = getRoom().flags.water;
|
||||
int modelIndex = water ? modelWater : modelLand;
|
||||
|
||||
if (modelIndex == -1) {
|
||||
water = modelWater != -1;
|
||||
modelIndex = water ? modelWater : modelLand;
|
||||
}
|
||||
|
||||
ASSERT(modelIndex > -1);
|
||||
const TR::Model *model = &level->models[modelIndex];
|
||||
if (animation.model != model) {
|
||||
@@ -985,6 +990,11 @@ struct Crocodile : Enemy {
|
||||
bool water = getRoom().flags.water;
|
||||
int modelIndex = water ? modelWater : modelLand;
|
||||
|
||||
if (modelIndex == -1) {
|
||||
water = modelWater != -1;
|
||||
modelIndex = water ? modelWater : modelLand;
|
||||
}
|
||||
|
||||
ASSERT(modelIndex > -1);
|
||||
const TR::Model *model = &level->models[modelIndex];
|
||||
if (animation.model != model) {
|
||||
|
121
src/gapi_d3d9.h
121
src/gapi_d3d9.h
@@ -70,7 +70,7 @@ namespace GAPI {
|
||||
int cullMode, blendMode;
|
||||
uint32 clearColor;
|
||||
|
||||
LPDIRECT3DSURFACE9 defBackBuffer;
|
||||
LPDIRECT3DSURFACE9 defRT, defDS;
|
||||
LPDIRECT3DVERTEXDECLARATION9 vertexDecl;
|
||||
|
||||
|
||||
@@ -118,15 +118,15 @@ namespace GAPI {
|
||||
{ 2, USAGE_VS | USAGE_PS }, // uViewProj
|
||||
{ 6, USAGE_VS | USAGE_PS }, // uBasis
|
||||
{ 70, USAGE_VS | USAGE_PS }, // uLightProj
|
||||
{ 102, USAGE_VS | USAGE_PS }, // uMaterial
|
||||
{ 103, USAGE_VS | USAGE_PS }, // uAmbient
|
||||
{ 109, USAGE_VS | USAGE_PS }, // uFogParams
|
||||
{ 110, USAGE_VS | USAGE_PS }, // uViewPos
|
||||
{ 111, USAGE_VS | USAGE_PS }, // uLightPos
|
||||
{ 115, USAGE_VS | USAGE_PS }, // uLightColor
|
||||
{ 119, USAGE_VS | USAGE_PS }, // uRoomSize
|
||||
{ 120, USAGE_VS | USAGE_PS }, // uPosScale
|
||||
{ 122, USAGE_VS | USAGE_PS }, // uContacts
|
||||
{ 74, USAGE_VS | USAGE_PS }, // uMaterial
|
||||
{ 75, USAGE_VS | USAGE_PS }, // uAmbient
|
||||
{ 81, USAGE_VS | USAGE_PS }, // uFogParams
|
||||
{ 82, USAGE_VS | USAGE_PS }, // uViewPos
|
||||
{ 83, USAGE_VS | USAGE_PS }, // uLightPos
|
||||
{ 87, USAGE_VS | USAGE_PS }, // uLightColor
|
||||
{ 91, USAGE_VS | USAGE_PS }, // uRoomSize
|
||||
{ 92, USAGE_VS | USAGE_PS }, // uPosScale
|
||||
{ 94, USAGE_VS | USAGE_PS }, // uContacts
|
||||
};
|
||||
|
||||
struct Shader {
|
||||
@@ -159,9 +159,8 @@ namespace GAPI {
|
||||
case SD_CLIP_PLANE : flags[ 7] = TRUE; break;
|
||||
case SD_OPT_AMBIENT : flags[ 8] = TRUE; break;
|
||||
case SD_OPT_SHADOW : flags[ 9] = TRUE; break;
|
||||
case SD_OPT_SHADOW_HIGH : flags[10] = TRUE; break;
|
||||
case SD_OPT_CONTACT : flags[11] = TRUE; break;
|
||||
case SD_OPT_CAUSTICS : flags[12] = TRUE; break;
|
||||
case SD_OPT_CONTACT : flags[10] = TRUE; break;
|
||||
case SD_OPT_CAUSTICS : flags[11] = TRUE; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,28 +217,24 @@ namespace GAPI {
|
||||
void init(void *data) {
|
||||
ASSERT((opt & OPT_PROXY) == 0);
|
||||
|
||||
bool filter = (opt & OPT_NEAREST) == 0;
|
||||
bool isDepth = fmt == FMT_DEPTH || fmt == FMT_SHADOW;
|
||||
bool mipmaps = (opt & OPT_MIPMAPS) != 0;
|
||||
bool cube = (opt & OPT_CUBEMAP) != 0;
|
||||
bool isTarget = (opt & OPT_TARGET) != 0;
|
||||
bool isShadow = fmt == FMT_SHADOW;
|
||||
bool isDepth = fmt == FMT_DEPTH || fmt == FMT_DEPTH_STENCIL || fmt == FMT_SHADOW;
|
||||
bool isTarget = (opt & OPT_TARGET) != 0 && !isDepth;
|
||||
|
||||
static const struct FormatDesc {
|
||||
int bpp;
|
||||
D3DFORMAT format;
|
||||
} formats[FMT_MAX] = {
|
||||
{ 8, D3DFMT_L8 },
|
||||
{ 32, D3DFMT_A8R8G8B8 },
|
||||
{ 16, D3DFMT_R5G6B5 },
|
||||
{ 16, D3DFMT_A1R5G5B5 },
|
||||
{ 64, D3DFMT_A16B16G16R16 },
|
||||
{ 64, D3DFMT_A16B16G16R16 },
|
||||
{ 16, D3DFMT_D16 },
|
||||
{ 32, D3DFMT_D24S8 },
|
||||
{ 16, D3DFMT_D16 },
|
||||
{ 32, D3DFMT_A8R8G8B8 },
|
||||
{ 16, D3DFMT_R5G6B5 },
|
||||
{ 16, D3DFMT_A1R5G5B5 },
|
||||
{ 64, D3DFMT_A16B16G16R16F },
|
||||
{128, D3DFMT_A32B32G32R32F },
|
||||
{ 16, D3DFMT_D16 },
|
||||
{ 16, D3DFMT_D24X8 },
|
||||
};
|
||||
|
||||
|
||||
FormatDesc desc = formats[fmt];
|
||||
|
||||
uint32 usage = 0;
|
||||
@@ -247,7 +242,7 @@ namespace GAPI {
|
||||
if (isDepth) usage |= D3DUSAGE_DEPTHSTENCIL;
|
||||
if (isTarget) usage |= D3DUSAGE_RENDERTARGET;
|
||||
|
||||
D3DPOOL pool = isTarget ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
|
||||
D3DPOOL pool = (isTarget || isDepth) ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
|
||||
|
||||
if (cube) {
|
||||
D3DCHECK(device->CreateCubeTexture(width, 1, usage, desc.format, pool, &texCube, NULL));
|
||||
@@ -291,8 +286,8 @@ namespace GAPI {
|
||||
bool mipmaps = (Core::settings.detail.filter > Core::Settings::MEDIUM) && (opt & OPT_MIPMAPS);
|
||||
bool aniso = filter && mipmaps && (Core::support.maxAniso > 0);
|
||||
|
||||
device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
|
||||
device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
|
||||
|
||||
if (aniso) {
|
||||
device->SetSamplerState(sampler, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
|
||||
@@ -387,7 +382,7 @@ namespace GAPI {
|
||||
struct RenderTargetCache {
|
||||
int count;
|
||||
struct Item {
|
||||
// GLuint ID;
|
||||
LPDIRECT3DSURFACE9 surface;
|
||||
int width;
|
||||
int height;
|
||||
} items[MAX_RENDER_BUFFERS];
|
||||
@@ -404,8 +399,8 @@ namespace GAPI {
|
||||
support.maxAniso = 8;
|
||||
support.maxVectors = 16;
|
||||
support.shaderBinary = false;
|
||||
support.VAO = false;
|
||||
support.depthTexture = false;
|
||||
support.VAO = false; // SHADOW_COLOR
|
||||
support.depthTexture = false; // SHADOW_DEPTH
|
||||
support.shadowSampler = false;
|
||||
support.discardFrame = false;
|
||||
support.texNPOT = false;
|
||||
@@ -440,6 +435,15 @@ namespace GAPI {
|
||||
}
|
||||
|
||||
void resetDevice() {
|
||||
// release dummy RTs
|
||||
for (int i = 0; i < 2; i++) {
|
||||
RenderTargetCache &cache = rtCache[i];
|
||||
for (int j = 0; j < cache.count; j++)
|
||||
cache.items[j].surface->Release();
|
||||
cache.count = 0;
|
||||
}
|
||||
|
||||
// release texture RTs
|
||||
int tmpCount = resCount;
|
||||
Resource tmpList[256];
|
||||
memcpy(tmpList, resList, sizeof(Resource) * tmpCount);
|
||||
@@ -454,6 +458,7 @@ namespace GAPI {
|
||||
|
||||
D3DCHECK(device->Reset(&d3dpp));
|
||||
|
||||
// reinit texture RTs
|
||||
for (int i = 0; i < tmpCount; i++) {
|
||||
Resource &res = tmpList[i];
|
||||
if (res.mesh)
|
||||
@@ -464,6 +469,14 @@ namespace GAPI {
|
||||
|
||||
}
|
||||
|
||||
mat4 ortho(float l, float r, float b, float t, float znear, float zfar) {
|
||||
return mat4(mat4::PROJ_ZERO_POS, l, r, b, t, znear, zfar);
|
||||
}
|
||||
|
||||
mat4 perspective(float fov, float aspect, float znear, float zfar) {
|
||||
return mat4(mat4::PROJ_ZERO_POS, fov, aspect, znear, zfar);
|
||||
}
|
||||
|
||||
bool beginFrame() {
|
||||
switch (device->TestCooperativeLevel()) {
|
||||
case D3D_OK :
|
||||
@@ -480,14 +493,16 @@ namespace GAPI {
|
||||
return false;
|
||||
}
|
||||
|
||||
device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &defBackBuffer);
|
||||
device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &defRT);
|
||||
device->GetDepthStencilSurface(&defDS);
|
||||
device->BeginScene();
|
||||
return true;
|
||||
}
|
||||
|
||||
void endFrame() {
|
||||
device->EndScene();
|
||||
defBackBuffer->Release();
|
||||
defRT->Release();
|
||||
defDS->Release();
|
||||
}
|
||||
|
||||
void resetState() {
|
||||
@@ -509,34 +524,42 @@ namespace GAPI {
|
||||
RenderTargetCache::Item &item = cache.items[cache.count];
|
||||
item.width = width;
|
||||
item.height = height;
|
||||
/*
|
||||
glGenRenderbuffers(1, &item.ID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, item.ID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, depth ? GL_RGB565 : GL_DEPTH_COMPONENT16, width, height);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
*/
|
||||
|
||||
if (depth)
|
||||
device->CreateDepthStencilSurface(width, height, D3DFMT_D16, D3DMULTISAMPLE_NONE, 0, true, &item.surface, NULL);
|
||||
else
|
||||
device->CreateRenderTarget(width, height, D3DFMT_R5G6B5, D3DMULTISAMPLE_NONE, 0, false, &item.surface, NULL);
|
||||
|
||||
return cache.count++;
|
||||
}
|
||||
|
||||
void bindTarget(Texture *target, int face) {
|
||||
if (!target) { // may be a null
|
||||
D3DCHECK(device->SetRenderTarget(0, defBackBuffer));
|
||||
D3DCHECK(device->SetRenderTarget(0, defRT));
|
||||
D3DCHECK(device->SetDepthStencilSurface(defDS));
|
||||
} else {
|
||||
ASSERT(target->opt & OPT_TARGET);
|
||||
|
||||
LPDIRECT3DSURFACE9 surface;
|
||||
|
||||
if (target->tex2D)
|
||||
bool depth = target->fmt == FMT_DEPTH || target->fmt == FMT_SHADOW;
|
||||
|
||||
if (target->tex2D) {
|
||||
D3DCHECK(target->tex2D->GetSurfaceLevel(0, &surface));
|
||||
else if (target->texCube)
|
||||
} else if (target->texCube)
|
||||
D3DCHECK(target->texCube->GetCubeMapSurface(D3DCUBEMAP_FACES(D3DCUBEMAP_FACE_POSITIVE_X + face), 0, &surface));
|
||||
|
||||
D3DCHECK(device->SetRenderTarget(0, surface));
|
||||
int rtIndex = cacheRenderTarget(!depth, target->width, target->height);
|
||||
|
||||
if (depth) {
|
||||
D3DCHECK(device->SetRenderTarget(0, rtCache[false].items[rtIndex].surface));
|
||||
D3DCHECK(device->SetDepthStencilSurface(surface));
|
||||
} else {
|
||||
D3DCHECK(device->SetRenderTarget(0, surface));
|
||||
D3DCHECK(device->SetDepthStencilSurface(rtCache[true].items[rtIndex].surface));
|
||||
}
|
||||
|
||||
surface->Release();
|
||||
|
||||
bool depth = target->fmt == FMT_DEPTH || target->fmt == FMT_SHADOW;
|
||||
int rtIndex = cacheRenderTarget(depth, target->width, target->height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -551,7 +574,7 @@ namespace GAPI {
|
||||
RECT srcRect = { x, y, x + width, y + height },
|
||||
dstRect = { xOffset, yOffset, xOffset + width, yOffset + height };
|
||||
|
||||
device->StretchRect(defBackBuffer, &srcRect, surface, &dstRect, D3DTEXF_POINT);
|
||||
device->StretchRect(defRT, &srcRect, surface, &dstRect, D3DTEXF_POINT);
|
||||
|
||||
surface->Release();
|
||||
}
|
||||
|
@@ -547,14 +547,12 @@ namespace GAPI {
|
||||
GLuint ifmt, fmt;
|
||||
GLenum type;
|
||||
} formats[FMT_MAX] = {
|
||||
{ GL_LUMINANCE, GL_LUMINANCE, GL_UNSIGNED_BYTE }, // LUMINANCE
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, // RGBA
|
||||
{ GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5 }, // RGB16
|
||||
{ GL_RGBA, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 }, // RGBA16
|
||||
{ GL_RGBA32F, GL_RGBA, GL_FLOAT }, // RGBA_FLOAT
|
||||
{ GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT }, // RGBA_HALF
|
||||
{ GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // DEPTH
|
||||
{ GL_DEPTH_STENCIL, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8 }, // DEPTH_STENCIL
|
||||
{ GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // SHADOW
|
||||
};
|
||||
|
||||
@@ -978,6 +976,14 @@ namespace GAPI {
|
||||
glDeleteRenderbuffers(1, &rtCache[b].items[i].ID);
|
||||
}
|
||||
|
||||
mat4 ortho(float l, float r, float b, float t, float znear, float zfar) {
|
||||
return mat4(mat4::PROJ_NEG_POS, l, r, b, t, znear, zfar);
|
||||
}
|
||||
|
||||
mat4 perspective(float fov, float aspect, float znear, float zfar) {
|
||||
return mat4(mat4::PROJ_NEG_POS, fov, aspect, znear, zfar);
|
||||
}
|
||||
|
||||
bool beginFrame() {
|
||||
return true;
|
||||
}
|
||||
@@ -1008,7 +1014,7 @@ namespace GAPI {
|
||||
|
||||
glGenRenderbuffers(1, &item.ID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, item.ID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, depth ? GL_RGB565 : GL_DEPTH_COMPONENT16, width, height);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, depth ? GL_DEPTH_COMPONENT16 : GL_RGB565, width, height);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
return cache.count++;
|
||||
}
|
||||
@@ -1023,11 +1029,11 @@ namespace GAPI {
|
||||
|
||||
bool depth = target->fmt == FMT_DEPTH || target->fmt == FMT_SHADOW;
|
||||
|
||||
int rtIndex = cacheRenderTarget(depth, target->width, target->height);
|
||||
int rtIndex = cacheRenderTarget(!depth, target->width, target->height);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, FBO);
|
||||
glFramebufferTexture2D (GL_FRAMEBUFFER, depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0, texTarget, target->ID, 0);
|
||||
glFramebufferRenderbuffer (GL_FRAMEBUFFER, depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rtCache[depth].items[rtIndex].ID);
|
||||
glFramebufferRenderbuffer (GL_FRAMEBUFFER, depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rtCache[!depth].items[rtIndex].ID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -289,6 +289,14 @@ namespace GAPI {
|
||||
delete[] cmdBuf;
|
||||
}
|
||||
|
||||
mat4 ortho(float l, float r, float b, float t, float znear, float zfar) {
|
||||
return mat4(mat4::PROJ_ZERO_POS, l, r, b, t, znear, zfar);
|
||||
}
|
||||
|
||||
mat4 perspective(float fov, float aspect, float znear, float zfar) {
|
||||
return mat4(mat4::PROJ_ZERO_POS, fov, aspect, znear, zfar);
|
||||
}
|
||||
|
||||
bool beginFrame() {
|
||||
return true;
|
||||
}
|
||||
|
@@ -1496,7 +1496,7 @@ struct Inventory {
|
||||
if (Core::settings.detail.stereo == Core::Settings::STEREO_VR)
|
||||
Core::mProj = Input::hmd.proj[Core::eye == -1.0f ? 0 : 1];
|
||||
else
|
||||
Core::mProj = mat4(70.0f, aspect, 32.0f, 2048.0f);
|
||||
Core::mProj = GAPI::perspective(70.0f, aspect, 32.0f, 2048.0f);
|
||||
|
||||
Core::mView = Core::mViewInv.inverseOrtho();
|
||||
Core::viewPos = Core::mViewInv.getPos();
|
||||
@@ -1514,8 +1514,7 @@ struct Inventory {
|
||||
// items
|
||||
game->setupBinding();
|
||||
|
||||
for (int i = 0; i < SHADOW_OBJ_MAX; i++)
|
||||
Core::mLightProj[i].identity();
|
||||
Core::mLightProj.identity();
|
||||
|
||||
setupCamera(aspect);
|
||||
|
||||
|
31
src/level.h
31
src/level.h
@@ -229,10 +229,8 @@ struct Level : IGame {
|
||||
|
||||
void initShadow() {
|
||||
delete shadow;
|
||||
if (Core::settings.detail.shadows > Core::Settings::MEDIUM)
|
||||
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, FMT_SHADOW);
|
||||
if (Core::settings.detail.shadows > Core::Settings::LOW)
|
||||
shadow = new Texture(SHADOW_TEX_WIDTH, SHADOW_TEX_HEIGHT, FMT_SHADOW, OPT_TARGET);
|
||||
else
|
||||
shadow = NULL;
|
||||
}
|
||||
@@ -1961,7 +1959,7 @@ struct Level : IGame {
|
||||
|
||||
Core::mViewInv = mat4(pos, pos + dir, up);
|
||||
Core::mView = Core::mViewInv.inverseOrtho();
|
||||
Core::mProj = mat4(90, 1.0f, camera->znear, camera->zfar);
|
||||
Core::mProj = GAPI::perspective(90, 1.0f, camera->znear, camera->zfar);
|
||||
Core::mViewProj = Core::mProj * Core::mView;
|
||||
Core::viewPos = Core::mViewInv.offset().xyz();
|
||||
|
||||
@@ -1971,15 +1969,17 @@ struct Level : IGame {
|
||||
void renderShadowView(int roomIndex) {
|
||||
vec3 pos = player->getBoundingBox().center();
|
||||
|
||||
float znear = camera->znear;
|
||||
float zfar = player->mainLightColor.w * 1.5f;
|
||||
|
||||
Core::mViewInv = mat4(player->mainLightPos, pos, vec3(0, -1, 0));
|
||||
Core::mView = Core::mViewInv.inverseOrtho();
|
||||
Core::mProj = mat4(90.0f, 1.0f, camera->znear, player->mainLightColor.w * 1.5f);
|
||||
Core::mProj = GAPI::perspective(90.0f, 1.0f, znear, zfar);
|
||||
|
||||
mat4 bias;
|
||||
bias.identity();
|
||||
bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f;
|
||||
|
||||
Core::mLightProj[0] = bias * (Core::mProj * Core::mView);
|
||||
//bias.e03 = bias.e13 = bias.e23 = bias.e00 = bias.e11 = bias.e22 = 0.5f;
|
||||
Core::mLightProj = bias * (Core::mProj * Core::mView);
|
||||
|
||||
camera->frustum->pos = Core::viewPos.xyz();
|
||||
camera->frustum->calcPlanes(Core::mViewProj);
|
||||
@@ -1987,7 +1987,7 @@ struct Level : IGame {
|
||||
setup();
|
||||
renderView(roomIndex, false, false);
|
||||
}
|
||||
|
||||
/*
|
||||
void renderShadowEntity(int index, Controller *controller, Controller *player) {
|
||||
Box box = controller->getSpheresBox(true);
|
||||
mat4 m = controller->getMatrix();
|
||||
@@ -2086,7 +2086,7 @@ struct Level : IGame {
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
*/
|
||||
void renderShadows(int roomIndex) {
|
||||
PROFILE_MARKER("PASS_SHADOW");
|
||||
|
||||
@@ -2104,10 +2104,10 @@ struct Level : IGame {
|
||||
if (colorShadow)
|
||||
Core::setClearColor(vec4(1.0f));
|
||||
Core::setTarget(shadow, RT_CLEAR_DEPTH | (colorShadow ? (RT_CLEAR_COLOR | RT_STORE_COLOR) : RT_STORE_DEPTH));
|
||||
//Core::setCullMode(cmBack);
|
||||
Core::validateRenderState();
|
||||
|
||||
Core::setCullMode(cmBack);
|
||||
|
||||
/*
|
||||
if (Core::settings.detail.shadows > Core::Settings::Quality::MEDIUM) { // per-object shadow map (atlas)
|
||||
NearObj nearObj[SHADOW_OBJ_MAX];
|
||||
int nearCount = getNearObjects(nearObj, SHADOW_OBJ_MAX);
|
||||
@@ -2120,9 +2120,10 @@ struct Level : IGame {
|
||||
for (int i = nearCount; i < SHADOW_OBJ_MAX; i++)
|
||||
Core::mLightProj[i].identity();
|
||||
} else // all-in-one shadow map
|
||||
renderShadowView(roomIndex);
|
||||
*/
|
||||
renderShadowView(roomIndex);
|
||||
|
||||
Core::setCullMode(cmFront);
|
||||
//Core::setCullMode(cmFront);
|
||||
if (colorShadow)
|
||||
Core::setClearColor(vec4(0.0f));
|
||||
|
||||
|
@@ -24,7 +24,7 @@ struct Shader : GAPI::Shader {
|
||||
void setup() {
|
||||
bind();
|
||||
setParam(uViewProj, Core::mViewProj);
|
||||
setParam(uLightProj, Core::mLightProj[0], Core::settings.detail.shadows > Core::Settings::Quality::MEDIUM ? SHADOW_OBJ_MAX : 1);
|
||||
setParam(uLightProj, Core::mLightProj);
|
||||
setParam(uViewPos, Core::viewPos);
|
||||
setParam(uParam, Core::params);
|
||||
setParam(uFogParams, Core::fogParams);
|
||||
|
@@ -1,15 +1,16 @@
|
||||
#include "common.hlsl"
|
||||
|
||||
struct VS_OUTPUT {
|
||||
float4 wpos : POSITION;
|
||||
float3 coord : TEXCOORD0;
|
||||
float4 texCoord : TEXCOORD1;
|
||||
float4 viewVec : TEXCOORD2;
|
||||
float4 normal : NORMAL;
|
||||
float4 diffuse : COLOR0;
|
||||
float3 ambient : COLOR1;
|
||||
float4 lightMap : COLOR2;
|
||||
float4 light : COLOR3;
|
||||
float4 pos : POSITION;
|
||||
float3 coord : TEXCOORD0;
|
||||
float4 texCoord : TEXCOORD1;
|
||||
float4 viewVec : TEXCOORD2;
|
||||
float4 normal : NORMAL;
|
||||
float4 diffuse : COLOR0;
|
||||
float3 ambient : COLOR1;
|
||||
float4 lightMap : COLOR2;
|
||||
float4 light : COLOR3;
|
||||
float4 hpos : TEXCOORD4;
|
||||
};
|
||||
|
||||
#ifdef VERTEX
|
||||
@@ -31,9 +32,9 @@ float3 calcAmbient(float3 n) {
|
||||
|
||||
VS_OUTPUT main(VS_INPUT In) {
|
||||
VS_OUTPUT Out;
|
||||
Out.ambient = 0.0;
|
||||
Out.lightMap = 0.0;
|
||||
Out.light = 0.0;
|
||||
Out.ambient = 0.0;
|
||||
Out.lightMap = 0.0;
|
||||
Out.light = 0.0;
|
||||
|
||||
int index = int(In.aCoord.w * 2.0);
|
||||
float4 rBasisRot = uBasis[index];
|
||||
@@ -56,7 +57,6 @@ VS_OUTPUT main(VS_INPUT In) {
|
||||
Out.viewVec = float4((uViewPos.xyz - Out.coord) * uFogParams.w, Out.coord.y * uParam.z);
|
||||
|
||||
#ifdef PASS_COMPOSE
|
||||
|
||||
if (TYPE_SPRITE) {
|
||||
Out.normal.xyz = normalize(Out.viewVec.xyz);
|
||||
} else {
|
||||
@@ -66,7 +66,6 @@ VS_OUTPUT main(VS_INPUT In) {
|
||||
float fog;
|
||||
|
||||
if (!TYPE_FLASH) {
|
||||
|
||||
float3 lv0 = (uLightPos[0].xyz - Out.coord) * uLightColor[0].w;
|
||||
float3 lv1 = (uLightPos[1].xyz - Out.coord) * uLightColor[1].w;
|
||||
float3 lv2 = (uLightPos[2].xyz - Out.coord) * uLightColor[2].w;
|
||||
@@ -150,15 +149,58 @@ VS_OUTPUT main(VS_INPUT In) {
|
||||
}
|
||||
#endif
|
||||
|
||||
Out.wpos = mul(uViewProj, float4(Out.coord, rBasisPos.w));
|
||||
|
||||
Out.pos = mul(uViewProj, float4(Out.coord, rBasisPos.w));
|
||||
Out.hpos = Out.pos;
|
||||
|
||||
return Out;
|
||||
}
|
||||
|
||||
#else // PIXEL
|
||||
|
||||
float getShadow(float3 lightVec) {
|
||||
return 1.0;
|
||||
float SHADOW(float2 p) {
|
||||
#ifdef SHADOW_DEPTH
|
||||
return tex2D(sShadow, p).x;
|
||||
#else
|
||||
return unpack(tex2D(sShadow, p));
|
||||
#endif
|
||||
}
|
||||
|
||||
float getShadow(float3 lightVec, float3 normal, float4 lightProj) {
|
||||
float3 p = lightProj.xyz / lightProj.w;
|
||||
|
||||
p.y = -p.y;
|
||||
p.xy = p.xy * 0.5 + 0.5;
|
||||
|
||||
p.z -= SHADOW_CONST_BIAS * SHADOW_TEXEL.x;
|
||||
|
||||
float vis = lightProj.w;
|
||||
if (TYPE_ROOM) {
|
||||
vis = min(vis, dot(normal, lightVec));
|
||||
}
|
||||
if (vis < 0.0 || p.x < 0.0 || p.y < 0.0 || p.x > 1.0 || p.y > 1.0) return 1.0;
|
||||
|
||||
p.z = saturate(p.z);
|
||||
|
||||
float4 samples = float4(
|
||||
SHADOW(p.xy ),
|
||||
SHADOW(p.xy + SHADOW_TEXEL.xz),
|
||||
SHADOW(p.xy + SHADOW_TEXEL.zy),
|
||||
SHADOW(p.xy + SHADOW_TEXEL.xy)
|
||||
);
|
||||
samples = step(p.zzzz, samples);
|
||||
|
||||
float2 f = frac(p.xy / SHADOW_TEXEL.xy);
|
||||
samples.xy = lerp(samples.xz, samples.yw, f.xx);
|
||||
float rShadow = lerp(samples.x, samples.y, f.y);
|
||||
|
||||
float fade = saturate(dot(lightVec, lightVec));
|
||||
return rShadow + (1.0 - rShadow) * fade;
|
||||
}
|
||||
|
||||
float getShadow(float3 coord, float3 lightVec, float3 normal) {
|
||||
float factor = clamp(1.0 - dot(normalize(lightVec), normal), 0.0, 1.0);
|
||||
factor *= SHADOW_NORMAL_BIAS;
|
||||
return getShadow(lightVec, normal, mul(uLightProj, float4(coord + normal * factor, 1.0)));
|
||||
}
|
||||
|
||||
float getContactAO(float3 p, float3 n) {
|
||||
@@ -167,7 +209,7 @@ float getContactAO(float3 p, float3 n) {
|
||||
float3 v = uContacts[i].xyz - p;
|
||||
float a = uContacts[i].w;
|
||||
float o = a * saturate(dot(n, v)) / dot(v, v);
|
||||
res *= clamp(1.0 - o, 0.0, 1.0);
|
||||
res *= saturate(1.0 - o);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -214,7 +256,11 @@ float4 main(VS_OUTPUT In) : COLOR0 {
|
||||
}
|
||||
|
||||
#ifdef PASS_SHADOW
|
||||
return 1.0;
|
||||
#ifdef SHADOW_DEPTH
|
||||
return 0.0;
|
||||
#else // SHADOW_COLOR
|
||||
return pack(In.hpos.z / In.hpos.w);
|
||||
#endif
|
||||
#else
|
||||
color *= In.diffuse;
|
||||
|
||||
@@ -241,11 +287,11 @@ float4 main(VS_OUTPUT In) : COLOR0 {
|
||||
light = uLightColor[1].xyz * In.light.y + uLightColor[2].xyz * In.light.z + uLightColor[3].xyz * In.light.w;
|
||||
|
||||
if (TYPE_ENTITY) {
|
||||
float rShadow = getShadow(lightVec);
|
||||
float rShadow = getShadow(In.coord, lightVec, normal);
|
||||
rSpecular = (uMaterial.z + 0.03) * rShadow;
|
||||
light += In.ambient + uLightColor[0].xyz * (In.light.x * rShadow);
|
||||
} else if (TYPE_ROOM) {
|
||||
float rShadow = getShadow(lightVec);
|
||||
float rShadow = getShadow(In.coord, lightVec, normal);
|
||||
light += lerp(In.ambient.xyz, In.lightMap.xyz, rShadow);
|
||||
} else if (TYPE_SPRITE) {
|
||||
light += In.lightMap.xyz;
|
||||
|
@@ -3,6 +3,14 @@
|
||||
#define WATER_FOG_DIST (1.0 / (6.0 * 1024.0))
|
||||
#define UNDERWATER_COLOR float3(0.6, 0.9, 0.9)
|
||||
|
||||
static const float3 SHADOW_TEXEL = float3(1.0 / 1024.0, 1.0 / 1024.0, 0.0);
|
||||
|
||||
#define SHADOW_NORMAL_BIAS 16.0
|
||||
#define SHADOW_CONST_BIAS 0.12
|
||||
|
||||
#define MAX_LIGHTS 4
|
||||
#define MAX_CONTACTS 15
|
||||
|
||||
struct VS_INPUT {
|
||||
float4 aCoord : POSITION;
|
||||
float4 aNormal : NORMAL;
|
||||
@@ -20,21 +28,21 @@ struct VS_INPUT {
|
||||
sampler sMask : register(s5);
|
||||
#endif
|
||||
|
||||
bool uFlags[16] : register( b0 );
|
||||
float4 uParam : register( c0 );
|
||||
float4 uTexParam : register( c1 );
|
||||
float4x4 uViewProj : register( c2 );
|
||||
float4 uBasis[32 * 2] : register( c6 );
|
||||
float4x4 uLightProj : register( c70 );
|
||||
float4 uMaterial : register( c102 );
|
||||
float4 uAmbient[6] : register( c103 );
|
||||
float4 uFogParams : register( c109 );
|
||||
float4 uViewPos : register( c110 );
|
||||
float4 uLightPos[MAX_LIGHTS] : register( c111 );
|
||||
float4 uLightColor[MAX_LIGHTS] : register( c115 );
|
||||
float4 uRoomSize : register( c119 );
|
||||
float4 uPosScale[2] : register( c120 );
|
||||
float4 uContacts[MAX_CONTACTS] : register( c122 );
|
||||
bool uFlags[16] : register( b0 );
|
||||
float4 uParam : register( c0 );
|
||||
float4 uTexParam : register( c1 );
|
||||
float4x4 uViewProj : register( c2 );
|
||||
float4 uBasis[32 * 2] : register( c6 );
|
||||
float4x4 uLightProj : register( c70 );
|
||||
float4 uMaterial : register( c74 );
|
||||
float4 uAmbient[6] : register( c75 );
|
||||
float4 uFogParams : register( c81 );
|
||||
float4 uViewPos : register( c82 );
|
||||
float4 uLightPos[MAX_LIGHTS] : register( c83 );
|
||||
float4 uLightColor[MAX_LIGHTS] : register( c87 );
|
||||
float4 uRoomSize : register( c91 );
|
||||
float4 uPosScale[2] : register( c92 );
|
||||
float4 uContacts[MAX_CONTACTS] : register( c94 );
|
||||
|
||||
#define TYPE_SPRITE uFlags[0]
|
||||
#define TYPE_FLASH uFlags[1]
|
||||
@@ -60,6 +68,18 @@ float4 uContacts[MAX_CONTACTS] : register( c122 );
|
||||
#define CLIP_PLANE uFlags[7]
|
||||
#define OPT_AMBIENT uFlags[8]
|
||||
#define OPT_SHADOW uFlags[9]
|
||||
#define OPT_SHADOW_HIGH uFlags[10]
|
||||
#define OPT_CONTACT uFlags[11]
|
||||
#define OPT_CAUSTICS uFlags[12]
|
||||
#define OPT_CONTACT uFlags[10]
|
||||
#define OPT_CAUSTICS uFlags[11]
|
||||
|
||||
float4 pack(float value) {
|
||||
float4 bitSh = float4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);
|
||||
float4 bitMsk = float4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);
|
||||
float4 res = frac(value * bitSh);
|
||||
res -= res.xxyz * bitMsk;
|
||||
return res;
|
||||
}
|
||||
|
||||
float unpack(float4 value) {
|
||||
float4 bitSh = float4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);
|
||||
return dot(value, bitSh);
|
||||
}
|
@@ -20,14 +20,8 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - trapezoidal correction
|
||||
#endif
|
||||
|
||||
#ifdef OPT_SHADOW
|
||||
#ifdef OPT_SHADOW_HIGH
|
||||
#define SHADOW_OBJ_MAX 8
|
||||
#define SHADOW_TEXEL vec3(1.0 / 512.0, 1.0 / 256.0, 0.0)
|
||||
#else
|
||||
#define SHADOW_OBJ_MAX 1
|
||||
#define SHADOW_TEXEL vec3(1.0 / 1024.0, 1.0 / 1024.0, 0.0)
|
||||
#endif
|
||||
uniform mat4 uLightProj[SHADOW_OBJ_MAX];
|
||||
#define SHADOW_TEXEL vec3(1.0 / 1024.0, 1.0 / 1024.0, 0.0)
|
||||
uniform mat4 uLightProj;
|
||||
#endif
|
||||
|
||||
uniform mat4 uViewProj;
|
||||
@@ -276,66 +270,55 @@ uniform vec4 uFogParams;
|
||||
#endif
|
||||
#else
|
||||
uniform sampler2D sShadow;
|
||||
#define CMP(a,b) step(min(1.0, b), a)
|
||||
|
||||
#ifdef SHADOW_DEPTH
|
||||
#define compare(p, z) CMP(texture2D(sShadow, (p)).x, (z));
|
||||
#elif defined(SHADOW_COLOR)
|
||||
float unpack(vec4 value) {
|
||||
vec4 bitSh = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);
|
||||
return dot(value, bitSh);
|
||||
}
|
||||
#define compare(p, z) CMP(unpack(texture2D(sShadow, (p))), (z));
|
||||
#endif
|
||||
float unpack(vec4 value) {
|
||||
vec4 bitSh = vec4(1.0/(256.0*256.0*256.0), 1.0/(256.0*256.0), 1.0/256.0, 1.0);
|
||||
return dot(value, bitSh);
|
||||
}
|
||||
|
||||
float SHADOW(vec3 p) {
|
||||
return compare(p.xy, p.z);
|
||||
float SHADOW(vec2 p) {
|
||||
#ifdef SHADOW_DEPTH
|
||||
return texture2D(sShadow, p).x;
|
||||
#else
|
||||
return unpack(texture2D(sShadow, p));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
float getShadow(vec3 lightVec, vec4 lightProj, vec2 tileOffset) {
|
||||
float getShadow(vec3 lightVec, vec3 normal, vec4 lightProj) {
|
||||
vec3 p = lightProj.xyz / lightProj.w;
|
||||
p.xyz = p.xyz * 0.5 + 0.5;
|
||||
p.z -= 0.04 * SHADOW_TEXEL.x;
|
||||
|
||||
float vis = lightProj.w;
|
||||
#ifdef TYPE_ROOM
|
||||
vis = min(vis, dot(vNormal.xyz, lightVec));
|
||||
vis = min(vis, dot(normal, lightVec));
|
||||
#endif
|
||||
if (vis < 0.0 || p.x < 0.0 || p.y < 0.0 || p.x > 1.0 || p.y > 1.0) return 1.0;
|
||||
|
||||
#ifdef OPT_SHADOW_HIGH
|
||||
p.xy = p.xy * vec2(0.25, 0.5) + tileOffset;
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW_SAMPLER
|
||||
float rShadow = SHADOW(p);
|
||||
#else
|
||||
vec4 samples = vec4(SHADOW(SHADOW_TEXEL * vec3(0.0, 0.0, 0.0) + p),
|
||||
SHADOW(SHADOW_TEXEL * vec3(1.0, 0.0, 0.0) + p),
|
||||
SHADOW(SHADOW_TEXEL * vec3(0.0, 1.0, 0.0) + p),
|
||||
SHADOW(SHADOW_TEXEL * vec3(1.0, 1.0, 0.0) + p));
|
||||
vec4 samples = vec4(SHADOW( p.xy),
|
||||
SHADOW(SHADOW_TEXEL.xz + p.xy),
|
||||
SHADOW(SHADOW_TEXEL.zy + p.xy),
|
||||
SHADOW(SHADOW_TEXEL.xy + p.xy));
|
||||
|
||||
samples = step(vec4(p.z), samples);
|
||||
|
||||
vec2 f = fract(p.xy / SHADOW_TEXEL.xy);
|
||||
float rShadow = mix(mix(samples.x, samples.y, f.x), mix(samples.z, samples.w, f.x), f.y);
|
||||
samples.xy = mix(samples.xz, samples.yw, f.x);
|
||||
float rShadow = mix(samples.x, samples.y, f.y);
|
||||
#endif
|
||||
|
||||
float fade = clamp(dot(lightVec, lightVec), 0.0, 1.0);
|
||||
return rShadow + (1.0 - rShadow) * fade;
|
||||
}
|
||||
|
||||
float getShadow(vec3 lightVec) {
|
||||
vec4 c = vec4(vCoord, 1.0);
|
||||
#ifdef OPT_SHADOW_HIGH
|
||||
return min(min(min(min(min(min(min( // hardcoded for 4x2 shadow atlas
|
||||
getShadow(lightVec, uLightProj[0] * c, vec2(0.00, 0.0)),
|
||||
getShadow(lightVec, uLightProj[1] * c, vec2(0.25, 0.0))),
|
||||
getShadow(lightVec, uLightProj[2] * c, vec2(0.50, 0.0))),
|
||||
getShadow(lightVec, uLightProj[3] * c, vec2(0.75, 0.0))),
|
||||
getShadow(lightVec, uLightProj[4] * c, vec2(0.00, 0.5))),
|
||||
getShadow(lightVec, uLightProj[5] * c, vec2(0.25, 0.5))),
|
||||
getShadow(lightVec, uLightProj[6] * c, vec2(0.50, 0.5))),
|
||||
getShadow(lightVec, uLightProj[7] * c, vec2(0.75, 0.5)));
|
||||
#else
|
||||
return getShadow(lightVec, uLightProj[0] * c, vec2(0.0, 0.0));
|
||||
#endif
|
||||
float getShadow(vec3 lightVec, vec3 normal) {
|
||||
float factor = clamp(1.0 - dot(normalize(lightVec), normal), 0.0, 1.0);
|
||||
factor *= 16.0;
|
||||
return getShadow(lightVec, normal, uLightProj * vec4(vCoord + normal * factor, 1.0));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -414,7 +397,6 @@ uniform vec4 uFogParams;
|
||||
#endif
|
||||
|
||||
#ifdef PASS_COMPOSE
|
||||
|
||||
vec3 lightVec = (uLightPos[0].xyz - vCoord) * uLightColor[0].w;
|
||||
vec3 normal = normalize(vNormal.xyz);
|
||||
|
||||
@@ -426,7 +408,7 @@ uniform vec4 uFogParams;
|
||||
vec3 light = uLightColor[1].xyz * vLight.y + uLightColor[2].xyz * vLight.z + uLightColor[3].xyz * vLight.w;
|
||||
|
||||
#if defined(TYPE_ENTITY) || defined(TYPE_ROOM)
|
||||
float rShadow = getShadow(lightVec);
|
||||
float rShadow = getShadow(lightVec, normal);
|
||||
#endif
|
||||
|
||||
#ifdef TYPE_ENTITY
|
||||
|
@@ -66,16 +66,13 @@ struct Texture : GAPI::Texture {
|
||||
bool filter = (opt & OPT_NEAREST) == 0;
|
||||
bool mipmaps = (opt & OPT_MIPMAPS) != 0;
|
||||
|
||||
if (format == FMT_SHADOW && !Core::support.shadowSampler) {
|
||||
if (format == FMT_SHADOW && !Core::support.shadowSampler)
|
||||
format = FMT_DEPTH;
|
||||
filter = false;
|
||||
}
|
||||
|
||||
if (format == FMT_DEPTH) {
|
||||
if (Core::support.depthTexture)
|
||||
filter = false;
|
||||
else
|
||||
if (!Core::support.depthTexture)
|
||||
format = FMT_RGBA;
|
||||
filter = false;
|
||||
}
|
||||
|
||||
if (format == FMT_RGBA_HALF) {
|
||||
|
4
src/ui.h
4
src/ui.h
@@ -280,7 +280,7 @@ namespace UI {
|
||||
void updateAspect(float aspect) {
|
||||
height = 480.0f;
|
||||
width = height * aspect;
|
||||
Core::mProj = mat4(0.0f, width, height, 0.0f, 0.0f, 1.0f);
|
||||
Core::mProj = GAPI::ortho(0.0f, width, height, 0.0f, 0.0f, 1.0f);
|
||||
Core::setViewProj(Core::mView, Core::mProj);
|
||||
Core::active.shader->setParam(uViewProj, Core::mViewProj);
|
||||
}
|
||||
@@ -493,7 +493,7 @@ namespace UI {
|
||||
Core::setBlendMode(bmAlpha);
|
||||
Core::setCullMode(cmNone);
|
||||
|
||||
Core::mViewProj = mat4(0.0f, float(Core::width), float(Core::height), 0.0f, 0.0f, 1.0f);
|
||||
Core::mViewProj = GAPI::ortho(0.0f, float(Core::width), float(Core::height), 0.0f, 0.0f, 1.0f);
|
||||
|
||||
game->setShader(Core::passGUI, Shader::DEFAULT);
|
||||
|
||||
|
31
src/utils.h
31
src/utils.h
@@ -466,6 +466,12 @@ struct quat {
|
||||
};
|
||||
|
||||
struct mat4 {
|
||||
|
||||
enum ProjRange {
|
||||
PROJ_NEG_POS,
|
||||
PROJ_ZERO_POS,
|
||||
};
|
||||
|
||||
float e00, e10, e20, e30,
|
||||
e01, e11, e21, e31,
|
||||
e02, e12, e22, e32,
|
||||
@@ -494,17 +500,24 @@ struct mat4 {
|
||||
e33 = 1.0f;
|
||||
}
|
||||
|
||||
mat4(float l, float r, float b, float t, float znear, float zfar) {
|
||||
mat4(ProjRange range, float l, float r, float b, float t, float znear, float zfar) {
|
||||
identity();
|
||||
e00 = 2.0f / (r - l);
|
||||
e11 = 2.0f / (t - b);
|
||||
e22 = 2.0f / (znear - zfar);
|
||||
e03 = (l + r) / (l - r);
|
||||
e13 = (t + b) / (b - t);
|
||||
e23 = znear / (znear - zfar);
|
||||
switch (range) {
|
||||
case PROJ_NEG_POS :
|
||||
e23 = (zfar + znear) / (znear - zfar);
|
||||
break;
|
||||
case PROJ_ZERO_POS :
|
||||
e23 = znear / (znear - zfar);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mat4(float fov, float aspect, float znear, float zfar) {
|
||||
mat4(ProjRange range, float fov, float aspect, float znear, float zfar) {
|
||||
float k = 1.0f / tanf(fov * 0.5f * DEG2RAD);
|
||||
identity();
|
||||
if (aspect >= 1.0f) {
|
||||
@@ -514,10 +527,18 @@ struct mat4 {
|
||||
e00 = k;
|
||||
e11 = k * aspect;
|
||||
}
|
||||
e22 = (znear + zfar) / (znear - zfar);
|
||||
e33 = 0.0f;
|
||||
e32 = -1.0f;
|
||||
e23 = 2.0f * zfar * znear / (znear - zfar);
|
||||
switch (range) {
|
||||
case PROJ_NEG_POS :
|
||||
e22 = (znear + zfar) / (znear - zfar);
|
||||
e23 = 2.0f * zfar * znear / (znear - zfar);
|
||||
break;
|
||||
case PROJ_ZERO_POS :
|
||||
e22 = zfar / (znear - zfar);
|
||||
e23 = znear * e22;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mat4(const vec3 &from, const vec3 &at, const vec3 &up) {
|
||||
|
Reference in New Issue
Block a user