New OpenGLSharedState class to manage shader variables

This commit is contained in:
Michaël Lemaire 2013-12-22 15:04:33 +01:00
parent 994dcb5f44
commit 666420bbb2
16 changed files with 237 additions and 66 deletions

View file

@ -7,7 +7,6 @@
#include "CameraDefinition.h"
#include "AtmosphereDefinition.h"
#include "AtmosphereRenderer.h"
#include "WaterRenderer.h"
#include "Scenery.h"
OpenGLPart::OpenGLPart(OpenGLRenderer* renderer):
@ -27,7 +26,7 @@ OpenGLPart::~OpenGLPart()
OpenGLShaderProgram* OpenGLPart::createShader(QString name)
{
OpenGLShaderProgram* program = new OpenGLShaderProgram(name, renderer->getOpenGlFunctions());
OpenGLShaderProgram* program = new OpenGLShaderProgram(name, renderer);
if (!shaders.contains(name))
{
@ -82,25 +81,6 @@ void OpenGLPart::updateCamera(CameraDefinition* camera)
void OpenGLPart::updateScenery(bool onlyCommon)
{
Scenery* scenery = renderer->getScenery();
// Collect common info
double water_height = renderer->getWaterRenderer()->getHeightInfo().max_height;
Vector3 orig_sun_direction = renderer->getAtmosphereRenderer()->getSunDirection();
QVector3D sun_direction = QVector3D(orig_sun_direction.x, orig_sun_direction.y, orig_sun_direction.z);
Color orig_sun_color = scenery->getAtmosphere()->sun_color;
QColor sun_color = QColor(orig_sun_color.r, orig_sun_color.g, orig_sun_color.b);
// Update shaders
QMapIterator<QString, OpenGLShaderProgram*> i(shaders);
while (i.hasNext())
{
i.next();
i.value()->updateWaterHeight(water_height);
i.value()->updateSun(sun_direction, sun_color);
}
// Let subclass do its own collecting
if (not onlyCommon)
{

View file

@ -2,6 +2,7 @@
#include <QOpenGLFunctions_3_2_Core>
#include "CameraDefinition.h"
#include "OpenGLSharedState.h"
#include "OpenGLSkybox.h"
#include "OpenGLWater.h"
@ -9,6 +10,8 @@ OpenGLRenderer::OpenGLRenderer(Scenery* scenery):
SoftwareRenderer(scenery)
{
functions = new QOpenGLFunctions_3_2_Core();
shared_state = new OpenGLSharedState();
skybox = new OpenGLSkybox(this);
water = new OpenGLWater(this);
}
@ -17,7 +20,9 @@ OpenGLRenderer::~OpenGLRenderer()
{
delete skybox;
delete water;
delete functions;
delete shared_state;
}
void OpenGLRenderer::initialize()

View file

@ -25,13 +25,15 @@ public:
void cameraChangeEvent(CameraDefinition* camera);
inline QOpenGLFunctions_3_2_Core* getOpenGlFunctions() {return functions;}
inline QOpenGLFunctions_3_2_Core* getOpenGlFunctions() const {return functions;}
inline OpenGLSharedState* getSharedState() const {return shared_state;}
virtual double getPrecision(const Vector3 &location) override;
virtual Color applyMediumTraversal(Vector3 location, Color color) override;
private:
QOpenGLFunctions_3_2_Core* functions;
OpenGLSharedState* shared_state;
OpenGLSkybox* skybox;
OpenGLWater* water;

View file

@ -3,15 +3,18 @@
#include <QOpenGLShaderProgram>
#include <QOpenGLFunctions_3_2_Core>
#include <QDir>
#include "OpenGLRenderer.h"
#include "OpenGLSharedState.h"
#include "Texture2D.h"
#include "Texture3D.h"
#include "Texture4D.h"
#include "Color.h"
OpenGLShaderProgram::OpenGLShaderProgram(QString name, QOpenGLFunctions_3_2_Core* functions):
name(name), functions(functions)
OpenGLShaderProgram::OpenGLShaderProgram(QString name, OpenGLRenderer* renderer):
renderer(renderer), name(name)
{
program = new QOpenGLShaderProgram();
functions = renderer->getOpenGlFunctions();
}
OpenGLShaderProgram::~OpenGLShaderProgram()
@ -47,17 +50,6 @@ void OpenGLShaderProgram::updateCamera(const QVector3D& location, const QMatrix4
this->view = view;
}
void OpenGLShaderProgram::updateWaterHeight(double height)
{
this->water_height = height;
}
void OpenGLShaderProgram::updateSun(const QVector3D& direction, const QColor& color)
{
this->sun_direction = direction;
this->sun_color = color;
}
void OpenGLShaderProgram::addTexture(QString sampler_name, Texture2D* texture)
{
GLuint texid;
@ -193,6 +185,8 @@ void OpenGLShaderProgram::bind()
{
program->bind();
renderer->getSharedState()->apply(this);
// TODO Keep locations in cache
int viewMatrix = program->uniformLocation("viewMatrix");
@ -207,24 +201,6 @@ void OpenGLShaderProgram::bind()
program->setUniformValue(cameraLocation, camera_location);
}
int waterHeight = program->uniformLocation("waterHeight");
if (waterHeight >= 0)
{
program->setUniformValue(waterHeight, water_height);
}
int sunDirection = program->uniformLocation("sunDirection");
if (sunDirection >= 0)
{
program->setUniformValue(sunDirection, sun_direction);
}
int sunColor = program->uniformLocation("sunColor");
if (sunColor >= 0)
{
program->setUniformValue(sunColor, sun_color);
}
QMapIterator<QString, QPair<int, unsigned int> > iter(textures);
int i = 0;
while (iter.hasNext())

View file

@ -18,7 +18,7 @@ namespace opengl {
class OPENGLSHARED_EXPORT OpenGLShaderProgram
{
public:
OpenGLShaderProgram(QString name, QOpenGLFunctions_3_2_Core* functions);
OpenGLShaderProgram(QString name, OpenGLRenderer* renderer);
~OpenGLShaderProgram();
void addVertexSource(QString path);
@ -26,8 +26,6 @@ public:
void compile();
void updateCamera(const QVector3D& location, const QMatrix4x4& view);
void updateWaterHeight(double height);
void updateSun(const QVector3D& direction, const QColor& color);
void addTexture(QString sampler_name, Texture2D* texture);
void addTexture(QString sampler_name, Texture3D* texture);
@ -36,18 +34,19 @@ public:
void drawTriangles(float* vertices, int triangle_count);
void drawTriangleStrip(float* vertices, int vertex_count);
protected:
inline QOpenGLShaderProgram* getProgram() const {return program;}
friend class OpenGLVariable;
private:
void bind();
void release();
OpenGLRenderer* renderer;
QMatrix4x4 view;
QVector3D camera_location;
float water_height;
QVector3D sun_direction;
QColor sun_color;
QString name;
QOpenGLShaderProgram* program;
QOpenGLFunctions_3_2_Core* functions;

View file

@ -0,0 +1,23 @@
#include "OpenGLSharedState.h"
OpenGLSharedState::OpenGLSharedState()
{
}
void OpenGLSharedState::apply(OpenGLShaderProgram *program)
{
for (const auto &pair : variables)
{
pair.second->apply(program);
}
}
OpenGLVariable *OpenGLSharedState::get(const std::string &name)
{
OpenGLVariable*& var = variables[name];
if (var == 0)
{
var = new OpenGLVariable(name);
}
return var;
}

View file

@ -0,0 +1,46 @@
#ifndef OPENGLSHAREDSTATE_H
#define OPENGLSHAREDSTATE_H
#include "opengl_global.h"
#include <map>
#include "OpenGLVariable.h"
namespace paysages {
namespace opengl {
/*!
* \brief OpenGL variables that can be shared between shaders.
*/
class OPENGLSHARED_EXPORT OpenGLSharedState
{
public:
OpenGLSharedState();
/*!
* \brief Apply the stored variables to the bound program.
*/
void apply(OpenGLShaderProgram* program);
/*!
* \brief Get or create a variable in the state.
*/
OpenGLVariable *get(const std::string &name);
// Shortcuts
inline void set(const std::string &name, const Texture2D *texture) {get(name)->set(texture);}
inline void set(const std::string &name, const Texture3D *texture) {get(name)->set(texture);}
inline void set(const std::string &name, const Texture4D *texture) {get(name)->set(texture);}
inline void set(const std::string &name, float value) {get(name)->set(value);}
inline void set(const std::string &name, const Vector3 &vector) {get(name)->set(vector);}
inline void set(const std::string &name, const Matrix4 &matrix) {get(name)->set(matrix);}
inline void set(const std::string &name, const Color &color) {get(name)->set(color);}
private:
std::map<std::string, OpenGLVariable*> variables;
};
}
}
#endif // OPENGLSHAREDSTATE_H

View file

@ -3,6 +3,7 @@
#include <cmath>
#include "OpenGLRenderer.h"
#include "OpenGLShaderProgram.h"
#include "OpenGLSharedState.h"
#include "Scenery.h"
#include "AtmosphereDefinition.h"
#include "AtmosphereRenderer.h"
@ -51,8 +52,13 @@ void OpenGLSkybox::initialize()
void OpenGLSkybox::update()
{
SoftwareBrunetonAtmosphereRenderer* bruneton = (SoftwareBrunetonAtmosphereRenderer*)renderer->getAtmosphereRenderer();
Vector3 sun_direction = renderer->getAtmosphereRenderer()->getSunDirection();
renderer->getSharedState()->set("sunDirection", sun_direction);
Color sun_color = renderer->getScenery()->getAtmosphere()->sun_color;
renderer->getSharedState()->set("sunColor", sun_color);
SoftwareBrunetonAtmosphereRenderer* bruneton = (SoftwareBrunetonAtmosphereRenderer*)renderer->getAtmosphereRenderer();
program->addTexture("transmittanceTexture", bruneton->getModel()->getTextureTransmittance());
program->addTexture("inscatterTexture", bruneton->getModel()->getTextureInscatter());
}

View file

@ -0,0 +1,57 @@
#include "OpenGLVariable.h"
#include <cassert>
#include <QOpenGLShaderProgram>
#include "OpenGLShaderProgram.h"
#include "Vector3.h"
#include "Color.h"
OpenGLVariable::OpenGLVariable(const std::string &name):
name(name)
{
type = TYPE_NONE;
}
void OpenGLVariable::apply(OpenGLShaderProgram *program)
{
QOpenGLShaderProgram* pr = program->getProgram();
switch (type)
{
case TYPE_FLOAT:
pr->setUniformValue(name.c_str(), value_float);
break;
case TYPE_COLOR:
pr->setUniformValue(name.c_str(), value_color);
break;
case TYPE_VECTOR3:
pr->setUniformValue(name.c_str(), value_vector3);
break;
case TYPE_NONE:
break;
}
}
void OpenGLVariable::set(float value)
{
assert(type == TYPE_NONE or type == TYPE_FLOAT);
type = TYPE_FLOAT;
value_float = value;
}
void OpenGLVariable::set(const Vector3 &vector)
{
assert(type == TYPE_NONE or type == TYPE_COLOR);
type = TYPE_VECTOR3;
value_vector3 = QVector3D(vector.x, vector.y, vector.z);
}
void OpenGLVariable::set(const Color &color)
{
assert(type == TYPE_NONE or type == TYPE_COLOR);
type = TYPE_COLOR;
value_color = QColor(color.r, color.g, color.b);
}

View file

@ -0,0 +1,54 @@
#ifndef OPENGLVARIABLE_H
#define OPENGLVARIABLE_H
#include "opengl_global.h"
#include <QColor>
#include <QVector3D>
namespace paysages {
namespace opengl {
/*!
* \brief OpenGL variable that can be bound to a uniform for shaders.
*/
class OpenGLVariable
{
public:
typedef enum {
TYPE_NONE,
TYPE_TEXTURE_2D,
TYPE_TEXTURE_3D,
TYPE_TEXTURE_4D,
TYPE_FLOAT,
TYPE_VECTOR3,
TYPE_MATRIX4,
TYPE_COLOR
} OpenGLVariableType;
public:
OpenGLVariable(const std::string &name);
void apply(OpenGLShaderProgram *program);
void set(const Texture2D *texture);
void set(const Texture3D *texture);
void set(const Texture4D *texture);
void set(float value);
void set(const Vector3 &vector);
void set(const Matrix4 &matrix);
void set(const Color &color);
private:
std::string name;
OpenGLVariableType type;
float value_float;
QColor value_color;
QVector3D value_vector3;
};
}
}
#endif // OPENGLVARIABLE_H

View file

@ -1,6 +1,9 @@
#include "OpenGLWater.h"
#include "OpenGLRenderer.h"
#include "OpenGLShaderProgram.h"
#include "OpenGLSharedState.h"
#include "WaterRenderer.h"
OpenGLWater::OpenGLWater(OpenGLRenderer *renderer):
OpenGLPart(renderer)
@ -27,6 +30,8 @@ void OpenGLWater::initialize()
void OpenGLWater::update()
{
double water_height = renderer->getWaterRenderer()->getHeightInfo().max_height;
renderer->getSharedState()->set("waterHeight", water_height);
}
void OpenGLWater::render()

View file

@ -21,7 +21,9 @@ SOURCES += \
OpenGLShaderProgram.cpp \
OpenGLPart.cpp \
OpenGLSkybox.cpp \
OpenGLWater.cpp
OpenGLWater.cpp \
OpenGLSharedState.cpp \
OpenGLVariable.cpp
HEADERS +=\
opengl_global.h \
@ -32,7 +34,9 @@ HEADERS +=\
OpenGLShaderProgram.h \
OpenGLPart.h \
OpenGLSkybox.h \
OpenGLWater.h
OpenGLWater.h \
OpenGLSharedState.h \
OpenGLVariable.h
unix:!symbian {
maemo5 {

View file

@ -17,6 +17,8 @@ namespace opengl {
class OpenGLRenderer;
class BaseExplorerChunk;
class OpenGLShaderProgram;
class OpenGLSharedState;
class OpenGLVariable;
class OpenGLSkybox;
class OpenGLWater;
}

1
src/system/Logs.cpp Normal file
View file

@ -0,0 +1 @@
#include "Logs.h"

9
src/system/Logs.h Normal file
View file

@ -0,0 +1,9 @@
#ifndef LOGS_H
#define LOGS_H
#include "system_global.h"
#define logWarning qWarning
#define logError qError
#endif // LOGS_H

View file

@ -23,7 +23,8 @@ SOURCES += \
ParallelWork.cpp \
ParallelQueue.cpp \
CacheFile.cpp \
PictureWriter.cpp
PictureWriter.cpp \
Logs.cpp
HEADERS += \
system_global.h \
@ -36,7 +37,8 @@ HEADERS += \
ParallelWork.h \
ParallelQueue.h \
CacheFile.h \
PictureWriter.h
PictureWriter.h \
Logs.h
unix:!symbian {
maemo5 {