mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-11 15:45:05 +02:00
19
src/cache.h
19
src/cache.h
@@ -17,12 +17,16 @@ const char SHADER[] =
|
||||
#include "shader.glsl"
|
||||
;
|
||||
|
||||
const char WATER[] =
|
||||
#include "water.glsl"
|
||||
;
|
||||
|
||||
const char FILTER[] =
|
||||
#include "filter.glsl"
|
||||
;
|
||||
|
||||
const char WATER[] =
|
||||
#include "water.glsl"
|
||||
const char VOLUME[] =
|
||||
#include "volume.glsl"
|
||||
;
|
||||
|
||||
const char GUI[] =
|
||||
@@ -113,7 +117,7 @@ struct ShaderCache {
|
||||
}
|
||||
}
|
||||
|
||||
const char *passNames[] = { "COMPOSE", "SHADOW", "AMBIENT", "WATER", "FILTER", "GUI" };
|
||||
const char *passNames[] = { "COMPOSE", "SHADOW", "AMBIENT", "WATER", "FILTER", "VOLUME", "GUI" };
|
||||
const char *src = NULL;
|
||||
const char *typ = NULL;
|
||||
switch (pass) {
|
||||
@@ -146,12 +150,19 @@ struct ShaderCache {
|
||||
break;
|
||||
}
|
||||
case Core::passFilter : {
|
||||
static const char *typeNames[] = { "DOWNSAMPLE" };
|
||||
static const char *typeNames[] = { "DEFAULT", "DOWNSAMPLE" };
|
||||
src = FILTER;
|
||||
typ = typeNames[type];
|
||||
sprintf(def, "%s#define PASS_%s\n#define FILTER_%s\n", ext, passNames[pass], typ);
|
||||
break;
|
||||
}
|
||||
case Core::passVolume : {
|
||||
static const char *typeNames[] = { "DEFAULT" };
|
||||
src = VOLUME;
|
||||
typ = typeNames[type];
|
||||
sprintf(def, "%s#define PASS_%s\n", ext, passNames[pass]);
|
||||
break;
|
||||
}
|
||||
case Core::passGUI : {
|
||||
static const char *typeNames[] = { "DEFAULT" };
|
||||
src = GUI;
|
||||
|
@@ -26,7 +26,7 @@ struct IGame {
|
||||
virtual void waterDrop(const vec3 &pos, float radius, float strength) {}
|
||||
virtual void setShader(Core::Pass pass, Shader::Type type, bool underwater = false, bool alphaTest = false) {}
|
||||
virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0) {}
|
||||
virtual void renderCompose(int roomIndex) {}
|
||||
virtual void renderCompose(int roomIndex, bool genShadowMask = false) {}
|
||||
};
|
||||
|
||||
struct Controller {
|
||||
@@ -489,23 +489,6 @@ struct Controller {
|
||||
}
|
||||
|
||||
void renderShadow(MeshBuilder *mesh, const vec3 &pos, const vec3 &offset, const vec3 &size, float angle) {
|
||||
/*
|
||||
mat4 m;
|
||||
m.identity();
|
||||
m.translate(pos);
|
||||
m.rotateY(angle);
|
||||
m.translate(vec3(offset.x, 0.0f, offset.z));
|
||||
m.scale(vec3(size.x, 0.0f, size.z) * (1.0f / 1024.0f));
|
||||
|
||||
game->setShader(Core::pass, Shader::FLASH, false, false);
|
||||
Core::active.shader->setParam(uBasis, Basis(m));
|
||||
Core::active.shader->setParam(uColor, vec4(0.5f, 0.5f, 0.5f, 1.0f));
|
||||
Core::active.shader->setParam(uAmbient, vec3(0.0f));
|
||||
|
||||
Core::setBlending(bmMultiply);
|
||||
mesh->renderShadowSpot();
|
||||
Core::setBlending(bmNone);
|
||||
*/
|
||||
mat4 m = Core::mViewProj;
|
||||
m.translate(pos);
|
||||
m.rotateY(angle);
|
||||
@@ -522,7 +505,7 @@ struct Controller {
|
||||
Core::active.shader->setParam(uAmbient, vec3(0.0f));
|
||||
|
||||
Core::setBlending(bmAlpha);
|
||||
mesh->renderShadowSpot();
|
||||
mesh->renderShadowBlob();
|
||||
Core::setBlending(bmNone);
|
||||
|
||||
Core::active.shader->setParam(uViewProj, Core::mViewProj);
|
||||
|
86
src/core.h
86
src/core.h
@@ -79,8 +79,10 @@
|
||||
#define GL_RGBA16F GL_RGBA
|
||||
#define GL_HALF_FLOAT GL_HALF_FLOAT_OES
|
||||
|
||||
#define glGetProgramBinary(...) 0
|
||||
#define glProgramBinary(...) 0
|
||||
#define GL_STENCIL_TEST_TWO_SIDE_EXT 0
|
||||
#define glGetProgramBinary(...)
|
||||
#define glProgramBinary(...)
|
||||
#define glActiveStencilFaceEXT(...)
|
||||
#endif
|
||||
|
||||
#include "utils.h"
|
||||
@@ -158,6 +160,10 @@
|
||||
PFNGLDELETEBUFFERSARBPROC glDeleteBuffers;
|
||||
PFNGLBINDBUFFERARBPROC glBindBuffer;
|
||||
PFNGLBUFFERDATAARBPROC glBufferData;
|
||||
// Stencil
|
||||
PFNGLACTIVESTENCILFACEEXTPROC glActiveStencilFaceEXT;
|
||||
PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate;
|
||||
PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate;
|
||||
#endif
|
||||
|
||||
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
|
||||
@@ -180,6 +186,7 @@ struct Texture;
|
||||
|
||||
namespace Core {
|
||||
struct {
|
||||
bool shaderBinary;
|
||||
bool VAO;
|
||||
bool depthTexture;
|
||||
bool shadowSampler;
|
||||
@@ -187,7 +194,7 @@ namespace Core {
|
||||
bool texNPOT;
|
||||
bool texFloat, texFloatLinear;
|
||||
bool texHalf, texHalfLinear;
|
||||
bool shaderBinary;
|
||||
char stencil;
|
||||
#ifdef PROFILE
|
||||
bool profMarker;
|
||||
bool profTiming;
|
||||
@@ -254,7 +261,7 @@ namespace Core {
|
||||
|
||||
Texture *blackTex, *whiteTex;
|
||||
|
||||
enum Pass { passCompose, passShadow, passAmbient, passWater, passFilter, passGUI, passMAX } pass;
|
||||
enum Pass { passCompose, passShadow, passAmbient, passWater, passFilter, passVolume, passGUI, passMAX } pass;
|
||||
|
||||
GLuint FBO;
|
||||
struct RenderTargetCache {
|
||||
@@ -274,6 +281,7 @@ namespace Core {
|
||||
GLuint VAO;
|
||||
BlendMode blendMode;
|
||||
CullMode cullMode;
|
||||
bool stencilTwoSide;
|
||||
} active;
|
||||
|
||||
struct Stats {
|
||||
@@ -312,7 +320,6 @@ namespace Core {
|
||||
|
||||
#include "texture.h"
|
||||
#include "shader.h"
|
||||
#include "mesh.h"
|
||||
|
||||
namespace Core {
|
||||
|
||||
@@ -379,6 +386,10 @@ namespace Core {
|
||||
GetProcOGL(glDeleteBuffers);
|
||||
GetProcOGL(glBindBuffer);
|
||||
GetProcOGL(glBufferData);
|
||||
|
||||
GetProcOGL(glActiveStencilFaceEXT);
|
||||
GetProcOGL(glStencilFuncSeparate);
|
||||
GetProcOGL(glStencilOpSeparate);
|
||||
#endif
|
||||
|
||||
#ifdef MOBILE
|
||||
@@ -395,7 +406,7 @@ namespace Core {
|
||||
char *ext = (char*)glGetString(GL_EXTENSIONS);
|
||||
//LOG("%s\n", ext);
|
||||
|
||||
support.shaderBinary = extSupport(ext, "_program_binary");
|
||||
support.shaderBinary = false;//extSupport(ext, "_program_binary");
|
||||
support.VAO = extSupport(ext, "_vertex_array_object");
|
||||
support.depthTexture = extSupport(ext, "_depth_texture");
|
||||
support.shadowSampler = extSupport(ext, "_shadow_samplers") || extSupport(ext, "GL_ARB_shadow");
|
||||
@@ -405,6 +416,15 @@ namespace Core {
|
||||
support.texFloat = support.texFloatLinear || extSupport(ext, "_texture_float");
|
||||
support.texHalfLinear = extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_half_float_linear");
|
||||
support.texHalf = support.texHalfLinear || extSupport(ext, "_texture_half_float");
|
||||
|
||||
if (extSupport(ext, "_ATI_separate_stencil"))
|
||||
support.stencil = 2;
|
||||
else
|
||||
if (extSupport(ext, "_stencil_two_side"))
|
||||
support.stencil = 1;
|
||||
else
|
||||
support.stencil = 0;
|
||||
|
||||
#ifdef PROFILE
|
||||
support.profMarker = extSupport(ext, "_KHR_debug");
|
||||
support.profTiming = extSupport(ext, "_timer_query");
|
||||
@@ -425,6 +445,7 @@ namespace Core {
|
||||
LOG(" float textures : float = %s, half = %s\n",
|
||||
support.texFloat ? (support.texFloatLinear ? "linear" : "nearest") : "false",
|
||||
support.texHalf ? (support.texHalfLinear ? "linear" : "nearest") : "false");
|
||||
LOG(" stencil : %s\n", support.stencil == 2 ? "separate" : (support.stencil == 1 ? "two_side" : "false"));
|
||||
LOG("\n");
|
||||
|
||||
glGenFramebuffers(1, &FBO);
|
||||
@@ -472,14 +493,14 @@ namespace Core {
|
||||
item.height = height;
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, item.ID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, depth ? GL_RGB : GL_DEPTH_COMPONENT16, width, height);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, depth ? GL_RGB565 : GL_DEPTH_COMPONENT16, width, height);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
|
||||
return cache.count++;
|
||||
}
|
||||
|
||||
void clear(bool clearColor, bool clearDepth) {
|
||||
if (GLbitfield mask = (clearColor ? GL_COLOR_BUFFER_BIT : 0) | (clearDepth ? GL_DEPTH_BUFFER_BIT : 0))
|
||||
void clear(bool clearColor, bool clearDepth, bool clearStencil = false) {
|
||||
if (GLbitfield mask = (clearColor ? GL_COLOR_BUFFER_BIT : 0) | (clearDepth ? GL_DEPTH_BUFFER_BIT : 0) | (clearStencil ? GL_STENCIL_BUFFER_BIT : 0))
|
||||
glClear(mask);
|
||||
}
|
||||
|
||||
@@ -487,6 +508,10 @@ namespace Core {
|
||||
glClearColor(color.x, color.y, color.z, color.w);
|
||||
}
|
||||
|
||||
void setClearStencil(int value) {
|
||||
glClearStencil(value);
|
||||
}
|
||||
|
||||
void setViewport(int x, int y, int width, int height) {
|
||||
glViewport(x, y, width, height);
|
||||
}
|
||||
@@ -555,6 +580,47 @@ namespace Core {
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
|
||||
void setStencilTest(bool test) {
|
||||
if (test)
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
else
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
|
||||
void setStencilTwoSide(int ref, bool test) { // preset for z-fail shadow volumes
|
||||
active.stencilTwoSide = test;
|
||||
if (test) {
|
||||
switch (Core::support.stencil) {
|
||||
case 0 :
|
||||
glStencilFunc(GL_ALWAYS, ref, ~0);
|
||||
break;
|
||||
case 1 :
|
||||
setCulling(cfNone);
|
||||
glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
glActiveStencilFaceEXT(GL_BACK);
|
||||
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
||||
glStencilFunc(GL_ALWAYS, ref, ~0);
|
||||
glActiveStencilFaceEXT(GL_FRONT);
|
||||
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
||||
glStencilFunc(GL_ALWAYS, ref, ~0);
|
||||
break;
|
||||
case 2 :
|
||||
setCulling(cfNone);
|
||||
glStencilFuncSeparate(GL_FRONT, GL_ALWAYS, ref, ~0);
|
||||
glStencilFuncSeparate(GL_BACK, GL_ALWAYS, ref, ~0);
|
||||
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_INCR, GL_KEEP);
|
||||
glStencilOpSeparate(GL_BACK, GL_KEEP, GL_DECR, GL_KEEP);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (Core::support.stencil == 1)
|
||||
glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilFunc(GL_NOTEQUAL, ref, ~0);
|
||||
setCulling(cfFront);
|
||||
}
|
||||
}
|
||||
|
||||
void invalidateTarget(bool color, bool depth) {
|
||||
#ifdef MOBILE
|
||||
if (support.discardFrame && (color || depth)) {
|
||||
@@ -619,4 +685,6 @@ namespace Core {
|
||||
}
|
||||
}
|
||||
|
||||
#include "mesh.h"
|
||||
|
||||
#endif
|
||||
|
54
src/level.h
54
src/level.h
@@ -86,7 +86,7 @@ struct Level : IGame {
|
||||
}
|
||||
}
|
||||
|
||||
virtual void renderCompose(int roomIndex) {
|
||||
virtual void renderCompose(int roomIndex, bool genShadowMask = false) {
|
||||
PROFILE_MARKER("PASS_COMPOSE");
|
||||
Core::pass = Core::passCompose;
|
||||
|
||||
@@ -95,6 +95,51 @@ struct Level : IGame {
|
||||
if (shadow)
|
||||
shadow->bind(sShadow);
|
||||
renderScene(roomIndex);
|
||||
|
||||
if (genShadowMask) {
|
||||
// renderShadowVolumes();
|
||||
}
|
||||
}
|
||||
|
||||
void renderShadowVolumes() {
|
||||
getLight(lara->pos, lara->getRoomIndex());
|
||||
|
||||
Core::setCulling(cfNone);
|
||||
Core::setDepthWrite(false);
|
||||
Core::setColorWrite(false, false, false, false);
|
||||
|
||||
Core::setStencilTest(true);
|
||||
Core::setStencilTwoSide(128, true);
|
||||
|
||||
setShader(Core::passVolume, Shader::DEFAULT, false, false);
|
||||
vec4 lp(Core::lightPos[0], Core::lightColor[0].w);
|
||||
Core::active.shader->setParam(uLightPos, lp);
|
||||
|
||||
for (int i = 0; i < level.entitiesCount; i++) {
|
||||
TR::Entity &e = level.entities[i];
|
||||
if (e.flags.rendered && TR::castShadow(e.type)) {
|
||||
Controller *controller = (Controller*)e.controller;
|
||||
|
||||
mat4 matrix = controller->getMatrix();
|
||||
Box box = controller->animation.getBoundingBox(vec3(0.0f), 0);
|
||||
matrix.translate(box.center());
|
||||
|
||||
Core::active.shader->setParam(uBasis, Basis(matrix) );
|
||||
Core::active.shader->setParam(uPosScale, box.size() * 0.5);
|
||||
|
||||
mesh->renderShadowBox();
|
||||
}
|
||||
}
|
||||
|
||||
Core::setDepthWrite(true);
|
||||
Core::setColorWrite(true, true, true, true);
|
||||
|
||||
Core::setStencilTwoSide(128, false);
|
||||
|
||||
setShader(Core::passFilter, Shader::DEFAULT, false, false);
|
||||
mesh->renderQuad();
|
||||
|
||||
Core::setStencilTest(false);
|
||||
}
|
||||
//==============================
|
||||
|
||||
@@ -739,14 +784,15 @@ struct Level : IGame {
|
||||
if (shadow)
|
||||
renderShadows(lara->getRoomIndex());
|
||||
|
||||
Core::setClearStencil(128);
|
||||
Core::setTarget(NULL);
|
||||
Core::clear(true, true);
|
||||
Core::clear(true, true, true);
|
||||
Core::setViewport(0, 0, Core::width, Core::height);
|
||||
|
||||
if (waterCache)
|
||||
waterCache->checkVisibility = true;
|
||||
|
||||
renderCompose(camera->getRoomIndex());
|
||||
renderCompose(camera->getRoomIndex(), true);
|
||||
|
||||
if (waterCache) {
|
||||
waterCache->checkVisibility = false;
|
||||
@@ -825,7 +871,7 @@ struct Level : IGame {
|
||||
Core::setDepthTest(true);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
91
src/mesh.h
91
src/mesh.h
@@ -90,13 +90,25 @@ struct Mesh {
|
||||
glEnableVertexAttribArray(aColor);
|
||||
}
|
||||
|
||||
void render(const MeshRange &range) {
|
||||
range.bind(VAO);
|
||||
void DIP(const MeshRange &range) {
|
||||
glDrawElements(GL_TRIANGLES, range.iCount, GL_UNSIGNED_SHORT, (GLvoid*)(range.iStart * sizeof(Index)));
|
||||
|
||||
Core::stats.dips++;
|
||||
Core::stats.tris += range.iCount / 3;
|
||||
}
|
||||
|
||||
void render(const MeshRange &range) {
|
||||
range.bind(VAO);
|
||||
|
||||
if (Core::active.stencilTwoSide && Core::support.stencil == 0) {
|
||||
Core::setCulling(cfBack);
|
||||
glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
|
||||
DIP(range);
|
||||
Core::setCulling(cfFront);
|
||||
glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
|
||||
}
|
||||
|
||||
DIP(range);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -145,7 +157,7 @@ struct MeshBuilder {
|
||||
} *models;
|
||||
MeshRange *sequences;
|
||||
// procedured
|
||||
MeshRange shadowBlob;
|
||||
MeshRange shadowBlob, shadowBox;
|
||||
MeshRange bar;
|
||||
MeshRange quad, circle;
|
||||
MeshRange plane;
|
||||
@@ -231,13 +243,20 @@ struct MeshBuilder {
|
||||
vCount += level.spriteSequences[i].sCount * 4;
|
||||
}
|
||||
|
||||
// get size of simple shadow spot mesh (8 triangles, 8 vertices)
|
||||
// shadow blob mesh (8 triangles, 8 vertices)
|
||||
shadowBlob.vStart = vCount;
|
||||
shadowBlob.iStart = iCount;
|
||||
shadowBlob.iCount = 8 * 3;
|
||||
iCount += shadowBlob.iCount;
|
||||
vCount += 8;
|
||||
|
||||
// shadow box (for stencil shadow volumes with degenerate triangles)
|
||||
shadowBox.vStart = vCount;
|
||||
shadowBox.iStart = iCount;
|
||||
shadowBox.iCount = (3 * (2 + 4)) * 6;
|
||||
iCount += shadowBox.iCount;
|
||||
vCount += 4 * 6;
|
||||
|
||||
// bar (health, oxygen)
|
||||
bar.vStart = vCount;
|
||||
bar.iStart = iCount;
|
||||
@@ -350,7 +369,7 @@ struct MeshBuilder {
|
||||
}
|
||||
aCount += level.spriteSequencesCount;
|
||||
|
||||
// build shadow spot
|
||||
// build shadow blob
|
||||
for (int i = 0; i < 8; i++) {
|
||||
Vertex &v = vertices[vCount + i];
|
||||
v.normal = { 0, -1, 0, 1 };
|
||||
@@ -371,6 +390,59 @@ struct MeshBuilder {
|
||||
iCount += shadowBlob.iCount;
|
||||
aCount++;
|
||||
|
||||
// build shadow box volume
|
||||
{
|
||||
static const Index tmpIndices[] = {
|
||||
0,1,2, 0,2,3, 0,7,1, 0,4,7,
|
||||
1,11,2, 1,8,11, 2,15,3, 2,12,15,
|
||||
3,19,0, 3,16,19, 21,6,5, 21,20,6,
|
||||
20,10,9, 20,23,10, 23,14,13, 23,22,14,
|
||||
22,18,17, 22,21,18, 20,21,22, 20,22,23,
|
||||
7,6,9, 7,9,8, 11,10,13, 11,13,12,
|
||||
15,14,17, 15,17,16, 19,5,4, 19,18,5,
|
||||
4,6,7, 4,5,6, 8,9,10, 8,10,11,
|
||||
12,14,15, 12,13,14, 16,18,19, 16,17,18
|
||||
};
|
||||
static const short4 tmpCoords[] = {
|
||||
{ -1, -1, -1, 0 }, { 1, -1, -1, 0 }, { 1, 1, -1, 0 }, { -1, 1, -1, 0 },
|
||||
{ -1, -1, -1, 0 }, { -1, -1, 1, 0 }, { 1, -1, 1, 0 }, { 1, -1, -1, 0 },
|
||||
{ 1, -1, -1, 0 }, { 1, -1, 1, 0 }, { 1, 1, 1, 0 }, { 1, 1, -1, 0 },
|
||||
{ 1, 1, -1, 0 }, { 1, 1, 1, 0 }, { -1, 1, 1, 0 }, { -1, 1, -1, 0 },
|
||||
{ -1, 1, -1, 0 }, { -1, 1, 1, 0 }, { -1, -1, 1, 0 }, { -1, -1, -1, 0 },
|
||||
{ 1, -1, 1, 0 }, { -1, -1, 1, 0 }, { -1, 1, 1, 0 }, { 1, 1, 1, 0 },
|
||||
};
|
||||
|
||||
const short n = 32767;
|
||||
static const short4 tmpNormals[] = {
|
||||
{ 0, 0, -n, 0 },
|
||||
{ 0, -n, 0, 0 },
|
||||
{ n, 0, 0, 0 },
|
||||
{ 0, n, 0, 0 },
|
||||
{ -n, 0, 0, 0 },
|
||||
{ 0, 0, n, 0 },
|
||||
};
|
||||
|
||||
static const ubyte4 tmpColors[] = {
|
||||
{ 255, 0, 0, 0 },
|
||||
{ 0, 255, 0, 0 },
|
||||
{ 0, 0, 255, 0 },
|
||||
{ 255, 0, 255, 0 },
|
||||
{ 255, 255, 0, 0 },
|
||||
{ 0, 255, 255, 0 },
|
||||
};
|
||||
|
||||
memcpy(&indices[iCount], &tmpIndices[0], shadowBox.iCount * sizeof(Index));
|
||||
memset(&vertices[vCount], 0, 4 * 6 * sizeof(Vertex));
|
||||
for (int i = 0; i < 4 * 6; i++) {
|
||||
vertices[vCount + i].coord = tmpCoords[i];
|
||||
vertices[vCount + i].normal = tmpNormals[i / 4];
|
||||
vertices[vCount + i].color = tmpColors[i / 4];
|
||||
}
|
||||
iCount += shadowBox.iCount;
|
||||
vCount += 4 * 6;
|
||||
aCount++;
|
||||
}
|
||||
|
||||
// white bar
|
||||
addQuad(indices, iCount, vCount, bar.vStart, vertices, &whiteTile);
|
||||
vertices[vCount + 0].coord = { 0, 0, 0, 0 };
|
||||
@@ -467,6 +539,7 @@ struct MeshBuilder {
|
||||
for (int i = 0; i < level.modelsCount; i++)
|
||||
mesh->initRange(models[i].geometry);
|
||||
mesh->initRange(shadowBlob);
|
||||
mesh->initRange(shadowBox);
|
||||
mesh->initRange(bar);
|
||||
mesh->initRange(quad);
|
||||
mesh->initRange(circle);
|
||||
@@ -856,12 +929,12 @@ struct MeshBuilder {
|
||||
mesh->render(range);
|
||||
}
|
||||
|
||||
void renderShadowSpot() {
|
||||
void renderShadowBlob() {
|
||||
mesh->render(shadowBlob);
|
||||
}
|
||||
|
||||
void renderLine(const vec2 &pos, const vec2 &size, uint32 color) {
|
||||
|
||||
void renderShadowBox() {
|
||||
mesh->render(shadowBox);
|
||||
}
|
||||
|
||||
void renderQuad() {
|
||||
|
@@ -218,6 +218,7 @@
|
||||
<None Include="..\..\filter.glsl" />
|
||||
<None Include="..\..\gui.glsl" />
|
||||
<None Include="..\..\shader.glsl" />
|
||||
<None Include="..\..\volume.glsl" />
|
||||
<None Include="..\..\water.glsl" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
@@ -57,9 +57,9 @@ struct Shader {
|
||||
vec4 params[uMAX][4];
|
||||
|
||||
enum Type : GLint {
|
||||
NONE = 0,
|
||||
DEFAULT = 0,
|
||||
/* shader */ SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4,
|
||||
/* filter */ FILTER_DOWNSAMPLE = 0,
|
||||
/* filter */ FILTER_DOWNSAMPLE = 1,
|
||||
/* water */ WATER_DROP = 0, WATER_STEP = 1, WATER_CAUSTICS = 2, WATER_MASK = 3, WATER_COMPOSE = 4,
|
||||
MAX = 5
|
||||
};
|
||||
|
17
src/ui.h
17
src/ui.h
@@ -66,13 +66,12 @@ struct UI {
|
||||
}
|
||||
|
||||
void update() {
|
||||
if (touch[zMove] != ikNone || touch[zLook] != ikNone || touch[zButton] != ikNone) {
|
||||
if (touchTimerTap > 0.0f)
|
||||
touchTimerTap = max(0.0f, touchTimerTap - Core::deltaTime);
|
||||
|
||||
if (touch[zMove] != ikNone || touch[zLook] != ikNone || touch[zButton] != ikNone)
|
||||
touchTimerVis = 30.0f;
|
||||
|
||||
if (touchTimerTap > 0.0f)
|
||||
touchTimerTap = max(0.0f, touchTimerTap - Core::deltaTime);
|
||||
|
||||
} else
|
||||
else
|
||||
if (touchTimerVis > 0.0f)
|
||||
touchTimerVis = max(0.0f, touchTimerVis - Core::deltaTime);
|
||||
|
||||
@@ -116,11 +115,11 @@ struct UI {
|
||||
if (t == ikNone) {
|
||||
t = key;
|
||||
if (zone == zMove) {
|
||||
if (touchTimerTap > 0.0f && touchTimerTap < 0.4f) { // 100 ms gap to reduce false positives (bad touch sensors)
|
||||
if (touchTimerTap > 0.0f && touchTimerTap < 0.3f) { // 100 ms gap to reduce false positives (bad touch sensors)
|
||||
doubleTap = true;
|
||||
touchTimerTap = 0.0f;
|
||||
} else
|
||||
touchTimerTap = 0.5f;
|
||||
touchTimerTap = 0.3f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -151,7 +150,7 @@ struct UI {
|
||||
|
||||
Core::mViewProj = mat4(0.0f, float(Core::width), float(Core::height), 0.0f, 0.0f, 1.0f);
|
||||
|
||||
game->setShader(Core::passGUI, Shader::NONE);
|
||||
game->setShader(Core::passGUI, Shader::DEFAULT);
|
||||
|
||||
float offset = Core::height * 0.25f;
|
||||
|
||||
|
Reference in New Issue
Block a user