mirror of
https://github.com/XProger/OpenLara.git
synced 2025-08-11 23:54:09 +02:00
#23 main shader optimizations; touch UI
This commit is contained in:
26
src/cache.h
26
src/cache.h
@@ -45,13 +45,15 @@ struct ShaderCache {
|
|||||||
if (Core::settings.ambient) {
|
if (Core::settings.ambient) {
|
||||||
compile(Core::passAmbient, Shader::ROOM, FX_NONE);
|
compile(Core::passAmbient, Shader::ROOM, FX_NONE);
|
||||||
compile(Core::passAmbient, Shader::ROOM, FX_ALPHA_TEST);
|
compile(Core::passAmbient, Shader::ROOM, FX_ALPHA_TEST);
|
||||||
|
compile(Core::passAmbient, Shader::ROOM, FX_UNDERWATER);
|
||||||
|
compile(Core::passAmbient, Shader::SPRITE, FX_ALPHA_TEST);
|
||||||
|
if (Core::settings.water) {
|
||||||
compile(Core::passAmbient, Shader::ROOM, FX_CLIP_PLANE);
|
compile(Core::passAmbient, Shader::ROOM, FX_CLIP_PLANE);
|
||||||
compile(Core::passAmbient, Shader::ROOM, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
compile(Core::passAmbient, Shader::ROOM, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
||||||
compile(Core::passAmbient, Shader::ROOM, FX_UNDERWATER);
|
|
||||||
compile(Core::passAmbient, Shader::ROOM, FX_UNDERWATER | FX_CLIP_PLANE);
|
compile(Core::passAmbient, Shader::ROOM, FX_UNDERWATER | FX_CLIP_PLANE);
|
||||||
compile(Core::passAmbient, Shader::SPRITE, FX_ALPHA_TEST);
|
|
||||||
compile(Core::passAmbient, Shader::SPRITE, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
compile(Core::passAmbient, Shader::SPRITE, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Core::settings.water) {
|
if (Core::settings.water) {
|
||||||
compile(Core::passWater, Shader::WATER_MASK, FX_NONE);
|
compile(Core::passWater, Shader::WATER_MASK, FX_NONE);
|
||||||
@@ -65,21 +67,23 @@ struct ShaderCache {
|
|||||||
|
|
||||||
compile(Core::passCompose, Shader::ROOM, FX_NONE);
|
compile(Core::passCompose, Shader::ROOM, FX_NONE);
|
||||||
compile(Core::passCompose, Shader::ROOM, FX_ALPHA_TEST);
|
compile(Core::passCompose, Shader::ROOM, FX_ALPHA_TEST);
|
||||||
compile(Core::passCompose, Shader::ROOM, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
|
||||||
compile(Core::passCompose, Shader::ROOM, FX_CLIP_PLANE);
|
|
||||||
compile(Core::passCompose, Shader::ROOM, FX_UNDERWATER);
|
compile(Core::passCompose, Shader::ROOM, FX_UNDERWATER);
|
||||||
compile(Core::passCompose, Shader::ROOM, FX_UNDERWATER | FX_CLIP_PLANE);
|
|
||||||
compile(Core::passCompose, Shader::ENTITY, FX_NONE);
|
compile(Core::passCompose, Shader::ENTITY, FX_NONE);
|
||||||
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_ALPHA_TEST);
|
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_UNDERWATER | FX_ALPHA_TEST);
|
compile(Core::passCompose, Shader::SPRITE, FX_UNDERWATER | FX_ALPHA_TEST);
|
||||||
compile(Core::passCompose, Shader::SPRITE, FX_UNDERWATER | FX_ALPHA_TEST | FX_CLIP_PLANE);
|
|
||||||
compile(Core::passCompose, Shader::FLASH, FX_ALPHA_TEST);
|
compile(Core::passCompose, Shader::FLASH, FX_ALPHA_TEST);
|
||||||
|
if (Core::settings.water) {
|
||||||
|
compile(Core::passCompose, Shader::ROOM, FX_CLIP_PLANE);
|
||||||
|
compile(Core::passCompose, Shader::ROOM, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
||||||
|
compile(Core::passCompose, Shader::ROOM, FX_UNDERWATER | FX_CLIP_PLANE);
|
||||||
|
compile(Core::passCompose, Shader::SPRITE, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
||||||
|
compile(Core::passCompose, Shader::ENTITY, FX_ALPHA_TEST | FX_CLIP_PLANE);
|
||||||
|
compile(Core::passCompose, Shader::ENTITY, FX_CLIP_PLANE);
|
||||||
|
compile(Core::passCompose, Shader::ENTITY, FX_UNDERWATER | FX_CLIP_PLANE);
|
||||||
|
compile(Core::passCompose, Shader::SPRITE, FX_UNDERWATER | FX_ALPHA_TEST | FX_CLIP_PLANE);
|
||||||
|
}
|
||||||
compile(Core::passCompose, Shader::MIRROR, FX_NONE);
|
compile(Core::passCompose, Shader::MIRROR, FX_NONE);
|
||||||
|
|
||||||
LOG("shader: cache is ready\n");
|
LOG("shader: cache is ready\n");
|
||||||
@@ -276,7 +280,7 @@ struct AmbientCache {
|
|||||||
TR::Color32 color;
|
TR::Color32 color;
|
||||||
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
|
glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color);
|
||||||
colors[j] = vec3(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f);
|
colors[j] = vec3(color.r / 255.0f, color.g / 255.0f, color.b / 255.0f);
|
||||||
colors[j] *= colors[j]; // to "linear" space
|
// colors[j] *= colors[j]; // to "linear" space
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::setDepthTest(true);
|
Core::setDepthTest(true);
|
||||||
|
@@ -291,7 +291,7 @@ struct Camera : Controller {
|
|||||||
advTimer = 0.0f;
|
advTimer = 0.0f;
|
||||||
|
|
||||||
fov = firstPerson ? 90.0f : 65.0f;
|
fov = firstPerson ? 90.0f : 65.0f;
|
||||||
znear = firstPerson ? 8.0f : 16.0f;
|
znear = firstPerson ? 8.0f : 128.0f;
|
||||||
zfar = 40.0f * 1024.0f;
|
zfar = 40.0f * 1024.0f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -23,8 +23,8 @@ namespace Game {
|
|||||||
|
|
||||||
Core::settings.ambient = true;
|
Core::settings.ambient = true;
|
||||||
Core::settings.lighting = true;
|
Core::settings.lighting = true;
|
||||||
Core::settings.shadows = true;
|
Core::settings.shadows = false;//true;
|
||||||
Core::settings.water = Core::support.texFloat || Core::support.texHalf;
|
Core::settings.water = false;//Core::support.texFloat || Core::support.texHalf;
|
||||||
|
|
||||||
level = NULL;
|
level = NULL;
|
||||||
ui = NULL;
|
ui = NULL;
|
||||||
|
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
#define DESCENT_SPEED 2048.0f
|
#define DESCENT_SPEED 2048.0f
|
||||||
#define MUZZLE_FLASH_TIME 0.1f
|
#define MUZZLE_FLASH_TIME 0.1f
|
||||||
#define FLASH_LIGHT_COLOR vec4(0.8f, 0.7f, 0.3f, 3072 * 3072)
|
#define FLASH_LIGHT_COLOR vec4(0.6f, 0.5f, 0.1f, 1.0f / 3072.0f)
|
||||||
#define TARGET_MAX_DIST (8.0f * 1024.0f)
|
#define TARGET_MAX_DIST (8.0f * 1024.0f)
|
||||||
|
|
||||||
struct Lara : Character {
|
struct Lara : Character {
|
||||||
@@ -417,6 +417,7 @@ struct Lara : Character {
|
|||||||
//reset(43, vec3(31400, -2560, 25200), PI); // level 2 (reach)
|
//reset(43, vec3(31400, -2560, 25200), PI); // level 2 (reach)
|
||||||
//reset(16, vec3(60907, 0, 39642), PI * 3 / 2); // level 2 (hang & climb)
|
//reset(16, vec3(60907, 0, 39642), PI * 3 / 2); // level 2 (hang & climb)
|
||||||
//reset(19, vec3(60843, 1024, 30557), PI); // level 2 (block)
|
//reset(19, vec3(60843, 1024, 30557), PI); // level 2 (block)
|
||||||
|
reset(1, vec3(62630, -1280, 19633), 0); // level 2 (dark medikit)
|
||||||
//reset(7, vec3(64108, -512, 16514), -PI * 0.5f); // level 2 (bat trigger)
|
//reset(7, vec3(64108, -512, 16514), -PI * 0.5f); // level 2 (bat trigger)
|
||||||
//reset(15, vec3(70082, -512, 26935), PI * 0.5f); // level 2 (bear)
|
//reset(15, vec3(70082, -512, 26935), PI * 0.5f); // level 2 (bear)
|
||||||
//reset(63, vec3(31390, -2048, 33472), 0.0f); // level 2 (trap floor)
|
//reset(63, vec3(31390, -2048, 33472), 0.0f); // level 2 (trap floor)
|
||||||
@@ -783,8 +784,8 @@ struct Lara : Character {
|
|||||||
arms[i].animation.update();
|
arms[i].animation.update();
|
||||||
arms[i].shotTimer += Core::deltaTime;
|
arms[i].shotTimer += Core::deltaTime;
|
||||||
|
|
||||||
float intensity = clamp((0.1f - arms[i].shotTimer) * 20.0f, 0.0f, 1.0f);
|
float intensity = clamp((0.1f - arms[i].shotTimer) * 20.0f, EPS, 1.0f);
|
||||||
Core::lightColor[1 + i] = FLASH_LIGHT_COLOR * vec4(intensity, intensity, intensity, sqrtf(intensity));
|
Core::lightColor[1 + i] = FLASH_LIGHT_COLOR * vec4(intensity, intensity, intensity, 1.0f / sqrtf(intensity));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRifle)
|
if (isRifle)
|
||||||
@@ -1644,7 +1645,7 @@ struct Lara : Character {
|
|||||||
if ((state == STATE_STOP || state == STATE_SURF_TREAD || state == STATE_HANG) && fabsf(Input::joy.L.x) < 0.5f && fabsf(Input::joy.L.y) < 0.5f)
|
if ((state == STATE_STOP || state == STATE_SURF_TREAD || state == STATE_HANG) && fabsf(Input::joy.L.x) < 0.5f && fabsf(Input::joy.L.y) < 0.5f)
|
||||||
return input;
|
return input;
|
||||||
|
|
||||||
bool moving = state == STATE_RUN || state == STATE_WALK || state == STATE_BACK || state == STATE_FAST_BACK || state == STATE_SURF_SWIM || state == STATE_SURF_BACK;
|
bool moving = state == STATE_RUN || state == STATE_WALK || state == STATE_BACK || state == STATE_FAST_BACK || state == STATE_SURF_SWIM || state == STATE_SURF_BACK || state == STATE_FORWARD_JUMP;
|
||||||
|
|
||||||
if (!moving) {
|
if (!moving) {
|
||||||
if (fabsf(Input::joy.L.x) < fabsf(Input::joy.L.y))
|
if (fabsf(Input::joy.L.x) < fabsf(Input::joy.L.y))
|
||||||
|
@@ -485,7 +485,7 @@ struct Level : IGame {
|
|||||||
TR::Room::Light &light = level.rooms[room].lights[idx];
|
TR::Room::Light &light = level.rooms[room].lights[idx];
|
||||||
float c = 1.0f - intensityf(level.rooms[room].lights[idx].intensity);
|
float c = 1.0f - intensityf(level.rooms[room].lights[idx].intensity);
|
||||||
Core::lightPos[0] = vec3(float(light.x), float(light.y), float(light.z));
|
Core::lightPos[0] = vec3(float(light.x), float(light.y), float(light.z));
|
||||||
Core::lightColor[0] = vec4(c, c, c, (float)light.radius * (float)light.radius);
|
Core::lightColor[0] = vec4(c, c, c, 1.0f / (float)light.radius);
|
||||||
} else {
|
} else {
|
||||||
Core::lightPos[0] = vec3(0);
|
Core::lightPos[0] = vec3(0);
|
||||||
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
Core::lightColor[0] = vec4(0, 0, 0, 1);
|
||||||
|
43
src/mesh.h
43
src/mesh.h
@@ -9,7 +9,7 @@ typedef unsigned short Index;
|
|||||||
struct Vertex {
|
struct Vertex {
|
||||||
short4 coord; // xyz - position, w - unused
|
short4 coord; // xyz - position, w - unused
|
||||||
short4 texCoord; // xy - texture coordinates, z - anim tex range index, w - anim tex frame index
|
short4 texCoord; // xy - texture coordinates, z - anim tex range index, w - anim tex frame index
|
||||||
short4 normal; // xyz - vertex normal, w - disable lighting (0, 1)
|
short4 normal; // xyz - vertex normal<EFBFBD> w - unused
|
||||||
ubyte4 color; // xyz - color, w - intensity
|
ubyte4 color; // xyz - color, w - intensity
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ struct MeshRange {
|
|||||||
Vertex *v = (Vertex*)(vStart * sizeof(Vertex));
|
Vertex *v = (Vertex*)(vStart * sizeof(Vertex));
|
||||||
glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->coord);
|
glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->coord);
|
||||||
glVertexAttribPointer(aTexCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->texCoord);
|
glVertexAttribPointer(aTexCoord, 4, GL_SHORT, false, sizeof(Vertex), &v->texCoord);
|
||||||
glVertexAttribPointer(aNormal, 4, GL_SHORT, false, sizeof(Vertex), &v->normal);
|
glVertexAttribPointer(aNormal, 4, GL_SHORT, true, sizeof(Vertex), &v->normal);
|
||||||
glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->color);
|
glVertexAttribPointer(aColor, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), &v->color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,6 +40,7 @@ struct MeshRange {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#define PLANE_DETAIL 48
|
#define PLANE_DETAIL 48
|
||||||
|
#define CIRCLE_SEGS 16
|
||||||
|
|
||||||
struct Mesh {
|
struct Mesh {
|
||||||
GLuint ID[2];
|
GLuint ID[2];
|
||||||
@@ -123,7 +124,7 @@ float intensityf(int lighting) {
|
|||||||
if (lighting < 0) return 1.0f;
|
if (lighting < 0) return 1.0f;
|
||||||
float lum = 1.0f - (lighting >> 5) / 255.0f;
|
float lum = 1.0f - (lighting >> 5) / 255.0f;
|
||||||
//return powf(lum, 2.2f); // gamma to linear space
|
//return powf(lum, 2.2f); // gamma to linear space
|
||||||
return lum * lum; // gamma to "linear" space
|
return lum;// * lum; // gamma to "linear" space
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 intensity(int lighting) {
|
uint8 intensity(int lighting) {
|
||||||
@@ -146,7 +147,7 @@ struct MeshBuilder {
|
|||||||
// procedured
|
// procedured
|
||||||
MeshRange shadowBlob;
|
MeshRange shadowBlob;
|
||||||
MeshRange bar;
|
MeshRange bar;
|
||||||
MeshRange quad;
|
MeshRange quad, circle;
|
||||||
MeshRange plane;
|
MeshRange plane;
|
||||||
|
|
||||||
vec2 *animTexRanges;
|
vec2 *animTexRanges;
|
||||||
@@ -251,6 +252,13 @@ struct MeshBuilder {
|
|||||||
iCount += quad.iCount;
|
iCount += quad.iCount;
|
||||||
vCount += 4;
|
vCount += 4;
|
||||||
|
|
||||||
|
// circle
|
||||||
|
circle.vStart = vCount;
|
||||||
|
circle.iStart = iCount;
|
||||||
|
circle.iCount = CIRCLE_SEGS * 3;
|
||||||
|
iCount += circle.iCount;
|
||||||
|
vCount += CIRCLE_SEGS + 1;
|
||||||
|
|
||||||
// detailed plane
|
// detailed plane
|
||||||
plane.vStart = vCount;
|
plane.vStart = vCount;
|
||||||
plane.iStart = iCount;
|
plane.iStart = iCount;
|
||||||
@@ -395,6 +403,28 @@ struct MeshBuilder {
|
|||||||
vCount += 4;
|
vCount += 4;
|
||||||
aCount++;
|
aCount++;
|
||||||
|
|
||||||
|
// circle
|
||||||
|
vec2 pos(32767.0f, 0.0f);
|
||||||
|
vec2 cs(cos(PI2 / CIRCLE_SEGS), sin(PI2 / CIRCLE_SEGS));
|
||||||
|
|
||||||
|
for (int i = 0; i < CIRCLE_SEGS; i++) {
|
||||||
|
Vertex &v = vertices[vCount + i];
|
||||||
|
pos.rotate(cs);
|
||||||
|
v.coord = { short(pos.x), short(pos.y), 0, 0 };
|
||||||
|
v.normal = { 0, 0, 0, 0 };
|
||||||
|
v.color = { 255, 255, 255, 255 };
|
||||||
|
v.texCoord = { 32688, 32688, 0, 0 };
|
||||||
|
|
||||||
|
indices[iCount++] = i;
|
||||||
|
indices[iCount++] = (i + 1) % CIRCLE_SEGS;
|
||||||
|
indices[iCount++] = CIRCLE_SEGS;
|
||||||
|
}
|
||||||
|
vertices[vCount + CIRCLE_SEGS] = vertices[vCount];
|
||||||
|
vertices[vCount + CIRCLE_SEGS].coord = { 0, 0, 0, 0 };
|
||||||
|
|
||||||
|
vCount += CIRCLE_SEGS + 1;
|
||||||
|
aCount++;
|
||||||
|
|
||||||
// plane
|
// plane
|
||||||
for (int16 j = -PLANE_DETAIL; j <= PLANE_DETAIL; j++)
|
for (int16 j = -PLANE_DETAIL; j <= PLANE_DETAIL; j++)
|
||||||
for (int16 i = -PLANE_DETAIL; i <= PLANE_DETAIL; i++) {
|
for (int16 i = -PLANE_DETAIL; i <= PLANE_DETAIL; i++) {
|
||||||
@@ -439,6 +469,7 @@ struct MeshBuilder {
|
|||||||
mesh->initRange(shadowBlob);
|
mesh->initRange(shadowBlob);
|
||||||
mesh->initRange(bar);
|
mesh->initRange(bar);
|
||||||
mesh->initRange(quad);
|
mesh->initRange(quad);
|
||||||
|
mesh->initRange(circle);
|
||||||
mesh->initRange(plane);
|
mesh->initRange(plane);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -837,6 +868,10 @@ struct MeshBuilder {
|
|||||||
mesh->render(quad);
|
mesh->render(quad);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderCircle() {
|
||||||
|
mesh->render(circle);
|
||||||
|
}
|
||||||
|
|
||||||
void renderPlane() {
|
void renderPlane() {
|
||||||
mesh->render(plane);
|
mesh->render(plane);
|
||||||
}
|
}
|
||||||
|
@@ -3,20 +3,19 @@
|
|||||||
android:versionCode="1"
|
android:versionCode="1"
|
||||||
android:versionName="0.1" >
|
android:versionName="0.1" >
|
||||||
|
|
||||||
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14" />
|
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="9" />
|
||||||
<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.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="com.qti.permission.PROFILER" />
|
<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"
|
||||||
|
@@ -11,4 +11,4 @@
|
|||||||
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
|
||||||
|
|
||||||
# Project target.
|
# Project target.
|
||||||
target=android-14
|
target=android-9
|
||||||
|
@@ -21,13 +21,13 @@ import android.view.InputDevice;
|
|||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.View.OnGenericMotionListener;
|
//import android.view.View.OnGenericMotionListener;
|
||||||
import android.view.View.OnKeyListener;
|
import android.view.View.OnKeyListener;
|
||||||
import android.view.View.OnTouchListener;
|
import android.view.View.OnTouchListener;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
|
|
||||||
public class MainActivity extends Activity implements OnTouchListener, OnGenericMotionListener, OnKeyListener {
|
public class MainActivity extends Activity implements OnTouchListener/*, OnGenericMotionListener, OnKeyListener*/ {
|
||||||
private GLSurfaceView view;
|
private GLSurfaceView view;
|
||||||
//private GvrLayout gvrLayout;
|
//private GvrLayout gvrLayout;
|
||||||
private Wrapper wrapper;
|
private Wrapper wrapper;
|
||||||
@@ -49,15 +49,15 @@ public class MainActivity extends Activity implements OnTouchListener, OnGeneric
|
|||||||
view = new GLSurfaceView(this);
|
view = new GLSurfaceView(this);
|
||||||
view.setEGLContextClientVersion(2);
|
view.setEGLContextClientVersion(2);
|
||||||
view.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
|
view.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
|
||||||
view.setPreserveEGLContextOnPause(true);
|
// view.setPreserveEGLContextOnPause(true);
|
||||||
view.setRenderer(wrapper = new Wrapper());
|
view.setRenderer(wrapper = new Wrapper());
|
||||||
|
|
||||||
view.setFocusable(true);
|
view.setFocusable(true);
|
||||||
view.setFocusableInTouchMode(true);
|
view.setFocusableInTouchMode(true);
|
||||||
|
|
||||||
view.setOnTouchListener(this);
|
view.setOnTouchListener(this);
|
||||||
view.setOnGenericMotionListener(this);
|
// view.setOnGenericMotionListener(this);
|
||||||
view.setOnKeyListener(this);
|
// view.setOnKeyListener(this);
|
||||||
/*
|
/*
|
||||||
gvrLayout = new GvrLayout(this);
|
gvrLayout = new GvrLayout(this);
|
||||||
gvrLayout.setPresentationView(view);
|
gvrLayout.setPresentationView(view);
|
||||||
@@ -120,7 +120,7 @@ public class MainActivity extends Activity implements OnTouchListener, OnGeneric
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
private int getJoyIndex(InputDevice dev) {
|
private int getJoyIndex(InputDevice dev) {
|
||||||
int src = dev.getSources();
|
int src = dev.getSources();
|
||||||
if ((src & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD ||
|
if ((src & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD ||
|
||||||
@@ -185,6 +185,7 @@ public class MainActivity extends Activity implements OnTouchListener, OnGeneric
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
static {
|
static {
|
||||||
System.loadLibrary("game");
|
System.loadLibrary("game");
|
||||||
@@ -198,8 +199,10 @@ class Sound {
|
|||||||
private static AudioTrack audioTrack;
|
private static AudioTrack audioTrack;
|
||||||
|
|
||||||
public void start(final Wrapper wrapper) {
|
public void start(final Wrapper wrapper) {
|
||||||
int bufferSize = AudioTrack.getMinBufferSize(22050, AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT);
|
int bufSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_CONFIGURATION_STEREO, AudioFormat.ENCODING_PCM_16BIT);
|
||||||
|
System.out.println(String.format("sound buffer size: %d", bufSize));
|
||||||
|
int bufferSize = AudioTrack.getMinBufferSize(44100, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT);
|
||||||
|
System.out.println(String.format("sound buffer size: %d", bufferSize));
|
||||||
buffer = new short [bufferSize / 2];
|
buffer = new short [bufferSize / 2];
|
||||||
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
|
audioTrack = new AudioTrack(AudioManager.STREAM_MUSIC,
|
||||||
44100,
|
44100,
|
||||||
@@ -220,7 +223,7 @@ class Sound {
|
|||||||
audioTrack.flush();
|
audioTrack.flush();
|
||||||
} else
|
} else
|
||||||
try {
|
try {
|
||||||
Thread.sleep(100);
|
Thread.sleep(10);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
//
|
//
|
||||||
};
|
};
|
||||||
|
452
src/shader.glsl
452
src/shader.glsl
@@ -11,35 +11,53 @@ R"====(
|
|||||||
varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
||||||
|
|
||||||
#ifndef PASS_SHADOW
|
#ifndef PASS_SHADOW
|
||||||
#ifndef PASS_AMBIENT
|
varying vec4 vViewVec; // xyz - dir * dist, w - coord.y
|
||||||
varying vec3 vCoord;
|
uniform vec3 uViewPos;
|
||||||
varying vec4 vNormal;
|
|
||||||
varying vec3 vViewVec;
|
#ifndef TYPE_FLASH
|
||||||
|
#ifdef PASS_COMPOSE
|
||||||
|
varying vec4 vNormal; // xyz - normal dir, w - fog factor
|
||||||
varying vec4 vLightProj;
|
varying vec4 vLightProj;
|
||||||
#endif
|
varying vec3 vLightVec;
|
||||||
varying vec4 vColor;
|
|
||||||
uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
|
#ifdef OPT_SHADOW
|
||||||
|
varying vec3 vAmbient;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PASS_COMPOSE
|
uniform vec3 uLightPos[MAX_LIGHTS];
|
||||||
uniform vec3 uViewPos;
|
uniform vec4 uLightColor[MAX_LIGHTS]; // xyz - color, w - radius * intensity
|
||||||
uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height
|
#endif
|
||||||
#ifdef UNDERWATER
|
|
||||||
|
varying vec4 vDiffuse;
|
||||||
|
varying vec4 vLight; // 4 lights intensity
|
||||||
|
|
||||||
|
#if defined(OPT_WATER) && defined(UNDERWATER)
|
||||||
uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ
|
uniform vec4 uRoomSize; // xy - minXZ, zw - maxXZ
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(OPT_AMBIENT) && defined(TYPE_ENTITY)
|
||||||
|
uniform vec3 uAmbient[6];
|
||||||
|
|
||||||
|
vec3 calcAmbient(vec3 n) {
|
||||||
|
vec3 sqr = n * n;
|
||||||
|
vec3 pos = step(0.0, n);
|
||||||
|
return sqr.x * mix(uAmbient[1], uAmbient[0], pos.x) +
|
||||||
|
sqr.y * mix(uAmbient[3], uAmbient[2], pos.y) +
|
||||||
|
sqr.z * mix(uAmbient[5], uAmbient[4], pos.z);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uniform vec4 uParam; // x - time, y - water height, z - clip plane sign, w - clip plane height
|
||||||
|
uniform vec4 uMaterial; // x - diffuse, y - ambient, z - specular, w - alpha
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VERTEX
|
#ifdef VERTEX
|
||||||
uniform mat4 uViewProj;
|
uniform mat4 uViewProj;
|
||||||
|
|
||||||
#ifdef TYPE_ENTITY
|
uniform mat4 uViewInv;
|
||||||
uniform vec4 uBasis[32 * 2];
|
|
||||||
#else
|
|
||||||
uniform vec4 uBasis[2];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef PASS_AMBIENT
|
#ifndef PASS_AMBIENT
|
||||||
uniform mat4 uViewInv;
|
|
||||||
uniform mat4 uLightProj;
|
uniform mat4 uLightProj;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -48,6 +66,12 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
|||||||
uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
|
uniform vec2 uAnimTexOffsets[MAX_OFFSETS];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TYPE_ENTITY
|
||||||
|
uniform vec4 uBasis[32 * 2];
|
||||||
|
#else
|
||||||
|
uniform vec4 uBasis[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
attribute vec4 aCoord;
|
attribute vec4 aCoord;
|
||||||
attribute vec4 aTexCoord;
|
attribute vec4 aTexCoord;
|
||||||
|
|
||||||
@@ -69,9 +93,9 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
|||||||
return mulQuat(rot, v) + pos.xyz;
|
return mulQuat(rot, v) + pos.xyz;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
vec4 _transform() {
|
||||||
#ifdef TYPE_ENTITY
|
#ifdef TYPE_ENTITY
|
||||||
int index = int(aCoord.w) * 2;
|
int index = int(aCoord.w * 2.0);
|
||||||
vec4 rBasisRot = uBasis[index];
|
vec4 rBasisRot = uBasis[index];
|
||||||
vec4 rBasisPos = uBasis[index + 1];
|
vec4 rBasisPos = uBasis[index + 1];
|
||||||
#else
|
#else
|
||||||
@@ -81,54 +105,146 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
|||||||
|
|
||||||
vec4 coord = vec4(mulBasis(rBasisRot, rBasisPos, aCoord.xyz), rBasisPos.w);
|
vec4 coord = vec4(mulBasis(rBasisRot, rBasisPos, aCoord.xyz), rBasisPos.w);
|
||||||
|
|
||||||
|
#ifdef TYPE_SPRITE
|
||||||
|
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PASS_SHADOW
|
#ifndef PASS_SHADOW
|
||||||
vColor = aColor;
|
vViewVec = vec4((uViewPos - coord.xyz) * FOG_DIST, coord.y);
|
||||||
vColor.xyz *= uMaterial.x; // apply diffuse intensity
|
|
||||||
#ifdef TYPE_MIRROR
|
|
||||||
vColor.xyz *= vec3(0.6, 0.6, 4.0); // blue color dodge for crystal
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PASS_COMPOSE) && !defined(TYPE_FLASH)
|
||||||
|
#ifdef TYPE_SPRITE
|
||||||
|
vNormal.xyz = normalize(vViewVec.xyz);
|
||||||
|
#else
|
||||||
|
vNormal.xyz = normalize(mulQuat(rBasisRot, aNormal.xyz));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
float fog;
|
||||||
#ifdef UNDERWATER
|
#ifdef UNDERWATER
|
||||||
#ifndef TYPE_ENTITY
|
float d = abs((vViewVec.w - max(uViewPos.y, uParam.y)) / normalize(vViewVec.xyz).y);
|
||||||
vColor.xyz *= UNDERWATER_COLOR; // underwater blue color
|
d *= step(0.0, vViewVec.w - uParam.y);
|
||||||
|
fog = d * WATER_FOG_DIST;
|
||||||
|
#else
|
||||||
|
fog = length(vViewVec.xyz);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
vNormal.w = 1.0 - clamp(1.0 / exp(fog), 0.0, 1.0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return coord;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _diffuse() {
|
||||||
|
#if !defined(PASS_SHADOW) && !defined(TYPE_FLASH)
|
||||||
|
vDiffuse = vec4(aColor.xyz * (uMaterial.x * 2.0), uMaterial.w);
|
||||||
|
|
||||||
|
#ifdef UNDERWATER
|
||||||
|
vDiffuse.xyz *= UNDERWATER_COLOR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TYPE_MIRROR
|
||||||
|
vDiffuse.xyz *= vec3(0.3, 0.3, 2.0); // blue color dodge for crystal
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void _lighting(vec3 coord) {
|
||||||
|
#ifndef TYPE_FLASH
|
||||||
|
#ifdef PASS_COMPOSE
|
||||||
|
vec3 lv0 = (uLightPos[0].xyz - coord) * uLightColor[0].w;
|
||||||
|
vec3 lv1 = (uLightPos[1].xyz - coord) * uLightColor[1].w;
|
||||||
|
vec3 lv2 = (uLightPos[2].xyz - coord) * uLightColor[2].w;
|
||||||
|
vec3 lv3 = vec3(0.0);
|
||||||
|
|
||||||
|
vLightVec = lv0;
|
||||||
|
|
||||||
|
vec4 lum, att;
|
||||||
|
#ifdef TYPE_ENTITY
|
||||||
|
lum.x = dot(vNormal.xyz, normalize(lv0)); att.x = dot(lv0, lv0);
|
||||||
|
#else
|
||||||
|
lum.x = aColor.w; att.x = 0.0;
|
||||||
|
|
||||||
|
#ifdef TYPE_SPRITE
|
||||||
|
lum.x *= uMaterial.y;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
lum.y = dot(vNormal.xyz, normalize(lv1)); att.y = dot(lv1, lv1);
|
||||||
|
lum.z = dot(vNormal.xyz, normalize(lv2)); att.z = dot(lv2, lv2);
|
||||||
|
lum.w = dot(vNormal.xyz, normalize(lv3)); att.w = dot(lv3, lv3);
|
||||||
|
vec4 light = max(vec4(0.0), lum) * max(vec4(0.0), vec4(1.0) - att);
|
||||||
|
|
||||||
|
#ifdef UNDERWATER
|
||||||
|
light.x *= abs(sin(dot(coord.xyz, vec3(1.0 / 512.0)) + uParam.x)) * 1.5 + 0.5;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec3 ambient;
|
||||||
|
#ifdef TYPE_ENTITY
|
||||||
|
|
||||||
|
#ifdef OPT_AMBIENT
|
||||||
|
ambient = calcAmbient(vNormal.xyz);
|
||||||
|
#else
|
||||||
|
ambient = vec3(uMaterial.y);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
ambient = vec3(min(uMaterial.y, light.x));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef OPT_SHADOW
|
||||||
|
vAmbient = ambient;
|
||||||
|
vLight = light;
|
||||||
|
#else
|
||||||
|
vLight.w = 0.0;
|
||||||
|
vLight.xyz = uLightColor[1].xyz * light.y + uLightColor[2].xyz * light.z;
|
||||||
|
|
||||||
|
#ifdef TYPE_ENTITY
|
||||||
|
vLight.xyz += ambient + uLightColor[0].xyz * light.x;
|
||||||
|
#else
|
||||||
|
vLight.xyz += light.x;
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PASS_COMPOSE
|
#ifdef PASS_AMBIENT
|
||||||
#ifndef TYPE_SPRITE
|
vLight = aColor.wwww;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void _uv(vec3 coord) {
|
||||||
|
#if defined(PASS_COMPOSE) && !defined(TYPE_SPRITE)
|
||||||
// animated texture coordinates
|
// animated texture coordinates
|
||||||
vec2 range = uAnimTexRanges[int(aTexCoord.z)]; // x - start index, y - count
|
vec2 range = uAnimTexRanges[int(aTexCoord.z)]; // x - start index, y - count
|
||||||
|
float frame = fract((aTexCoord.w + uParam.x * 4.0 - range.x) / range.y) * range.y;
|
||||||
float f = fract((aTexCoord.w + uParam.x * 4.0 - range.x) / range.y) * range.y;
|
vec2 offset = uAnimTexOffsets[int(range.x + frame)]; // texCoord offset from first frame
|
||||||
vec2 offset = uAnimTexOffsets[int(range.x + f)]; // texCoord offset from first frame
|
vTexCoord.xy = (aTexCoord.xy + offset) * TEXCOORD_SCALE;
|
||||||
|
|
||||||
vTexCoord.xy = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated
|
|
||||||
vNormal = vec4(mulQuat(rBasisRot, aNormal.xyz), aNormal.w);
|
|
||||||
|
|
||||||
#ifdef UNDERWATER
|
|
||||||
float sum = coord.x + coord.y + coord.z;
|
|
||||||
vColor.xyz *= abs(sin(sum / 512.0 + uParam.x)) * 1.5 + 0.5; // color dodge
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
coord.xyz += uViewInv[0].xyz * aTexCoord.z - uViewInv[1].xyz * aTexCoord.w;
|
|
||||||
vTexCoord.xy = aTexCoord.xy * TEXCOORD_SCALE;
|
vTexCoord.xy = aTexCoord.xy * TEXCOORD_SCALE;
|
||||||
vNormal = vec4(uViewPos.xyz - coord.xyz, 0.0);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef UNDERWATER
|
#if defined(OPT_WATER) && defined(UNDERWATER)
|
||||||
vTexCoord.zw = clamp((coord.xz - uRoomSize.xy) / (uRoomSize.zw - uRoomSize.xy), vec2(0.0), vec2(1.0));
|
vTexCoord.zw = clamp((coord.xz - uRoomSize.xy) / (uRoomSize.zw - uRoomSize.xy), vec2(0.0), vec2(1.0));
|
||||||
#else
|
#else
|
||||||
vTexCoord.zw = vec2(1.0);
|
vTexCoord.zw = vec2(1.0);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
vViewVec = uViewPos - coord.xyz;
|
void main() {
|
||||||
|
vec4 coord = _transform();
|
||||||
|
|
||||||
|
#ifndef PASS_SHADOW
|
||||||
|
_diffuse();
|
||||||
|
_lighting(coord.xyz);
|
||||||
|
|
||||||
|
#if defined(PASS_COMPOSE) && !defined(TYPE_FLASH)
|
||||||
vLightProj = uLightProj * coord;
|
vLightProj = uLightProj * coord;
|
||||||
|
|
||||||
vCoord = coord.xyz;
|
|
||||||
#else
|
|
||||||
vTexCoord.xy = aTexCoord.xy * TEXCOORD_SCALE;
|
|
||||||
vTexCoord.zw = vec2(0.0);
|
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
_uv(coord.xyz);
|
||||||
|
|
||||||
gl_Position = uViewProj * coord;
|
gl_Position = uViewProj * coord;
|
||||||
}
|
}
|
||||||
@@ -143,13 +259,6 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
|||||||
#ifdef TYPE_MIRROR
|
#ifdef TYPE_MIRROR
|
||||||
uniform samplerCube sEnvironment;
|
uniform samplerCube sEnvironment;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef OPT_AMBIENT
|
|
||||||
uniform vec3 uAmbient[6];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uniform vec3 uLightPos[MAX_LIGHTS];
|
|
||||||
uniform vec4 uLightColor[MAX_LIGHTS];
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PASS_SHADOW
|
#ifdef PASS_SHADOW
|
||||||
@@ -166,7 +275,7 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
|||||||
|
|
||||||
#ifdef PASS_COMPOSE
|
#ifdef PASS_COMPOSE
|
||||||
|
|
||||||
#ifdef OPT_SHADOW
|
#if defined(OPT_SHADOW) && !defined(TYPE_FLASH)
|
||||||
#ifdef SHADOW_SAMPLER
|
#ifdef SHADOW_SAMPLER
|
||||||
uniform sampler2DShadow sShadow;
|
uniform sampler2DShadow sShadow;
|
||||||
#ifdef GL_ES
|
#ifdef GL_ES
|
||||||
@@ -190,207 +299,162 @@ varying vec4 vTexCoord; // xy - atlas coords, zw - caustics coords
|
|||||||
|
|
||||||
float SHADOW(vec3 p) {
|
float SHADOW(vec3 p) {
|
||||||
return compare(p.xy, p.z);
|
return compare(p.xy, p.z);
|
||||||
/*
|
|
||||||
vec2 t = vec2(0.0, 1.0 / 1024.0);
|
|
||||||
vec2 c = floor(p.xy * 1024.0 + 0.5) / 1024.0;
|
|
||||||
vec4 s;
|
|
||||||
s.x = compare(c + t.xx, p.z);
|
|
||||||
s.y = compare(c + t.xy, p.z);
|
|
||||||
s.z = compare(c + t.yx, p.z);
|
|
||||||
s.w = compare(c + t.yy, p.z);
|
|
||||||
vec2 f = fract(p.xy * 1024.0 + 0.5);
|
|
||||||
return mix(mix(s.x, s.y, f.y), mix(s.z, s.w, f.y), f.x);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define SHADOW_TEXEL (1.5 / 1024.0)
|
#define SHADOW_TEXEL (2.0 / 1024.0)
|
||||||
|
|
||||||
|
float random(vec3 seed, float freq) {
|
||||||
|
float dt = dot(floor(seed * freq), vec3(53.1215, 21.1352, 9.1322));
|
||||||
|
return fract(sin(dt) * 2105.2354);
|
||||||
|
}
|
||||||
|
|
||||||
|
float randomAngle(vec3 seed, float freq) {
|
||||||
|
return random(seed, freq) * 6.283285;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 rotate(vec2 sc, vec2 v) {
|
||||||
|
return vec3(v.x * sc.y + v.y * sc.x, v.x * -sc.x + v.y * sc.y, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
float getShadow(vec4 lightProj) {
|
float getShadow(vec4 lightProj) {
|
||||||
vec3 p = lightProj.xyz / lightProj.w;
|
vec3 p = lightProj.xyz / lightProj.w;
|
||||||
|
|
||||||
float rShadow = 0.0;
|
float rShadow = SHADOW(SHADOW_TEXEL * vec3(-0.93289, -0.03146, 0.0) + p) +
|
||||||
rShadow += SHADOW(p + (vec3(-0.94201624, -0.39906216, 0.0) * SHADOW_TEXEL));
|
SHADOW(SHADOW_TEXEL * vec3( 0.81628, -0.05965, 0.0) + p) +
|
||||||
rShadow += SHADOW(p + (vec3( 0.94558609, -0.76890725, 0.0) * SHADOW_TEXEL));
|
SHADOW(SHADOW_TEXEL * vec3(-0.18455, 0.97225, 0.0) + p) +
|
||||||
rShadow += SHADOW(p + (vec3(-0.09418410, -0.92938870, 0.0) * SHADOW_TEXEL));
|
SHADOW(SHADOW_TEXEL * vec3( 0.04032, -0.85898, 0.0) + p);
|
||||||
rShadow += SHADOW(p + (vec3( 0.34495938, 0.29387760, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3(-0.91588581, 0.45771432, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3(-0.81544232, -0.87912464, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3(-0.38277543, 0.27676845, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3( 0.97484398, 0.75648379, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3( 0.44323325, -0.97511554, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3( 0.53742981, -0.47373420, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3(-0.26496911, -0.41893023, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3( 0.79197514, 0.19090188, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3(-0.24188840, 0.99706507, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3(-0.81409955, 0.91437590, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3( 0.19984126, 0.78641367, 0.0) * SHADOW_TEXEL));
|
|
||||||
rShadow += SHADOW(p + (vec3( 0.14383161, -0.14100790, 0.0) * SHADOW_TEXEL));
|
|
||||||
|
|
||||||
rShadow /= 16.0;
|
if (rShadow > 0.1 && rShadow < 3.9) {
|
||||||
|
float angle = randomAngle(vTexCoord.xyy, 15.0);
|
||||||
|
vec2 sc = vec2(sin(angle), cos(angle));
|
||||||
|
|
||||||
vec3 lv = uLightPos[0].xyz - vCoord.xyz;
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2(-0.54316, 0.21186)) + p);
|
||||||
float fade = clamp(dot(lv, lv) / uLightColor[0].w, 0.0, 1.0);
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2(-0.03925, -0.34345)) + p);
|
||||||
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2( 0.07695, 0.40667)) + p);
|
||||||
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2(-0.66378, -0.54068)) + p);
|
||||||
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2(-0.54130, 0.66730)) + p);
|
||||||
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2( 0.69301, 0.46990)) + p);
|
||||||
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2( 0.37228, 0.03811)) + p);
|
||||||
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2( 0.28597, 0.80228)) + p);
|
||||||
|
rShadow += SHADOW(SHADOW_TEXEL * rotate(sc, vec2( 0.44801, -0.43844)) + p);
|
||||||
|
rShadow /= 13.0;
|
||||||
|
} else
|
||||||
|
rShadow /= 4.0;
|
||||||
|
|
||||||
|
vec3 lv = vLightVec;
|
||||||
|
float fade = clamp(dot(lv, lv), 0.0, 1.0);
|
||||||
|
|
||||||
return mix(rShadow, 1.0, fade);
|
return mix(rShadow, 1.0, fade);
|
||||||
}
|
}
|
||||||
|
|
||||||
float getShadow() {
|
float getShadow() {
|
||||||
return min(dot(vNormal.xyz, uLightPos[0].xyz - vCoord), vLightProj.w) > 0.0 ? getShadow(vLightProj) : 1.0;
|
return min(dot(vNormal.xyz, vLightVec), vLightProj.w) > 0.0 ? getShadow(vLightProj) : 1.0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec3 calcLight(vec3 normal, vec3 pos, vec4 color) {
|
float calcSpecular(vec3 normal, vec3 viewVec, vec3 lightVec, vec4 color, float intensity) {
|
||||||
vec3 lv = pos - vCoord.xyz;
|
vec3 vv = normalize(viewVec);
|
||||||
float lum = max(0.0, dot(normal, normalize(lv)));
|
vec3 rv = reflect(-vv, normal);
|
||||||
float att = max(0.0, 1.0 - dot(lv, lv) / color.w);
|
vec3 lv = normalize(lightVec);
|
||||||
return color.xyz * (lum * att);
|
return pow(max(0.0, dot(rv, lv)), 8.0) * intensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 calcSpecular(vec3 normal, vec3 viewVec, vec3 pos, vec4 color, float intensity) {
|
#if defined(OPT_WATER) && defined(UNDERWATER)
|
||||||
vec3 rv = reflect(-viewVec, normal);
|
|
||||||
vec3 lv = normalize(pos - vCoord.xyz);
|
|
||||||
float spec = pow(max(0.0, dot(rv, lv)), 8.0) * intensity;
|
|
||||||
return vec3(spec);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef OPT_AMBIENT
|
|
||||||
vec3 calcAmbient(vec3 n) {
|
|
||||||
vec3 sqr = n * n;
|
|
||||||
vec3 pos = step(0.0, n);
|
|
||||||
return sqr.x * mix(uAmbient[1], uAmbient[0], pos.x) +
|
|
||||||
sqr.y * mix(uAmbient[3], uAmbient[2], pos.y) +
|
|
||||||
sqr.z * mix(uAmbient[5], uAmbient[4], pos.z);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(UNDERWATER) && defined(OPT_WATER)
|
|
||||||
float calcCaustics(vec3 n) {
|
float calcCaustics(vec3 n) {
|
||||||
vec2 fade = smoothstep(uRoomSize.xy, uRoomSize.xy + vec2(256.0), vCoord.xz) * (1.0 - smoothstep(uRoomSize.zw - vec2(256.0), uRoomSize.zw, vCoord.xz));
|
vec2 border = vec2(256.0) / (uRoomSize.zw - uRoomSize.xy);
|
||||||
return texture2D(sReflect, vTexCoord.zw).g * (max(0.0, -n.y)) * fade.x * fade.y;
|
vec2 fade = smoothstep(vec2(0.0), border, vTexCoord.zw) * (1.0 - smoothstep(vec2(1.0) - border, vec2(1.0), vTexCoord.zw));
|
||||||
|
return texture2D(sReflect, vTexCoord.zw).g * max(0.0, -n.y) * fade.x * fade.y;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vec3 applyFog(vec3 color, vec3 fogColor, float factor) {
|
|
||||||
float fog = clamp(1.0 / exp(factor), 0.0, 1.0);
|
|
||||||
return mix(fogColor, color, fog);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
#ifndef PASS_SHADOW
|
#ifdef PASS_COMPOSE
|
||||||
#ifndef PASS_AMBIENT
|
|
||||||
#ifdef CLIP_PLANE
|
#ifdef CLIP_PLANE
|
||||||
if (vCoord.y * uParam.z > uParam.w)
|
if (vViewVec.w * uParam.z > uParam.w)
|
||||||
discard;
|
discard;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
vec4 color = texture2D(sDiffuse, vTexCoord.xy);
|
vec4 color;
|
||||||
|
#ifdef TYPE_MIRROR
|
||||||
|
#ifdef PASS_COMPOSE
|
||||||
|
vec3 rv = reflect(-normalize(vViewVec.xyz), normalize(vNormal.xyz));
|
||||||
|
color = textureCube(sEnvironment, normalize(rv));
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
color = texture2D(sDiffuse, vTexCoord.xy);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef ALPHA_TEST
|
#ifdef ALPHA_TEST
|
||||||
if (color.w <= 0.1)
|
if (color.w <= 0.5)
|
||||||
discard;
|
discard;
|
||||||
//color.xyz *= vec3(1.0, 0.0, 0.0);
|
#endif
|
||||||
|
|
||||||
|
#ifndef PASS_SHADOW
|
||||||
|
#ifdef TYPE_FLASH
|
||||||
|
color *= uMaterial.xxxw;
|
||||||
|
#else
|
||||||
|
color *= vDiffuse;
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PASS_SHADOW
|
#ifdef PASS_SHADOW
|
||||||
|
|
||||||
#ifdef SHADOW_COLOR
|
#ifdef SHADOW_COLOR
|
||||||
gl_FragColor = pack(gl_FragCoord.z);
|
gl_FragColor = pack(gl_FragCoord.z);
|
||||||
#else
|
#else
|
||||||
gl_FragColor = vec4(1.0);
|
gl_FragColor = vec4(1.0);
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
color.xyz *= vColor.xyz;
|
|
||||||
color.xyz *= color.xyz; // to "linear" space
|
|
||||||
|
|
||||||
#ifdef PASS_AMBIENT
|
|
||||||
color.xyz *= vColor.w;
|
|
||||||
#else
|
#else
|
||||||
// calc point lights
|
|
||||||
#ifndef TYPE_FLASH
|
#ifndef TYPE_FLASH
|
||||||
vec3 normal = normalize(vNormal.xyz);
|
#ifdef OPT_SHADOW
|
||||||
vec3 viewVec = normalize(vViewVec);
|
#ifdef PASS_COMPOSE
|
||||||
vec3 light = vec3(0.0);
|
vec3 light = uLightColor[1].xyz * vLight.y + uLightColor[2].xyz * vLight.z;
|
||||||
|
|
||||||
#ifdef OPT_LIGHTING
|
#ifdef TYPE_ENTITY
|
||||||
light += calcLight(normal, uLightPos[1], uLightColor[1]);
|
light += vAmbient + uLightColor[0].xyz * (vLight.x * getShadow());
|
||||||
light += calcLight(normal, uLightPos[2], uLightColor[2]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// apply lighting
|
|
||||||
#ifdef TYPE_SPRITE
|
|
||||||
light += vColor.w * uMaterial.y; // apply diffuse intensity
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TYPE_ROOM
|
#ifdef TYPE_ROOM
|
||||||
#ifdef OPT_SHADOW
|
vec3 n = normalize(vNormal.xyz);
|
||||||
light += mix(min(uMaterial.y, vColor.w), vColor.w, getShadow());
|
light += mix(vAmbient.x, vLight.x, getShadow());
|
||||||
#else
|
#if defined(OPT_WATER) && defined(UNDERWATER)
|
||||||
light += vColor.w;
|
light += calcCaustics(n);
|
||||||
#endif
|
|
||||||
#if defined(UNDERWATER) && defined(OPT_WATER)
|
|
||||||
light += calcCaustics(normal);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TYPE_ENTITY
|
#ifdef TYPE_SPRITE
|
||||||
vec3 mainLight = calcLight(normal, uLightPos[0], uLightColor[0]);
|
light += vLight.x;
|
||||||
float mainSpec = uMaterial.z;
|
|
||||||
|
|
||||||
#ifdef OPT_SHADOW
|
|
||||||
float rShadow = getShadow();
|
|
||||||
mainLight *= rShadow;
|
|
||||||
mainSpec *= rShadow;
|
|
||||||
#endif
|
|
||||||
light += mainLight;
|
|
||||||
|
|
||||||
#ifdef OPT_AMBIENT
|
|
||||||
light += calcAmbient(normal);
|
|
||||||
#else
|
|
||||||
light += uMaterial.y;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNDERWATER
|
|
||||||
if (vCoord.y > uParam.y) {
|
|
||||||
color.xyz *= UNDERWATER_COLOR;
|
|
||||||
#ifdef OPT_WATER
|
|
||||||
light += calcCaustics(normal);
|
|
||||||
#endif
|
|
||||||
} else
|
|
||||||
color.xyz += calcSpecular(normal, viewVec, uLightPos[0], uLightColor[0], mainSpec + 0.03);
|
|
||||||
#else
|
|
||||||
color.xyz += calcSpecular(normal, viewVec, uLightPos[0], uLightColor[0], mainSpec + 0.03);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef TYPE_MIRROR
|
||||||
color.xyz *= light;
|
color.xyz *= light;
|
||||||
|
|
||||||
#else // ifndef TYPE_FLASH
|
|
||||||
|
|
||||||
color.w *= uMaterial.w;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
color.xyz = sqrt(color.xyz); // back to "gamma" space
|
#ifdef PASS_AMBIENT
|
||||||
|
color.xyz *= vLight.x;
|
||||||
#ifdef PASS_COMPOSE
|
|
||||||
#ifdef TYPE_MIRROR
|
|
||||||
vec3 rv = reflect(-normalize(vViewVec), normalize(vNormal.xyz));
|
|
||||||
color.xyz = vColor.xyz * textureCube(sEnvironment, normalize(rv)).xyz;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
color.xyz = applyFog(color.xyz, vec3(0.0), length(vViewVec) * FOG_DIST);
|
#else
|
||||||
#if defined(UNDERWATER) && defined(OPT_WATER)
|
#ifndef TYPE_MIRROR
|
||||||
float d = abs((vCoord.y - max(uViewPos.y, uParam.y)) / normalize(vViewVec).y);
|
color.xyz *= vLight.xyz;
|
||||||
d *= step(0.0, vCoord.y - uParam.y);
|
|
||||||
color.xyz = applyFog(color.xyz, UNDERWATER_COLOR * 0.2, d * WATER_FOG_DIST);
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
color.xyz *= 1.5; // add contrast
|
#if defined(PASS_COMPOSE) && !defined(TYPE_FLASH)
|
||||||
|
#ifdef UNDERWATER
|
||||||
|
color.xyz = mix(color.xyz, UNDERWATER_COLOR * 0.2, vNormal.w);
|
||||||
|
#else
|
||||||
|
color.xyz = mix(color.xyz, vec3(0.0), vNormal.w);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
gl_FragColor = color;
|
gl_FragColor = color;
|
||||||
#endif
|
#endif
|
||||||
|
179
src/ui.h
Normal file
179
src/ui.h
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
#ifndef H_UI
|
||||||
|
#define H_UI
|
||||||
|
|
||||||
|
#include "core.h"
|
||||||
|
#include "controller.h"
|
||||||
|
|
||||||
|
struct UI {
|
||||||
|
enum TouchButton { bWeapon, bWalk, bAction, bJump, bMAX };
|
||||||
|
enum TouchZone { zMove, zLook, zButton, zMAX };
|
||||||
|
|
||||||
|
IGame *game;
|
||||||
|
float touchTimerVis, touchTimerTap;
|
||||||
|
InputKey touch[zMAX];
|
||||||
|
TouchButton btn;
|
||||||
|
vec2 btnPos[bMAX];
|
||||||
|
float btnRadius;
|
||||||
|
bool doubleTap;
|
||||||
|
|
||||||
|
UI(IGame *game) : game(game), touchTimerVis(0.0f), touchTimerTap(0.0f), doubleTap(false) {
|
||||||
|
touch[zMove] = touch[zLook] = touch[zButton] = ikNone;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkTouchZone(TouchZone zone) {
|
||||||
|
InputKey &t = touch[zone];
|
||||||
|
if (t != ikNone && !Input::down[t]) {
|
||||||
|
t = ikNone;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getTouchDir(InputKey touch, vec2 &dir) {
|
||||||
|
vec2 delta = vec2(0.0f);
|
||||||
|
if (touch == ikNone)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Input::Touch &t = Input::touch[touch - ikTouchA];
|
||||||
|
vec2 d = t.pos - t.start;
|
||||||
|
float len = d.length();
|
||||||
|
if (len > EPS)
|
||||||
|
delta = d * (min(len / 100.0f, 1.0f) / len);
|
||||||
|
|
||||||
|
dir = delta;
|
||||||
|
}
|
||||||
|
|
||||||
|
void getTouchButton(const vec2 &pos) {
|
||||||
|
btn = bMAX;
|
||||||
|
float minDist = 1000.0f;
|
||||||
|
for (int i = 0; i < bMAX; i++) {
|
||||||
|
float d = (pos - btnPos[i]).length();
|
||||||
|
if (d < minDist) {
|
||||||
|
minDist = d;
|
||||||
|
btn = TouchButton(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void touchSetDown(bool down) {
|
||||||
|
switch (btn) {
|
||||||
|
case bWeapon : Input::setDown(ikJoyY, down); break;
|
||||||
|
case bWalk : Input::setDown(ikJoyLB, down); break;
|
||||||
|
case bAction : Input::setDown(ikJoyA, down); break;
|
||||||
|
case bJump : Input::setDown(ikJoyX, down); break;
|
||||||
|
default : ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
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
|
||||||
|
if (touchTimerVis > 0.0f)
|
||||||
|
touchTimerVis = max(0.0f, touchTimerVis - Core::deltaTime);
|
||||||
|
|
||||||
|
// update buttons
|
||||||
|
float offset = Core::height * 0.25f;
|
||||||
|
float radius = offset;
|
||||||
|
vec2 center = vec2(Core::width - offset * 0.7f, Core::height - offset * 0.7f);
|
||||||
|
|
||||||
|
btnPos[bWeapon] = center;
|
||||||
|
btnPos[bJump] = center + vec2(cos(-PI * 0.5f), sin(-PI * 0.5f)) * radius;
|
||||||
|
btnPos[bAction] = center + vec2(cos(-PI * 3.0f / 4.0f), sin(-PI * 3.0f / 4.0f)) * radius;
|
||||||
|
btnPos[bWalk] = center + vec2(cos(-PI), sin(-PI)) * radius;
|
||||||
|
btnRadius = Core::height * (25.0f / 1080.0f);
|
||||||
|
|
||||||
|
// touch update
|
||||||
|
if (checkTouchZone(zMove))
|
||||||
|
Input::joy.L = vec2(0.0f);
|
||||||
|
|
||||||
|
if (checkTouchZone(zLook))
|
||||||
|
Input::joy.R = vec2(0.0f);
|
||||||
|
|
||||||
|
if (checkTouchZone(zButton))
|
||||||
|
touchSetDown(false);
|
||||||
|
|
||||||
|
if (doubleTap) {
|
||||||
|
doubleTap = false;
|
||||||
|
Input::setDown(ikJoyB, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
float zoneSize = Core::width / 3.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < COUNT(Input::touch); i++) {
|
||||||
|
InputKey key = InputKey(i + ikTouchA);
|
||||||
|
|
||||||
|
if (!Input::down[key]) continue;
|
||||||
|
if (key == touch[zMove] || key == touch[zLook] || key == touch[zButton]) continue;
|
||||||
|
|
||||||
|
int zone = clamp(int(Input::touch[i].pos.x / zoneSize), 0, 2);
|
||||||
|
InputKey &t = touch[zone];
|
||||||
|
|
||||||
|
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)
|
||||||
|
doubleTap = true;
|
||||||
|
touchTimerTap = 0.0f;
|
||||||
|
} else
|
||||||
|
touchTimerTap = 0.5f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// set active touches as gamepad controls
|
||||||
|
getTouchDir(touch[zMove], Input::joy.L);
|
||||||
|
getTouchDir(touch[zLook], Input::joy.R);
|
||||||
|
if (touch[zButton] != ikNone) {
|
||||||
|
getTouchButton(Input::touch[touch[zButton] - ikTouchA].pos);
|
||||||
|
touchSetDown(true);
|
||||||
|
}
|
||||||
|
if (doubleTap)
|
||||||
|
Input::setDown(ikJoyB, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderControl(const vec2 &pos, const vec2 &size, const vec4 &color) {
|
||||||
|
Core::active.shader->setParam(uPosScale, vec4(pos, size * vec2(1.0f / 32767.0f)));
|
||||||
|
Core::active.shader->setParam(uMaterial, color);
|
||||||
|
game->getMesh()->renderCircle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderTouch() {
|
||||||
|
if (touchTimerVis <= 0.0f) return;
|
||||||
|
|
||||||
|
Core::setDepthTest(false);
|
||||||
|
Core::setBlending(bmAlpha);
|
||||||
|
Core::setCulling(cfNone);
|
||||||
|
|
||||||
|
Core::mViewProj = mat4(0.0f, float(Core::width), float(Core::height), 0.0f, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
game->setShader(Core::passGUI, Shader::NONE);
|
||||||
|
|
||||||
|
float offset = Core::height * 0.25f;
|
||||||
|
|
||||||
|
vec2 pos = vec2(offset, Core::height - offset);
|
||||||
|
if (Input::down[touch[zMove]]) {
|
||||||
|
Input::Touch &t = Input::touch[touch[zMove] - ikTouchA];
|
||||||
|
renderControl(t.pos, vec2(btnRadius), vec4(0.5f));
|
||||||
|
pos = t.start;
|
||||||
|
}
|
||||||
|
renderControl(pos, vec2(btnRadius), vec4(0.5f));
|
||||||
|
|
||||||
|
for (int i = 0; i < bMAX; i++)
|
||||||
|
renderControl(btnPos[i], vec2(btnRadius), vec4(0.5f));
|
||||||
|
|
||||||
|
Core::setCulling(cfFront);
|
||||||
|
Core::setBlending(bmNone);
|
||||||
|
Core::setDepthTest(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderBar(const vec2 &pos, const vec2 &size, float value) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@@ -167,6 +167,8 @@ struct vec2 {
|
|||||||
float length() const { return sqrtf(length2()); }
|
float length() const { return sqrtf(length2()); }
|
||||||
vec2 normal() const { float s = length(); return s == 0.0 ? (*this) : (*this)*(1.0f/s); }
|
vec2 normal() const { float s = length(); return s == 0.0 ? (*this) : (*this)*(1.0f/s); }
|
||||||
float angle() const { return atan2f(y, x); }
|
float angle() const { return atan2f(y, x); }
|
||||||
|
vec2& rotate(const vec2 &cs) { *this = vec2(x*cs.x - y*cs.y, x*cs.y + y*cs.x); return *this; }
|
||||||
|
vec2& rotate(float angle) { return rotate(vec2(cosf(angle), sinf(angle))); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vec3 {
|
struct vec3 {
|
||||||
|
Reference in New Issue
Block a user