mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-14 09:04:31 +02:00
Merge branch 'master' of https://github.com/XProger/OpenLara
This commit is contained in:
13
src/cache.h
13
src/cache.h
@@ -73,6 +73,8 @@ struct ShaderCache {
|
|||||||
compile(Core::passCompose, Shader::ENTITY, FX_CLIP_PLANE);
|
compile(Core::passCompose, Shader::ENTITY, FX_CLIP_PLANE);
|
||||||
compile(Core::passCompose, Shader::ENTITY, FX_UNDERWATER);
|
compile(Core::passCompose, Shader::ENTITY, FX_UNDERWATER);
|
||||||
compile(Core::passCompose, Shader::ENTITY, FX_UNDERWATER | FX_CLIP_PLANE);
|
compile(Core::passCompose, Shader::ENTITY, FX_UNDERWATER | FX_CLIP_PLANE);
|
||||||
|
compile(Core::passCompose, Shader::ENTITY, FX_ALPHA_TEST);
|
||||||
|
compile(Core::passCompose, Shader::ENTITY, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
||||||
compile(Core::passCompose, Shader::SPRITE, FX_ALPHA_TEST);
|
compile(Core::passCompose, Shader::SPRITE, FX_ALPHA_TEST);
|
||||||
compile(Core::passCompose, Shader::SPRITE, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
compile(Core::passCompose, Shader::SPRITE, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
||||||
compile(Core::passCompose, Shader::SPRITE, FX_UNDERWATER | FX_ALPHA_TEST);
|
compile(Core::passCompose, Shader::SPRITE, FX_UNDERWATER | FX_ALPHA_TEST);
|
||||||
@@ -107,7 +109,7 @@ struct ShaderCache {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *passNames[] = { "COMPOSE", "SHADOW", "AMBIENT", "FILTER", "WATER" };
|
const char *passNames[] = { "COMPOSE", "SHADOW", "AMBIENT", "WATER", "FILTER", "GUI" };
|
||||||
const char *src = NULL;
|
const char *src = NULL;
|
||||||
const char *typ = NULL;
|
const char *typ = NULL;
|
||||||
switch (pass) {
|
switch (pass) {
|
||||||
@@ -146,6 +148,13 @@ struct ShaderCache {
|
|||||||
sprintf(def, "%s#define PASS_%s\n#define FILTER_%s\n", ext, passNames[pass], typ);
|
sprintf(def, "%s#define PASS_%s\n#define FILTER_%s\n", ext, passNames[pass], typ);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case Core::passGUI : {
|
||||||
|
static const char *typeNames[] = { "DEFAULT" };
|
||||||
|
src = GUI;
|
||||||
|
typ = typeNames[type];
|
||||||
|
sprintf(def, "%s#define PASS_%s\n", ext, passNames[pass]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default : ASSERT(false);
|
default : ASSERT(false);
|
||||||
}
|
}
|
||||||
LOG("shader: compile %s -> %s %s%s%s\n", passNames[pass], typ, (fx & FX_UNDERWATER) ? "underwater " : "", (fx & FX_ALPHA_TEST) ? "alphaTest " : "", (fx & FX_CLIP_PLANE) ? "clipPlane" : "");
|
LOG("shader: compile %s -> %s %s%s%s\n", passNames[pass], typ, (fx & FX_UNDERWATER) ? "underwater " : "", (fx & FX_ALPHA_TEST) ? "alphaTest " : "", (fx & FX_CLIP_PLANE) ? "clipPlane" : "");
|
||||||
@@ -610,7 +619,7 @@ struct WaterCache {
|
|||||||
Core::setCulling(cfFront);
|
Core::setCulling(cfFront);
|
||||||
|
|
||||||
// get refraction texture
|
// get refraction texture
|
||||||
if (!refract || Core::width > refract->width || Core::height > refract->height) {
|
if (!refract || Core::width != refract->width || Core::height != refract->height) {
|
||||||
delete refract;
|
delete refract;
|
||||||
refract = new Texture(Core::width, Core::height, Texture::RGBA, false);
|
refract = new Texture(Core::width, Core::height, Texture::RGBA, false);
|
||||||
}
|
}
|
||||||
|
76
src/core.h
76
src/core.h
@@ -114,6 +114,11 @@
|
|||||||
PFNGLOBJECTLABELPROC glObjectLabel;
|
PFNGLOBJECTLABELPROC glObjectLabel;
|
||||||
PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup;
|
PFNGLPUSHDEBUGGROUPPROC glPushDebugGroup;
|
||||||
PFNGLPOPDEBUGGROUPPROC glPopDebugGroup;
|
PFNGLPOPDEBUGGROUPPROC glPopDebugGroup;
|
||||||
|
PFNGLGENQUERIESPROC glGenQueries;
|
||||||
|
PFNGLDELETEQUERIESPROC glDeleteQueries;
|
||||||
|
PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv;
|
||||||
|
PFNGLBEGINQUERYPROC glBeginQuery;
|
||||||
|
PFNGLENDQUERYPROC glEndQuery;
|
||||||
#endif
|
#endif
|
||||||
// Shader
|
// Shader
|
||||||
PFNGLCREATEPROGRAMPROC glCreateProgram;
|
PFNGLCREATEPROGRAMPROC glCreateProgram;
|
||||||
@@ -173,26 +178,63 @@
|
|||||||
struct Shader;
|
struct Shader;
|
||||||
struct Texture;
|
struct Texture;
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
struct {
|
||||||
|
bool VAO;
|
||||||
|
bool depthTexture;
|
||||||
|
bool shadowSampler;
|
||||||
|
bool discardFrame;
|
||||||
|
bool texNPOT;
|
||||||
|
bool texFloat, texFloatLinear;
|
||||||
|
bool texHalf, texHalfLinear;
|
||||||
|
bool shaderBinary;
|
||||||
|
#ifdef PROFILE
|
||||||
|
bool profMarker;
|
||||||
|
bool profTiming;
|
||||||
|
#endif
|
||||||
|
} support;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef PROFILE
|
#ifdef PROFILE
|
||||||
struct Marker {
|
struct Marker {
|
||||||
Marker(const char *title) {
|
Marker(const char *title) {
|
||||||
if (glPushDebugGroup) glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, title);
|
if (Core::support.profMarker) glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 1, -1, title);
|
||||||
}
|
}
|
||||||
|
|
||||||
~Marker() {
|
~Marker() {
|
||||||
if (glPopDebugGroup) glPopDebugGroup();
|
if (Core::support.profMarker) glPopDebugGroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setLabel(GLenum id, GLuint name, const char *label) {
|
static void setLabel(GLenum id, GLuint name, const char *label) {
|
||||||
if (glObjectLabel) glObjectLabel(id, name, -1, label);
|
if (Core::support.profMarker) glObjectLabel(id, name, -1, label);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Timing {
|
||||||
|
GLuint ID;
|
||||||
|
int &result;
|
||||||
|
|
||||||
|
Timing(int &result) : result(result) {
|
||||||
|
if (!Core::support.profTiming) return;
|
||||||
|
glGenQueries(1, &ID);
|
||||||
|
glBeginQuery(GL_TIME_ELAPSED, ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
~Timing() {
|
||||||
|
if (!Core::support.profTiming) return;
|
||||||
|
glEndQuery(GL_TIME_ELAPSED);
|
||||||
|
glGetQueryObjectiv(ID, GL_QUERY_RESULT, (GLint*)&result);
|
||||||
|
glDeleteQueries(1, &ID);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PROFILE_MARKER(title) Marker marker(title)
|
#define PROFILE_MARKER(title) Marker marker(title)
|
||||||
#define PROFILE_LABEL(id, name, label) Marker::setLabel(GL_##id, name, label)
|
#define PROFILE_LABEL(id, name, label) Marker::setLabel(GL_##id, name, label)
|
||||||
|
#define PROFILE_TIMING(result) Timing timing(result)
|
||||||
#else
|
#else
|
||||||
#define PROFILE_MARKER(title)
|
#define PROFILE_MARKER(title)
|
||||||
#define PROFILE_LABEL(id, name, label)
|
#define PROFILE_LABEL(id, name, label)
|
||||||
|
#define PROFILE_TIMING(time)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum CullMode { cfNone, cfBack, cfFront };
|
enum CullMode { cfNone, cfBack, cfFront };
|
||||||
@@ -212,7 +254,7 @@ namespace Core {
|
|||||||
|
|
||||||
Texture *blackTex, *whiteTex;
|
Texture *blackTex, *whiteTex;
|
||||||
|
|
||||||
enum Pass { passCompose, passShadow, passAmbient, passFilter, passWater, passMAX } pass;
|
enum Pass { passCompose, passShadow, passAmbient, passWater, passFilter, passGUI, passMAX } pass;
|
||||||
|
|
||||||
GLuint FBO;
|
GLuint FBO;
|
||||||
struct RenderTargetCache {
|
struct RenderTargetCache {
|
||||||
@@ -236,6 +278,9 @@ namespace Core {
|
|||||||
|
|
||||||
struct Stats {
|
struct Stats {
|
||||||
int dips, tris, frame, fps, fpsTime;
|
int dips, tris, frame, fps, fpsTime;
|
||||||
|
#ifdef PROFILE
|
||||||
|
int tFrame;
|
||||||
|
#endif
|
||||||
|
|
||||||
Stats() : frame(0), fps(0), fpsTime(0) {}
|
Stats() : frame(0), fps(0), fpsTime(0) {}
|
||||||
|
|
||||||
@@ -246,6 +291,9 @@ namespace Core {
|
|||||||
void stop() {
|
void stop() {
|
||||||
if (fpsTime < getTime()) {
|
if (fpsTime < getTime()) {
|
||||||
LOG("FPS: %d DIP: %d TRI: %d\n", fps, dips, tris);
|
LOG("FPS: %d DIP: %d TRI: %d\n", fps, dips, tris);
|
||||||
|
#ifdef PROFILE
|
||||||
|
LOG("frame time: %d mcs\n", tFrame / 1000);
|
||||||
|
#endif
|
||||||
fps = frame;
|
fps = frame;
|
||||||
frame = 0;
|
frame = 0;
|
||||||
fpsTime = getTime() + 1000;
|
fpsTime = getTime() + 1000;
|
||||||
@@ -254,17 +302,6 @@ namespace Core {
|
|||||||
}
|
}
|
||||||
} stats;
|
} stats;
|
||||||
|
|
||||||
struct {
|
|
||||||
bool VAO;
|
|
||||||
bool depthTexture;
|
|
||||||
bool shadowSampler;
|
|
||||||
bool discardFrame;
|
|
||||||
bool texNPOT;
|
|
||||||
bool texFloat, texFloatLinear;
|
|
||||||
bool texHalf, texHalfLinear;
|
|
||||||
bool shaderBinary;
|
|
||||||
} support;
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
bool ambient;
|
bool ambient;
|
||||||
bool lighting;
|
bool lighting;
|
||||||
@@ -298,6 +335,11 @@ namespace Core {
|
|||||||
GetProcOGL(glObjectLabel);
|
GetProcOGL(glObjectLabel);
|
||||||
GetProcOGL(glPushDebugGroup);
|
GetProcOGL(glPushDebugGroup);
|
||||||
GetProcOGL(glPopDebugGroup);
|
GetProcOGL(glPopDebugGroup);
|
||||||
|
GetProcOGL(glGenQueries);
|
||||||
|
GetProcOGL(glDeleteQueries);
|
||||||
|
GetProcOGL(glGetQueryObjectiv);
|
||||||
|
GetProcOGL(glBeginQuery);
|
||||||
|
GetProcOGL(glEndQuery);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
GetProcOGL(glCreateProgram);
|
GetProcOGL(glCreateProgram);
|
||||||
@@ -363,6 +405,10 @@ namespace Core {
|
|||||||
support.texFloat = support.texFloatLinear || extSupport(ext, "_texture_float");
|
support.texFloat = support.texFloatLinear || extSupport(ext, "_texture_float");
|
||||||
support.texHalfLinear = extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_half_float_linear");
|
support.texHalfLinear = extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_half_float_linear");
|
||||||
support.texHalf = support.texHalfLinear || extSupport(ext, "_texture_half_float");
|
support.texHalf = support.texHalfLinear || extSupport(ext, "_texture_half_float");
|
||||||
|
#ifdef PROFILE
|
||||||
|
support.profMarker = extSupport(ext, "_KHR_debug");
|
||||||
|
support.profTiming = extSupport(ext, "_timer_query");
|
||||||
|
#endif
|
||||||
|
|
||||||
char *vendor = (char*)glGetString(GL_VENDOR);
|
char *vendor = (char*)glGetString(GL_VENDOR);
|
||||||
LOG("Vendor : %s\n", vendor);
|
LOG("Vendor : %s\n", vendor);
|
||||||
|
22
src/game.h
22
src/game.h
@@ -4,13 +4,17 @@
|
|||||||
#include "core.h"
|
#include "core.h"
|
||||||
#include "format.h"
|
#include "format.h"
|
||||||
#include "level.h"
|
#include "level.h"
|
||||||
|
#include "ui.h"
|
||||||
|
|
||||||
namespace Game {
|
namespace Game {
|
||||||
Level *level;
|
Level *level;
|
||||||
|
UI *ui;
|
||||||
|
|
||||||
void startLevel(Stream *lvl, Stream *snd, bool demo, bool home) {
|
void startLevel(Stream *lvl, Stream *snd, bool demo, bool home) {
|
||||||
|
delete ui;
|
||||||
delete level;
|
delete level;
|
||||||
level = new Level(*lvl, snd, demo, home);
|
level = new Level(*lvl, snd, demo, home);
|
||||||
|
ui = new UI(level);
|
||||||
delete lvl;
|
delete lvl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,6 +27,7 @@ namespace Game {
|
|||||||
Core::settings.water = Core::support.texFloat || Core::support.texHalf;
|
Core::settings.water = Core::support.texFloat || Core::support.texHalf;
|
||||||
|
|
||||||
level = NULL;
|
level = NULL;
|
||||||
|
ui = NULL;
|
||||||
startLevel(lvl, snd, false, false);
|
startLevel(lvl, snd, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,17 +40,13 @@ namespace Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void free() {
|
void free() {
|
||||||
|
delete ui;
|
||||||
delete level;
|
delete level;
|
||||||
Core::free();
|
Core::free();
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTick() {
|
void updateTick() {
|
||||||
float dt = Core::deltaTime;
|
float dt = Core::deltaTime;
|
||||||
if (Input::down[ikV]) { // third <-> first person view
|
|
||||||
level->camera->changeView(!level->camera->firstPerson);
|
|
||||||
Input::down[ikV] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Input::down[ikR]) // slow motion (for animation debugging)
|
if (Input::down[ikR]) // slow motion (for animation debugging)
|
||||||
Core::deltaTime /= 10.0f;
|
Core::deltaTime /= 10.0f;
|
||||||
|
|
||||||
@@ -59,7 +60,14 @@ namespace Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void update(float delta) {
|
void update(float delta) {
|
||||||
delta = min(1.0f, delta);
|
if (Input::down[ikV]) { // third <-> first person view
|
||||||
|
level->camera->changeView(!level->camera->firstPerson);
|
||||||
|
Input::down[ikV] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Core::deltaTime = delta = min(1.0f, delta);
|
||||||
|
ui->update();
|
||||||
|
|
||||||
while (delta > EPS) {
|
while (delta > EPS) {
|
||||||
Core::deltaTime = min(delta, 1.0f / 30.0f);
|
Core::deltaTime = min(delta, 1.0f / 30.0f);
|
||||||
Game::updateTick();
|
Game::updateTick();
|
||||||
@@ -68,8 +76,10 @@ namespace Game {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void render() {
|
void render() {
|
||||||
|
PROFILE_TIMING(Core::stats.tFrame);
|
||||||
Core::beginFrame();
|
Core::beginFrame();
|
||||||
level->render();
|
level->render();
|
||||||
|
ui->renderTouch();
|
||||||
Core::endFrame();
|
Core::endFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
src/gui.glsl
12
src/gui.glsl
@@ -1,6 +1,6 @@
|
|||||||
R"====(
|
R"====(
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
precision highp int;
|
precision lowp int;
|
||||||
precision highp float;
|
precision highp float;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ varying vec2 vTexCoord;
|
|||||||
|
|
||||||
#ifdef VERTEX
|
#ifdef VERTEX
|
||||||
uniform mat4 uViewProj;
|
uniform mat4 uViewProj;
|
||||||
uniform mat4 uModel;
|
uniform vec4 uPosScale;
|
||||||
|
|
||||||
attribute vec4 aCoord;
|
attribute vec4 aCoord;
|
||||||
attribute vec4 aTexCoord;
|
attribute vec4 aTexCoord;
|
||||||
@@ -16,17 +16,15 @@ varying vec2 vTexCoord;
|
|||||||
#define TEXCOORD_SCALE (1.0 / 32767.0)
|
#define TEXCOORD_SCALE (1.0 / 32767.0)
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 coord = uModel * vec4(aCoord.xyz, 1.0);
|
|
||||||
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
vTexCoord = aTexCoord.xy * TEXCOORD_SCALE;
|
||||||
coord.xy += aTexCoord.zw;
|
gl_Position = uViewProj * vec4(aCoord.xy * uPosScale.zw + uPosScale.xy, 0.0, 1.0);
|
||||||
gl_Position = uViewProj * coord;
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
uniform sampler2D sDiffuse;
|
uniform sampler2D sDiffuse;
|
||||||
uniform vec4 uColor;
|
uniform vec4 uMaterial;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
gl_FragColor = texture2D(sDiffuse, vTexCoord) * uColor;
|
gl_FragColor = /* texture2D(sDiffuse, vTexCoord) * */ uMaterial;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
)===="
|
)===="
|
46
src/input.h
46
src/input.h
@@ -12,7 +12,7 @@ enum InputKey { ikNone,
|
|||||||
// mouse
|
// mouse
|
||||||
ikMouseL, ikMouseR, ikMouseM,
|
ikMouseL, ikMouseR, ikMouseM,
|
||||||
// touch
|
// touch
|
||||||
ikTouchA, ikTouchB,
|
ikTouchA, ikTouchB, ikTouchC, ikTouchD, ikTouchE, ikTouchF,
|
||||||
// gamepad
|
// gamepad
|
||||||
ikJoyA, ikJoyB, ikJoyX, ikJoyY, ikJoyLB, ikJoyRB, ikJoySelect, ikJoyStart, ikJoyL, ikJoyR, ikJoyLT, ikJoyRT, ikJoyPOV,
|
ikJoyA, ikJoyB, ikJoyX, ikJoyY, ikJoyLB, ikJoyRB, ikJoySelect, ikJoyStart, ikJoyL, ikJoyR, ikJoyLT, ikJoyRT, ikJoyPOV,
|
||||||
ikMAX };
|
ikMAX };
|
||||||
@@ -34,13 +34,11 @@ namespace Input {
|
|||||||
int POV;
|
int POV;
|
||||||
} joy;
|
} joy;
|
||||||
|
|
||||||
struct {
|
struct Touch {
|
||||||
vec2 A, B;
|
int id;
|
||||||
|
vec2 start;
|
||||||
struct {
|
vec2 pos;
|
||||||
vec2 A, B;
|
} touch[6];
|
||||||
} start;
|
|
||||||
} touch;
|
|
||||||
|
|
||||||
void reset() {
|
void reset() {
|
||||||
memset(down, 0, sizeof(down));
|
memset(down, 0, sizeof(down));
|
||||||
@@ -58,8 +56,12 @@ namespace Input {
|
|||||||
case ikMouseL : mouse.start.L = mouse.pos; break;
|
case ikMouseL : mouse.start.L = mouse.pos; break;
|
||||||
case ikMouseR : mouse.start.R = mouse.pos; break;
|
case ikMouseR : mouse.start.R = mouse.pos; break;
|
||||||
case ikMouseM : mouse.start.M = mouse.pos; break;
|
case ikMouseM : mouse.start.M = mouse.pos; break;
|
||||||
case ikTouchA : touch.start.A = touch.A; break;
|
case ikTouchA :
|
||||||
case ikTouchB : touch.start.B = touch.B; break;
|
case ikTouchB :
|
||||||
|
case ikTouchC :
|
||||||
|
case ikTouchD :
|
||||||
|
case ikTouchE :
|
||||||
|
case ikTouchF : touch[key - ikTouchA].start = touch[key - ikTouchA].pos; break;
|
||||||
default : ;
|
default : ;
|
||||||
}
|
}
|
||||||
down[key] = value;
|
down[key] = value;
|
||||||
@@ -72,14 +74,32 @@ namespace Input {
|
|||||||
case ikMouseM : mouse.pos = pos; return;
|
case ikMouseM : mouse.pos = pos; return;
|
||||||
case ikJoyL : joy.L = pos; return;
|
case ikJoyL : joy.L = pos; return;
|
||||||
case ikJoyR : joy.R = pos; return;
|
case ikJoyR : joy.R = pos; return;
|
||||||
case ikTouchA : touch.A = pos; return;
|
|
||||||
case ikTouchB : touch.B = pos; return;
|
|
||||||
case ikJoyLT : joy.LT = pos.x; break;
|
case ikJoyLT : joy.LT = pos.x; break;
|
||||||
case ikJoyRT : joy.RT = pos.x; break;
|
case ikJoyRT : joy.RT = pos.x; break;
|
||||||
case ikJoyPOV : joy.POV = (int)pos.x; break;
|
case ikJoyPOV : joy.POV = (int)pos.x; break;
|
||||||
|
case ikTouchA :
|
||||||
|
case ikTouchB :
|
||||||
|
case ikTouchC :
|
||||||
|
case ikTouchD :
|
||||||
|
case ikTouchE :
|
||||||
|
case ikTouchF : touch[key - ikTouchA].pos = pos; return;
|
||||||
default : return;
|
default : return;
|
||||||
}
|
}
|
||||||
setDown(key, pos.x > 0.0f);
|
setDown(key, pos.x > 0.0f); // gamepad LT, RT, POV auto-down state
|
||||||
|
}
|
||||||
|
|
||||||
|
InputKey getTouch(int id) {
|
||||||
|
for (int i = 0; i < COUNT(touch); i++)
|
||||||
|
if (down[ikTouchA + i] && touch[i].id == id)
|
||||||
|
return InputKey(ikTouchA + i);
|
||||||
|
|
||||||
|
for (int i = 0; i < COUNT(touch); i++)
|
||||||
|
if (!down[ikTouchA + i]) {
|
||||||
|
touch[i].id = id;
|
||||||
|
return InputKey(ikTouchA + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ikNone;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1656,13 +1656,13 @@ struct Lara : Character {
|
|||||||
if (Input::joy.L.x != 0.0f) {
|
if (Input::joy.L.x != 0.0f) {
|
||||||
input |= (Input::joy.L.x < 0.0f) ? LEFT : RIGHT;
|
input |= (Input::joy.L.x < 0.0f) ? LEFT : RIGHT;
|
||||||
if (moving || stand == STAND_UNDERWATER || stand == STAND_ONWATER)
|
if (moving || stand == STAND_UNDERWATER || stand == STAND_ONWATER)
|
||||||
rotFactor.y = min(fabsf(Input::joy.L.x) / 0.75f, 1.0f);
|
rotFactor.y = min(fabsf(Input::joy.L.x) / 0.9f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Input::joy.L.y != 0.0f) {
|
if (Input::joy.L.y != 0.0f) {
|
||||||
input |= (Input::joy.L.y < 0.0f) ? FORTH : BACK;
|
input |= (Input::joy.L.y < 0.0f) ? FORTH : BACK;
|
||||||
if (stand == STAND_UNDERWATER)
|
if (stand == STAND_UNDERWATER)
|
||||||
rotFactor.x = min(fabsf(Input::joy.L.y) / 0.75f, 1.0f);
|
rotFactor.x = min(fabsf(Input::joy.L.y) / 0.9f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
|
10
src/level.h
10
src/level.h
@@ -70,7 +70,7 @@ struct Level : IGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
virtual void setShader(Core::Pass pass, Shader::Type type, bool underwater = false, bool alphaTest = false) {
|
virtual void setShader(Core::Pass pass, Shader::Type type, bool underwater = false, bool alphaTest = false) {
|
||||||
shaderCache->bind(pass, type, (underwater ? ShaderCache::FX_UNDERWATER : 0) | (alphaTest ? ShaderCache::FX_ALPHA_TEST : 0) | (params->clipHeight != NO_CLIP_PLANE ? ShaderCache::FX_CLIP_PLANE : 0));
|
shaderCache->bind(pass, type, (underwater ? ShaderCache::FX_UNDERWATER : 0) | (alphaTest ? ShaderCache::FX_ALPHA_TEST : 0) | ((params->clipHeight != NO_CLIP_PLANE && pass == Core::passCompose) ? ShaderCache::FX_CLIP_PLANE : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0) {
|
virtual void renderEnvironment(int roomIndex, const vec3 &pos, Texture **targets, int stride = 0) {
|
||||||
@@ -824,7 +824,7 @@ struct Level : IGame {
|
|||||||
glEnd();
|
glEnd();
|
||||||
Core::setDepthTest(true);
|
Core::setDepthTest(true);
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
@@ -834,9 +834,9 @@ struct Level : IGame {
|
|||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glOrtho(0, Core::width, 0, Core::height, 0, 1);
|
glOrtho(0, Core::width, 0, Core::height, 0, 1);
|
||||||
|
|
||||||
// if (waterCache->count)
|
if (waterCache->count)
|
||||||
// waterCache->refract->bind(sDiffuse);
|
waterCache->refract->bind(sDiffuse);
|
||||||
// else
|
else
|
||||||
shadow->bind(sDiffuse);
|
shadow->bind(sDiffuse);
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
glDisable(GL_CULL_FACE);
|
glDisable(GL_CULL_FACE);
|
||||||
|
@@ -7,16 +7,16 @@
|
|||||||
<supports-screens android:smallScreens="true" android:largeScreens="true" android:normalScreens="true" android:xlargeScreens="true" />
|
<supports-screens android:smallScreens="true" android:largeScreens="true" android:normalScreens="true" android:xlargeScreens="true" />
|
||||||
|
|
||||||
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
|
<uses-permission android:name="com.qti.permission.PROFILER" />
|
||||||
<!--
|
<!--
|
||||||
android:debuggable="true"
|
android:debuggable="true"
|
||||||
-->
|
-->
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@drawable/ic_launcher"
|
||||||
android:label="@string/app_name">
|
android:label="@string/app_name"
|
||||||
|
android:debuggable="true">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
@@ -107,7 +107,6 @@ int getPOV(int x, int y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JNI_METHOD(void, nativeTouch)(JNIEnv* env, jobject obj, jint id, jint state, jfloat x, jfloat y) {
|
JNI_METHOD(void, nativeTouch)(JNIEnv* env, jobject obj, jint id, jint state, jfloat x, jfloat y) {
|
||||||
if (id > 1) return;
|
|
||||||
// gamepad
|
// gamepad
|
||||||
if (state < 0) {
|
if (state < 0) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
@@ -118,32 +117,12 @@ JNI_METHOD(void, nativeTouch)(JNIEnv* env, jobject obj, jint id, jint state, jfl
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// touch
|
||||||
if (state == 3 && x < Core::width / 2) {
|
InputKey key = Input::getTouch(id);
|
||||||
vec2 center(Core::width * 0.25f, Core::height * 0.6f);
|
if (key == ikNone) return;
|
||||||
vec2 pos(x, y);
|
Input::setPos(key, vec2(x, y));
|
||||||
vec2 d = pos - center;
|
if (state == 1 || state == 2)
|
||||||
Input::setPos(ikJoyL, d.normal());
|
Input::setDown(key, state == 2);
|
||||||
};
|
|
||||||
|
|
||||||
if (state == 2 && x > Core::width / 2) {
|
|
||||||
int i = y / (Core::height / 3);
|
|
||||||
InputKey key;
|
|
||||||
if (i == 0)
|
|
||||||
key = ikJoyX;
|
|
||||||
else if (i == 1)
|
|
||||||
key = ikJoyA;
|
|
||||||
else
|
|
||||||
key = ikJoyY;
|
|
||||||
Input::setDown(key, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state == 1) {
|
|
||||||
Input::setPos(ikJoyL, vec2(0.0f));
|
|
||||||
Input::setDown(ikJoyA, false);
|
|
||||||
Input::setDown(ikJoyX, false);
|
|
||||||
Input::setDown(ikJoyY, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JNI_METHOD(void, nativeSoundFill)(JNIEnv* env, jobject obj, jshortArray buffer) {
|
JNI_METHOD(void, nativeSoundFill)(JNIEnv* env, jobject obj, jshortArray buffer) {
|
||||||
|
@@ -199,44 +199,16 @@ EM_BOOL keyCallback(int eventType, const EmscriptenKeyboardEvent *e, void *userD
|
|||||||
}
|
}
|
||||||
|
|
||||||
EM_BOOL touchCallback(int eventType, const EmscriptenTouchEvent *e, void *userData) {
|
EM_BOOL touchCallback(int eventType, const EmscriptenTouchEvent *e, void *userData) {
|
||||||
bool flag = false;
|
for (int i = 0; i < e->numTouches; i++) {
|
||||||
/*
|
InputKey key = Input::getTouch(e->touches[i].identifier);
|
||||||
for (int i = 0; i < e->numTouches; i++) {
|
if (key == ikNone) continue;
|
||||||
long x = e->touches[i].canvasX;
|
Input::setPos(key, vec2(e->touches[i].canvasX, e->touches[i].canvasY));
|
||||||
long y = e->touches[i].canvasY;
|
|
||||||
if (x < 0 || y < 0 || x >= Core::width || y >= Core::height) continue;
|
|
||||||
flag = true;
|
|
||||||
|
|
||||||
switch (eventType) {
|
if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART || eventType == EMSCRIPTEN_EVENT_TOUCHEND || eventType == EMSCRIPTEN_EVENT_TOUCHCANCEL)
|
||||||
case EMSCRIPTEN_EVENT_TOUCHSTART :
|
Input::setDown(key, eventType == EMSCRIPTEN_EVENT_TOUCHSTART);
|
||||||
if (x > Core::width / 2)
|
|
||||||
Input::joy.down[(y > Core::height / 2) ? 1 : 4] = true;
|
|
||||||
break;
|
|
||||||
case EMSCRIPTEN_EVENT_TOUCHMOVE :
|
|
||||||
if (x < Core::width / 2) {
|
|
||||||
vec2 center(Core::width * 0.25f, Core::height * 0.6f);
|
|
||||||
vec2 pos(x, y);
|
|
||||||
vec2 d = pos - center;
|
|
||||||
|
|
||||||
Input::Joystick &joy = Input::joy;
|
|
||||||
|
|
||||||
joy.L.x = d.x;
|
|
||||||
joy.L.y = d.y;
|
|
||||||
if (joy.L != vec2(0.0f))
|
|
||||||
joy.L.normalize();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case EMSCRIPTEN_EVENT_TOUCHEND :
|
|
||||||
case EMSCRIPTEN_EVENT_TOUCHCANCEL : {
|
|
||||||
Input::joy.L = vec2(0.0f);
|
|
||||||
Input::joy.down[1] = false;
|
|
||||||
Input::joy.down[4] = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
return flag;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
EM_BOOL mouseCallback(int eventType, const EmscriptenMouseEvent *e, void *userData) {
|
EM_BOOL mouseCallback(int eventType, const EmscriptenMouseEvent *e, void *userData) {
|
||||||
@@ -267,10 +239,10 @@ int main() {
|
|||||||
emscripten_set_keyup_callback(0, 0, 1, keyCallback);
|
emscripten_set_keyup_callback(0, 0, 1, keyCallback);
|
||||||
emscripten_set_resize_callback(0, 0, 1, resizeCallback);
|
emscripten_set_resize_callback(0, 0, 1, resizeCallback);
|
||||||
|
|
||||||
emscripten_set_touchstart_callback(0, 0, 1, touchCallback);
|
emscripten_set_touchstart_callback(0, 0, 0, touchCallback);
|
||||||
emscripten_set_touchend_callback(0, 0, 1, touchCallback);
|
emscripten_set_touchend_callback(0, 0, 0, touchCallback);
|
||||||
emscripten_set_touchmove_callback(0, 0, 1, touchCallback);
|
emscripten_set_touchmove_callback(0, 0, 0, touchCallback);
|
||||||
emscripten_set_touchcancel_callback(0, 0, 1, touchCallback);
|
emscripten_set_touchcancel_callback(0, 0, 0, touchCallback);
|
||||||
|
|
||||||
emscripten_set_mousedown_callback(0, 0, 1, mouseCallback);
|
emscripten_set_mousedown_callback(0, 0, 1, mouseCallback);
|
||||||
emscripten_set_mouseup_callback(0, 0, 1, mouseCallback);
|
emscripten_set_mouseup_callback(0, 0, 1, mouseCallback);
|
||||||
|
@@ -198,6 +198,7 @@
|
|||||||
<ClInclude Include="..\..\enemy.h" />
|
<ClInclude Include="..\..\enemy.h" />
|
||||||
<ClInclude Include="..\..\frustum.h" />
|
<ClInclude Include="..\..\frustum.h" />
|
||||||
<ClInclude Include="..\..\game.h" />
|
<ClInclude Include="..\..\game.h" />
|
||||||
|
<ClInclude Include="..\..\ui.h" />
|
||||||
<ClInclude Include="..\..\input.h" />
|
<ClInclude Include="..\..\input.h" />
|
||||||
<ClInclude Include="..\..\inventory.h" />
|
<ClInclude Include="..\..\inventory.h" />
|
||||||
<ClInclude Include="..\..\lara.h" />
|
<ClInclude Include="..\..\lara.h" />
|
||||||
|
@@ -128,7 +128,7 @@ PREGISTERTOUCHWINDOW RegisterTouchWindowX;
|
|||||||
PGETTOUCHINPUTINFO GetTouchInputInfoX;
|
PGETTOUCHINPUTINFO GetTouchInputInfoX;
|
||||||
PCLOSETOUCHINPUTHANDLE CloseTouchInputHandleX;
|
PCLOSETOUCHINPUTHANDLE CloseTouchInputHandleX;
|
||||||
|
|
||||||
#define MAX_TOUCH_COUNT 10
|
#define MAX_TOUCH_COUNT 6
|
||||||
|
|
||||||
void touchInit(HWND hWnd) {
|
void touchInit(HWND hWnd) {
|
||||||
int value = GetSystemMetrics(SM_DIGITIZER);
|
int value = GetSystemMetrics(SM_DIGITIZER);
|
||||||
@@ -142,17 +142,23 @@ void touchInit(HWND hWnd) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void touchUpdate(HTOUCHINPUT hTouch, int count) {
|
void touchUpdate(HWND hWnd, HTOUCHINPUT hTouch, int count) {
|
||||||
TOUCHINPUT touches[MAX_TOUCH_COUNT];
|
TOUCHINPUT touch[MAX_TOUCH_COUNT];
|
||||||
count = min(count, MAX_TOUCH_COUNT);
|
count = min(count, MAX_TOUCH_COUNT);
|
||||||
|
|
||||||
if (!GetTouchInputInfoX(hTouch, count, touches, sizeof(TOUCHINPUT)))
|
if (!GetTouchInputInfoX(hTouch, count, touch, sizeof(TOUCHINPUT)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LOG("touch [ ", count);
|
for (int i = 0; i < count; i++) {
|
||||||
for (int i = 0; i < count; i++)
|
InputKey key = Input::getTouch(touch[i].dwID);
|
||||||
LOG("%d (%d, %d) ", i, touches[i].x, touches[i].y);
|
if (key == ikNone) continue;
|
||||||
LOG("]\n");
|
POINT pos = { touch[i].x / 100, touch[i].y / 100 };
|
||||||
|
ScreenToClient(hWnd, &pos);
|
||||||
|
Input::setPos(key, vec2(float(pos.x), float(pos.y)));
|
||||||
|
|
||||||
|
if (touch[i].dwFlags & (TOUCHEVENTF_DOWN | TOUCHEVENTF_UP))
|
||||||
|
Input::setDown(key, (touch[i].dwFlags & TOUCHEVENTF_DOWN) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
CloseTouchInputHandleX(hTouch);
|
CloseTouchInputHandleX(hTouch);
|
||||||
}
|
}
|
||||||
@@ -283,10 +289,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPara
|
|||||||
return 1;
|
return 1;
|
||||||
// touch
|
// touch
|
||||||
case WM_TOUCH :
|
case WM_TOUCH :
|
||||||
touchUpdate((HTOUCHINPUT)lParam, wParam);
|
touchUpdate(hWnd, (HTOUCHINPUT)lParam, wParam);
|
||||||
break;
|
break;
|
||||||
// TODO
|
|
||||||
// sound
|
|
||||||
default :
|
default :
|
||||||
return DefWindowProc(hWnd, msg, wParam, lParam);
|
return DefWindowProc(hWnd, msg, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
@@ -47,6 +47,8 @@ typedef unsigned int uint32;
|
|||||||
|
|
||||||
#define FOURCC(str) (*((uint32*)str))
|
#define FOURCC(str) (*((uint32*)str))
|
||||||
|
|
||||||
|
#define COUNT(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline const T& min(const T &a, const T &b) {
|
inline const T& min(const T &a, const T &b) {
|
||||||
return a < b ? a : b;
|
return a < b ? a : b;
|
||||||
@@ -231,7 +233,7 @@ struct vec3 {
|
|||||||
|
|
||||||
struct vec4 {
|
struct vec4 {
|
||||||
union {
|
union {
|
||||||
struct { vec2 xy; };
|
struct { vec2 xy, zw; };
|
||||||
struct { vec3 xyz; };
|
struct { vec3 xyz; };
|
||||||
struct { float x, y, z, w; };
|
struct { float x, y, z, w; };
|
||||||
};
|
};
|
||||||
@@ -240,6 +242,7 @@ struct vec4 {
|
|||||||
vec4(float s) : x(s), y(s), z(s), w(s) {}
|
vec4(float s) : x(s), y(s), z(s), w(s) {}
|
||||||
vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
|
vec4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}
|
||||||
vec4(const vec3 &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) {}
|
vec4(const vec3 &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) {}
|
||||||
|
vec4(const vec2 &xy, const vec2 &zw) : x(xy.x), y(xy.y), z(zw.x), w(zw.y) {}
|
||||||
|
|
||||||
vec4 operator * (const vec4 &v) const { return vec4(x*v.x, y*v.y, z*v.z, w*v.w); }
|
vec4 operator * (const vec4 &v) const { return vec4(x*v.x, y*v.y, z*v.z, w*v.w); }
|
||||||
vec4& operator *= (const vec4 &v) { x*=v.x; y*=v.y; z*=v.z; w*=v.w; return *this; }
|
vec4& operator *= (const vec4 &v) { x*=v.x; y*=v.y; z*=v.z; w*=v.w; return *this; }
|
||||||
|
Reference in New Issue
Block a user