Added FractalNoise value to OpenGLVariable

This commit is contained in:
Michaël Lemaire 2015-12-24 01:21:12 +01:00
parent 77ba82408d
commit 391f1a7f41
11 changed files with 83 additions and 23 deletions

View file

@ -16,6 +16,19 @@ class BASICSSHARED_EXPORT FractalNoise {
FractalNoise(); FractalNoise();
virtual ~FractalNoise(); virtual ~FractalNoise();
inline double getScaling() const {
return scaling;
}
inline double getHeight() const {
return height;
}
inline double getStepScaling() const {
return step_scaling;
}
inline double getStepHeight() const {
return step_height;
}
void setScaling(double scaling, double height = 1.0); void setScaling(double scaling, double height = 1.0);
void setStep(double scaling_factor, double height_factor = 1.0); void setStep(double scaling_factor, double height_factor = 1.0);
void setSlope(double slope_factor); void setSlope(double slope_factor);

View file

@ -507,6 +507,7 @@ const Texture2D *NoiseFunctionSimplex::getNormalTexture() {
for (int x = 0; x < width; x++) { for (int x = 0; x < width; x++) {
for (int z = 0; z < height; z++) { for (int z = 0; z < height; z++) {
// TODO Make texture tileable
double vcenter = noiseSimplexGet2DValue(0.01 * to_double(x), 0.01 * to_double(z)); double vcenter = noiseSimplexGet2DValue(0.01 * to_double(x), 0.01 * to_double(z));
double vsouth = noiseSimplexGet2DValue(0.01 * to_double(x), 0.01 * to_double(z) + 0.001); double vsouth = noiseSimplexGet2DValue(0.01 * to_double(x), 0.01 * to_double(z) + 0.001);
double veast = noiseSimplexGet2DValue(0.01 * to_double(x) + 0.001, 0.01 * to_double(z)); double veast = noiseSimplexGet2DValue(0.01 * to_double(x) + 0.001, 0.01 * to_double(z));

View file

@ -16,6 +16,7 @@
#include "GodRaysSampler.h" #include "GodRaysSampler.h"
#include "Logs.h" #include "Logs.h"
#include "Vector3.h" #include "Vector3.h"
#include "NoiseFunctionSimplex.h"
OpenGLRenderer::OpenGLRenderer(Scenery *scenery) : SoftwareRenderer(scenery) { OpenGLRenderer::OpenGLRenderer(Scenery *scenery) : SoftwareRenderer(scenery) {
ready = false; ready = false;
@ -105,6 +106,9 @@ void OpenGLRenderer::initialize() {
part->updateScenery(); part->updateScenery();
} }
// Common state values
shared_state->set("simplexSampler", NoiseFunctionSimplex::getNormalTexture(), true, true);
cameraChangeEvent(render_camera); cameraChangeEvent(render_camera);
checkForErrors("initialize"); checkForErrors("initialize");

View file

@ -62,6 +62,9 @@ class OPENGLSHARED_EXPORT OpenGLSharedState {
inline void set(const string &name, const Color &color) { inline void set(const string &name, const Color &color) {
get(name)->set(color); get(name)->set(color);
} }
inline void set(const string &name, const FractalNoise &noise) {
get(name)->set(noise);
}
private: private:
map<string, OpenGLVariable *> variables; map<string, OpenGLVariable *> variables;

View file

@ -13,6 +13,7 @@
#include "Texture2D.h" #include "Texture2D.h"
#include "Texture3D.h" #include "Texture3D.h"
#include "Texture4D.h" #include "Texture4D.h"
#include "FractalNoise.h"
typedef enum { typedef enum {
TYPE_NONE, TYPE_NONE,
@ -23,6 +24,7 @@ typedef enum {
TYPE_FLOAT, TYPE_FLOAT,
TYPE_VECTOR3, TYPE_VECTOR3,
TYPE_MATRIX4, TYPE_MATRIX4,
TYPE_NOISE,
TYPE_COLOR TYPE_COLOR
} OpenGLVariableType; } OpenGLVariableType;
@ -104,6 +106,9 @@ void OpenGLVariable::apply(OpenGLShaderProgram *program, unsigned int &texture_u
functions->glUniform1i(loc, static_cast<int>(texture_unit)); functions->glUniform1i(loc, static_cast<int>(texture_unit));
texture_unit++; texture_unit++;
break; break;
case TYPE_NOISE:
functions->glUniform1fv(loc, impl->value_int, impl->value_array_float.get());
break;
case TYPE_NONE: case TYPE_NONE:
break; break;
} }
@ -242,6 +247,19 @@ void OpenGLVariable::set(float value) {
impl->value_float = value; impl->value_float = value;
} }
void OpenGLVariable::set(const FractalNoise &noise) {
impl->type = TYPE_NOISE;
impl->value_int = 4;
float *data = new float[4];
data[0] = to_float(noise.getScaling());
data[1] = to_float(noise.getHeight());
data[2] = to_float(noise.getStepScaling());
data[3] = to_float(noise.getStepHeight());
impl->value_array_float = unique_ptr<float[]>(data);
}
void OpenGLVariable::set(const Vector3 &vector) { void OpenGLVariable::set(const Vector3 &vector) {
impl->type = TYPE_VECTOR3; impl->type = TYPE_VECTOR3;
impl->value_vector3 = make_unique<Vector3>(vector); impl->value_vector3 = make_unique<Vector3>(vector);
@ -284,6 +302,10 @@ float OpenGLVariable::getFloatValue() const {
return impl->value_float; return impl->value_float;
} }
float OpenGLVariable::getFloatArrayValue(unsigned int index) const {
return impl->value_array_float[index];
}
void OpenGLVariable::uploadTexture(OpenGLFunctions *functions) { void OpenGLVariable::uploadTexture(OpenGLFunctions *functions) {
assert(impl->type == TYPE_TEXTURE_2D or impl->type == TYPE_TEXTURE_3D or impl->type == TYPE_TEXTURE_4D); assert(impl->type == TYPE_TEXTURE_2D or impl->type == TYPE_TEXTURE_3D or impl->type == TYPE_TEXTURE_4D);

View file

@ -14,19 +14,6 @@ namespace opengl {
* \brief OpenGL variable that can be bound to a uniform for shaders. * \brief OpenGL variable that can be bound to a uniform for shaders.
*/ */
class OpenGLVariable final { class OpenGLVariable final {
public:
typedef enum {
TYPE_NONE,
TYPE_TEXTURE_2D,
TYPE_TEXTURE_3D,
TYPE_TEXTURE_4D,
TYPE_INTEGER,
TYPE_FLOAT,
TYPE_VECTOR3,
TYPE_MATRIX4,
TYPE_COLOR
} OpenGLVariableType;
public: public:
OpenGLVariable(const string &name); OpenGLVariable(const string &name);
~OpenGLVariable(); ~OpenGLVariable();
@ -53,12 +40,14 @@ class OpenGLVariable final {
void set(const Texture4D *texture, bool repeat = false, bool color = true); void set(const Texture4D *texture, bool repeat = false, bool color = true);
void set(int value); void set(int value);
void set(float value); void set(float value);
void set(const FractalNoise &noise);
void set(const Vector3 &vector); void set(const Vector3 &vector);
void set(const Matrix4 &matrix); void set(const Matrix4 &matrix);
void set(const Color &color); void set(const Color &color);
int getIntValue() const; int getIntValue() const;
float getFloatValue() const; float getFloatValue() const;
float getFloatArrayValue(unsigned int index) const;
protected: protected:
void uploadTexture(OpenGLFunctions *renderer); void uploadTexture(OpenGLFunctions *renderer);

View file

@ -8,7 +8,6 @@
#include "Scenery.h" #include "Scenery.h"
#include "WaterDefinition.h" #include "WaterDefinition.h"
#include "SurfaceMaterial.h" #include "SurfaceMaterial.h"
#include "NoiseFunctionSimplex.h"
#include "FloatNode.h" #include "FloatNode.h"
#include "FloatDiff.h" #include "FloatDiff.h"
#include "IntNode.h" #include "IntNode.h"
@ -58,8 +57,7 @@ void OpenGLWater::update() {
state->set("waterMaterialShininess", water->material->shininess); state->set("waterMaterialShininess", water->material->shininess);
state->set("waterMaterialHardness", water->material->hardness); state->set("waterMaterialHardness", water->material->hardness);
Logs::debug("OpenGL") << "Updating simplex texture" << endl; state->set("waterNoise", renderer->getWaterRenderer()->getNoise());
state->set("simplexSampler", NoiseFunctionSimplex::getNormalTexture(), true, true);
} }
void OpenGLWater::render() { void OpenGLWater::render() {

View file

@ -1,15 +1,19 @@
uniform float noiseInitScaling;
uniform float noiseInitHeight;
uniform float noiseStepScaling;
uniform float noiseStepHeight;
uniform sampler2D simplexSampler; uniform sampler2D simplexSampler;
vec3 noiseNormal2d(vec2 location, float detail) vec3 noiseNormal2d(float[4] data, vec2 location, float detail)
{ {
vec3 normal = vec3(0.0, 0.0, 0.0); vec3 normal = vec3(0.0, 0.0, 0.0);
for (float scaling = 1.0; scaling < 400.0; scaling *= 1.5) float scaling = data[0];
float height = data[1];
float step_scaling = data[2];
float step_height = data[3];
while (height > detail)
{ {
// TODO offsets
// TODO parametrized texture scaling (0.01)
normal += texture(simplexSampler, location * 0.01 * scaling).xyz; normal += texture(simplexSampler, location * 0.01 * scaling).xyz;
scaling *= step_scaling;
height *= step_height;
} }
return normalize(normal); return normalize(normal);
} }

View file

@ -3,11 +3,13 @@ uniform float waterMaterialReflection;
uniform float waterMaterialShininess; uniform float waterMaterialShininess;
uniform float waterMaterialHardness; uniform float waterMaterialHardness;
uniform float waterReflection; uniform float waterReflection;
uniform float[4] waterNoise;
out vec4 final_color; out vec4 final_color;
void main(void) void main(void)
{ {
vec3 normal = noiseNormal2d(unprojected.xz, 0.001); // TODO Increased detail near camera
vec3 normal = noiseNormal2d(waterNoise, unprojected.xz, 0.00001);
final_color = applyLighting(unprojected, normal, waterMaterialColor, waterMaterialReflection, waterMaterialShininess, waterMaterialHardness); final_color = applyLighting(unprojected, normal, waterMaterialColor, waterMaterialReflection, waterMaterialShininess, waterMaterialHardness);

View file

@ -27,6 +27,10 @@ class SOFTWARESHARED_EXPORT WaterRenderer : public LightFilter {
WaterRenderer(SoftwareRenderer *parent); WaterRenderer(SoftwareRenderer *parent);
virtual ~WaterRenderer(); virtual ~WaterRenderer();
inline const FractalNoise &getNoise() const {
return *noise;
}
virtual void update(); virtual void update();
virtual HeightInfo getHeightInfo(); virtual HeightInfo getHeightInfo();

View file

@ -0,0 +1,20 @@
#include "BaseTestCase.h"
#include "OpenGLVariable.h"
#include "NoiseFunctionSimplex.h"
TEST(OpenGLVariable, setNoise) {
OpenGLVariable var("test");
NoiseFunctionSimplex noise;
noise.setScaling(0.5, 2.0);
noise.setStep(3.0, 0.4);
var.set(noise);
EXPECT_EQ(4, var.getIntValue());
EXPECT_FLOAT_EQ(2.0f, var.getFloatArrayValue(0));
EXPECT_FLOAT_EQ(1.0f, var.getFloatArrayValue(1));
EXPECT_FLOAT_EQ(1.0f / 3.0f, var.getFloatArrayValue(2));
EXPECT_FLOAT_EQ(1.2f, var.getFloatArrayValue(3));
}