From 6077400b3ca2444c0e7f6ce5038158093bbbce17 Mon Sep 17 00:00:00 2001 From: Leonardo Zide Date: Sat, 19 Jan 2019 20:04:08 -0800 Subject: [PATCH] Round viewsphere highlight. --- common/lc_context.cpp | 3 +- common/lc_context.h | 10 ++- common/lc_viewsphere.cpp | 94 ++++++++++++++------- common/lc_viewsphere.h | 1 + resources/shaders/unlit_view_sphere_ps.glsl | 15 +--- 5 files changed, 77 insertions(+), 46 deletions(-) diff --git a/common/lc_context.cpp b/common/lc_context.cpp index 0e290459..ea7fe953 100644 --- a/common/lc_context.cpp +++ b/common/lc_context.cpp @@ -51,6 +51,7 @@ lcContext::lcContext() mHighlightParams[0] = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mHighlightParams[1] = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mHighlightParams[2] = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); + mHighlightParams[3] = lcVector4(0.0f, 0.0f, 0.0f, 0.0f); mColorDirty = false; mWorldMatrixDirty = false; mViewMatrixDirty = false; @@ -1178,7 +1179,7 @@ void lcContext::FlushState() if (mHighlightParamsDirty && Program.HighlightParamsLocation != -1) { - glUniform4fv(Program.HighlightParamsLocation, 2, mHighlightParams[0]); + glUniform4fv(Program.HighlightParamsLocation, 4, mHighlightParams[0]); mHighlightParamsDirty = false; } } diff --git a/common/lc_context.h b/common/lc_context.h index ccfcd848..c62a7e29 100644 --- a/common/lc_context.h +++ b/common/lc_context.h @@ -153,10 +153,12 @@ public: mColorDirty = true; } - void SetHighlightParams(const lcVector4& HighlightMin, const lcVector4& HighlightMax) + void SetHighlightParams(const lcVector4& HighlightPosition, const lcVector4& TextColor, const lcVector4& BackgroundColor, const lcVector4& HighlightColor) { - mHighlightParams[0] = HighlightMin; - mHighlightParams[1] = HighlightMax; + mHighlightParams[0] = HighlightPosition; + mHighlightParams[1] = TextColor; + mHighlightParams[2] = BackgroundColor; + mHighlightParams[3] = HighlightColor; mHighlightParamsDirty = true; } @@ -227,7 +229,7 @@ protected: lcMatrix44 mViewMatrix; lcMatrix44 mProjectionMatrix; lcMatrix44 mViewProjectionMatrix; - lcVector4 mHighlightParams[3]; + lcVector4 mHighlightParams[4]; bool mColorDirty; bool mWorldMatrixDirty; bool mViewMatrixDirty; diff --git a/common/lc_viewsphere.cpp b/common/lc_viewsphere.cpp index c699ed92..00fcdea4 100644 --- a/common/lc_viewsphere.cpp +++ b/common/lc_viewsphere.cpp @@ -11,6 +11,7 @@ lcTexture* lcViewSphere::mTexture; lcVertexBuffer lcViewSphere::mVertexBuffer; lcIndexBuffer lcViewSphere::mIndexBuffer; const float lcViewSphere::mRadius = 1.0f; +const float lcViewSphere::mHighlightRadius = 0.35f; const int lcViewSphere::mSubdivisions = 7; lcViewSphere::lcViewSphere(View* View) @@ -179,39 +180,28 @@ void lcViewSphere::Draw() Context->SetVertexFormatPosition(3); Context->SetIndexBuffer(mIndexBuffer); - Context->SetHighlightParams(lcVector4(10.0f, 10.0f, 10.0f, 0.0f), lcVector4(-10.0f, -10.0f, -10.0f, 0.0f)); - Context->DrawIndexedPrimitives(GL_TRIANGLES, mSubdivisions * mSubdivisions * 6 * 6, GL_UNSIGNED_SHORT, 0); + lcVector4 HighlightPosition(0.0f, 0.0f, 0.0f, 0.0f); if (mIntersectionFlags.any()) { - lcVector4 HighlightMin(-10.0f, -10.0f, -10.0f, 0.0f), HighlightMax(10.0f, 10.0f, 10.0f, 0.0f); - for (int AxisIdx = 0; AxisIdx < 3; AxisIdx++) { if (mIntersectionFlags.test(2 * AxisIdx)) - { - HighlightMin[AxisIdx] = 0.5f; - HighlightMax[AxisIdx] = 10.0f; - } + HighlightPosition[AxisIdx] = 1.0f; else if (mIntersectionFlags.test(2 * AxisIdx + 1)) - { - HighlightMin[AxisIdx] = -10.0f; - HighlightMax[AxisIdx] = -0.5f; - } + HighlightPosition[AxisIdx] = -1.0f; } - Context->SetHighlightParams(HighlightMin, HighlightMax); - - for (int FlagIdx = 0; FlagIdx < 6; FlagIdx++) - { - if (mIntersectionFlags.test(FlagIdx)) - { - int FaceBase = FlagIdx * (mSubdivisions) * (mSubdivisions) * 6; - Context->DrawIndexedPrimitives(GL_TRIANGLES, mSubdivisions * mSubdivisions * 6, GL_UNSIGNED_SHORT, FaceBase * sizeof(GLushort)); - } - } + HighlightPosition = lcVector4(lcNormalize(lcVector3(HighlightPosition)), mHighlightRadius); } + const lcVector4 TextColor(0.0, 0.0, 0.0, 1.0); + const lcVector4 BackgroundColor(1.0, 1.0, 1.0, 1.0); + const lcVector4 HighlightColor(1.0, 0.0, 0.0, 1.0); + + Context->SetHighlightParams(HighlightPosition, TextColor, BackgroundColor, HighlightColor); + Context->DrawIndexedPrimitives(GL_TRIANGLES, mSubdivisions * mSubdivisions * 6 * 6, GL_UNSIGNED_SHORT, 0); + glDisable(GL_CULL_FACE); glDepthFunc(GL_LEQUAL); @@ -326,15 +316,59 @@ std::bitset<6> lcViewSphere::GetIntersectionFlags(lcVector3& Intersection) const { Intersection = (StartEnd[0] + (StartEnd[1] - StartEnd[0]) * Distance) / mRadius; - const float Side = 0.5f; - - for (int AxisIdx = 0; AxisIdx < 3; AxisIdx++) + auto CheckIntersection = [&]() { - if (mIntersection[AxisIdx] > Side) - IntersectionFlags.set(2 * AxisIdx); - else if (mIntersection[AxisIdx] < -Side) - IntersectionFlags.set(2 * AxisIdx + 1); - } + for (int Axis1Idx = 0; Axis1Idx < 6; Axis1Idx++) + { + lcVector3 Point(0.0f, 0.0f, 0.0f); + + Point[Axis1Idx / 2] = Axis1Idx % 2 ? -1.0f : 1.0f; + + if (lcLengthSquared(Point - Intersection) < mHighlightRadius * mHighlightRadius) + { + IntersectionFlags.set(Axis1Idx); + return; + } + + for (int Axis2Idx = 0; Axis2Idx < 6; Axis2Idx++) + { + if (Axis1Idx / 2 == Axis2Idx / 2) + continue; + + lcVector3 Point(0.0f, 0.0f, 0.0f); + Point[Axis1Idx / 2] = Axis1Idx % 2 ? -0.70710678118f : 0.70710678118f; + Point[Axis2Idx / 2] = Axis2Idx % 2 ? -0.70710678118f : 0.70710678118f; + + if (lcLengthSquared(Point - Intersection) < mHighlightRadius * mHighlightRadius) + { + IntersectionFlags.set(Axis1Idx); + IntersectionFlags.set(Axis2Idx); + return; + } + + for (int Axis3Idx = 0; Axis3Idx < 6; Axis3Idx++) + { + if (Axis1Idx / 2 == Axis3Idx / 2 || Axis2Idx / 2 == Axis3Idx / 2) + continue; + + lcVector3 Point(0.0f, 0.0f, 0.0f); + Point[Axis1Idx / 2] = Axis1Idx % 2 ? -0.57735026919f : 0.57735026919f; + Point[Axis2Idx / 2] = Axis2Idx % 2 ? -0.57735026919f : 0.57735026919f; + Point[Axis3Idx / 2] = Axis3Idx % 2 ? -0.57735026919f : 0.57735026919f; + + if (lcLengthSquared(Point - Intersection) < mHighlightRadius * mHighlightRadius) + { + IntersectionFlags.set(Axis1Idx); + IntersectionFlags.set(Axis2Idx); + IntersectionFlags.set(Axis3Idx); + return; + } + } + } + } + }; + + CheckIntersection(); } return IntersectionFlags; diff --git a/common/lc_viewsphere.h b/common/lc_viewsphere.h index 0bda5294..a9d1913b 100644 --- a/common/lc_viewsphere.h +++ b/common/lc_viewsphere.h @@ -36,5 +36,6 @@ protected: static lcVertexBuffer mVertexBuffer; static lcIndexBuffer mIndexBuffer; static const float mRadius; + static const float mHighlightRadius; static const int mSubdivisions; }; diff --git a/resources/shaders/unlit_view_sphere_ps.glsl b/resources/shaders/unlit_view_sphere_ps.glsl index 17d10efd..f44f2497 100644 --- a/resources/shaders/unlit_view_sphere_ps.glsl +++ b/resources/shaders/unlit_view_sphere_ps.glsl @@ -1,20 +1,13 @@ LC_PIXEL_INPUT vec3 PixelNormal; LC_PIXEL_OUTPUT -uniform mediump vec4 HighlightParams[2]; +uniform mediump vec4 HighlightParams[4]; uniform samplerCube Texture; -const mediump vec4 TextColor = vec4(0.0, 0.0, 0.0, 1.0); -const mediump vec4 BackgroundColor = vec4(1.0, 1.0, 1.0, 1.0); -const mediump vec4 HighlightColor = vec4(1.0, 0.0, 0.0, 1.0); - void main() { LC_SHADER_PRECISION float TexelAlpha = textureCube(Texture, PixelNormal).a; - - if (PixelNormal.x > HighlightParams[0].x && PixelNormal.y > HighlightParams[0].y && PixelNormal.z > HighlightParams[0].z && - PixelNormal.x < HighlightParams[1].x && PixelNormal.y < HighlightParams[1].y && PixelNormal.z < HighlightParams[1].z) - gl_FragColor = mix(HighlightColor, TextColor, TexelAlpha); - else - gl_FragColor = mix(BackgroundColor, TextColor, TexelAlpha); + LC_SHADER_PRECISION float Distance = length(vec3(HighlightParams[0]) - PixelNormal); + LC_SHADER_PRECISION float Highlight = step(Distance, HighlightParams[0].w); + gl_FragColor = mix(mix(HighlightParams[2], HighlightParams[3], Highlight), HighlightParams[1], TexelAlpha); }