diff --git a/src/camera.h b/src/camera.h index 8337e96..8e63a55 100644 --- a/src/camera.h +++ b/src/camera.h @@ -111,7 +111,7 @@ struct Camera : Controller { if (Input::down[ikS]) v = v - d; if (Input::down[ikA]) v = v + d.cross(vec3(0, 1, 0)); if (Input::down[ikD]) v = v - d.cross(vec3(0, 1, 0)); - pos = pos + v.normal() * (Core::deltaTime * 2048.0f * 10.0f); + pos = pos + v.normal() * (Core::deltaTime * 512.0 * 10.0f); mViewInv.identity(); mViewInv.translate(pos); diff --git a/src/controller.h b/src/controller.h index 1dfd767..93f7a56 100644 --- a/src/controller.h +++ b/src/controller.h @@ -52,6 +52,7 @@ struct Controller { joints = m ? new Basis[m->mCount] : NULL; frameIndex = -1; specular = 0.0f; + ambient[0] = ambient[1] = ambient[2] = ambient[3] = ambient[4] = ambient[5] = vec3(intensityf(getRoom().ambient)); } virtual ~Controller() { @@ -338,7 +339,7 @@ struct Controller { case TR::Action::CLEAR : case TR::Action::CAMERA_FLYBY : case TR::Action::CUTSCENE : - LOG("! action is not implemented\n"); + //LOG("! action is not implemented\n"); actionCommand = next; activateNext(); break; @@ -430,7 +431,7 @@ struct Controller { mat4 matrix; TR::Entity &e = getEntity(); - if (e.type < TR::Entity::CUT_1 || e.type > TR::Entity::CUT_3) { // TODO: move to ctor + if (e.type < TR::Entity::CUT_1 || e.type > TR::Entity::CUT_4) { // TODO: move to ctor matrix.identity(); matrix.translate(pos); if (angle.y != 0.0f) matrix.rotateY(angle.y - (animation.flip ? PI * animation.delta : 0.0f)); diff --git a/src/core.h b/src/core.h index 42150b8..0c3cb15 100644 --- a/src/core.h +++ b/src/core.h @@ -142,7 +142,7 @@ namespace Core { vec4 lightColor[MAX_LIGHTS]; vec4 color; - enum Pass { passCompose, passShadow, passAmbient, passFilter } pass; + enum Pass { passCompose, passShadow, passAmbient, passFilter, passWater } pass; GLuint FBO; GLuint renderBuffers[2][MAX_RENDER_BUFFERS]; @@ -162,6 +162,8 @@ namespace Core { bool depthTexture; bool shadowSampler; bool VAO; + bool texFloat, texFloatLinear; + bool texHalf, texHalfLinear; } support; } @@ -232,10 +234,14 @@ namespace Core { #endif char *ext = (char*)glGetString(GL_EXTENSIONS); //LOG("%s\n", ext); - support.depthTexture = extSupport(ext, "_depth_texture"); - support.shadowSampler = extSupport(ext, "EXT_shadow_samplers") || extSupport(ext, "GL_ARB_shadow"); - support.VAO = extSupport(ext, "_vertex_array_object"); - + support.depthTexture = extSupport(ext, "_depth_texture"); + support.shadowSampler = extSupport(ext, "EXT_shadow_samplers") || extSupport(ext, "GL_ARB_shadow"); + support.VAO = extSupport(ext, "_vertex_array_object"); + support.texFloatLinear = extSupport(ext, "GL_ARB_texture_float") || extSupport(ext, "_texture_float_linear"); + 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"); + char *vendor = (char*)glGetString(GL_VENDOR); LOG("Vendor : %s\n", vendor); LOG("Renderer : %s\n", glGetString(GL_RENDERER)); @@ -245,6 +251,9 @@ namespace Core { LOG(" depth texture : %s\n", support.depthTexture ? "true" : "false"); LOG(" shadow sampler : %s\n", support.shadowSampler ? "true" : "false"); LOG(" vertex arrays : %s\n", support.VAO ? "true" : "false"); + LOG(" float textures : float = %s, half = %s\n", + support.texFloat ? (support.texFloatLinear ? "linear" : "nearest") : "false", + support.texHalf ? (support.texHalfLinear ? "linear" : "nearest") : "false"); LOG("\n"); glGenFramebuffers(1, &FBO); @@ -339,10 +348,11 @@ namespace Core { ASSERT(target->width == (1 << dummyBuffer) ) glBindFramebuffer(GL_FRAMEBUFFER, FBO); - glFramebufferTexture2D (GL_FRAMEBUFFER, target->depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0, texTarget, target->ID, 0); - glFramebufferRenderbuffer (GL_FRAMEBUFFER, target->depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffers[target->depth][dummyBuffer]); + bool depth = target->format == Texture::DEPTH || target->format == Texture::SHADOW; + glFramebufferTexture2D (GL_FRAMEBUFFER, depth ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0, texTarget, target->ID, 0); + glFramebufferRenderbuffer (GL_FRAMEBUFFER, depth ? GL_COLOR_ATTACHMENT0 : GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffers[depth][dummyBuffer]); - if (target->depth) + if (depth) glColorMask(false, false, false, false); } diff --git a/src/filter.glsl b/src/filter.glsl index e79d144..0de2d39 100644 --- a/src/filter.glsl +++ b/src/filter.glsl @@ -1,24 +1,24 @@ R"====( varying vec2 vTexCoord; -#define TYPE_DOWNSAMPLE 10 +#define FILTER_DOWNSAMPLE 0 uniform int uType; #ifdef VERTEX attribute vec4 aCoord; - void main() { - vTexCoord = aCoord.zw; + void main() { + vTexCoord = aCoord.zw; gl_Position = vec4(aCoord.xy, 0.0, 1.0); + } #else uniform sampler2D sDiffuse; - - uniform float uTime; // texture size + uniform vec4 uParam; // texture size vec4 downsample() { - float k = 1.0 / uTime; + float k = 1.0 / uParam.x; vec4 color = vec4(0.0); for (float y = -1.5; y < 2.0; y++) @@ -34,9 +34,7 @@ uniform int uType; } vec4 filter() { - if (uType == TYPE_DOWNSAMPLE) { - return downsample(); - } + if (uType == FILTER_DOWNSAMPLE) return downsample(); return vec4(1.0, 0.0, 0.0, 1.0); } diff --git a/src/format.h b/src/format.h index 894f42f..93a8cb0 100644 --- a/src/format.h +++ b/src/format.h @@ -415,6 +415,7 @@ namespace TR { CUT_1 = 77, CUT_2 = 78, CUT_3 = 79, + CUT_4 = 79, CRYSTAL = 83, // sprite WEAPON_PISTOLS = 84, // sprite @@ -1228,10 +1229,15 @@ namespace TR { } #define RECALC_ZERO_NORMALS(mesh, face, count)\ + int fn = -1;\ for (int j = 0; j < count; j++) {\ Mesh::Vertex &v = mesh.vertices[face.vertices[j]];\ short4 &n = v.normal;\ if (!(n.x | n.y | n.z)) {\ + if (fn > -1) {\ + n = mesh.vertices[face.vertices[fn]].normal;\ + continue;\ + }\ vec3 o(mesh.vertices[face.vertices[0]].coord);\ vec3 a = o - mesh.vertices[face.vertices[1]].coord;\ vec3 b = o - mesh.vertices[face.vertices[2]].coord;\ @@ -1239,6 +1245,7 @@ namespace TR { n.x = (int)o.x;\ n.y = (int)o.y;\ n.z = (int)o.z;\ + fn = j;\ }\ } diff --git a/src/lara.h b/src/lara.h index 0e67b1f..53b2737 100644 --- a/src/lara.h +++ b/src/lara.h @@ -236,7 +236,14 @@ struct Lara : Character { pos = vec3(43182, 2473, 51556); angle = vec3(0.0f, PI * 0.5f, 0.0f); getEntity().room = 12; - + */ + // gym (pool) + pos = vec3(40448, 3584, 60928); + angle = vec3(0.0f, PI * 0.5f, 0.0f); + getEntity().room = 14; + stand = STAND_ONWATER; + animation.setAnim(ANIM_TO_ONWATER); + /* // level 2 (pool) pos = vec3(70067, -256, 29104); angle = vec3(0.0f, -0.68f, 0.0f); diff --git a/src/level.h b/src/level.h index e6e534b..f1c6282 100644 --- a/src/level.h +++ b/src/level.h @@ -21,22 +21,31 @@ const char FILTER[] = #include "filter.glsl" ; +const char WATER[] = + #include "water.glsl" +; + const char GUI[] = #include "gui.glsl" ; struct Level { - enum { shCompose, shShadow, shAmbient, shFilter, shGUI, shMAX }; + enum { shCompose, shShadow, shAmbient, shFilter, shWater, shGUI, shMAX }; TR::Level level; Shader *shaders[shMAX]; - Texture *atlas, *cube; + Texture *atlas; MeshBuilder *mesh; Lara *lara; Camera *camera; Texture *shadow; +#ifdef _DEBUG + Texture *water[2]; + Texture *waterCube; +#endif + float time; struct AmbientCache { @@ -74,7 +83,7 @@ struct Level { // init downsample textures for (int j = 0; j < 6; j++) for (int i = 0; i < 4; i++) - textures[j * 4 + i] = new Texture(64 >> (i << 1), 64 >> (i << 1), false, false); + textures[j * 4 + i] = new Texture(64 >> (i << 1), 64 >> (i << 1), Texture::RGBA, false); } ~AmbientCache() { @@ -111,12 +120,12 @@ struct Level { glDisable(GL_DEPTH_TEST); // glDisable(GL_CULL_FACE); level->setPassShader(Core::passFilter); - Core::active.shader->setParam(uType, Shader::DOWNSAMPLE); + Core::active.shader->setParam(uType, Shader::FILTER_DOWNSAMPLE); for (int i = 1; i < 4; i++) { int size = 64 >> (i << 1); - Core::active.shader->setParam(uTime, float(size << 2)); + Core::active.shader->setParam(uParam, vec4(float(size << 2), 0.0f, 0.0f, 0.0f)); Core::setViewport(0, 0, size, size); for (int j = 0; j < 6; j++) { @@ -134,7 +143,7 @@ struct Level { TR::Color32 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(powf(color.r / 255.0f, 2.2f), powf(color.g / 255.0f, 2.2f), powf(color.b / 255.0f, 2.2f)); // to linear space } Core::setTarget(NULL); @@ -166,13 +175,10 @@ struct Level { int sector = sx * r.zSectors + sz; Cube *a = getAmbient(room, sector); - if (a) { + if (a) value = *a; - } else { + else value.status = Cube::BLANK; - value.colors[0] = value.colors[1] = value.colors[2] = - value.colors[3] = value.colors[4] = value.colors[5] = vec3(intensityf(r.ambient)); - } } } *ambientCache; @@ -222,8 +228,6 @@ struct Level { #endif mesh = new MeshBuilder(level); - shadow = new Texture(1024, 1024, true, false); - initTextures(); initShaders(); initOverrides(); @@ -341,15 +345,34 @@ struct Level { delete shadow; delete ambientCache; - +#ifdef _DEBUG + delete water[0]; + delete water[1]; + delete waterCube; +#endif delete atlas; - delete cube; delete mesh; delete camera; } void initTextures() { + shadow = new Texture(1024, 1024, Texture::SHADOW, false); + + float *ddd = NULL;//new float[4 * 256 * 256]; +// memset(ddd, 0, sizeof(float) * 4 * 256 * 256); +// for (int i = 0; i < 512 * 512 * 2; i += 2) +// ddd[i] = randf(); +// ddd[(128 * 256 + 128) * 4] = 50.0f; +// ddd[(192 * 256 + 192) * 4] = 100.0f; +// ddd[(64 * 256 + 128) * 4] = 20.0f; + + #ifdef _DEBUG + water[0] = new Texture(256, 256, Texture::RGBA_FLOAT, false, ddd); + water[1] = new Texture(256, 256, Texture::RGBA_FLOAT, false, ddd); + #endif + delete[] ddd; + if (!level.tilesCount) { atlas = NULL; return; @@ -380,12 +403,9 @@ struct Level { fclose(f); */ - atlas = new Texture(1024, 1024, false, false, data); + atlas = new Texture(1024, 1024, Texture::RGBA, false, data); PROFILE_LABEL(TEXTURE, atlas->ID, "atlas"); - uint32 whitePix = 0xFFFFFFFF; - cube = new Texture(1, 1, false, true, &whitePix); - delete[] data; delete[] level.tiles; level.tiles = NULL; @@ -413,6 +433,7 @@ struct Level { sprintf(def, "%s#define PASS_AMBIENT\n", ext); shaders[shAmbient] = new Shader(SHADER, def); shaders[shFilter] = new Shader(FILTER, ""); + shaders[shWater] = new Shader(WATER, ""); shaders[shGUI] = new Shader(GUI, ""); } @@ -462,6 +483,11 @@ struct Level { renderEnvironment(c->getRoomIndex(), c->pos - vec3(0, 512, 0), &c->environment); } } + + #ifdef _DEBUG + waterCube = new Texture(512, 512, Texture::RGBA, true); + renderEnvironment(14, vec3(40448, 3584, 60928), &waterCube); + #endif } #ifdef LEVEL_EDITOR @@ -709,7 +735,6 @@ struct Level { camera->setup(Core::pass == Core::passCompose); atlas->bind(sDiffuse); - cube->bind(sEnvironment); // dummy texture binding to prevent "there is no texture bound to the unit 2" warnings if (!Core::support.VAO) mesh->bind(); @@ -721,7 +746,7 @@ struct Level { sh->setParam(uLightProj, Core::mLightProj); sh->setParam(uViewInv, Core::mViewInv); sh->setParam(uViewPos, Core::viewPos); - sh->setParam(uTime, time); + sh->setParam(uParam, vec4(time, 0.0f, 0.0f, 0.0f)); sh->setParam(uLightsCount, 3); sh->setParam(uAnimTexRanges, mesh->animTexRanges[0], mesh->animTexRangesCount); sh->setParam(uAnimTexOffsets, mesh->animTexOffsets[0], mesh->animTexOffsetsCount); @@ -817,6 +842,7 @@ struct Level { case Core::passShadow : sh = shaders[shShadow]; break; case Core::passAmbient : sh = shaders[shAmbient]; break; case Core::passFilter : sh = shaders[shFilter]; break; + case Core::passWater : sh = shaders[shWater]; break; } ASSERT(sh); sh->bind(); @@ -867,11 +893,86 @@ struct Level { Core::resetStates(); ambientCache->precessQueue(); - //renderEnvironment(lara->getRoomIndex(), lara->pos - vec3(0, , ambientCache->textures, 4); renderShadows(lara->getRoomIndex()); renderCompose(camera->getRoomIndex()); #ifdef _DEBUG + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + Core::setViewport(0, 0, water[0]->width, water[0]->height); + setPassShader(Core::passWater); + + static vec3 lastPos = vec3(0.0); + bool flag = (lara->pos - lastPos).length() > 16.0f; + bool flag2 = lara->animation.frameIndex == 20;//isFrameActive(22) || lara->animation.isFrameActive(21); + + if (Input::down[ikU] || flag || flag2) { + vec2 p(randf(), randf()); + if (flag || flag2) { + vec3 c(40448, 0.0, 60928); + p.x = (lara->pos.x - c.x) / 5120.0f + 0.5; + p.y = (lara->pos.z - c.z) / 5120.0f + 0.5; + lastPos = lara->pos; + } + + water[0]->bind(sDiffuse); + Core::setTarget(water[1]); + Core::active.shader->setParam(uType, Shader::WATER_DROP); + Core::active.shader->setParam(uParam, vec4(p.x, p.y, 128.0f / 5120.0f * (flag2 ? 1.0f : randf() + 0.2f), flag2 ? 0.001f : randf() * 0.05f)); + mesh->renderQuad(); + swap(water[0], water[1]); + Input::down[ikU] = false; + } + + + Core::active.shader->setParam(uParam, vec4(1.0f / water[0]->width, 1.0f / water[0]->height, Core::deltaTime * 4.0f, 0.0f)); + + water[0]->bind(sDiffuse); + Core::setTarget(water[1]); + Core::active.shader->setParam(uType, Shader::WATER_STEP); + mesh->renderQuad(); + swap(water[0], water[1]); + + water[0]->bind(sDiffuse); + Core::setTarget(water[1]); + Core::active.shader->setParam(uType, Shader::WATER_NORMAL); + mesh->renderQuad(); + swap(water[0], water[1]); + Core::setTarget(NULL); + +/* + waterCube->bind(sEnvironment); + Core::setViewport(Core::width - water[0]->width - 16, Core::height - water[0]->height - 16, water[0]->width, water[0]->height); + water[0]->bind(sDiffuse); + Core::active.shader->setParam(uType, Shader::WATER_TEST); + mesh->renderQuad(); +*/ + Core::setViewport(0, 0, Core::width, Core::height); + + glEnable(GL_BLEND); + glEnable(GL_DEPTH_TEST); + + int dx, dz; + TR::Room::Sector &s = level.getSector(lara->getRoomIndex(), int(lara->pos.x), int(lara->pos.z), dx, dz); + if (s.roomAbove != 0xFF && level.rooms[s.roomAbove].lightsCount) { + TR::Room::Light &light = level.rooms[s.roomAbove].lights[0]; + Core::lightPos[0] = vec3(float(light.x), float(light.y), float(light.z)); + float lum = intensityf(light.intensity); + Core::lightColor[0] = vec4(lum, lum, lum, float(light.radius) * float(light.radius)); + } + + Core::active.shader->setParam(uType, Shader::WATER_TEST); + Core::active.shader->setParam(uViewProj, Core::mViewProj); + Core::active.shader->setParam(uViewPos, Core::viewPos); + Core::active.shader->setParam(uLightPos, Core::lightPos[0], 1); + Core::active.shader->setParam(uLightColor, Core::lightColor[0], 1); + + water[0]->bind(sDiffuse); + waterCube->bind(sEnvironment); + + mesh->renderQuad(); + + static int modelIndex = 0; static bool lastStateK = false; static int lastEntity = -1; @@ -902,13 +1003,12 @@ struct Level { // Debug::Level::sectors(level, lara->getRoomIndex(), (int)lara->pos.y); // Debug::Level::portals(level); // Debug::Level::meshes(level); - Debug::Level::entities(level); - + // Debug::Level::entities(level); + /* static int dbg_ambient = 0; dbg_ambient = int(time * 2) % 4; shadow->unbind(sShadow); - cube->unbind(sEnvironment); atlas->bind(sDiffuse); glEnable(GL_TEXTURE_2D); glDisable(GL_CULL_FACE); @@ -938,6 +1038,7 @@ struct Level { glPopMatrix(); } + glEnable(GL_CULL_FACE); glDisable(GL_TEXTURE_2D); @@ -954,27 +1055,27 @@ struct Level { AmbientCache::Cube &cube = ambientCache->items[ambientCache->offsets[i] + j]; if (cube.status == AmbientCache::Cube::READY) { - glColor3fv((GLfloat*)&cube.colors[0]); + glColor3f(powf(cube.colors[0].x, 1.0f / 2.2f), powf(cube.colors[0].y, 1.0f / 2.2f), powf(cube.colors[0].z, 1.0f / 2.2f)); glVertex3f(p.x + 0, p.y + 0, p.z + 0); glVertex3f(p.x + S, p.y + 0, p.z + 0); - glColor3fv((GLfloat*)&cube.colors[1]); + glColor3f(powf(cube.colors[1].x, 1.0f / 2.2f), powf(cube.colors[1].y, 1.0f / 2.2f), powf(cube.colors[1].z, 1.0f / 2.2f)); glVertex3f(p.x + 0, p.y + 0, p.z + 0); glVertex3f(p.x - S, p.y + 0, p.z + 0); - glColor3fv((GLfloat*)&cube.colors[2]); + glColor3f(powf(cube.colors[2].x, 1.0f / 2.2f), powf(cube.colors[2].y, 1.0f / 2.2f), powf(cube.colors[2].z, 1.0f / 2.2f)); glVertex3f(p.x + 0, p.y + 0, p.z + 0); glVertex3f(p.x + 0, p.y + S, p.z + 0); - glColor3fv((GLfloat*)&cube.colors[3]); + glColor3f(powf(cube.colors[3].x, 1.0f / 2.2f), powf(cube.colors[3].y, 1.0f / 2.2f), powf(cube.colors[3].z, 1.0f / 2.2f)); glVertex3f(p.x + 0, p.y + 0, p.z + 0); glVertex3f(p.x + 0, p.y - S, p.z + 0); - glColor3fv((GLfloat*)&cube.colors[4]); + glColor3f(powf(cube.colors[4].x, 1.0f / 2.2f), powf(cube.colors[4].y, 1.0f / 2.2f), powf(cube.colors[4].z, 1.0f / 2.2f)); glVertex3f(p.x + 0, p.y + 0, p.z + 0); glVertex3f(p.x + 0, p.y + 0, p.z + S); - glColor3fv((GLfloat*)&cube.colors[5]); + glColor3f(powf(cube.colors[5].x, 1.0f / 2.2f), powf(cube.colors[5].y, 1.0f / 2.2f), powf(cube.colors[5].z, 1.0f / 2.2f)); glVertex3f(p.x + 0, p.y + 0, p.z + 0); glVertex3f(p.x + 0, p.y + 0, p.z - S); } @@ -983,7 +1084,7 @@ struct Level { glEnd(); glLineWidth(1); - + */ /* shaders[shGUI]->bind(); Core::mViewProj = mat4(0, (float)Core::width, (float)Core::height, 0, 0, 1); @@ -997,7 +1098,10 @@ struct Level { glEnable(GL_DEPTH_TEST); */ - Debug::Level::info(level, lara->getEntity(), lara->animation); + + //Debug::Level::info(level, lara->getEntity(), lara->animation); + + Debug::end(); #endif } diff --git a/src/mesh.h b/src/mesh.h index 5b7e127..8d48175 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -120,7 +120,7 @@ struct Mesh { float intensityf(int lighting) { if (lighting < 0) return 1.0f; float lum = 1.0f - (lighting >> 5) / 255.0f; - return lum * lum; // gamma to linear space + return powf(lum, 2.2f); // gamma to linear space } uint8 intensity(int lighting) { diff --git a/src/platform/win/OpenLara.vcxproj b/src/platform/win/OpenLara.vcxproj index 5576d3b..13197d7 100644 --- a/src/platform/win/OpenLara.vcxproj +++ b/src/platform/win/OpenLara.vcxproj @@ -214,6 +214,7 @@ + diff --git a/src/shader.glsl b/src/shader.glsl index d50d32a..b910c30 100644 --- a/src/shader.glsl +++ b/src/shader.glsl @@ -20,8 +20,8 @@ varying vec2 vTexCoord; uniform int uType; #ifdef PASS_COMPOSE - uniform int uCaustics; - uniform float uTime; + uniform int uCaustics; + uniform vec4 uParam; #endif #ifdef VERTEX @@ -72,7 +72,7 @@ uniform int uType; // animated texture coordinates vec2 range = uAnimTexRanges[int(aTexCoord.z)]; // x - start index, y - count - float f = fract((aTexCoord.w + uTime * 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 + f)]; // texCoord offset from first frame vTexCoord = (aTexCoord.xy + offset) * TEXCOORD_SCALE; // first frame + offset * isAnimated @@ -93,7 +93,7 @@ uniform int uType; #ifdef PASS_COMPOSE if (uCaustics != 0) { float sum = coord.x + coord.y + coord.z; - vColor.xyz *= abs(sin(sum / 512.0 + uTime)) * 1.5 + 0.5; // color dodge + vColor.xyz *= abs(sin(sum / 512.0 + uParam.x)) * 1.5 + 0.5; // color dodge } vViewVec = uViewPos - coord.xyz; @@ -285,7 +285,7 @@ uniform int uType; } if (uType == TYPE_ENTITY) { - vec3 rAmbient = pow(abs(calcAmbient(normal)), vec3(2.2)); + vec3 rAmbient = calcAmbient(normal); float rShadow = getShadow(vLightProj); light += calcLight(normal, uLightPos[0], uLightColor[0]) * rShadow + rAmbient; color.xyz += calcSpecular(normal, viewVec, uLightPos[0], uLightColor[0], uColor.w * rShadow + 0.03); @@ -298,6 +298,7 @@ uniform int uType; } color.xyz *= light; + //color.xyz = normal * 0.5 + 0.5; } else { color.w = uColor.w; diff --git a/src/shader.h b/src/shader.h index 34957f0..7db7857 100644 --- a/src/shader.h +++ b/src/shader.h @@ -5,17 +5,21 @@ enum AttribType { aCoord, aTexCoord, aNormal, aColor, aMAX }; enum SamplerType { sDiffuse, sShadow, sEnvironment, sMAX }; -enum UniformType { uType, uCaustics, uTime, uViewProj, uViewInv, uBasis, uLightProj, uColor, uAmbient, uViewPos, uLightsCount, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uMAX }; +enum UniformType { uType, uCaustics, uParam, uViewProj, uViewInv, uBasis, uLightProj, uColor, uAmbient, uViewPos, uLightsCount, uLightPos, uLightColor, uAnimTexRanges, uAnimTexOffsets, uMAX }; const char *AttribName[aMAX] = { "aCoord", "aTexCoord", "aNormal", "aColor" }; const char *SamplerName[sMAX] = { "sDiffuse", "sShadow", "sEnvironment" }; -const char *UniformName[uMAX] = { "uType", "uCaustics", "uTime", "uViewProj", "uViewInv", "uBasis", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets" }; +const char *UniformName[uMAX] = { "uType", "uCaustics", "uParam", "uViewProj", "uViewInv", "uBasis", "uLightProj", "uColor", "uAmbient", "uViewPos", "uLightsCount", "uLightPos", "uLightColor", "uAnimTexRanges", "uAnimTexOffsets" }; struct Shader { GLuint ID; GLint uID[uMAX]; - enum : GLint { SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4, DOWNSAMPLE = 10 }; + enum : GLint { + /* shader */ SPRITE = 0, FLASH = 1, ROOM = 2, ENTITY = 3, MIRROR = 4, + /* filter */ FILTER_DOWNSAMPLE = 0, + /* water */ WATER_DROP = 0, WATER_STEP = 1, WATER_NORMAL = 2, WATER_TEST = 3 + }; Shader(const char *text, const char *defines = "") { #ifdef MOBILE diff --git a/src/texture.h b/src/texture.h index b679b6d..27ce2d3 100644 --- a/src/texture.h +++ b/src/texture.h @@ -4,38 +4,74 @@ #include "core.h" struct Texture { - GLuint ID; + enum Format : uint32 { RGBA, RGBA_FLOAT, RGBA_HALF, DEPTH, SHADOW, MAX }; + + GLuint ID; int width, height; - bool depth; + Format format; bool cube; - Texture(int width, int height, bool depth, bool cube, void *data = NULL) : width(width), height(height), cube(cube) { + Texture(int width, int height, Format format, bool cube, void *data = NULL) : width(width), height(height), cube(cube) { glGenTextures(1, &ID); bind(0); bool filter = true; - if (depth && !Core::support.depthTexture) - depth = false; - this->depth = depth; GLenum target = cube ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; - GLint format = depth ? GL_DEPTH_COMPONENT : GL_RGBA; - if (depth) { - if (Core::support.shadowSampler) { - glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); - glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); - } else + if (format == SHADOW && !Core::support.shadowSampler) { + format = DEPTH; + filter = false; + } + + if (format == DEPTH) { + if (Core::support.depthTexture) filter = false; - } + else + format = RGBA; + } + + if (format == RGBA_HALF) { + if (Core::support.texHalf) + filter = Core::support.texHalfLinear; + else + format = RGBA_FLOAT; + } + + if (format == RGBA_FLOAT) { + if (Core::support.texFloat) + filter = Core::support.texFloatLinear; + else + format = RGBA; + } + + this->format = format; + + if (format == SHADOW) { + glTexParameteri(target, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); + glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + } glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(target, GL_TEXTURE_MAG_FILTER, filter ? GL_LINEAR : GL_NEAREST); glTexParameteri(target, GL_TEXTURE_MIN_FILTER, filter ? GL_LINEAR : GL_NEAREST); + + struct FormatDesc { + GLuint ifmt, fmt; + GLenum type; + } formats[MAX] = { + { GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE }, // RGBA + { GL_RGBA32F, GL_RGBA, GL_FLOAT }, // RGBA_FLOAT + { GL_RGBA16F, GL_RGBA, GL_HALF_FLOAT }, // RGBA_HALF + { GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // DEPTH + { GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT }, // SHADOW + }; + FormatDesc &desc = formats[format]; + for (int i = 0; i < 6; i++) { - glTexImage2D(cube ? (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) : GL_TEXTURE_2D, 0, format, width, height, 0, format, depth ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, data); + glTexImage2D(cube ? (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i) : GL_TEXTURE_2D, 0, desc.ifmt, width, height, 0, desc.fmt, desc.type, data); if (!cube) break; } } diff --git a/src/trigger.h b/src/trigger.h index ce0e201..b41cd0c 100644 --- a/src/trigger.h +++ b/src/trigger.h @@ -292,7 +292,7 @@ struct Crystal : Controller { Texture *environment; Crystal(TR::Level *level, int entity) : Controller(level, entity) { - environment = new Texture(64, 64, false, true); + environment = new Texture(64, 64, Texture::RGBA, true); } virtual ~Crystal() {