Render crosshair using glsl and common BO

pull/3/head
Hleb Valoshka 2019-11-08 16:19:56 +03:00
parent 3f757998f4
commit fecd61fcb1
5 changed files with 81 additions and 49 deletions

View File

@ -0,0 +1,8 @@
#version 120
uniform vec4 color;
void main(void)
{
gl_FragColor = color;
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -7252,45 +7252,6 @@ void Renderer::renderParticles(const vector<Particle>& 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<Annotation>& annotations, FontStyle fs)
{
if (font[fs] == nullptr)
@ -7332,12 +7293,10 @@ void Renderer::renderAnnotations(const vector<Annotation>& 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<Annotation>::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<Annotation>::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())
{

View File

@ -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,