diff --git a/src/core.h b/src/core.h index b9e7faa..2b686e2 100644 --- a/src/core.h +++ b/src/core.h @@ -139,7 +139,7 @@ namespace Core { vec4 lightColor[MAX_LIGHTS]; vec4 color; - enum Pass { passCompose, passShadow, passAmbient } pass; + enum Pass { passCompose, passShadow, passAmbient, passFilter } pass; GLuint RT, RB; diff --git a/src/filter.glsl b/src/filter.glsl new file mode 100644 index 0000000..8920e96 --- /dev/null +++ b/src/filter.glsl @@ -0,0 +1,34 @@ +R"====( +varying vec2 vTexCoord; + +#define TYPE_DOWNSAMPLE 10 + +uniform int uType; + +#ifdef VERTEX + attribute vec4 aCoord; + + void main() { + vTexCoord = aCoord.zw; + gl_Position = vec4(aCoord.xy, 1.0, 1.0); + } +#else + uniform sampler2D sDiffuse; + + vec4 downsample() { + vec4 color = texture2D(sDiffuse, vTexCoord); + return vec4(vec3((color.x + color.y + color.z) / 3.0), color.w); + } + + vec4 filter() { + if (uType == TYPE_DOWNSAMPLE) { + return downsample(); + } + return vec4(1.0, 0.0, 0.0, 1.0); + } + + void main() { + gl_FragColor = filter(); + } +#endif +)====" \ No newline at end of file diff --git a/src/level.h b/src/level.h index 089e603..96e87c9 100644 --- a/src/level.h +++ b/src/level.h @@ -17,12 +17,16 @@ const char SHADER[] = #include "shader.glsl" ; +const char FILTER[] = + #include "filter.glsl" +; + const char GUI[] = #include "gui.glsl" ; struct Level { - enum { shCompose, shShadow, shAmbient, shGUI, shMAX }; + enum { shCompose, shShadow, shAmbient, shFilter, shGUI, shMAX }; TR::Level level; Shader *shaders[shMAX]; @@ -226,6 +230,7 @@ struct Level { shaders[shShadow] = new Shader(SHADER, def); sprintf(def, "%s#define PASS_AMBIENT\n", ext); shaders[shAmbient] = new Shader(SHADER, def); + shaders[shFilter] = new Shader(FILTER, ""); shaders[shGUI] = new Shader(GUI, ""); } @@ -637,11 +642,26 @@ struct Level { case Core::passCompose : sh = shaders[shCompose]; break; case Core::passShadow : sh = shaders[shShadow]; break; case Core::passAmbient : sh = shaders[shAmbient]; break; + case Core::passFilter : sh = shaders[shFilter]; break; } ASSERT(sh); sh->bind(); } + + void readAmbientResult() { + Core::setTarget(ambient[0]); + 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); + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); + glReadPixels(0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &color); + // LOG("%d %d %d %d\n", (int)color.r, (int)color.g, (int)color.b, (int)color.a); + Core::setTarget(NULL); + } + void renderAmbient(int roomIndex, const vec3 &pos, vec3 *cube) { PROFILE_MARKER("PASS_AMBIENT"); setupCubeCamera(pos, 4); @@ -652,7 +672,19 @@ struct Level { Core::setViewport(0, 0, ambient[0]->width, ambient[0]->height); Core::clear(vec4(0, 0, 0, 1)); renderScene(roomIndex); + + glDisable(GL_DEPTH_TEST); + glDisable(GL_CULL_FACE); + setPassShader(Core::passFilter); + Core::active.shader->setParam(uType, Shader::DOWNSAMPLE); + ambient[0]->bind(sDiffuse); + Core::setTarget(ambient[1]); + Core::setViewport(0, 0, ambient[1]->width, ambient[1]->height); + Core::clear(vec4(randf(), 0, 1, 1)); + mesh->renderQuad(); Core::setTarget(NULL); + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); } void renderShadows(int roomIndex) { @@ -685,9 +717,10 @@ struct Level { Core::resetStates(); vec3 cube[6]; - // renderAmbient(lara->getRoomIndex(), lara->pos - vec3(0, 512, 0), cube); + renderAmbient(lara->getRoomIndex(), lara->pos - vec3(0, 512, 0), cube); renderShadows(lara->getRoomIndex()); renderCompose(camera->getRoomIndex()); + //readAmbientResult(); #ifdef _DEBUG static int modelIndex = 0; @@ -729,7 +762,7 @@ struct Level { glColor3f(1, 1, 1); glTranslatef(lara->pos.x, lara->pos.y, lara->pos.z); Texture::unbind(sShadow); - ambient[0]->bind(sDiffuse); + ambient[1]->bind(sDiffuse); glEnable(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); glBegin(GL_QUADS); diff --git a/src/mesh.h b/src/mesh.h index 1d6709b..faef9d4 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -143,6 +143,7 @@ struct MeshBuilder { MeshRange *spriteSequences; MeshRange shadowBlob; MeshRange bar; + MeshRange quad; // indexed mesh Mesh *mesh; @@ -238,6 +239,14 @@ struct MeshBuilder { iCount += bar.iCount; vCount += 4; + // quad (post effect filter) + quad.vStart = vCount; + quad.iStart = iCount; + quad.iCount = 2 * 3; + aCount++; + iCount += quad.iCount; + vCount += 4; + // make meshes buffer (single vertex buffer object for all geometry & sprites on level) Index *indices = new Index[iCount]; Vertex *vertices = new Vertex[vCount]; @@ -381,7 +390,6 @@ struct MeshBuilder { indices[idx + 1] = 0; indices[idx + 2] = (i + 1) % 8; } - iCount += shadowBlob.iCount; vCount += 8; // white bar @@ -397,8 +405,22 @@ struct MeshBuilder { v.color = { 255, 255, 255, 255 }; v.texCoord = { 32688, 32688, 0, 0 }; } - iCount += bar.iCount; - vCount += 8; + vCount += 4; + + // quad + addQuad(indices, iCount, vCount, quad.vStart, vertices, &whiteTileQuad); + vertices[vCount + 0].coord = { -1, -1, 0, 0 }; + vertices[vCount + 1].coord = { 1, -1, 1, 0 }; + vertices[vCount + 2].coord = { 1, 1, 1, 1 }; + vertices[vCount + 3].coord = { -1, 1, 0, 1 }; + + for (int i = 0; i < 4; i++) { + Vertex &v = vertices[vCount + i]; + v.normal = { 0, 0, 0, 0 }; + v.color = { 255, 255, 255, 255 }; + v.texCoord = { 32688, 32688, 0, 0 }; + } + vCount += 4; // compile buffer and ranges mesh = new Mesh(indices, iCount, vertices, vCount, aCount); @@ -421,6 +443,8 @@ struct MeshBuilder { for (int i = 0; i < level.meshesCount; i++) mesh->initRange(meshInfo[i]); mesh->initRange(shadowBlob); + mesh->initRange(bar); + mesh->initRange(quad); } ~MeshBuilder() { @@ -611,6 +635,10 @@ struct MeshBuilder { } + void renderQuad() { + mesh->render(quad); + } + void renderBar(const vec2 &size, float value) { /* float w = size.y / 9.0f; diff --git a/src/shader.h b/src/shader.h index d45416a..91ca6d5 100644 --- a/src/shader.h +++ b/src/shader.h @@ -15,7 +15,7 @@ struct Shader { GLuint ID; GLint uID[uMAX]; - enum : GLint { SPRITE, ROOM, ENTITY, FLASH }; + enum : GLint { SPRITE = 0, ROOM = 1, ENTITY = 2, FLASH = 3, DOWNSAMPLE = 10 }; Shader(const char *text, const char *defines = "") { #ifdef MOBILE