Use opengl shaders for water rendering

This commit is contained in:
Michaël Lemaire 2013-12-22 00:41:19 +01:00
parent 65e5a194ba
commit 3696adc90b
10 changed files with 110 additions and 19 deletions

View file

@ -1,23 +1,22 @@
#include "OpenGLRenderer.h" #include "OpenGLRenderer.h"
#include <QOpenGLFunctions_3_2_Core> #include <QOpenGLFunctions_3_2_Core>
#include <cmath>
#include <GL/gl.h>
#include <GL/glu.h>
#include "Scenery.h"
#include "CameraDefinition.h" #include "CameraDefinition.h"
#include "OpenGLSkybox.h" #include "OpenGLSkybox.h"
#include "OpenGLWater.h"
OpenGLRenderer::OpenGLRenderer(Scenery* scenery): OpenGLRenderer::OpenGLRenderer(Scenery* scenery):
SoftwareRenderer(scenery) SoftwareRenderer(scenery)
{ {
functions = new QOpenGLFunctions_3_2_Core(); functions = new QOpenGLFunctions_3_2_Core();
skybox = new OpenGLSkybox(this); skybox = new OpenGLSkybox(this);
water = new OpenGLWater(this);
} }
OpenGLRenderer::~OpenGLRenderer() OpenGLRenderer::~OpenGLRenderer()
{ {
delete skybox; delete skybox;
delete water;
delete functions; delete functions;
} }
@ -50,6 +49,9 @@ void OpenGLRenderer::initialize()
skybox->initialize(); skybox->initialize();
skybox->updateScenery(); skybox->updateScenery();
water->initialize();
water->updateScenery();
} }
void OpenGLRenderer::resize(int width, int height) void OpenGLRenderer::resize(int width, int height)
@ -63,11 +65,13 @@ void OpenGLRenderer::paint()
functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); functions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
skybox->render(); skybox->render();
water->render();
} }
void OpenGLRenderer::cameraChangeEvent(CameraDefinition *camera) void OpenGLRenderer::cameraChangeEvent(CameraDefinition *camera)
{ {
skybox->updateCamera(camera); skybox->updateCamera(camera);
water->updateCamera(camera);
} }
double OpenGLRenderer::getPrecision(const Vector3 &) double OpenGLRenderer::getPrecision(const Vector3 &)

View file

@ -34,6 +34,7 @@ private:
QOpenGLFunctions_3_2_Core* functions; QOpenGLFunctions_3_2_Core* functions;
OpenGLSkybox* skybox; OpenGLSkybox* skybox;
OpenGLWater* water;
}; };
} }

View file

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

View file

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

View file

@ -365,7 +365,6 @@ void WidgetExplorer::paintGL()
GLenum error_code; GLenum error_code;
QTime start_time; QTime start_time;
double frame_time; double frame_time;
WaterDefinition* water = _renderer->getScenery()->getWater();
// Don't do this at each frame, only on camera change // Don't do this at each frame, only on camera change
_renderer->getScenery()->setCamera(_current_camera); _renderer->getScenery()->setCamera(_current_camera);
@ -384,17 +383,6 @@ void WidgetExplorer::paintGL()
Vector3 camera_up = _current_camera->getUpVector(); 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); 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 // Render chunks
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
for (int i = 0; i < _chunks.count(); i++) for (int i = 0; i < _chunks.count(); i++)

View file

@ -20,7 +20,8 @@ SOURCES += \
WidgetExplorer.cpp \ WidgetExplorer.cpp \
OpenGLShaderProgram.cpp \ OpenGLShaderProgram.cpp \
OpenGLPart.cpp \ OpenGLPart.cpp \
OpenGLSkybox.cpp OpenGLSkybox.cpp \
OpenGLWater.cpp
HEADERS +=\ HEADERS +=\
opengl_global.h \ opengl_global.h \
@ -30,7 +31,8 @@ HEADERS +=\
WidgetExplorer.h \ WidgetExplorer.h \
OpenGLShaderProgram.h \ OpenGLShaderProgram.h \
OpenGLPart.h \ OpenGLPart.h \
OpenGLSkybox.h OpenGLSkybox.h \
OpenGLWater.h
unix:!symbian { unix:!symbian {
maemo5 { maemo5 {
@ -70,4 +72,7 @@ RESOURCES += \
OTHER_FILES += \ OTHER_FILES += \
shaders/skybox.frag \ shaders/skybox.frag \
shaders/skybox.vert shaders/skybox.vert \
shaders/water.vert \
shaders/water.frag \
shaders/bruneton.frag

View file

@ -18,6 +18,7 @@ namespace opengl {
class BaseExplorerChunk; class BaseExplorerChunk;
class OpenGLShaderProgram; class OpenGLShaderProgram;
class OpenGLSkybox; class OpenGLSkybox;
class OpenGLWater;
} }
} }
using namespace paysages::opengl; using namespace paysages::opengl;

View file

@ -2,5 +2,7 @@
<qresource prefix="/shaders"> <qresource prefix="/shaders">
<file>skybox.frag</file> <file>skybox.frag</file>
<file>skybox.vert</file> <file>skybox.vert</file>
<file>water.frag</file>
<file>water.vert</file>
</qresource> </qresource>
</RCC> </RCC>

View file

@ -0,0 +1,6 @@
varying vec3 unprojected;
void main(void)
{
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
}

View file

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