1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-15 09:34:18 +02:00

#15 D3D9 WIP, port some shaders, handle device reset & lost

This commit is contained in:
XProger
2018-05-13 05:52:23 +03:00
parent c9b37b4ec9
commit d875a66aaf
18 changed files with 687 additions and 217 deletions

View File

@@ -84,6 +84,7 @@ struct ShaderCache {
void prepareShadows(int fx) {
compile(Core::passShadow, Shader::ENTITY, fx, rsShadow);
compile(Core::passShadow, Shader::ENTITY, fx, rsShadow | RS_DISCARD);
compile(Core::passShadow, Shader::MIRROR, fx, rsShadow);
}
void prepareWater(int fx) {
@@ -169,7 +170,7 @@ struct ShaderCache {
#undef SD_ADD
LOG("shader: %s(%d) %s%s%s\n", Core::passNames[pass], type, (fx & FX_UNDERWATER) ? "u" : "", (fx & FX_ALPHA_TEST) ? "a" : "", (fx & FX_CLIP_PLANE) ? "c" : "");
return shaders[pass][type][fx] = new Shader(pass, def, defCount);
return shaders[pass][type][fx] = new Shader(pass, type, def, defCount);
#else
return NULL;
#endif
@@ -233,7 +234,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), FMT_RGBA, false);
textures[j * 4 + i] = new Texture(64 >> (i << 1), 64 >> (i << 1), FMT_RGBA, OPT_TARGET | OPT_NEAREST);
}
~AmbientCache() {
@@ -277,7 +278,7 @@ struct AmbientCache {
for (int i = 1; i < 4; i++) {
int size = 64 >> (i << 1);
Core::active.shader->setParam(uParam, vec4(float(size << 2), 0.0f, 0.0f, 0.0f));
Core::active.shader->setParam(uParam, vec4(1.0f / (size << 2), 0.0f, 0.0f, 0.0f));
for (int j = 0; j < 6; j++) {
Texture *src = textures[j * 4 + i - 1];
@@ -300,6 +301,7 @@ struct AmbientCache {
void processQueue() {
game->setupBinding();
for (int i = 0; i < tasksCount; i++) {
Task &task = tasks[i];

View File

@@ -122,6 +122,7 @@ struct Lock {
#define OS_LOCK(mutex) Lock _lock(mutex)
/*
extern void* osRWLockInit ();
extern void osRWLockFree (void *obj);
extern void osRWLockRead (void *obj);
@@ -156,6 +157,7 @@ struct LockWrite {
#define OS_LOCK_READ(rwLock) LockRead _rLock(rwLock)
#define OS_LOCK_WRITE(rwLock) LockWrite _wLock(rwLock)
*/
enum InputKey { ikNone,
// keyboard
@@ -926,9 +928,9 @@ namespace Core {
validateRenderState();
}
void beginFrame() {
bool beginFrame() {
Core::stats.start();
GAPI::beginFrame();
return GAPI::beginFrame();
}
void endFrame() {

View File

@@ -169,11 +169,14 @@ namespace Game {
return true;
}
void frameBegin() {
if (Core::settings.version == SETTINGS_READING) return;
bool frameBegin() {
if (Core::settings.version == SETTINGS_READING) return false;
Core::reset();
Core::beginFrame();
level->renderPrepare();
if (Core::beginFrame()) {
level->renderPrepare();
return true;
}
return false;
}
void frameRender() {
@@ -195,10 +198,13 @@ namespace Game {
Core::endFrame();
}
void render() {
frameBegin();
frameRender();
frameEnd();
bool render() {
if (frameBegin()) {
frameRender();
frameEnd();
return true;
}
return false;
}
}

View File

@@ -8,12 +8,54 @@
#define PROFILE_LABEL(id, name, label)
#define PROFILE_TIMING(time)
extern LPDIRECT3D9 D3D;
extern LPDIRECT3DDEVICE9 device;
extern LPDIRECT3D9 D3D;
extern LPDIRECT3DDEVICE9 device;
extern D3DPRESENT_PARAMETERS d3dpp;
#ifdef _DEBUG
void D3DCHECK(HRESULT res) {
if (res == D3D_OK) return;
LOG("! ");
switch (res) {
case D3DERR_WRONGTEXTUREFORMAT : LOG("D3DERR_WRONGTEXTUREFORMAT"); break;
case D3DERR_UNSUPPORTEDCOLOROPERATION : LOG("D3DERR_UNSUPPORTEDCOLOROPERATION"); break;
case D3DERR_UNSUPPORTEDCOLORARG : LOG("D3DERR_UNSUPPORTEDCOLORARG"); break;
case D3DERR_UNSUPPORTEDALPHAOPERATION : LOG("D3DERR_UNSUPPORTEDALPHAOPERATION"); break;
case D3DERR_UNSUPPORTEDALPHAARG : LOG("D3DERR_UNSUPPORTEDALPHAARG"); break;
case D3DERR_TOOMANYOPERATIONS : LOG("D3DERR_TOOMANYOPERATIONS"); break;
case D3DERR_CONFLICTINGTEXTUREFILTER : LOG("D3DERR_CONFLICTINGTEXTUREFILTER"); break;
case D3DERR_UNSUPPORTEDFACTORVALUE : LOG("D3DERR_UNSUPPORTEDFACTORVALUE"); break;
case D3DERR_CONFLICTINGRENDERSTATE : LOG("D3DERR_CONFLICTINGRENDERSTATE"); break;
case D3DERR_UNSUPPORTEDTEXTUREFILTER : LOG("D3DERR_UNSUPPORTEDTEXTUREFILTER"); break;
case D3DERR_CONFLICTINGTEXTUREPALETTE : LOG("D3DERR_CONFLICTINGTEXTUREPALETTE"); break;
case D3DERR_DRIVERINTERNALERROR : LOG("D3DERR_DRIVERINTERNALERROR"); break;
case D3DERR_NOTFOUND : LOG("D3DERR_NOTFOUND"); break;
case D3DERR_MOREDATA : LOG("D3DERR_MOREDATA"); break;
case D3DERR_DEVICELOST : LOG("D3DERR_DEVICELOST"); break;
case D3DERR_DEVICENOTRESET : LOG("D3DERR_DEVICENOTRESET"); break;
case D3DERR_NOTAVAILABLE : LOG("D3DERR_NOTAVAILABLE"); break;
case D3DERR_OUTOFVIDEOMEMORY : LOG("D3DERR_OUTOFVIDEOMEMORY"); break;
case D3DERR_INVALIDDEVICE : LOG("D3DERR_INVALIDDEVICE"); break;
case D3DERR_INVALIDCALL : LOG("D3DERR_INVALIDCALL"); break;
case D3DERR_DRIVERINVALIDCALL : LOG("D3DERR_DRIVERINVALIDCALL"); break;
case D3DERR_WASSTILLDRAWING : LOG("D3DERR_WASSTILLDRAWING"); break;
default : LOG("D3DERR_UNKNOWN"); break;
}
LOG("\n");
ASSERT(false);
}
#else
#define D3DCHECK(res) res
#endif
namespace GAPI {
#include "shaders/base_vs.h"
#include "shaders/base_ps.h"
#include "shaders/compose_vs.h"
#include "shaders/compose_ps.h"
#include "shaders/shadow_vs.h"
#include "shaders/shadow_ps.h"
#include "shaders/ambient_vs.h"
#include "shaders/ambient_ps.h"
#include "shaders/water_vs.h"
#include "shaders/water_ps.h"
#include "shaders/filter_vs.h"
@@ -28,8 +70,39 @@ namespace GAPI {
int cullMode, blendMode;
uint32 clearColor;
LPDIRECT3DSURFACE9 defBackBuffer;
LPDIRECT3DVERTEXDECLARATION9 vertexDecl;
struct Texture;
struct Mesh;
struct Resource {
Texture *texture;
Mesh *mesh;
} resList[256];
int resCount;
void registerResource(Mesh *mesh) {
resList[resCount].mesh = mesh;
resList[resCount].texture = NULL;
resCount++;
}
void registerResource(Texture *texture) {
resList[resCount].mesh = NULL;
resList[resCount].texture = texture;
resCount++;
}
void unregisterResource(void *res) {
for (int i = 0; i < resCount; i++)
if (resList[i].mesh == res || resList[i].texture == res) {
resList[i] = resList[--resCount];
break;
}
}
// Shader
enum {
USAGE_VS,
@@ -40,40 +113,58 @@ namespace GAPI {
int reg;
int usage;
} bindings[uMAX] = {
{ 1, USAGE_VS | USAGE_PS }, // uParam
{ 2, USAGE_VS | USAGE_PS }, // uTexParam
{ 3, USAGE_VS | USAGE_PS }, // uViewProj
{ 7, USAGE_VS | USAGE_PS }, // uBasis
{ 71, USAGE_VS | USAGE_PS }, // uLightProj
{ 103, USAGE_VS | USAGE_PS }, // uMaterial
{ 104, USAGE_VS | USAGE_PS }, // uAmbient
{ 110, USAGE_VS | USAGE_PS }, // uFogParams
{ 111, USAGE_VS | USAGE_PS }, // uViewPos
{ 112, USAGE_VS | USAGE_PS }, // uLightPos
{ 116, USAGE_VS | USAGE_PS }, // uLightColor
{ 120, USAGE_VS | USAGE_PS }, // uRoomSize
{ 121, USAGE_VS | USAGE_PS }, // uPosScale
{ 123, USAGE_VS | USAGE_PS }, // uContacts
{ 0, USAGE_VS | USAGE_PS }, // uParam
{ 1, USAGE_VS | USAGE_PS }, // uTexParam
{ 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
};
struct Shader {
LPDIRECT3DVERTEXSHADER9 VS;
LPDIRECT3DPIXELSHADER9 PS;
BOOL flags[16];
Shader() : VS(NULL), PS(NULL) {}
void init(Core::Pass pass, int *def, int defCount) {
void init(Core::Pass pass, int type, int *def, int defCount) {
const BYTE *vSrc, *pSrc;
switch (pass) {
case Core::passCompose :
case Core::passShadow :
case Core::passAmbient : vSrc = BASE_VS; pSrc = BASE_PS; break;
case Core::passWater : vSrc = WATER_VS; pSrc = WATER_PS; break;
case Core::passFilter : vSrc = FILTER_VS; pSrc = FILTER_PS; break;
case Core::passGUI : vSrc = GUI_VS; pSrc = GUI_PS; break;
case Core::passCompose : vSrc = COMPOSE_VS; pSrc = COMPOSE_PS; break;
case Core::passShadow : vSrc = SHADOW_VS; pSrc = SHADOW_PS; break;
case Core::passAmbient : vSrc = AMBIENT_VS; pSrc = AMBIENT_PS; break;
case Core::passWater : vSrc = WATER_VS; pSrc = WATER_PS; break;
case Core::passFilter : vSrc = FILTER_VS; pSrc = FILTER_PS; break;
case Core::passGUI : vSrc = GUI_VS; pSrc = GUI_PS; break;
default : ASSERT(false); LOG("! wrong pass id\n"); return;
}
memset(flags, 0, sizeof(flags));
flags[type] = TRUE;
for (int i = 0; i < defCount; i++) {
switch (def[i]) {
case SD_UNDERWATER : flags[ 5] = TRUE; break;
case SD_ALPHA_TEST : flags[ 6] = TRUE; break;
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;
}
}
device->CreateVertexShader ((DWORD*)vSrc, &VS);
device->CreatePixelShader ((DWORD*)pSrc, &PS);
}
@@ -88,6 +179,9 @@ namespace GAPI {
Core::active.shader = this;
device->SetVertexShader(VS);
device->SetPixelShader(PS);
device->SetVertexShaderConstantB (0, flags, COUNT(flags));
device->SetPixelShaderConstantB (0, flags, COUNT(flags));
}
}
@@ -127,7 +221,9 @@ namespace GAPI {
bool filter = (opt & OPT_NEAREST) == 0;
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;
static const struct FormatDesc {
int bpp;
@@ -146,26 +242,38 @@ namespace GAPI {
FormatDesc desc = formats[fmt];
uint32 usage = 0;
if (mipmaps) usage |= D3DUSAGE_AUTOGENMIPMAP;
if (isDepth) usage |= D3DUSAGE_DEPTHSTENCIL;
if (isTarget) usage |= D3DUSAGE_RENDERTARGET;
D3DPOOL pool = isTarget ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
if (cube) {
device->CreateCubeTexture(width, 1, 0, desc.format, D3DPOOL_MANAGED, &texCube, NULL);
D3DCHECK(device->CreateCubeTexture(width, 1, usage, desc.format, pool, &texCube, NULL));
} else {
device->CreateTexture(width, height, 1, 0, desc.format, D3DPOOL_MANAGED, &tex2D, NULL);
if (data) {
D3DCHECK(device->CreateTexture(width, height, 1, usage, desc.format, pool, &tex2D, NULL));
if (data && !isTarget) {
D3DLOCKED_RECT rect;
tex2D->LockRect(0, &rect, NULL, 0);
D3DCHECK(tex2D->LockRect(0, &rect, NULL, 0));
memcpy(rect.pBits, data, width * height * (desc.bpp / 8));
tex2D->UnlockRect(0);
D3DCHECK(tex2D->UnlockRect(0));
}
}
if (pool != D3DPOOL_MANAGED)
registerResource(this);
}
void deinit() {
unregisterResource(this);
if (tex2D) tex2D->Release();
if (texCube) texCube->Release();
}
void generateMipMap() {
// TODO
if (texCube) texCube->GenerateMipSubLevels();
if (tex2D) tex2D->GenerateMipSubLevels();
}
void bind(int sampler) {
@@ -178,6 +286,25 @@ namespace GAPI {
device->SetTexture(sampler, tex2D);
else if (texCube)
device->SetTexture(sampler, texCube);
bool filter = (Core::settings.detail.filter > Core::Settings::LOW) && !(opt & OPT_NEAREST);
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);
if (aniso) {
device->SetSamplerState(sampler, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
device->SetSamplerState(sampler, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, D3DTEXF_NONE);
device->SetSamplerState(sampler, D3DSAMP_MAXANISOTROPY, support.maxAniso);
} else {
device->SetSamplerState(sampler, D3DSAMP_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
device->SetSamplerState(sampler, D3DSAMP_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, mipmaps ? (filter ? D3DTEXF_LINEAR : D3DTEXF_POINT) : D3DTEXF_NONE);
device->SetSamplerState(sampler, D3DSAMP_MAXANISOTROPY, 1);
}
}
}
@@ -188,18 +315,7 @@ namespace GAPI {
}
}
void setFilterQuality(int value) {
bool filter = value > Core::Settings::LOW;
bool mipmaps = value > Core::Settings::MEDIUM;
for (int i = 0; i < sMAX; i++) {
device->SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
device->SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
device->SetSamplerState(i, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);
device->SetSamplerState(i, D3DSAMP_MAGFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
device->SetSamplerState(i, D3DSAMP_MINFILTER, filter ? D3DTEXF_LINEAR : D3DTEXF_POINT);
}
}
void setFilterQuality(int value) {}
};
// Mesh
@@ -216,15 +332,22 @@ namespace GAPI {
void init(Index *indices, int iCount, ::Vertex *vertices, int vCount, int aCount) {
this->iCount = iCount;
this->vCount = vCount;
ASSERT(sizeof(GAPI::Vertex) == sizeof(::Vertex));
device->CreateIndexBuffer (iCount * sizeof(indices[0]), D3DUSAGE_WRITEONLY, D3DFMT_INDEX16, D3DPOOL_MANAGED, &IB, NULL);
device->CreateVertexBuffer (vCount * sizeof(vertices[0]), D3DUSAGE_WRITEONLY, 0, D3DPOOL_MANAGED, &VB, NULL);
uint32 usage = D3DUSAGE_WRITEONLY | (dynamic ? D3DUSAGE_DYNAMIC : 0);
D3DPOOL pool = dynamic ? D3DPOOL_DEFAULT : D3DPOOL_MANAGED;
D3DCHECK(device->CreateIndexBuffer (iCount * sizeof(Index), usage, D3DFMT_INDEX16, pool, &IB, NULL));
D3DCHECK(device->CreateVertexBuffer (vCount * sizeof(Vertex), usage, D3DFMT_UNKNOWN, pool, &VB, NULL));
update(indices, iCount, vertices, vCount);
if (pool != D3DPOOL_MANAGED)
registerResource(this);
}
void deinit() {
unregisterResource(this);
IB->Release();
VB->Release();
}
@@ -236,15 +359,17 @@ namespace GAPI {
int size;
if (indices && iCount) {
IB->Lock(0, size = iCount * sizeof(indices[0]), &ptr, 0);
size = iCount * sizeof(indices[0]);
D3DCHECK(IB->Lock(0, 0, &ptr, dynamic ? D3DLOCK_DISCARD : 0));
memcpy(ptr, indices, size);
IB->Unlock();
D3DCHECK(IB->Unlock());
}
if (vertices && vCount) {
VB->Lock(0, size = vCount * sizeof(vertices[0]), &ptr, 0);
size = vCount * sizeof(vertices[0]);
D3DCHECK(VB->Lock(0, 0, &ptr, dynamic ? D3DLOCK_DISCARD: 0));
memcpy(ptr, vertices, size);
VB->Unlock();
D3DCHECK(VB->Unlock());
}
}
@@ -276,7 +401,7 @@ namespace GAPI {
LOG("Vendor : %s\n", adapterInfo.Description);
LOG("Renderer : Direct3D 9.0c\n");
support.maxAniso = 16;
support.maxAniso = 8;
support.maxVectors = 16;
support.shaderBinary = false;
support.VAO = false;
@@ -308,40 +433,61 @@ namespace GAPI {
};
device->CreateVertexDeclaration(VERTEX_DECL, &vertexDecl);
/*
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
glEnable(GL_SCISSOR_TEST);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*)&defaultFBO);
glGenFramebuffers(1, &FBO);
*/
}
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);
*/
vertexDecl->Release();
}
void beginFrame() {
void resetDevice() {
int tmpCount = resCount;
Resource tmpList[256];
memcpy(tmpList, resList, sizeof(Resource) * tmpCount);
for (int i = 0; i < tmpCount; i++) {
Resource &res = tmpList[i];
if (res.mesh)
res.mesh->deinit();
else
res.texture->deinit();
}
D3DCHECK(device->Reset(&d3dpp));
for (int i = 0; i < tmpCount; i++) {
Resource &res = tmpList[i];
if (res.mesh)
res.mesh->init(NULL, res.mesh->iCount, NULL, res.mesh->vCount, 0);
else
res.texture->init(NULL);
}
}
bool beginFrame() {
switch (device->TestCooperativeLevel()) {
case D3D_OK :
break;
case D3DERR_DEVICELOST :
return false;
case D3DERR_DEVICENOTRESET :
switch (device->Reset(&d3dpp)) {
case D3D_OK : break;
default : return false;
}
case D3DERR_DRIVERINTERNALERROR :
Core::quit();
return false;
}
device->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &defBackBuffer);
device->BeginScene();
return true;
}
void endFrame() {
device->EndScene();
defBackBuffer->Release();
}
void resetState() {
@@ -373,39 +519,46 @@ namespace GAPI {
}
void bindTarget(Texture *target, int face) {
/*
if (!target) { // may be a null
glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO);
D3DCHECK(device->SetRenderTarget(0, defBackBuffer));
} else {
GLenum texTarget = GL_TEXTURE_2D;
if (target->opt & OPT_CUBEMAP)
texTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + face;
ASSERT(target->opt & OPT_TARGET);
LPDIRECT3DSURFACE9 surface;
if (target->tex2D)
D3DCHECK(target->tex2D->GetSurfaceLevel(0, &surface));
else if (target->texCube)
D3DCHECK(target->texCube->GetCubeMapSurface(D3DCUBEMAP_FACES(D3DCUBEMAP_FACE_POSITIVE_X + face), 0, &surface));
D3DCHECK(device->SetRenderTarget(0, surface));
surface->Release();
bool depth = target->fmt == FMT_DEPTH || target->fmt == FMT_SHADOW;
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);
}
*/
}
void discardTarget(bool color, bool depth) {}
void copyTarget(Texture *dst, int xOffset, int yOffset, int x, int y, int width, int height) {
Core::active.textures[0] = NULL;
/*
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, dst->ID);
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, x, y, width, height);
glBindTexture(GL_TEXTURE_2D, 0);
*/
ASSERT(dst && dst->tex2D);
LPDIRECT3DSURFACE9 surface;
dst->tex2D->GetSurfaceLevel(0, &surface);
RECT srcRect = { x, y, x + width, y + height },
dstRect = { xOffset, yOffset, xOffset + width, yOffset + height };
device->StretchRect(defBackBuffer, &srcRect, surface, &dstRect, D3DTEXF_POINT);
surface->Release();
}
void setVSync(bool enable) {
//
d3dpp.PresentationInterval = enable ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
GAPI::resetDevice();
}
void waitVBlank() {}
@@ -502,9 +655,24 @@ namespace GAPI {
}
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);
GAPI::Texture *t = Core::active.target;
ASSERT(t && t->tex2D);
LPDIRECT3DSURFACE9 surface, texSurface;
D3DCHECK(t->tex2D->GetSurfaceLevel(0, &texSurface));
D3DCHECK(device->CreateOffscreenPlainSurface(t->width, t->height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL));
D3DCHECK(device->GetRenderTargetData(texSurface, surface));
RECT r = { x, y, x + 1, y + 1 };
D3DLOCKED_RECT rect;
surface->LockRect(&rect, &r, D3DLOCK_READONLY);
ubyte4 c = *((ubyte4*)rect.pBits);
surface->UnlockRect();
texSurface->Release();
surface->Release();
return vec4(float(c.z), float(c.y), float(c.x), float(c.w)) * (1.0f / 255.0f);
}
void initPSO(PSO *pso) {

View File

@@ -335,7 +335,7 @@ namespace GAPI {
struct Shader {
#ifdef FFP
void init(Core::Pass pass, int *def, int defCount) {}
void init(Core::Pass pass, int type, int *def, int defCount) {}
void deinit() {}
void bind() {}
void setParam(UniformType uType, const vec4 &value, int count = 1) {}
@@ -345,7 +345,7 @@ namespace GAPI {
uint32 ID;
int32 uID[uMAX];
void init(Core::Pass pass, int *def, int defCount) {
void init(Core::Pass pass, int type, int *def, int defCount) {
const char *source;
switch (pass) {
case Core::passCompose :
@@ -977,7 +977,9 @@ namespace GAPI {
glDeleteRenderbuffers(1, &rtCache[b].items[i].ID);
}
void beginFrame() {}
bool beginFrame() {
return true;
}
void endFrame() {}

View File

@@ -289,7 +289,9 @@ namespace GAPI {
delete[] cmdBuf;
}
void beginFrame() {}
bool beginFrame() {
return true;
}
void endFrame() {}

View File

@@ -1443,7 +1443,7 @@ struct Lara : Character {
void bakeEnvironment() {
flags.invisible = true;
if (!environment)
environment = new Texture(256, 256, FMT_RGBA, OPT_CUBEMAP | OPT_MIPMAPS);
environment = new Texture(256, 256, FMT_RGBA, OPT_CUBEMAP | OPT_MIPMAPS | OPT_TARGET);
game->renderEnvironment(getRoomIndex(), pos - vec3(0.0f, 384.0f, 0.0f), &environment, 0, Core::passCompose);
environment->generateMipMap();
flags.invisible = false;

View File

@@ -50,26 +50,6 @@ void osMutexUnlock(void *obj) {
}
/*
void* osMutexInit() {
HANDLE *mutex = new HANDLE();
*mutex = CreateMutex(NULL, FALSE, NULL);
return mutex;
}
void osMutexFree(void *obj) {
CloseHandle(*(HANDLE*)obj);
delete (HANDLE*)obj;
}
void osMutexLock(void *obj) {
WaitForSingleObject(*(HANDLE*)obj, INFINITE);
}
void osMutexUnlock(void *obj) {
ReleaseMutex(*(HANDLE*)obj);
}
*/
void* osRWLockInit() {
SRWLOCK *lock = new SRWLOCK();
InitializeSRWLock(lock);
@@ -95,7 +75,7 @@ void osRWLockWrite(void *obj) {
void osRWUnlockWrite(void *obj) {
ReleaseSRWLockExclusive((SRWLOCK*)obj);
}
*/
// timing
int osStartTime = 0;
@@ -441,16 +421,14 @@ HWND hWnd;
SwapBuffers(hDC);
}
#else
D3DPRESENT_PARAMETERS d3dpp;
LPDIRECT3D9 D3D;
LPDIRECT3DDEVICE9 device;
D3DPRESENT_PARAMETERS d3dpp;
void ContextCreate() {
memset(&d3dpp, 0, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.BackBufferCount = 1;
d3dpp.BackBufferWidth = 1;
d3dpp.BackBufferHeight = 1;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
@@ -474,14 +452,16 @@ HWND hWnd;
}
void ContextResize() {
d3dpp.BackBufferWidth = Core::width;
d3dpp.BackBufferHeight = Core::height;
device->Reset(&d3dpp);
if (Core::width <= 0 || Core::height <= 0)
return;
d3dpp.BackBufferWidth = Core::width;
d3dpp.BackBufferHeight = Core::height;
GAPI::resetDevice();
}
void ContextSwap() {
if (device->Present(NULL, NULL, NULL, NULL) == D3DERR_DEVICELOST)
ContextResize();
GAPI::resetDevice();
}
#endif

View File

@@ -13,8 +13,8 @@ struct Shader : GAPI::Shader {
MAX = 6
};
Shader(Core::Pass pass, int *def, int defCount) : GAPI::Shader() {
init(pass, def, defCount);
Shader(Core::Pass pass, Type type, int *def, int defCount) : GAPI::Shader() {
init(pass, type, def, defCount);
}
virtual ~Shader() {

View File

@@ -1,15 +1,15 @@
#include "common.hlsl"
struct VS_OUTPUT {
float4 wPos : POSITION;
float3 vCoord : TEXCOORD2;
float4 vTexCoord : TEXCOORD0;
float4 vDiffuse : COLOR0;
float4 vNormal : NORMAL;
float4 vViewVec : TEXCOORD1;
float3 vAmbient : COLOR1;
float4 vLightMap : COLOR2;
float4 vLight : COLOR3;
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;
};
#ifdef VERTEX
@@ -20,38 +20,262 @@ float3 mulQuat(float4 q, float3 v) {
float3 mulBasis(float4 rot, float3 pos, float3 v) {
return mulQuat(rot, v) + pos;
}
float3 calcAmbient(float3 n) {
float3 sqr = n * n;
float3 pos = step(0.0, n);
return sqr.x * lerp(uAmbient[1].xyz, uAmbient[0].xyz, pos.x) +
sqr.y * lerp(uAmbient[3].xyz, uAmbient[2].xyz, pos.y) +
sqr.z * lerp(uAmbient[5].xyz, uAmbient[4].xyz, pos.z);
}
VS_OUTPUT main(VS_INPUT In) {
VS_OUTPUT Out;
Out.ambient = 0.0;
Out.lightMap = 0.0;
Out.light = 0.0;
int index = int(In.aCoord.w * 2.0);
float4 rBasisRot = uBasis[index];
float4 rBasisPos = uBasis[index + 1];
Out.vCoord = mulBasis(rBasisRot, rBasisPos.xyz, In.aCoord.xyz);
Out.wPos = mul(uViewProj, float4(Out.vCoord, rBasisPos.w));
Out.vTexCoord = In.aTexCoord * (1.0 / 32767.0);
Out.vTexCoord.xy *= Out.vTexCoord.zw;
Out.texCoord = In.aTexCoord * (1.0 / 32767.0);
if (TYPE_SPRITE) {
Out.coord = mulBasis(rBasisRot, rBasisPos.xyz + In.aCoord.xyz, float3(In.aTexCoord.z, In.aTexCoord.w, 0.0));
} else {
Out.coord = mulBasis(rBasisRot, rBasisPos.xyz, In.aCoord.xyz);
Out.texCoord.xy *= Out.texCoord.zw;
}
#ifdef PASS_SHADOW
Out.viewVec = 0.0;
Out.normal = 0.0;
Out.diffuse = 0.0;
#else
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 {
Out.normal.xyz = mulQuat(rBasisRot, normalize(In.aNormal.xyz));
}
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;
float3 lv3 = (uLightPos[3].xyz - Out.coord) * uLightColor[3].w;
float4 lum, att;
if (TYPE_ENTITY) {
lum.x = dot(Out.normal.xyz, normalize(lv0));
att.x = dot(lv0, lv0);
if (OPT_AMBIENT) {
Out.ambient = calcAmbient(Out.normal.xyz);
} else {
Out.ambient = min(uMaterial.yyy, In.aLight.xyz);
}
} else {
if (TYPE_SPRITE) {
lum.x = uMaterial.y;
} else {
lum.x = 1.0;
}
att.x = 0.0;
Out.ambient = min(uMaterial.yyy, In.aLight.zyx);
}
float4 light;
lum.y = dot(Out.normal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
lum.z = dot(Out.normal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
lum.w = dot(Out.normal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
light = max(0.0, lum) * max(0.0, 1.0 - att);
if (UNDERWATER) {
light.x *= abs(sin(dot(Out.coord.xyz, 1.0 / 512.0) + uParam.x)) * 1.5 + 0.5;
float d;
if (uViewPos.y < uParam.y) {
d = abs((Out.coord.y - uParam.y) / normalize(Out.viewVec.xyz).y);
} else {
d = length(uViewPos.xyz - Out.coord.xyz);
}
fog = d * WATER_FOG_DIST;
} else {
fog = length(Out.viewVec.xyz);
}
Out.normal.w = saturate(1.0 / exp(fog));
if (OPT_SHADOW) {
Out.light = light;
Out.lightMap = In.aLight.zyxw * light.x;
} else {
Out.light.xyz = uLightColor[1].xyz * light.y + uLightColor[2].xyz * light.z + uLightColor[3].xyz * light.w;
Out.light.w = 0.0;
if (TYPE_ENTITY) {
Out.light.xyz += Out.ambient + uLightColor[0].xyz * light.x;
} else {
Out.light.xyz += In.aLight.xyz * light.x;
}
}
} else
Out.normal.w = 1.0;
#else
Out.normal = In.aNormal;
Out.light = float4(In.aLight.xyz, 1.0);
#endif
if (TYPE_MIRROR) {
Out.diffuse = uMaterial;
} else {
Out.diffuse = float4(In.aColor.zyx * (uMaterial.x * 1.8), uMaterial.w);
if (UNDERWATER) {
Out.diffuse.xyz *= UNDERWATER_COLOR;
}
if (TYPE_FLASH) {
Out.diffuse.xyz += uMaterial.w;
}
}
#endif
Out.wpos = mul(uViewProj, float4(Out.coord, rBasisPos.w));
Out.vDiffuse = float4(In.aColor.xyz * (uMaterial.x), uMaterial.w);
Out.vNormal = In.aNormal;
Out.vViewVec = float4(uViewPos.xyz - Out.vCoord, 0.0);
Out.vAmbient = float3(0.2, 0.2, 0.2);
Out.vLightMap = In.aLight;
Out.vLight = float4(0.5, 0.5, 0.5, 0.5);
return Out;
}
#else // PIXEL
sampler sDiffuse : register(s0);
sampler sNormal : register(s1);
sampler sReflect : register(s2);
sampler sShadow : register(s3);
sampler sEnvironment : register(s4);
sampler sMask : register(s5);
float getShadow(float3 lightVec) {
return 1.0;
}
float getContactAO(float3 p, float3 n) {
float res = 1.0;
for (int i = 0; i < MAX_CONTACTS; i++) {
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);
}
return res;
}
float calcCaustics(float3 coord, float3 n) {
float2 cc = saturate((coord.xz - uRoomSize.xy) / uRoomSize.zw);
return tex2D(sReflect, cc).x * max(0.0, -n.y);
}
float calcSpecular(float3 normal, float3 viewVec, float3 lightVec, float4 color, float intensity) {
float3 vv = normalize(viewVec);
float3 rv = reflect(-vv, normal);
float3 lv = normalize(lightVec);
return pow(max(0.0, dot(rv, lv)), 8.0) * intensity;
}
float4 main(VS_OUTPUT In) : COLOR0 {
return (In.vDiffuse * In.vLightMap * tex2D(sDiffuse, In.vTexCoord.xy / In.vTexCoord.zw)).bgra;
float2 uv = In.texCoord.xy;
#ifdef PASS_COMPOSE
if (CLIP_PLANE) {
if (In.viewVec.w > uParam.w) {
discard;
}
}
if (!TYPE_SPRITE) {
uv /= In.texCoord.zw;
}
#endif
float4 color;
if (TYPE_MIRROR) {
float3 rv = reflect(-normalize(In.viewVec.xyz), normalize(In.normal.xyz));
color = texCUBE(sEnvironment, normalize(rv));
} else {
color = tex2D(sDiffuse, uv).bgra;
if (ALPHA_TEST) {
if (color.w <= 0.5)
discard;
}
}
#ifdef PASS_SHADOW
return 1.0;
#else
color *= In.diffuse;
if (TYPE_FLASH) {
return color;
}
if (TYPE_MIRROR) {
return color;
}
#ifdef PASS_AMBIENT
color.xyz *= In.light.xyz;
#endif
#ifdef PASS_COMPOSE
float3 lightVec = (uLightPos[0].xyz - In.coord) * uLightColor[0].w;
float3 normal = normalize(In.normal.xyz);
float rSpecular = 0.0;
float3 light;
if (OPT_SHADOW) {
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);
rSpecular = (uMaterial.z + 0.03) * rShadow;
light += In.ambient + uLightColor[0].xyz * (In.light.x * rShadow);
} else if (TYPE_ROOM) {
float rShadow = getShadow(lightVec);
light += lerp(In.ambient.xyz, In.lightMap.xyz, rShadow);
} else if (TYPE_SPRITE) {
light += In.lightMap.xyz;
}
} else {
light = In.light.xyz;
}
if (OPT_CAUSTICS) {
light += calcCaustics(In.coord, normal);
}
if (OPT_CONTACT) {
light *= getContactAO(In.coord, normal) * 0.5 + 0.5;
}
color.xyz *= light;
if (TYPE_ENTITY) {
color.xyz += calcSpecular(normal, In.viewVec.xyz, lightVec, uLightColor[0], rSpecular);
}
if (UNDERWATER) {
color.xyz = lerp(UNDERWATER_COLOR * 0.2, color.xyz, In.normal.w);
} else {
color.xyz = lerp(uFogParams.xyz, color.xyz, In.normal.w);
}
#endif
#endif
return color;
}
#endif

View File

@@ -1,5 +1,7 @@
#define MAX_LIGHTS 4
#define MAX_CONTACTS 15
#define MAX_LIGHTS 4
#define MAX_CONTACTS 15
#define WATER_FOG_DIST (1.0 / (6.0 * 1024.0))
#define UNDERWATER_COLOR float3(0.6, 0.9, 0.9)
struct VS_INPUT {
float4 aCoord : POSITION;
@@ -9,18 +11,55 @@ struct VS_INPUT {
float4 aLight : COLOR1;
};
int4 uInfo : register( c0 );
float4 uParam : register( c1 );
float4 uTexParam : register( c2 );
float4x4 uViewProj : register( c3 );
float4 uBasis[32 * 2] : register( c7 );
float4x4 uLightProj : register( c71 );
float4 uMaterial : register( c103 );
float4 uAmbient[6] : register( c104 );
float4 uFogParams : register( c110 );
float4 uViewPos : register( c111 );
float4 uLightPos[MAX_LIGHTS] : register( c112 );
float4 uLightColor[MAX_LIGHTS] : register( c116 );
float4 uRoomSize : register( c120 );
float4 uPosScale[2] : register( c121 );
float4 uContacts[MAX_CONTACTS] : register( c123 );
#ifdef PIXEL
sampler sDiffuse : register(s0);
sampler sNormal : register(s1);
sampler sReflect : register(s2);
sampler sShadow : register(s3);
sampler sEnvironment : register(s4);
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 );
#define TYPE_SPRITE uFlags[0]
#define TYPE_FLASH uFlags[1]
#define TYPE_ROOM uFlags[2]
#define TYPE_ENTITY uFlags[3]
#define TYPE_MIRROR uFlags[4]
#define FILTER_DEFAULT uFlags[0]
#define FILTER_DOWNSAMPLE uFlags[1]
#define FILTER_GRAYSCALE uFlags[2]
#define FILTER_BLUR uFlags[3]
#define FILTER_EQUIRECTANGULAR uFlags[4]
#define WATER_DROP uFlags[0]
#define WATER_STEP uFlags[1]
#define WATER_CAUSTICS uFlags[2]
#define WATER_MASK uFlags[3]
#define WATER_COMPOSE uFlags[4]
// options for compose, shadow, ambient passes
#define UNDERWATER uFlags[5]
#define ALPHA_TEST uFlags[6]
#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]

View File

@@ -1,6 +1,10 @@
@echo off
fxc /nologo /T vs_3_0 /O3 /Vn BASE_VS /Fh base_vs.h base.hlsl /DVERTEX
fxc /nologo /T ps_3_0 /O3 /Vn BASE_PS /Fh base_ps.h base.hlsl /DPIXEL
fxc /nologo /T vs_3_0 /O3 /Vn COMPOSE_VS /Fh compose_vs.h base.hlsl /DPASS_COMPOSE /DVERTEX
fxc /nologo /T ps_3_0 /O3 /Vn COMPOSE_PS /Fh compose_ps.h base.hlsl /DPASS_COMPOSE /DPIXEL
fxc /nologo /T vs_3_0 /O3 /Vn SHADOW_VS /Fh shadow_vs.h base.hlsl /DPASS_SHADOW /DVERTEX
fxc /nologo /T ps_3_0 /O3 /Vn SHADOW_PS /Fh shadow_ps.h base.hlsl /DPASS_SHADOW /DPIXEL
fxc /nologo /T vs_3_0 /O3 /Vn AMBIENT_VS /Fh ambient_vs.h base.hlsl /DPASS_AMBIENT /DVERTEX
fxc /nologo /T ps_3_0 /O3 /Vn AMBIENT_PS /Fh ambient_ps.h base.hlsl /DPASS_AMBIENT /DPIXEL
fxc /nologo /T vs_3_0 /O3 /Vn WATER_VS /Fh water_vs.h water.hlsl /DVERTEX
fxc /nologo /T ps_3_0 /O3 /Vn WATER_PS /Fh water_ps.h water.hlsl /DPIXEL
fxc /nologo /T vs_3_0 /O3 /Vn FILTER_VS /Fh filter_vs.h filter.hlsl /DVERTEX

View File

@@ -23,13 +23,11 @@ uniform vec4 uParam;
uniform sampler2D sNormal;
vec4 downsample() { // uParam (textureSize, unused, unused, unused)
float k = 1.0 / uParam.x; // inverted texture size
vec4 color = vec4(0.0);
for (float y = -1.5; y < 2.0; y++)
for (float x = -1.5; x < 2.0; x++) {
vec4 p;
p.xyz = texture2D(sDiffuse, vTexCoord + vec2(x, y) * k).xyz;
p.xyz = texture2D(sDiffuse, vTexCoord + vec2(x, y) * uParam.x).xyz;
p.w = dot(p.xyz, vec3(0.299, 0.587, 0.114));
p.xyz *= p.w;
color += p;

View File

@@ -1,25 +1,77 @@
#include "common.hlsl"
struct VS_OUTPUT {
float4 wPos : POSITION;
float2 vTexCoord : TEXCOORD0;
float4 vDiffuse : COLOR0;
float4 wpos : POSITION;
float2 texCoord : TEXCOORD0;
float4 diffuse : COLOR0;
};
#ifdef VERTEX
VS_OUTPUT main(VS_INPUT In) {
VS_OUTPUT Out;
Out.wPos = float4(In.aCoord.xy * (1.0 / 32767.0), 0.0, 1.0);
Out.vTexCoord = In.aTexCoord.xy * (1.0 / 32767.0);
Out.vDiffuse = In.aLight;
Out.wpos = float4(In.aCoord.xy * (1.0 / 32767.0), 0.0, 1.0);
Out.texCoord = In.aTexCoord.xy * (1.0 / 32767.0);
Out.diffuse = In.aLight;
// D3D9 specific
if (FILTER_DOWNSAMPLE) {
Out.texCoord += float2(2.0, -2.0) * uParam.x;
} else if (FILTER_BLUR) {
Out.texCoord += float2(1.0, -1.0) * uParam.z;
}
return Out;
}
#else // PIXEL
sampler sDiffuse : register(s0);
float4 downsample(float2 uv) { // uParam (1 / textureSize, unused, unused, unused)
float4 color = 0.0;
[unroll]
for (float y = -1.5; y < 2.0; y++) {
[unroll]
for (float x = -1.5; x < 2.0; x++) {
float4 p;
p.xyz = tex2D(sDiffuse, uv + float2(x, y) * uParam.x).xyz;
p.w = dot(p.xyz, float3(0.299, 0.587, 0.114));
p.xyz *= p.w;
color += p;
}
}
return float4(color.xyz / color.w, 1.0);
}
float4 grayscale(float2 uv) { // uParam (factor, unused, unused, unused)
float4 color = tex2D(sDiffuse, uv);
float3 gray = dot(color, float4(0.299, 0.587, 0.114, 0.0));
return float4(lerp(color.xyz, gray, uParam.x), color.w);
}
float4 blur(float2 uv) { // uParam (dirX, dirY, 1 / textureSize, unused)
const float3 offset = float3( 0.0, 1.3846153846, 3.2307692308);
const float3 weight = float3(0.2270270270, 0.3162162162, 0.0702702703);
float2 dir = uParam.xy * uParam.z;
float4 color = tex2D(sDiffuse, uv) * weight[0];
color += tex2D(sDiffuse, uv + dir * offset[1]) * weight[1];
color += tex2D(sDiffuse, uv - dir * offset[1]) * weight[1];
color += tex2D(sDiffuse, uv + dir * offset[2]) * weight[2];
color += tex2D(sDiffuse, uv - dir * offset[2]) * weight[2];
return color;
}
float4 main(VS_OUTPUT In) : COLOR0 {
return (In.vDiffuse * tex2D(sDiffuse, In.vTexCoord.xy)).bgra;
if (FILTER_DOWNSAMPLE)
return downsample(In.texCoord.xy);
if (FILTER_GRAYSCALE)
return grayscale(In.texCoord.xy);
if (FILTER_BLUR)
return blur(In.texCoord.xy);
return (tex2D(sDiffuse, In.texCoord.xy) * In.diffuse).bgra;
}
#endif

View File

@@ -17,8 +17,6 @@ VS_OUTPUT main(VS_INPUT In) {
#else // PIXEL
sampler sDiffuse : register(s0);
float4 main(VS_OUTPUT In) : COLOR0 {
return (In.vDiffuse * tex2D(sDiffuse, In.vTexCoord.xy)).bgra;
}

View File

@@ -402,7 +402,6 @@ uniform vec4 uFogParams;
color *= vDiffuse;
#if !defined(TYPE_FLASH) && !defined(TYPE_MIRROR)
vec3 lightVec = (uLightPos[0].xyz - vCoord) * uLightColor[0].w;
#ifdef PASS_AMBIENT
color.xyz *= vLight.xyz;
@@ -410,7 +409,8 @@ uniform vec4 uFogParams;
#ifdef PASS_COMPOSE
vec3 n = normalize(vNormal.xyz);
vec3 lightVec = (uLightPos[0].xyz - vCoord) * uLightColor[0].w;
vec3 normal = normalize(vNormal.xyz);
#ifdef TYPE_ENTITY
float rSpecular = uMaterial.z + 0.03;
@@ -441,17 +441,17 @@ uniform vec4 uFogParams;
#endif
#ifdef OPT_CAUSTICS
light += calcCaustics(n);
light += calcCaustics(normal);
#endif
#ifdef OPT_CONTACT
light *= getContactAO(vCoord, n) * 0.5 + 0.5;
light *= getContactAO(vCoord, normal) * 0.5 + 0.5;
#endif
color.xyz *= light;
#ifdef TYPE_ENTITY
color.xyz += calcSpecular(n, vViewVec.xyz, lightVec.xyz, uLightColor[0], rSpecular);
color.xyz += calcSpecular(normal, vViewVec.xyz, lightVec, uLightColor[0], rSpecular);
#endif
#ifdef UNDERWATER

View File

@@ -44,13 +44,6 @@ VS_OUTPUT main(VS_INPUT In) {
#else // PIXEL
sampler sDiffuse : register(s0);
sampler sNormal : register(s1);
sampler sReflect : register(s2);
sampler sShadow : register(s3);
sampler sEnvironment : register(s4);
sampler sMask : register(s5);
float4 main(VS_OUTPUT In) : COLOR0 {
return (In.vDiffuse * tex2D(sDiffuse, In.vTexCoord.xy / In.vTexCoord.zw)).bgra;
}

View File

@@ -762,7 +762,7 @@ struct Crystal : Controller {
Texture *environment;
Crystal(IGame *game, int entity) : Controller(game, entity) {
environment = new Texture(64, 64, FMT_RGBA, OPT_CUBEMAP | OPT_MIPMAPS);
environment = new Texture(64, 64, FMT_RGBA, OPT_CUBEMAP | OPT_MIPMAPS | OPT_TARGET);
activate();
}