Refactor selection pointer to use glsl and common BO
parent
08907c5883
commit
ae02fe2c38
|
@ -0,0 +1,8 @@
|
|||
#version 120
|
||||
|
||||
uniform vec4 color;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
gl_FragColor = color;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#version 120
|
||||
|
||||
uniform float pixelSize;
|
||||
uniform float s, c;
|
||||
uniform float x0, y0;
|
||||
uniform vec3 u, v;
|
||||
|
||||
void main(void)
|
||||
{
|
||||
float x = gl_Vertex.x * pixelSize;
|
||||
float y = gl_Vertex.y * pixelSize;
|
||||
vec3 pos = (x * c - y * s + x0) * u + (x * s + y * c + y0) * v;
|
||||
gl_Position = gl_ModelViewProjectionMatrix * vec4(pos, 1.0f);
|
||||
}
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "marker.h"
|
||||
#include <celmath/mathlib.h>
|
||||
#include <celutil/util.h>
|
||||
#include <GL/glew.h>
|
||||
#include <vector>
|
||||
#include "render.h"
|
||||
|
@ -130,9 +131,18 @@ static GLfloat DownArrow[DownArrowCount * 2] =
|
|||
0.0f, 1.0f
|
||||
};
|
||||
|
||||
constexpr const int StaticVtxCount = DownArrowOffset + DownArrowCount;
|
||||
constexpr const int SelPointerOffset = DownArrowOffset + DownArrowCount;
|
||||
constexpr const int SelPointerCount = 3;
|
||||
static GLfloat SelPointer[SelPointerCount * 2] =
|
||||
{
|
||||
0.0f, 0.0f,
|
||||
-20.0f, 6.0f,
|
||||
-20.0f, -6.0f
|
||||
};
|
||||
|
||||
constexpr const int SmallCircleOffset = DownArrowOffset + DownArrowCount;
|
||||
constexpr const int StaticVtxCount = SelPointerOffset + SelPointerCount;
|
||||
|
||||
constexpr const int SmallCircleOffset = StaticVtxCount;
|
||||
static int SmallCircleCount = 0;
|
||||
static int LargeCircleOffset = 0;
|
||||
static int LargeCircleCount = 0;
|
||||
|
@ -170,10 +180,11 @@ static void initVO(VertexObject& vo)
|
|||
VOSTREAM(LeftArrow);
|
||||
VOSTREAM(UpArrow);
|
||||
VOSTREAM(DownArrow);
|
||||
VOSTREAM(SelPointer);
|
||||
#undef VOSTREAM
|
||||
|
||||
vo.setBufferData(small.data(), VTXTOMEM(SmallCircleOffset), small.size() * sizeof(GLfloat));
|
||||
vo.setBufferData(large.data(), VTXTOMEM(LargeCircleOffset), large.size() * sizeof(GLfloat));
|
||||
vo.setBufferData(small.data(), VTXTOMEM(SmallCircleOffset), memsize(small));
|
||||
vo.setBufferData(large.data(), VTXTOMEM(LargeCircleOffset), memsize(large));
|
||||
#undef VTXTOMEM
|
||||
|
||||
vo.setVertices(2, GL_FLOAT, false, 0, 0);
|
||||
|
@ -181,16 +192,15 @@ static void initVO(VertexObject& vo)
|
|||
|
||||
void Renderer::renderMarker(MarkerRepresentation::Symbol symbol, float size, const Color& color)
|
||||
{
|
||||
markerVO.bind();
|
||||
|
||||
if (!markerVO.initialized())
|
||||
initVO(markerVO);
|
||||
|
||||
assert(shaderManager != nullptr);
|
||||
auto* prog = shaderManager->getShader("marker");
|
||||
if (prog == nullptr)
|
||||
return;
|
||||
|
||||
markerVO.bind();
|
||||
if (!markerVO.initialized())
|
||||
initVO(markerVO);
|
||||
|
||||
float s = size / 2.0f;
|
||||
prog->use();
|
||||
prog->vec4Param("color") = color.toVector4();
|
||||
|
@ -259,3 +269,83 @@ void Renderer::renderMarker(MarkerRepresentation::Symbol symbol, float size, con
|
|||
glUseProgram(0);
|
||||
markerVO.unbind();
|
||||
}
|
||||
|
||||
/*! Draw an arrow at the view border pointing to an offscreen selection. This method
|
||||
* should only be called when the selection lies outside the view frustum.
|
||||
*/
|
||||
void Renderer::renderSelectionPointer(const Observer& observer,
|
||||
double now,
|
||||
const Frustum& viewFrustum,
|
||||
const Selection& sel)
|
||||
{
|
||||
constexpr const float cursorDistance = 20.0f;
|
||||
if (sel.empty())
|
||||
return;
|
||||
|
||||
// Get the position of the cursor relative to the eye
|
||||
Vector3d position = sel.getPosition(now).offsetFromKm(observer.getPosition());
|
||||
if (viewFrustum.testSphere(position, sel.radius()) != Frustum::Outside)
|
||||
return;
|
||||
|
||||
assert(shaderManager != nullptr);
|
||||
auto* prog = shaderManager->getShader("selpointer");
|
||||
if (prog == nullptr)
|
||||
return;
|
||||
|
||||
Matrix3f cameraMatrix = observer.getOrientationf().conjugate().toRotationMatrix();
|
||||
const Vector3f u = cameraMatrix.col(0);
|
||||
const Vector3f v = cameraMatrix.col(1);
|
||||
double distance = position.norm();
|
||||
position *= cursorDistance / distance;
|
||||
|
||||
#ifdef USE_HDR
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
#endif
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
float vfov = (float) observer.getFOV();
|
||||
float h = tan(vfov / 2);
|
||||
float w = h * getAspectRatio();
|
||||
float diag = sqrt(h * h + w * w);
|
||||
|
||||
Vector3f posf = position.cast<float>() / cursorDistance;
|
||||
float x = u.dot(posf);
|
||||
float y = v.dot(posf);
|
||||
float c, s;
|
||||
sincos(atan2(y, x), s, c);
|
||||
|
||||
float x0 = c * diag;
|
||||
float y0 = s * diag;
|
||||
float t = (std::abs(x0) < w) ? h / abs(y0) : w / abs(x0);
|
||||
x0 *= t;
|
||||
y0 *= t;
|
||||
|
||||
const Vector3f ¢er = cameraMatrix.col(2);
|
||||
glPushMatrix();
|
||||
glTranslatef(-center.x(), -center.y(), -center.z());
|
||||
|
||||
markerVO.bind();
|
||||
if (!markerVO.initialized())
|
||||
initVO(markerVO);
|
||||
prog->use();
|
||||
prog->vec4Param("color") = Color(SelectionCursorColor, 0.6f).toVector4();
|
||||
prog->floatParam("pixelSize") = pixelSize;
|
||||
prog->floatParam("s") = s;
|
||||
prog->floatParam("c") = c;
|
||||
prog->floatParam("x0") = x0;
|
||||
prog->floatParam("y0") = y0;
|
||||
prog->vec3Param("u") = u;
|
||||
prog->vec3Param("v") = v;
|
||||
markerVO.draw(GL_TRIANGLES, SelPointerCount, SelPointerOffset);
|
||||
|
||||
glUseProgram(0);
|
||||
markerVO.unbind();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
#ifdef USE_HDR
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -7174,89 +7174,6 @@ void Renderer::renderSkyGrids(const Observer& observer)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/*! Draw an arrow at the view border pointing to an offscreen selection. This method
|
||||
* should only be called when the selection lies outside the view frustum.
|
||||
*/
|
||||
void Renderer::renderSelectionPointer(const Observer& observer,
|
||||
double now,
|
||||
const Frustum& viewFrustum,
|
||||
const Selection& sel)
|
||||
{
|
||||
const float cursorDistance = 20.0f;
|
||||
if (sel.empty())
|
||||
return;
|
||||
|
||||
Matrix3f cameraMatrix = observer.getOrientationf().conjugate().toRotationMatrix();
|
||||
Vector3f u = cameraMatrix * Vector3f::UnitX();
|
||||
Vector3f v = cameraMatrix * Vector3f::UnitY();
|
||||
|
||||
// Get the position of the cursor relative to the eye
|
||||
Vector3d position = sel.getPosition(now).offsetFromKm(observer.getPosition());
|
||||
double distance = position.norm();
|
||||
bool isVisible = viewFrustum.testSphere(position, sel.radius()) != Frustum::Outside;
|
||||
position *= cursorDistance / distance;
|
||||
|
||||
#ifdef USE_HDR
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
#endif
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
if (!isVisible)
|
||||
{
|
||||
double viewAspectRatio = (double) windowWidth / (double) windowHeight;
|
||||
double vfov = observer.getFOV();
|
||||
auto h = (float) tan(vfov / 2);
|
||||
auto w = (float) (h * viewAspectRatio);
|
||||
float diag = std::sqrt(h * h + w * w);
|
||||
|
||||
Vector3f posf = position.cast<float>();
|
||||
posf *= (1.0f / cursorDistance);
|
||||
float x = u.dot(posf);
|
||||
float y = v.dot(posf);
|
||||
float angle = std::atan2(y, x);
|
||||
float c = std::cos(angle);
|
||||
float s = std::sin(angle);
|
||||
|
||||
float t = 1.0f;
|
||||
float x0 = c * diag;
|
||||
float y0 = s * diag;
|
||||
if (std::abs(x0) < w)
|
||||
t = h / std::abs(y0);
|
||||
else
|
||||
t = w / std::abs(x0);
|
||||
x0 *= t;
|
||||
y0 *= t;
|
||||
glColor(SelectionCursorColor, 0.6f);
|
||||
Vector3f center = -cameraMatrix * Vector3f::UnitZ();
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(center.x(), center.y(), center.z());
|
||||
|
||||
Vector3f p0(Vector3f::Zero());
|
||||
Vector3f p1(-20.0f * pixelSize, 6.0f * pixelSize, 0.0f);
|
||||
Vector3f p2(-20.0f * pixelSize, -6.0f * pixelSize, 0.0f);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex((p0.x() * c - p0.y() * s + x0) * u + (p0.x() * s + p0.y() * c + y0) * v);
|
||||
glVertex((p1.x() * c - p1.y() * s + x0) * u + (p1.x() * s + p1.y() * c + y0) * v);
|
||||
glVertex((p2.x() * c - p2.y() * s + x0) * u + (p2.x() * s + p2.y() * c + y0) * v);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
#ifdef USE_HDR
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
#endif
|
||||
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
|
||||
void Renderer::labelConstellations(const AsterismList& asterisms,
|
||||
const Observer& observer)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue