diff --git a/shaders/crosshair_frag.glsl b/shaders/crosshair_frag.glsl new file mode 100644 index 00000000..a8301b3c --- /dev/null +++ b/shaders/crosshair_frag.glsl @@ -0,0 +1,8 @@ +#version 120 + +uniform vec4 color; + +void main(void) +{ + gl_FragColor = color; +} diff --git a/shaders/crosshair_vert.glsl b/shaders/crosshair_vert.glsl new file mode 100644 index 00000000..82ebd5b0 --- /dev/null +++ b/shaders/crosshair_vert.glsl @@ -0,0 +1,18 @@ +#version 120 + +uniform float radius; +uniform float width; +uniform float h; +uniform float angle; + +void main(void) +{ + float c = cos(angle); + float s = sin(angle); + mat3 rot = mat3(c, s, 0.0f, -s, c, 0.0f, 0.0f, 0.0f, 1.0f); + + float x = gl_Vertex.x * width + radius; + float y = gl_Vertex.y * h; + vec3 p = rot * vec3(x, y, 0.0f); + gl_Position = gl_ModelViewProjectionMatrix * vec4(p, 1.0f); +} diff --git a/src/celengine/glmarker.cpp b/src/celengine/glmarker.cpp index f95f18af..0eafb59c 100644 --- a/src/celengine/glmarker.cpp +++ b/src/celengine/glmarker.cpp @@ -140,7 +140,16 @@ static GLfloat SelPointer[SelPointerCount * 2] = -20.0f, -6.0f }; -constexpr const int StaticVtxCount = SelPointerOffset + SelPointerCount; +constexpr const int CrosshairOffset = SelPointerOffset + SelPointerCount; +constexpr const int CrosshairCount = 3; +static GLfloat Crosshair[CrosshairCount * 2 ] = +{ + 0.0f, 0.0f, + 1.0f, -1.0f, + 1.0f, 1.0f +}; + +constexpr const int StaticVtxCount = CrosshairOffset + CrosshairCount; constexpr const int SmallCircleOffset = StaticVtxCount; static int SmallCircleCount = 0; @@ -193,6 +202,7 @@ static void initVO(VertexObject& vo) VOSTREAM(UpArrow); VOSTREAM(DownArrow); VOSTREAM(SelPointer); + VOSTREAM(Crosshair); #undef VOSTREAM vo.setBufferData(small.data(), VTXTOMEM(SmallCircleOffset), memsize(small)); @@ -387,3 +397,43 @@ void Renderer::renderEclipticLine() glUseProgram(0); markerVO.unbind(); } + +void Renderer::renderCrosshair(float selectionSizeInPixels, double tsec, const Color &color) +{ + assert(shaderManager != nullptr); + auto* prog = shaderManager->getShader("crosshair"); + if (prog == nullptr) + return; + + markerVO.bind(); + if (!markerVO.initialized()) + initVO(markerVO); + + const float cursorMinRadius = 6.0f; + const float cursorRadiusVariability = 4.0f; + const float minCursorWidth = 7.0f; + const float cursorPulsePeriod = 1.5f; + + float cursorRadius = selectionSizeInPixels + cursorMinRadius; + cursorRadius += cursorRadiusVariability * (float) (0.5 + 0.5 * sin(tsec * 2 * PI / cursorPulsePeriod)); + + // Enlarge the size of the cross hair sligtly when the selection + // has a large apparent size + float cursorGrow = max(1.0f, min(2.5f, (selectionSizeInPixels - 10.0f) / 100.0f)); + + prog->use(); + prog->vec4Param("color") = color.toVector4(); + prog->floatParam("radius") = cursorRadius; + prog->floatParam("width") = minCursorWidth * cursorGrow; + prog->floatParam("h") = 2.0f * cursorGrow; + + const unsigned int markCount = 4; + for (unsigned int i = 0; i < markCount; i++) + { + float theta = (float) (PI / 4.0) + (float) i / (float) markCount * (float) (2 * PI); + prog->floatParam("angle") = theta; + markerVO.draw(GL_TRIANGLES, CrosshairCount, CrosshairOffset); + } + glUseProgram(0); + markerVO.unbind(); +} diff --git a/src/celengine/render.cpp b/src/celengine/render.cpp index 9de0a5c0..6657da56 100644 --- a/src/celengine/render.cpp +++ b/src/celengine/render.cpp @@ -7252,45 +7252,6 @@ void Renderer::renderParticles(const vector& particles, } } - -static void renderCrosshair(float pixelSize, double tsec) -{ - const float cursorMinRadius = 6.0f; - const float cursorRadiusVariability = 4.0f; - const float minCursorWidth = 7.0f; - const float cursorPulsePeriod = 1.5f; - - float selectionSizeInPixels = pixelSize; - float cursorRadius = selectionSizeInPixels + cursorMinRadius; - cursorRadius += cursorRadiusVariability * (float) (0.5 + 0.5 * std::sin(tsec * 2 * PI / cursorPulsePeriod)); - - // Enlarge the size of the cross hair sligtly when the selection - // has a large apparent size - float cursorGrow = max(1.0f, min(2.5f, (selectionSizeInPixels - 10.0f) / 100.0f)); - - float h = 2.0f * cursorGrow; - float cursorWidth = minCursorWidth * cursorGrow; - float r0 = cursorRadius; - float r1 = cursorRadius + cursorWidth; - - const unsigned int markCount = 4; - Vector3f p0(r0, 0.0f, 0.0f); - Vector3f p1(r1, -h, 0.0f); - Vector3f p2(r1, h, 0.0f); - - glBegin(GL_TRIANGLES); - for (unsigned int i = 0; i < markCount; i++) - { - float theta = (float) (PI / 4.0) + (float) i / (float) markCount * (float) (2 * PI); - Matrix3f rotation = AngleAxisf(theta, Vector3f::UnitZ()).toRotationMatrix(); - glVertex(rotation * p0); - glVertex(rotation * p1); - glVertex(rotation * p2); - } - glEnd(); -} - - void Renderer::renderAnnotations(const vector& annotations, FontStyle fs) { if (font[fs] == nullptr) @@ -7332,12 +7293,10 @@ void Renderer::renderAnnotations(const vector& annotations, FontStyl glTranslatef((GLfloat) (int) annotations[i].position.x(), (GLfloat) (int) annotations[i].position.y(), 0.0f); - glDisable(GL_TEXTURE_2D); if (markerRep.symbol() == MarkerRepresentation::Crosshair) - renderCrosshair(size, realTime); + renderCrosshair(size, realTime, annotations[i].color); else markerRep.render(*this, size); - glEnable(GL_TEXTURE_2D); if (!markerRep.label().empty()) { @@ -7481,12 +7440,10 @@ Renderer::renderSortedAnnotations(vector::iterator iter, glTranslatef((GLfloat) (int) iter->position.x(), (GLfloat) (int) iter->position.y(), ndc_z); glColor(iter->color); - glDisable(GL_TEXTURE_2D); if (markerRep.symbol() == MarkerRepresentation::Crosshair) - renderCrosshair(size, realTime); + renderCrosshair(size, realTime, iter->color); else markerRep.render(*this, size); - glEnable(GL_TEXTURE_2D); if (!markerRep.label().empty()) { @@ -7571,12 +7528,10 @@ Renderer::renderAnnotations(vector::iterator startIter, glTranslatef((GLfloat) (int) iter->position.x(), (GLfloat) (int) iter->position.y(), ndc_z); glColor(iter->color); - glDisable(GL_TEXTURE_2D); if (markerRep.symbol() == MarkerRepresentation::Crosshair) - renderCrosshair(size, realTime); + renderCrosshair(size, realTime, iter->color); else markerRep.render(*this, size); - glEnable(GL_TEXTURE_2D); if (!markerRep.label().empty()) { diff --git a/src/celengine/render.h b/src/celengine/render.h index e90668c5..2ff9cdbb 100644 --- a/src/celengine/render.h +++ b/src/celengine/render.h @@ -485,6 +485,7 @@ class Renderer void renderAsterisms(const Universe&, float); void renderBoundaries(const Universe&, float); void renderEclipticLine(); + void renderCrosshair(float size, double tsec, const Color &color); void buildRenderLists(const Eigen::Vector3d& astrocentricObserverPos, const celmath::Frustum& viewFrustum,