From 3696adc90b92f2cbf3ac526cdf799f78d4d4042a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Sun, 22 Dec 2013 00:41:19 +0100 Subject: [PATCH] Use opengl shaders for water rendering --- src/render/opengl/OpenGLRenderer.cpp | 12 ++++--- src/render/opengl/OpenGLRenderer.h | 1 + src/render/opengl/OpenGLWater.cpp | 42 +++++++++++++++++++++++++ src/render/opengl/OpenGLWater.h | 31 ++++++++++++++++++ src/render/opengl/WidgetExplorer.cpp | 12 ------- src/render/opengl/opengl.pro | 11 +++++-- src/render/opengl/opengl_global.h | 1 + src/render/opengl/shaders/resources.qrc | 2 ++ src/render/opengl/shaders/water.frag | 6 ++++ src/render/opengl/shaders/water.vert | 11 +++++++ 10 files changed, 110 insertions(+), 19 deletions(-) create mode 100644 src/render/opengl/OpenGLWater.cpp create mode 100644 src/render/opengl/OpenGLWater.h create mode 100644 src/render/opengl/shaders/water.frag create mode 100644 src/render/opengl/shaders/water.vert diff --git a/src/render/opengl/OpenGLRenderer.cpp b/src/render/opengl/OpenGLRenderer.cpp index 8bb5254..65a6b5b 100644 --- a/src/render/opengl/OpenGLRenderer.cpp +++ b/src/render/opengl/OpenGLRenderer.cpp @@ -1,23 +1,22 @@ #include "OpenGLRenderer.h" #include -#include -#include -#include -#include "Scenery.h" #include "CameraDefinition.h" #include "OpenGLSkybox.h" +#include "OpenGLWater.h" OpenGLRenderer::OpenGLRenderer(Scenery* scenery): SoftwareRenderer(scenery) { functions = new QOpenGLFunctions_3_2_Core(); skybox = new OpenGLSkybox(this); + water = new OpenGLWater(this); } OpenGLRenderer::~OpenGLRenderer() { delete skybox; + delete water; delete functions; } @@ -50,6 +49,9 @@ void OpenGLRenderer::initialize() skybox->initialize(); skybox->updateScenery(); + + water->initialize(); + water->updateScenery(); } void OpenGLRenderer::resize(int width, int height) @@ -63,11 +65,13 @@ void OpenGLRenderer::paint() functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); skybox->render(); + water->render(); } void OpenGLRenderer::cameraChangeEvent(CameraDefinition *camera) { skybox->updateCamera(camera); + water->updateCamera(camera); } double OpenGLRenderer::getPrecision(const Vector3 &) diff --git a/src/render/opengl/OpenGLRenderer.h b/src/render/opengl/OpenGLRenderer.h index 664dc9f..1021f4c 100644 --- a/src/render/opengl/OpenGLRenderer.h +++ b/src/render/opengl/OpenGLRenderer.h @@ -34,6 +34,7 @@ private: QOpenGLFunctions_3_2_Core* functions; OpenGLSkybox* skybox; + OpenGLWater* water; }; } diff --git a/src/render/opengl/OpenGLWater.cpp b/src/render/opengl/OpenGLWater.cpp new file mode 100644 index 0000000..bebef71 --- /dev/null +++ b/src/render/opengl/OpenGLWater.cpp @@ -0,0 +1,42 @@ +#include "OpenGLWater.h" + +#include "OpenGLShaderProgram.h" + +OpenGLWater::OpenGLWater(OpenGLRenderer *renderer): + OpenGLPart(renderer) +{ + vertices = new float[4 * 3]; +} + +OpenGLWater::~OpenGLWater() +{ + delete[] vertices; +} + +void OpenGLWater::initialize() +{ + program = createShader("water"); + program->addVertexSource("water"); + program->addFragmentSource("water"); + + setVertex(0, -1.0f, 0.0f, -1.0f); + setVertex(1, -1.0f, 0.0f, 1.0f); + setVertex(2, 1.0f, 0.0f, -1.0f); + setVertex(3, 1.0f, 0.0f, 1.0f); +} + +void OpenGLWater::update() +{ +} + +void OpenGLWater::render() +{ + program->drawTriangleStrip(vertices, 4); +} + +void OpenGLWater::setVertex(int i, float x, float y, float z) +{ + vertices[i * 3] = x; + vertices[i * 3 + 1] = y; + vertices[i * 3 + 2] = z; +} diff --git a/src/render/opengl/OpenGLWater.h b/src/render/opengl/OpenGLWater.h new file mode 100644 index 0000000..a30d4bc --- /dev/null +++ b/src/render/opengl/OpenGLWater.h @@ -0,0 +1,31 @@ +#ifndef OPENGLWATER_H +#define OPENGLWATER_H + +#include "opengl_global.h" + +#include "OpenGLPart.h" + +namespace paysages { +namespace opengl { + +class OPENGLSHARED_EXPORT OpenGLWater: public OpenGLPart +{ +public: + OpenGLWater(OpenGLRenderer* renderer); + virtual ~OpenGLWater(); + + virtual void initialize() override; + virtual void update() override; + virtual void render() override; + +private: + void setVertex(int i, float x, float y, float z); + + OpenGLShaderProgram* program; + float* vertices; +}; + +} +} + +#endif // OPENGLWATER_H diff --git a/src/render/opengl/WidgetExplorer.cpp b/src/render/opengl/WidgetExplorer.cpp index f0f8890..b1e00b0 100644 --- a/src/render/opengl/WidgetExplorer.cpp +++ b/src/render/opengl/WidgetExplorer.cpp @@ -365,7 +365,6 @@ void WidgetExplorer::paintGL() GLenum error_code; QTime start_time; double frame_time; - WaterDefinition* water = _renderer->getScenery()->getWater(); // Don't do this at each frame, only on camera change _renderer->getScenery()->setCamera(_current_camera); @@ -384,17 +383,6 @@ void WidgetExplorer::paintGL() Vector3 camera_up = _current_camera->getUpVector(); gluLookAt(camera_location.x, camera_location.y, camera_location.z, camera_target.x, camera_target.y, camera_target.z, camera_up.x, camera_up.y, camera_up.z); - // Render water - double water_height = _renderer->getTerrainRenderer()->getWaterHeight(); - glDisable(GL_TEXTURE_2D); - glColor3f(water->material->_rgb.r, water->material->_rgb.g, water->material->_rgb.b); - glBegin(GL_QUADS); - glVertex3f(camera_location.x - 500.0, water_height, camera_location.z - 500.0); - glVertex3f(camera_location.x - 500.0, water_height, camera_location.z + 500.0); - glVertex3f(camera_location.x + 500.0, water_height, camera_location.z + 500.0); - glVertex3f(camera_location.x + 500.0, water_height, camera_location.z - 500.0); - glEnd(); - // Render chunks glEnable(GL_TEXTURE_2D); for (int i = 0; i < _chunks.count(); i++) diff --git a/src/render/opengl/opengl.pro b/src/render/opengl/opengl.pro index 5e47964..fe2ea41 100644 --- a/src/render/opengl/opengl.pro +++ b/src/render/opengl/opengl.pro @@ -20,7 +20,8 @@ SOURCES += \ WidgetExplorer.cpp \ OpenGLShaderProgram.cpp \ OpenGLPart.cpp \ - OpenGLSkybox.cpp + OpenGLSkybox.cpp \ + OpenGLWater.cpp HEADERS +=\ opengl_global.h \ @@ -30,7 +31,8 @@ HEADERS +=\ WidgetExplorer.h \ OpenGLShaderProgram.h \ OpenGLPart.h \ - OpenGLSkybox.h + OpenGLSkybox.h \ + OpenGLWater.h unix:!symbian { maemo5 { @@ -70,4 +72,7 @@ RESOURCES += \ OTHER_FILES += \ shaders/skybox.frag \ - shaders/skybox.vert + shaders/skybox.vert \ + shaders/water.vert \ + shaders/water.frag \ + shaders/bruneton.frag diff --git a/src/render/opengl/opengl_global.h b/src/render/opengl/opengl_global.h index 63b65f6..b949e60 100644 --- a/src/render/opengl/opengl_global.h +++ b/src/render/opengl/opengl_global.h @@ -18,6 +18,7 @@ namespace opengl { class BaseExplorerChunk; class OpenGLShaderProgram; class OpenGLSkybox; + class OpenGLWater; } } using namespace paysages::opengl; diff --git a/src/render/opengl/shaders/resources.qrc b/src/render/opengl/shaders/resources.qrc index a922c12..5d1b756 100644 --- a/src/render/opengl/shaders/resources.qrc +++ b/src/render/opengl/shaders/resources.qrc @@ -2,5 +2,7 @@ skybox.frag skybox.vert + water.frag + water.vert diff --git a/src/render/opengl/shaders/water.frag b/src/render/opengl/shaders/water.frag new file mode 100644 index 0000000..e6c4b07 --- /dev/null +++ b/src/render/opengl/shaders/water.frag @@ -0,0 +1,6 @@ +varying vec3 unprojected; + +void main(void) +{ + gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0); +} diff --git a/src/render/opengl/shaders/water.vert b/src/render/opengl/shaders/water.vert new file mode 100644 index 0000000..485fe10 --- /dev/null +++ b/src/render/opengl/shaders/water.vert @@ -0,0 +1,11 @@ +attribute highp vec4 vertex; +uniform highp mat4 viewMatrix; +uniform float waterHeight; +uniform vec3 cameraLocation; +varying vec3 unprojected; + +void main(void) +{ + unprojected = vec3(cameraLocation.x + vertex.x * 500.0, vertex.y + waterHeight, cameraLocation.z + vertex.z * 500.0); + gl_Position = viewMatrix * vec4(unprojected, 1.0); +}