From 9388002bf457bcc5329871983316a294756b30e3 Mon Sep 17 00:00:00 2001 From: XProger Date: Sat, 3 Mar 2018 14:06:44 +0300 Subject: [PATCH] #11 detail quality checks; #23 CPU-host memory for dynamic geometry buffers --- src/core.h | 4 +-- src/inventory.h | 28 ++++++++++----- src/mesh.h | 81 +++++++++++++++++++++++++++--------------- src/shaders/water.glsl | 5 +-- 4 files changed, 77 insertions(+), 41 deletions(-) diff --git a/src/core.h b/src/core.h index 1c99619..ecafcb4 100644 --- a/src/core.h +++ b/src/core.h @@ -1507,7 +1507,7 @@ namespace Core { #endif } - void DIP(int iStart, int iCount) { + void DIP(int iStart, int iCount, void *iBuffer) { validateRenderState(); #ifdef FFP @@ -1526,7 +1526,7 @@ namespace Core { #ifdef _PSP sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_16BIT | GU_COLOR_8888 | GU_NORMAL_16BIT | GU_VERTEX_16BIT | GU_INDEX_16BIT | GU_TRANSFORM_3D, iCount, active.iBuffer + iStart, active.vBuffer); #else - glDrawElements(GL_TRIANGLES, iCount, GL_UNSIGNED_SHORT, (Index*)NULL + iStart); + glDrawElements(GL_TRIANGLES, iCount, GL_UNSIGNED_SHORT, (Index*)iBuffer + iStart); #endif stats.dips++; diff --git a/src/inventory.h b/src/inventory.h index 6f5644a..1c18c6d 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -40,6 +40,18 @@ struct OptionItem { *(uint8*)(intptr_t(settings) + offset) = value; } + bool checkValue(uint8 value) const { + if (value >= maxValue) return false; + Core::Settings stg; + switch (title) { + case STR_OPT_DETAIL_FILTER : stg.detail.setFilter((Core::Settings::Quality)value); return stg.detail.filter == value; + case STR_OPT_DETAIL_LIGHTING : stg.detail.setLighting((Core::Settings::Quality)value); return stg.detail.lighting == value; + case STR_OPT_DETAIL_SHADOWS : stg.detail.setShadows((Core::Settings::Quality)value); return stg.detail.shadows == value; + case STR_OPT_DETAIL_WATER : stg.detail.setWater((Core::Settings::Quality)value); return stg.detail.water == value; + default : return true; + } + } + float drawParam(float x, float y, float w, StringID oStr, bool active, uint8 value) const { if (oStr != STR_NOT_IMPLEMENTED) { UI::textOut(vec2(x + 32.0f, y), oStr); @@ -63,8 +75,8 @@ struct OptionItem { float maxWidth = UI::getTextSize(STR[color + value]).x; maxWidth = maxWidth * 0.5f + 8.0f; x += w * 0.5f; - if (value > 0) UI::specOut(vec2(x - maxWidth - 16.0f, y), 108); - if (value < maxValue) UI::specOut(vec2(x + maxWidth, y), 109); + if (checkValue(value - 1)) UI::specOut(vec2(x - maxWidth - 16.0f, y), 108); + if (checkValue(value + 1)) UI::specOut(vec2(x + maxWidth, y), 109); } return y + LINE_HEIGHT; } @@ -91,10 +103,10 @@ struct OptionItem { UI::textOut(vec2(x, y), title, UI::aCenter, w, 255, UI::SHADE_GRAY); case TYPE_EMPTY : break; case TYPE_BUTTON : { - const char *caption = offset ? (char*)offset : STR[title]; - UI::textOut(vec2(x, y), caption, UI::aCenter, w); - break; - } + const char *caption = offset ? (char*)offset : STR[title]; + UI::textOut(vec2(x, y), caption, UI::aCenter, w); + break; + } case TYPE_PARAM : case TYPE_KEY : return bar ? drawBar(x, y, w, active, value) : drawParam(x, y, w, title, active, value); @@ -358,14 +370,14 @@ struct Inventory { case cUp : nextSlot(slot, -1); break; case cDown : nextSlot(slot, +1); break; case cLeft : - if (opt->type == OptionItem::TYPE_PARAM && value > 0) { + if (opt->type == OptionItem::TYPE_PARAM && opt->checkValue(value - 1)) { value--; timer = 0.2f; return opt; } break; case cRight : - if (opt->type == OptionItem::TYPE_PARAM && value < opt->maxValue) { + if (opt->type == OptionItem::TYPE_PARAM && opt->checkValue(value + 1)) { value++; timer = 0.2f; return opt; diff --git a/src/mesh.h b/src/mesh.h index a5f39c1..106c183 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -35,14 +35,14 @@ struct MeshRange { void bind(uint32 *VAO) const {} #else - void setup() const { + void setup(void *vBuffer) const { glEnableVertexAttribArray(aCoord); glEnableVertexAttribArray(aNormal); glEnableVertexAttribArray(aTexCoord); glEnableVertexAttribArray(aColor); glEnableVertexAttribArray(aLight); - VertexGPU *v = (VertexGPU*)NULL + vStart; + VertexGPU *v = (VertexGPU*)vBuffer + vStart; glVertexAttribPointer(aCoord, 4, GL_SHORT, false, sizeof(*v), &v->coord); glVertexAttribPointer(aNormal, 4, GL_SHORT, true, sizeof(*v), &v->normal); glVertexAttribPointer(aTexCoord, 4, GL_SHORT, true, sizeof(*v), &v->texCoord); @@ -66,10 +66,9 @@ struct MeshRange { #define MAX_ROOM_DYN_FACES 256 struct Mesh { - #ifdef _PSP - Index *iBuffer; - VertexGPU *vBuffer; - #else + Index *iBuffer; + VertexGPU *vBuffer; + #ifndef _PSP GLuint ID[2]; GLuint *VAO; #endif @@ -80,12 +79,12 @@ struct Mesh { int aIndex; bool cmdBufAlloc; - Mesh(int iCount, int vCount) : iCount(iCount), vCount(vCount), aCount(0), aIndex(-1), cmdBufAlloc(true) { - #ifdef _PSP +#ifdef _PSP + Mesh(int iCount, int vCount, bool dynamic) : iCount(iCount), vCount(vCount), aCount(0), aIndex(-1), cmdBufAlloc(true) { iBuffer = (Index*)sceGuGetMemory(iCount * sizeof(Index)); vBuffer = (VertexGPU*)sceGuGetMemory(vCount * sizeof(VertexGPU)); - #endif } +#endif Mesh(Index *indices, int iCount, Vertex *vertices, int vCount, int aCount) : iCount(iCount), vCount(vCount), aCount(aCount), aIndex(0), cmdBufAlloc(false) { #ifdef _PSP @@ -103,14 +102,22 @@ struct Mesh { if (Core::support.VAO) glBindVertexArray(Core::active.VAO = 0); - glGenBuffers(2, ID); - bind(true); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, iCount * sizeof(Index), indices, GL_STATIC_DRAW); - glBufferData(GL_ARRAY_BUFFER, vCount * sizeof(Vertex), vertices, GL_STATIC_DRAW); - - if (Core::support.VAO && aCount) { - VAO = new GLuint[aCount]; - glGenVertexArrays(aCount, VAO); + if (vertices || indices) { + glGenBuffers(2, ID); + bind(true); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, iCount * sizeof(Index), indices, GL_STATIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, vCount * sizeof(VertexGPU), vertices, GL_STATIC_DRAW); + + if (Core::support.VAO && aCount) { + VAO = new GLuint[aCount]; + glGenVertexArrays(aCount, VAO); + } + iBuffer = NULL; + vBuffer = NULL; + } else { + ID[0] = ID[1] = 0; + iBuffer = new Index[iCount]; + vBuffer = new VertexGPU[vCount]; } #endif } @@ -135,16 +142,27 @@ struct Mesh { } } #else + // !!! typeof vertices[0] == Vertex == VertexGPU + ASSERT(sizeof(VertexGPU) == sizeof(Vertex)); + if (Core::support.VAO) glBindVertexArray(Core::active.VAO = 0); if (indices && iCount) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Core::active.iBuffer = ID[0]); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, iCount * sizeof(Index), indices); + if (iBuffer) { + memcpy(iBuffer, indices, iCount * sizeof(Index)); + } else { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Core::active.iBuffer = ID[0]); + glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, iCount * sizeof(Index), indices); + } } if (vertices && vCount) { - glBindBuffer(GL_ARRAY_BUFFER, Core::active.vBuffer = ID[1]); - glBufferSubData(GL_ARRAY_BUFFER, 0, vCount * sizeof(Vertex), vertices); + if (vBuffer) { + memcpy(vBuffer, vertices, vCount * sizeof(VertexGPU)); + } else { + glBindBuffer(GL_ARRAY_BUFFER, Core::active.vBuffer = ID[1]); + glBufferSubData(GL_ARRAY_BUFFER, 0, vCount * sizeof(VertexGPU), vertices); + } } #endif } @@ -158,11 +176,16 @@ struct Mesh { } #endif #else - if (VAO) { - glDeleteVertexArrays(aCount, VAO); - delete[] VAO; + if (iBuffer || vBuffer) { + delete[] iBuffer; + delete[] vBuffer; + } else { + if (VAO) { + glDeleteVertexArrays(aCount, VAO); + delete[] VAO; + } + glDeleteBuffers(2, ID); } - glDeleteBuffers(2, ID); #endif } @@ -173,7 +196,7 @@ struct Mesh { range.aIndex = aIndex++; range.bind(VAO); bind(true); - range.setup(); + range.setup(vBuffer); } else #endif range.aIndex = -1; @@ -198,10 +221,10 @@ struct Mesh { if (range.aIndex == -1) { bind(); - range.setup(); + range.setup(vBuffer); }; - Core::DIP(range.iStart, range.iCount); + Core::DIP(range.iStart, range.iCount, iBuffer); } }; @@ -1410,4 +1433,4 @@ struct MeshBuilder { } }; -#endif \ No newline at end of file +#endif diff --git a/src/shaders/water.glsl b/src/shaders/water.glsl index 00313b7..d02c291 100644 --- a/src/shaders/water.glsl +++ b/src/shaders/water.glsl @@ -161,13 +161,14 @@ uniform sampler2D sNormal; return v; } - +#ifdef WATER_CAUSTICS vec4 caustics() { float rOldArea = length(dFdx(vOldPos.xyz)) * length(dFdy(vOldPos.xyz)); float rNewArea = length(dFdx(vNewPos.xyz)) * length(dFdy(vNewPos.xyz)); float value = clamp(rOldArea / rNewArea * 0.2, 0.0, 1.0) * vOldPos.w; return vec4(value, 0.0, 0.0, 0.0); } +#endif vec4 mask() { return vec4(0.0); @@ -232,4 +233,4 @@ uniform sampler2D sNormal; gl_FragColor = pass(); } #endif -)====" \ No newline at end of file +)===="