diff --git a/src/definition/CameraDefinition.h b/src/definition/CameraDefinition.h
index f93fd55..2daddf6 100644
--- a/src/definition/CameraDefinition.h
+++ b/src/definition/CameraDefinition.h
@@ -39,6 +39,8 @@ public:
inline const Matrix4 &getTransformationMatrix() const {return projector;}
inline VectorSpherical getDirectionSpherical() const {return direction;}
inline CameraPerspective getPerspective() const {return perspective;}
+ inline double getWidth() const {return width;}
+ inline double getHeight() const {return height;}
double getRealDepth(const Vector3 &projected) const;
diff --git a/src/interface/modeler/quickapp/OpenGLView.cpp b/src/interface/modeler/quickapp/OpenGLView.cpp
index e1a90f8..04f47a5 100644
--- a/src/interface/modeler/quickapp/OpenGLView.cpp
+++ b/src/interface/modeler/quickapp/OpenGLView.cpp
@@ -14,6 +14,7 @@ OpenGLView::OpenGLView(QQuickItem *parent) :
renderer = NULL;
setAcceptedMouseButtons(Qt::AllButtons);
+ setAcceptHoverEvents(true);
mouse_button = Qt::NoButton;
@@ -120,6 +121,13 @@ void OpenGLView::mouseMoveEvent(QMouseEvent *event)
window->getCamera()->processScroll(-0.02 * factor * diff.x(), 0.02 * factor * diff.y());
}
mouse_pos = event->windowPos();
+
+ renderer->setMouseLocation(event->pos().x(), height() - event->pos().y());
+}
+
+void OpenGLView::hoverMoveEvent(QHoverEvent *event)
+{
+ renderer->setMouseLocation(event->pos().x(), height() - event->pos().y());
}
void OpenGLView::timerEvent(QTimerEvent *)
diff --git a/src/interface/modeler/quickapp/OpenGLView.h b/src/interface/modeler/quickapp/OpenGLView.h
index 58f2075..f007004 100644
--- a/src/interface/modeler/quickapp/OpenGLView.h
+++ b/src/interface/modeler/quickapp/OpenGLView.h
@@ -24,6 +24,7 @@ protected:
virtual void mousePressEvent(QMouseEvent *event) override;
virtual void mouseReleaseEvent(QMouseEvent *event) override;
virtual void mouseMoveEvent(QMouseEvent *event) override;
+ virtual void hoverMoveEvent(QHoverEvent *event) override;
virtual void timerEvent(QTimerEvent *event) override;
private:
diff --git a/src/render/opengl/OpenGLRenderer.cpp b/src/render/opengl/OpenGLRenderer.cpp
index a2a3ae8..c3b8c65 100644
--- a/src/render/opengl/OpenGLRenderer.cpp
+++ b/src/render/opengl/OpenGLRenderer.cpp
@@ -10,6 +10,7 @@
#include "Scenery.h"
#include "LightingManager.h"
#include "Logs.h"
+#include "Vector3.h"
#include "GL/glu.h" // TEMP
@@ -21,6 +22,13 @@ OpenGLRenderer::OpenGLRenderer(Scenery* scenery):
vp_width = 1;
vp_height = 1;
+ mouse_tracking = true;
+ mouse_x = 0;
+ mouse_y = 0;
+ mouse_projected = new Vector3();
+
+ view_matrix = new QMatrix4x4;
+
render_quality = 3;
functions = new OpenGLFunctions();
@@ -40,6 +48,10 @@ OpenGLRenderer::~OpenGLRenderer()
water->interrupt();
skybox->interrupt();
+ delete mouse_projected;
+
+ delete view_matrix;
+
delete skybox;
delete water;
delete terrain;
@@ -140,6 +152,11 @@ void OpenGLRenderer::paint()
terrain->render();
water->render();
+ if (mouse_tracking)
+ {
+ updateMouseProjection();
+ }
+
int error_code;
while ((error_code = glGetError()) != GL_NO_ERROR)
{
@@ -172,6 +189,17 @@ void OpenGLRenderer::resume()
terrain->resume();
}
+void OpenGLRenderer::setMouseLocation(int x, int y)
+{
+ mouse_x = x;
+ mouse_y = y;
+}
+
+const Vector3 &OpenGLRenderer::getMouseProjection()
+{
+ return *mouse_projected;
+}
+
void OpenGLRenderer::cameraChangeEvent(CameraDefinition *camera)
{
// Get camera info
@@ -191,9 +219,11 @@ void OpenGLRenderer::cameraChangeEvent(CameraDefinition *camera)
projection.setToIdentity();
projection.perspective(perspective.yfov * 180.0 / M_PI, perspective.xratio, perspective.znear, perspective.zfar);
+ *view_matrix = projection * transform;
+
// Set in shaders
shared_state->set("cameraLocation", location);
- shared_state->set("viewMatrix", projection * transform);
+ shared_state->set("viewMatrix", *view_matrix);
}
double OpenGLRenderer::getPrecision(const Vector3 &)
@@ -205,3 +235,15 @@ Color OpenGLRenderer::applyMediumTraversal(Vector3, Color color)
{
return color;
}
+
+void OpenGLRenderer::updateMouseProjection()
+{
+ GLfloat z;
+ functions->glReadPixels(mouse_x, mouse_y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
+
+ QVector4D located(mouse_x / render_camera->getWidth(), mouse_y / render_camera->getHeight(), z, 1.0);
+ QVector4D unprojected = view_matrix->inverted() * 2.0 * (located - QVector4D(0.5, 0.5, 0.5, 0.5));
+ *mouse_projected = Vector3(unprojected.x() / unprojected.w(), unprojected.y() / unprojected.w(), unprojected.z() / unprojected.w());
+
+ shared_state->set("mouseProjection", *mouse_projected);
+}
diff --git a/src/render/opengl/OpenGLRenderer.h b/src/render/opengl/OpenGLRenderer.h
index 0d0de51..265cca6 100644
--- a/src/render/opengl/OpenGLRenderer.h
+++ b/src/render/opengl/OpenGLRenderer.h
@@ -5,6 +5,8 @@
#include "SoftwareRenderer.h"
+class QMatrix4x4;
+
namespace paysages {
namespace opengl {
@@ -42,6 +44,16 @@ public:
*/
void resume();
+ /**
+ * Set the current mouse location, for use by getMouseProjection().
+ */
+ void setMouseLocation(int x, int y);
+
+ /**
+ * Get the coordinates of the mouse, projected in world space.
+ */
+ const Vector3 &getMouseProjection();
+
/**
* Change the camera location.
*/
@@ -54,12 +66,25 @@ public:
virtual double getPrecision(const Vector3 &location) override;
virtual Color applyMediumTraversal(Vector3 location, Color color) override;
+private:
+ /**
+ * Update the mouse_projected member.
+ */
+ void updateMouseProjection();
+
private:
bool ready;
bool paused;
int vp_width;
int vp_height;
+ bool mouse_tracking;
+ int mouse_x;
+ int mouse_y;
+ Vector3 *mouse_projected;
+
+ QMatrix4x4 *view_matrix;
+
OpenGLFunctions* functions;
OpenGLSharedState* shared_state;
diff --git a/src/render/opengl/OpenGLTerrain.cpp b/src/render/opengl/OpenGLTerrain.cpp
index ee6aee2..8df2fd8 100644
--- a/src/render/opengl/OpenGLTerrain.cpp
+++ b/src/render/opengl/OpenGLTerrain.cpp
@@ -63,6 +63,7 @@ void OpenGLTerrain::initialize()
program->addFragmentSource("atmosphere");
program->addFragmentSource("tonemapping");
program->addFragmentSource("fadeout");
+ program->addFragmentSource("ui");
program->addFragmentSource("terrain");
// Add terrain chunks
diff --git a/src/render/opengl/OpenGLWater.cpp b/src/render/opengl/OpenGLWater.cpp
index 81c6289..5406e1e 100644
--- a/src/render/opengl/OpenGLWater.cpp
+++ b/src/render/opengl/OpenGLWater.cpp
@@ -30,6 +30,7 @@ void OpenGLWater::initialize()
program->addFragmentSource("atmosphere");
program->addFragmentSource("tonemapping");
program->addFragmentSource("fadeout");
+ program->addFragmentSource("ui");
program->addFragmentSource("noise");
program->addFragmentSource("water");
diff --git a/src/render/opengl/shaders/resources.qrc b/src/render/opengl/shaders/resources.qrc
index ed4c445..68f3f23 100644
--- a/src/render/opengl/shaders/resources.qrc
+++ b/src/render/opengl/shaders/resources.qrc
@@ -10,5 +10,6 @@
terrain.vert
fadeout.frag
noise.frag
+ ui.frag
diff --git a/src/render/opengl/shaders/terrain.frag b/src/render/opengl/shaders/terrain.frag
index de2f60c..5343e7f 100644
--- a/src/render/opengl/shaders/terrain.frag
+++ b/src/render/opengl/shaders/terrain.frag
@@ -9,5 +9,7 @@ void main(void)
gl_FragColor = applyToneMapping(gl_FragColor);
+ gl_FragColor = applyMouseTracking(unprojected, gl_FragColor);
+
gl_FragColor.a = distanceFadeout();
}
diff --git a/src/render/opengl/shaders/ui.frag b/src/render/opengl/shaders/ui.frag
new file mode 100644
index 0000000..1c399a8
--- /dev/null
+++ b/src/render/opengl/shaders/ui.frag
@@ -0,0 +1,14 @@
+uniform vec3 mouseProjection;
+
+vec4 applyMouseTracking(vec3 location, vec4 color)
+{
+ float dist = length(location - mouseProjection);
+ if (dist > 2.0)
+ {
+ return color;
+ }
+ else
+ {
+ return mix(color, vec4(1.0, 0.0, 0.0, 1.0), 1.0 - dist / 2.0);
+ }
+}
diff --git a/src/render/opengl/shaders/water.frag b/src/render/opengl/shaders/water.frag
index d6b5279..4a873a3 100644
--- a/src/render/opengl/shaders/water.frag
+++ b/src/render/opengl/shaders/water.frag
@@ -15,5 +15,7 @@ void main(void)
gl_FragColor = applyToneMapping(gl_FragColor);
+ gl_FragColor = applyMouseTracking(unprojected, gl_FragColor);
+
gl_FragColor.a = distanceFadeout();
}