[Broken WIP] Refactored textures, pictures and cache

This commit is contained in:
Michaël Lemaire 2013-12-09 22:16:00 +01:00
parent ec444b7c26
commit 2aed1f07ae
31 changed files with 977 additions and 983 deletions

View file

@ -32,6 +32,7 @@ public:
void limitPower(double max_power);
Color add(const Color& other) const;
Color lerp(const Color& other, double f) const;
public:
double r;

View file

@ -187,3 +187,14 @@ METHSPEC Color Color::add(const Color& other) const
{
return Color(r + other.r, g + other.g, b + other.b, a);
}
METHSPEC Color Color::lerp(const Color& other, double f) const
{
Color result(
r * (1.0 - f) + other.r * f,
g * (1.0 - f) + other.g * f,
b * (1.0 - f) + other.b * f,
a * (1.0 - f) + other.a * f
);
return result;
}

168
src/basics/Texture2D.cpp Normal file
View file

@ -0,0 +1,168 @@
#include "Texture2D.h"
#include <cassert>
#include "Color.h"
#include "PackStream.h"
#include "PictureWriter.h"
Texture2D::Texture2D(int xsize, int ysize)
{
assert(xsize > 0 && ysize > 0);
this->xsize = xsize;
this->ysize = ysize;
this->data = new Color[xsize * ysize];
}
Texture2D::~Texture2D()
{
delete[] data;
}
void Texture2D::getSize(int* xsize, int* ysize)
{
*xsize = this->xsize;
*ysize = this->ysize;
}
void Texture2D::setPixel(int x, int y, Color col)
{
assert(x >= 0 && x < xsize);
assert(y >= 0 && y < ysize);
data[y * xsize + x] = col;
}
Color Texture2D::getPixel(int x, int y)
{
assert(x >= 0 && x < xsize);
assert(y >= 0 && y < ysize);
return data[y * xsize + x];
}
Color Texture2D::getNearest(double dx, double dy)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
int ix = (int)(dx * (double)(this->xsize - 1));
int iy = (int)(dy * (double)(this->ysize - 1));
assert(ix >= 0 && ix < this->xsize);
assert(iy >= 0 && iy < this->ysize);
return this->data[iy * this->xsize + ix];
}
Color Texture2D::getLinear(double dx, double dy)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
dx *= (double)(this->xsize - 1);
dy *= (double)(this->ysize - 1);
int ix = (int)floor(dx);
if (ix == this->xsize - 1)
{
ix--;
}
int iy = (int)floor(dy);
if (iy == this->ysize - 1)
{
iy--;
}
dx -= (double)ix;
dy -= (double)iy;
Color* data = this->data + iy * this->xsize + ix;
Color c1 = data->lerp(*(data + 1), dx);
Color c2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
return c1.lerp(c2, dy);
}
Color Texture2D::getCubic(double dx, double dy)
{
/* TODO */
return getLinear(dx, dy);
}
void Texture2D::fill(Color col)
{
int i, n;
n = this->xsize * this->ysize;
for (i = 0; i < n; i++)
{
this->data[i] = col;
}
}
void Texture2D::add(Texture2D* source)
{
int i, n;
assert(source->xsize == this->xsize);
assert(source->ysize == this->ysize);
n = source->xsize * source->ysize;
for (i = 0; i < n; i++)
{
this->data[i].r += source->data[i].r;
this->data[i].g += source->data[i].g;
this->data[i].b += source->data[i].b;
/* destination->data[i].a += source->data[i].a; */
}
}
void Texture2D::save(PackStream* stream)
{
int i, n;
stream->write(&this->xsize);
stream->write(&this->ysize);
n = this->xsize * this->ysize;
for (i = 0; i < n; i++)
{
colorSave(stream, this->data + i);
}
}
void Texture2D::load(PackStream* stream)
{
int i, n;
stream->read(&this->xsize);
stream->read(&this->ysize);
n = this->xsize * this->ysize;
delete[] this->data;
this->data = new Color[n];
for (i = 0; i < n; i++)
{
colorLoad(stream, this->data + i);
}
}
class Texture2DWriter:public PictureWriter
{
public:
Texture2DWriter(Texture2D *tex): tex(tex) {}
virtual unsigned int getPixel(int x, int y) override
{
return tex->getPixel(x, y).to32BitBGRA();
}
private:
Texture2D *tex;
};
void Texture2D::saveToFile(const std::string &filepath)
{
Texture2DWriter writer(this);
writer.save(filepath, xsize, ysize);
}

36
src/basics/Texture2D.h Normal file
View file

@ -0,0 +1,36 @@
#ifndef TEXTURE2D_H
#define TEXTURE2D_H
#include "basics_global.h"
namespace paysages {
namespace basics {
class Texture2D
{
public:
Texture2D(int xsize, int ysize);
~Texture2D();
void getSize(int* xsize, int* ysize);
void setPixel(int x, int y, Color col);
Color getPixel(int x, int y);
Color getNearest(double dx, double dy);
Color getLinear(double dx, double dy);
Color getCubic(double dx, double dy);
void fill(Color col);
void add(Texture2D* other);
void save(PackStream* stream);
void load(PackStream* stream);
void saveToFile(const std::string &filepath);
private:
int xsize;
int ysize;
Color* data;
};
}
}
#endif // TEXTURE2D_H

200
src/basics/Texture3D.cpp Normal file
View file

@ -0,0 +1,200 @@
#include "Texture3D.h"
#include <cassert>
#include "Color.h"
#include "PackStream.h"
#include "PictureWriter.h"
Texture3D::Texture3D(int xsize, int ysize, int zsize)
{
assert(xsize > 0 && ysize > 0 && zsize > 0);
this->xsize = xsize;
this->ysize = ysize;
this->zsize = zsize;
this->data = new Color[xsize * ysize * zsize];
}
Texture3D::~Texture3D()
{
delete[] data;
}
void Texture3D::getSize(int* xsize, int* ysize, int* zsize)
{
*xsize = this->xsize;
*ysize = this->ysize;
*zsize = this->zsize;
}
void Texture3D::setPixel(int x, int y, int z, Color col)
{
assert(x >= 0 && x < this->xsize);
assert(y >= 0 && y < this->ysize);
assert(z >= 0 && z < this->ysize);
this->data[z * this->xsize * this->ysize + y * this->xsize + x] = col;
}
Color Texture3D::getPixel(int x, int y, int z)
{
assert(x >= 0 && x < this->xsize);
assert(y >= 0 && y < this->ysize);
assert(z >= 0 && z < this->zsize);
return this->data[z * this->xsize * this->ysize + y * this->xsize + x];
}
Color Texture3D::getNearest(double dx, double dy, double dz)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
int ix = (int)(dx * (double)(this->xsize - 1));
int iy = (int)(dy * (double)(this->ysize - 1));
int iz = (int)(dz * (double)(this->zsize - 1));
assert(ix >= 0 && ix < this->xsize);
assert(iy >= 0 && iy < this->ysize);
assert(iz >= 0 && iz < this->zsize);
return this->data[iz * this->xsize * this->ysize + iy * this->xsize + ix];
}
Color Texture3D::getLinear(double dx, double dy, double dz)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
dx *= (double)(this->xsize - 1);
dy *= (double)(this->ysize - 1);
dz *= (double)(this->zsize - 1);
int ix = (int)floor(dx);
if (ix == this->xsize - 1)
{
ix--;
}
int iy = (int)floor(dy);
if (iy == this->ysize - 1)
{
iy--;
}
int iz = (int)floor(dz);
if (iz == this->zsize - 1)
{
iz--;
}
dx -= (double)ix;
dy -= (double)iy;
dz -= (double)iz;
Color* data = this->data + iz * this->xsize * this->ysize + iy * this->xsize + ix;
Color cx1 = data->lerp(*(data + 1), dx);
Color cx2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
Color cy1 = cx1.lerp(cx2, dy);
data += this->xsize * this->ysize;
cx1 = data->lerp(*(data + 1), dx);
cx2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
Color cy2 = cx1.lerp(cx2, dy);
return cy1.lerp(cy2, dz);
}
Color Texture3D::getCubic(double dx, double dy, double dz)
{
/* TODO */
return getLinear(dx, dy, dz);
}
void Texture3D::fill(Color col)
{
int i, n;
n = this->xsize * this->ysize * this->zsize;
for (i = 0; i < n; i++)
{
this->data[i] = col;
}
}
void Texture3D::add(Texture3D* source)
{
int i, n;
assert(source->xsize == this->xsize);
assert(source->ysize == this->ysize);
assert(source->zsize == this->zsize);
n = source->xsize * source->ysize * source->zsize;
for (i = 0; i < n; i++)
{
this->data[i].r += source->data[i].r;
this->data[i].g += source->data[i].g;
this->data[i].b += source->data[i].b;
/* destination->data[i].a += source->data[i].a; */
}
}
void Texture3D::save(PackStream* stream)
{
int i, n;
stream->write(&this->xsize);
stream->write(&this->ysize);
stream->write(&this->zsize);
n = this->xsize * this->ysize * this->zsize;
for (i = 0; i < n; i++)
{
colorSave(stream, this->data + i);
}
}
void Texture3D::load(PackStream* stream)
{
int i, n;
stream->read(&this->xsize);
stream->read(&this->ysize);
stream->read(&this->zsize);
n = this->xsize * this->ysize * this->zsize;
delete[] this->data;
this->data = new Color[n];
for (i = 0; i < n; i++)
{
colorLoad(stream, this->data + i);
}
}
class Texture3DWriter:public PictureWriter
{
public:
Texture3DWriter(Texture3D *tex): tex(tex) {}
virtual unsigned int getPixel(int x, int y) override
{
int xsize, ysize, zsize;
tex->getSize(&xsize, &ysize, &zsize);
int z = y / ysize;
y = y % ysize;
return tex->getPixel(x, y, z).to32BitBGRA();
}
private:
Texture3D *tex;
};
void Texture3D::saveToFile(const std::string &filepath)
{
Texture3DWriter writer(this);
writer.save(filepath, xsize, ysize * zsize);
}

37
src/basics/Texture3D.h Normal file
View file

@ -0,0 +1,37 @@
#ifndef TEXTURE3D_H
#define TEXTURE3D_H
#include "basics_global.h"
namespace paysages {
namespace basics {
class Texture3D
{
public:
Texture3D(int xsize, int ysize, int zsize);
~Texture3D();
void getSize(int* xsize, int* ysize, int* zsize);
void setPixel(int x, int y, int z, Color col);
Color getPixel(int x, int y, int z);
Color getNearest(double dx, double dy, double dz);
Color getLinear(double dx, double dy, double dz);
Color getCubic(double dx, double dy, double dz);
void fill(Color col);
void add(Texture3D* other);
void save(PackStream* stream);
void load(PackStream* stream);
void saveToFile(const std::string &filepath);
private:
int xsize;
int ysize;
int zsize;
Color* data;
};
}
}
#endif // TEXTURE3D_H

238
src/basics/Texture4D.cpp Normal file
View file

@ -0,0 +1,238 @@
#include "Texture4D.h"
#include <cassert>
#include "Color.h"
#include "PackStream.h"
#include "PictureWriter.h"
Texture4D::Texture4D(int xsize, int ysize, int zsize, int wsize)
{
assert(xsize > 0 && ysize > 0 && zsize > 0 && wsize > 0);
this->xsize = xsize;
this->ysize = ysize;
this->zsize = zsize;
this->wsize = wsize;
this->data = new Color[xsize * ysize * zsize * wsize];
}
Texture4D::~Texture4D()
{
delete[] data;
}
void Texture4D::getSize(int* xsize, int* ysize, int* zsize, int* wsize)
{
*xsize = this->xsize;
*ysize = this->ysize;
*zsize = this->zsize;
*wsize = this->wsize;
}
void Texture4D::setPixel(int x, int y, int z, int w, Color col)
{
assert(x >= 0 && x < this->xsize);
assert(y >= 0 && y < this->ysize);
assert(z >= 0 && z < this->zsize);
assert(w >= 0 && w < this->wsize);
this->data[w * this->xsize * this->ysize * this->zsize + z * this->xsize * this->ysize + y * this->xsize + x] = col;
}
Color Texture4D::getPixel(int x, int y, int z, int w)
{
assert(x >= 0 && x < this->xsize);
assert(y >= 0 && y < this->ysize);
assert(z >= 0 && z < this->zsize);
assert(w >= 0 && w < this->wsize);
return this->data[w * this->xsize * this->ysize * this->zsize + z * this->xsize * this->ysize + y * this->xsize + x];
}
Color Texture4D::getNearest(double dx, double dy, double dz, double dw)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
if (dw < 0.0) dw = 0.0;
if (dw > 1.0) dw = 1.0;
int ix = (int)(dx * (double)(this->xsize - 1));
int iy = (int)(dy * (double)(this->ysize - 1));
int iz = (int)(dz * (double)(this->zsize - 1));
int iw = (int)(dw * (double)(this->wsize - 1));
assert(ix >= 0 && ix < this->xsize);
assert(iy >= 0 && iy < this->ysize);
assert(iz >= 0 && iz < this->zsize);
assert(iw >= 0 && iw < this->wsize);
return this->data[iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize + iy * this->xsize + ix];
}
Color Texture4D::getLinear(double dx, double dy, double dz, double dw)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
if (dw < 0.0) dw = 0.0;
if (dw > 1.0) dw = 1.0;
dx *= (double)(this->xsize - 1);
dy *= (double)(this->ysize - 1);
dz *= (double)(this->zsize - 1);
dw *= (double)(this->wsize - 1);
int ix = (int)floor(dx);
if (ix == this->xsize - 1)
{
ix--;
}
int iy = (int)floor(dy);
if (iy == this->ysize - 1)
{
iy--;
}
int iz = (int)floor(dz);
if (iz == this->zsize - 1)
{
iz--;
}
int iw = (int)floor(dw);
if (iw == this->wsize - 1)
{
iw--;
}
dx -= (double)ix;
dy -= (double)iy;
dz -= (double)iz;
dw -= (double)iw;
Color* data = this->data + iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize + iy * this->xsize + ix;
Color cz1, cz2;
Color cx1 = data->lerp(*(data + 1), dx);
Color cx2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
Color cy1 = cx1.lerp(cx2, dy);
data += this->xsize * this->ysize;
cx1 = data->lerp(*(data + 1), dx);
cx2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
Color cy2 = cx1.lerp(cx2, dy);
data += this->xsize * this->ysize * this->zsize;
cz1 = cy1.lerp(cy2, dz);
cx1 = data->lerp(*(data + 1), dx);
cx2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
cy1 = cx1.lerp(cx2, dy);
cx1 = data->lerp(*(data + 1), dx);
cx2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
cy2 = cx1.lerp(cx2, dy);
cz2 = cy1.lerp(cy2, dz);
return cz1.lerp(cz2, dw);
}
Color Texture4D::getCubic(double dx, double dy, double dz, double dw)
{
/* TODO */
return getLinear(dx, dy, dz, dw);
}
void Texture4D::fill(Color col)
{
int i, n;
n = this->xsize * this->ysize * this->zsize * this->wsize;
for (i = 0; i < n; i++)
{
this->data[i] = col;
}
}
void Texture4D::add(Texture4D* source)
{
int i, n;
assert(source->xsize == this->xsize);
assert(source->ysize == this->ysize);
assert(source->zsize == this->zsize);
assert(source->wsize == this->wsize);
n = source->xsize * source->ysize * source->zsize * source->wsize;
for (i = 0; i < n; i++)
{
this->data[i].r += source->data[i].r;
this->data[i].g += source->data[i].g;
this->data[i].b += source->data[i].b;
/* destination->data[i].a += source->data[i].a; */
}
}
void Texture4D::save(PackStream* stream)
{
int i, n;
stream->write(&this->xsize);
stream->write(&this->ysize);
stream->write(&this->zsize);
stream->write(&this->wsize);
n = this->xsize * this->ysize * this->zsize * this->wsize;
for (i = 0; i < n; i++)
{
colorSave(stream, this->data + i);
}
}
void Texture4D::load(PackStream* stream)
{
int i, n;
stream->read(&this->xsize);
stream->read(&this->ysize);
stream->read(&this->zsize);
stream->read(&this->wsize);
n = this->xsize * this->ysize * this->zsize * this->wsize;
delete[] this->data;
this->data = new Color[n];
for (i = 0; i < n; i++)
{
colorLoad(stream, this->data + i);
}
}
class Texture4DWriter:public PictureWriter
{
public:
Texture4DWriter(Texture4D *tex): tex(tex) {}
virtual unsigned int getPixel(int x, int y) override
{
int xsize, ysize, zsize, wsize;
tex->getSize(&xsize, &ysize, &zsize, &wsize);
int w = x / xsize;
x = x % xsize;
int z = y / ysize;
y = y % ysize;
return tex->getPixel(x, y, z, w).to32BitBGRA();
}
private:
Texture4D *tex;
};
void Texture4D::saveToFile(const std::string &filepath)
{
Texture4DWriter writer(this);
writer.save(filepath, xsize * wsize, ysize * zsize);
}

38
src/basics/Texture4D.h Normal file
View file

@ -0,0 +1,38 @@
#ifndef TEXTURE4D_H
#define TEXTURE4D_H
#include "basics_global.h"
namespace paysages {
namespace basics {
class Texture4D
{
public:
Texture4D(int xsize, int ysize, int zsize, int wsize);
~Texture4D();
void getSize(int* xsize, int* ysize, int* zsize, int* wsize);
void setPixel(int x, int y, int z, int w, Color col);
Color getPixel(int x, int y, int z, int w);
Color getNearest(double dx, double dy, double dz, double dw);
Color getLinear(double dx, double dy, double dz, double dw);
Color getCubic(double dx, double dy, double dz, double dw);
void fill(Color col);
void add(Texture4D* other);
void save(PackStream* stream);
void load(PackStream* stream);
void saveToFile(const std::string &filepath);
private:
int xsize;
int ysize;
int zsize;
int wsize;
Color* data;
};
}
}
#endif // TEXTURE4D_H

View file

@ -29,7 +29,10 @@ SOURCES += \
Matrix4.cpp \
Curve.cpp \
ColorProfile.cpp \
Geometry.cpp
Geometry.cpp \
Texture2D.cpp \
Texture3D.cpp \
Texture4D.cpp
HEADERS +=\
basics_global.h \
@ -46,7 +49,10 @@ HEADERS +=\
Matrix4.h \
Curve.h \
ColorProfile.h \
Geometry.h
Geometry.h \
Texture2D.h \
Texture3D.h \
Texture4D.h
unix:!symbian {
maemo5 {

View file

@ -23,20 +23,20 @@ void RenderingScenery::setCustomSaveCallbacks(SceneryCustomDataCallback callback
void RenderingScenery::save(PackStream* stream) const
{
Scenery::save(stream);
if (_custom_save)
{
_custom_save(stream, _custom_data);
}
Scenery::save(stream);
}
void RenderingScenery::load(PackStream* stream)
{
Scenery::load(stream);
if (_custom_load)
{
_custom_load(stream, _custom_data);
}
Scenery::load(stream);
}

View file

@ -1,7 +1,7 @@
#ifndef RENDERINGSCENERY_H
#define RENDERINGSCENERY_H
#include "rendering_global.h"
#include "desktop_global.h"
#include "Scenery.h"
@ -12,7 +12,7 @@ typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
*
* This class contains the whole scenery definition.
*/
class RENDERINGSHARED_EXPORT RenderingScenery: public Scenery
class RenderingScenery: public Scenery
{
public:
RenderingScenery();
@ -30,4 +30,4 @@ private:
void* _custom_data;
};
#endif // SCENERY_H
#endif // RENDERINGSCENERY_H

View file

@ -55,7 +55,8 @@ HEADERS += \
textures/PreviewLayerLook.h \
textures/PreviewCumul.h \
textures/DialogTexturesLayer.h \
desktop_global.h
desktop_global.h \
RenderingScenery.h
SOURCES += \
terrain/widgetheightmap.cpp \
@ -102,7 +103,8 @@ SOURCES += \
textures/PreviewLayerCoverage.cpp \
textures/PreviewLayerLook.cpp \
textures/PreviewCumul.cpp \
textures/DialogTexturesLayer.cpp
textures/DialogTexturesLayer.cpp \
RenderingScenery.cpp
FORMS += \
terrain/dialogterrainpainting.ui \

View file

@ -6,7 +6,6 @@
#include <cmath>
#include <GL/glu.h>
#include <QThread>
#include "RenderingScenery.h"
#include "SoftwareRenderer.h"
#include "OpenGLRenderer.h"
#include "WaterDefinition.h"
@ -16,6 +15,7 @@
#include "ExplorerChunkTerrain.h"
#include "TerrainRenderer.h"
#include "WaterRenderer.h"
#include "Scenery.h"
class ChunkMaintenanceThread : public QThread
{
@ -80,16 +80,7 @@ QGLWidget(parent)
_base_camera = camera;
camera->copy(_current_camera);
if (renderer)
{
_renderer = renderer;
_renderer_created = false;
}
else
{
_renderer = new SoftwareRenderer(RenderingScenery::getCurrent());
_renderer_created = true;
}
_opengl_renderer = new OpenGLRenderer(NULL);
_renderer->prepare();
_renderer->render_quality = 3;
@ -118,11 +109,6 @@ WidgetExplorer::~WidgetExplorer()
delete _chunks[i];
}
delete _current_camera;
if (_renderer_created)
{
delete _renderer;
}
delete _opengl_renderer;
}

View file

@ -14,7 +14,7 @@ class OPENGLSHARED_EXPORT WidgetExplorer : public QGLWidget
{
Q_OBJECT
public:
WidgetExplorer(QWidget* parent, CameraDefinition* camera, SoftwareRenderer* renderer=0);
WidgetExplorer(QWidget* parent, CameraDefinition* camera, SoftwareRenderer* renderer);
~WidgetExplorer();
void performChunksMaintenance();
@ -43,7 +43,6 @@ private:
OpenGLRenderer* _opengl_renderer;
SoftwareRenderer* _renderer;
bool _renderer_created;
bool _inited;
bool _updated;

View file

@ -5,9 +5,6 @@
#include "TerrainDefinition.h"
#include "WaterRenderer.h"
// TEMP
#include "RenderingScenery.h"
WaterCoveragePreviewRenderer::WaterCoveragePreviewRenderer(WaterDefinition* definition):
TerrainShapePreviewRenderer(new TerrainDefinition(NULL)), definition(definition)
{
@ -39,7 +36,7 @@ void WaterCoveragePreviewRenderer::toggleChangeEvent(const std::string &key, boo
void WaterCoveragePreviewRenderer::updateEvent()
{
RenderingScenery::getCurrent()->getTerrain(_terrain);
//RenderingScenery::getCurrent()->getTerrain(_terrain);
TerrainShapePreviewRenderer::updateEvent();
getScenery()->setWater(definition);

View file

@ -19,8 +19,9 @@
#include "WaterRenderer.h"
#include "LightComponent.h"
#include "LightStatus.h"
#include "tools/cache.h"
#include "tools/texture.h"
#include "Texture2D.h"
#include "Texture4D.h"
#include "CacheFile.h"
/* Factor to convert software units to kilometers */
// TODO This is copied in AtmosphereRenderer
@ -177,7 +178,7 @@ static Color _texture4D(Texture4D* tex, double r, double mu, double muS, double
double uMu = cst.a + (rmu * cst.r + sqrt(delta + cst.g)) / (rho + cst.b) * (0.5 - 1.0 / (double)(RES_MU));
double uMuS = 0.5 / (double)(RES_MU_S) + (atan(max(muS, -0.1975) * tan(1.26 * 1.1)) / 1.1 + (1.0 - 0.26)) * 0.5 * (1.0 - 1.0 / (double)(RES_MU_S));
return texture4DGetLinear(tex, uMu, uMuS, nu, uR);
return tex->getLinear(uMu, uMuS, nu, uR);
}
/*********************** Physics functions ***********************/
@ -239,7 +240,7 @@ static Color _transmittance(double r, double mu)
{
double u, v;
_getTransmittanceUV(r, mu, &u, &v);
return texture2DGetLinear(_transmittanceTexture, u, v);
return _transmittanceTexture->getLinear(u, v);
}
/* transmittance(=transparency) of atmosphere between x and x0
@ -345,7 +346,7 @@ static Color _irradiance(Texture2D* sampler, double r, double muS)
{
double u, v;
_getIrradianceUV(r, muS, &u, &v);
return texture2DGetLinear(sampler, u, v);
return sampler->getLinear(u, v);
}
/*********************** transmittance.glsl ***********************/
@ -388,7 +389,7 @@ static void _precomputeTransmittanceTexture()
trans.g = exp(-(betaR.g * depth1 + betaMEx.y * depth2));
trans.b = exp(-(betaR.b * depth1 + betaMEx.z * depth2));
trans.a = 1.0;
texture2DSetPixel(_transmittanceTexture, x, y, trans); /* Eq (5) */
_transmittanceTexture->setPixel(x, y, trans); /* Eq (5) */
}
}
}
@ -414,7 +415,7 @@ static void _precomputeIrrDeltaETexture(Texture2D* destination)
irr.b = trans.b * max(muS, 0.0);
irr.a = 1.0;
texture2DSetPixel(destination, x, y, irr);
destination->setPixel(x, y, irr);
}
}
}
@ -524,8 +525,8 @@ static int _inscatter1Worker(ParallelWork*, int layer, void* data)
_inscatter1(r, mu, muS, nu, &ray, &mie);
/* store separately Rayleigh and Mie contributions, WITHOUT the phase function factor
* (cf "Angular precision") */
texture4DSetPixel(params->ray, x, y, z, layer, ray);
texture4DSetPixel(params->mie, x, y, z, layer, mie);
params->ray->setPixel(x, y, z, layer, ray);
params->mie->setPixel(x, y, z, layer, mie);
}
}
}
@ -660,7 +661,7 @@ static int _jWorker(ParallelWork*, int layer, void* data)
double mu, muS, nu;
_texCoordToMuMuSNu((double)x, (double)y, (double)z, r, dhdH, &mu, &muS, &nu);
raymie = _inscatterS(r, mu, muS, nu, params->first, params->deltaE, params->deltaSR, params->deltaSM);
texture4DSetPixel(params->result, x, y, z, layer, raymie);
params->result->setPixel(x, y, z, layer, raymie);
}
}
}
@ -717,7 +718,7 @@ void _irradianceNProg(Texture2D* destination, Texture4D* deltaSR, Texture4D* del
}
}
texture2DSetPixel(destination, x, y, result);
destination->setPixel(x, y, result);
}
}
}
@ -780,7 +781,7 @@ static int _inscatterNWorker(ParallelWork*, int layer, void* data)
{
double mu, muS, nu;
_texCoordToMuMuSNu((double)x, (double)y, (double)z, r, dhdH, &mu, &muS, &nu);
texture4DSetPixel(params->destination, x, y, z, layer, _inscatterN(params->deltaJ, r, mu, muS, nu));
params->destination->setPixel(x, y, z, layer, _inscatterN(params->deltaJ, r, mu, muS, nu));
}
}
}
@ -812,12 +813,12 @@ static int _copyInscatterNWorker(ParallelWork*, int layer, void* data)
{
double mu, muS, nu;
_texCoordToMuMuSNu((double)x, (double)y, (double)z, r, dhdH, &mu, &muS, &nu);
Color col1 = texture4DGetPixel(params->source, x, y, z, layer);
Color col2 = texture4DGetPixel(params->destination, x, y, z, layer);
Color col1 = params->source->getPixel(x, y, z, layer);
Color col2 = params->destination->getPixel(x, y, z, layer);
col2.r += col1.r / _phaseFunctionR(nu);
col2.g += col1.g / _phaseFunctionR(nu);
col2.b += col1.b / _phaseFunctionR(nu);
texture4DSetPixel(params->destination, x, y, z, layer, col2);
params->destination->setPixel(x, y, z, layer, col2);
}
}
}
@ -946,108 +947,94 @@ static Color _sunColor(Vector3 v, Vector3 s, double r, double mu, double radius)
static int _tryLoadCache2D(Texture2D* tex, const char* tag, int order)
{
CacheFile* cache;
int xsize, ysize;
tex->getSize(&xsize, &ysize);
texture2DGetSize(tex, &xsize, &ysize);
cache = cacheFileCreateAccessor("atmo-br", "cache", tag, xsize, ysize, 0, 0, order);
if (cacheFileIsReadable(cache))
CacheFile cache("atmo-br", "cache", tag, xsize, ysize, 0, 0, order);
if (cache.isReadable())
{
PackStream stream;
stream.bindToFile(cacheFileGetPath(cache));
texture2DLoad(&stream, tex);
stream.bindToFile(cache.getPath());
tex->load(&stream);
cacheFileDeleteAccessor(cache);
return 1;
}
else
{
cacheFileDeleteAccessor(cache);
return 0;
}
}
static void _saveCache2D(Texture2D* tex, const char* tag, int order)
{
CacheFile* cache;
int xsize, ysize;
tex->getSize(&xsize, &ysize);
texture2DGetSize(tex, &xsize, &ysize);
cache = cacheFileCreateAccessor("atmo-br", "cache", tag, xsize, ysize, 0, 0, order);
if (cacheFileIsWritable(cache))
CacheFile cache("atmo-br", "cache", tag, xsize, ysize, 0, 0, order);
if (cache.isWritable())
{
PackStream stream;
stream.bindToFile(cacheFileGetPath(cache));
texture2DSave(&stream, tex);
stream.bindToFile(cache.getPath());
tex->save(&stream);
}
cacheFileDeleteAccessor(cache);
}
static void _saveDebug2D(Texture2D* tex, const char* tag, int order)
{
CacheFile* cache;
int xsize, ysize;
tex->getSize(&xsize, &ysize);
texture2DGetSize(tex, &xsize, &ysize);
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, 0, 0, order);
if (cacheFileIsWritable(cache))
CacheFile cache("atmo-br", "png", tag, xsize, ysize, 0, 0, order);
if (cache.isWritable())
{
texture2DSaveToFile(tex, cacheFileGetPath(cache));
tex->saveToFile(cache.getPath());
}
cacheFileDeleteAccessor(cache);
}
static int _tryLoadCache4D(Texture4D* tex, const char* tag, int order)
{
CacheFile* cache;
int xsize, ysize, zsize, wsize;
tex->getSize(&xsize, &ysize, &zsize, &wsize);
texture4DGetSize(tex, &xsize, &ysize, &zsize, &wsize);
cache = cacheFileCreateAccessor("atmo-br", "cache", tag, xsize, ysize, zsize, wsize, order);
if (cacheFileIsReadable(cache))
CacheFile cache("atmo-br", "cache", tag, xsize, ysize, zsize, wsize, order);
if (cache.isReadable())
{
PackStream stream;
stream.bindToFile(cacheFileGetPath(cache));
texture4DLoad(&stream, tex);
stream.bindToFile(cache.getPath());
tex->load(&stream);
cacheFileDeleteAccessor(cache);
return 1;
}
else
{
cacheFileDeleteAccessor(cache);
return 0;
}
}
static void _saveCache4D(Texture4D* tex, const char* tag, int order)
{
CacheFile* cache;
int xsize, ysize, zsize, wsize;
tex->getSize(&xsize, &ysize, &zsize, &wsize);
texture4DGetSize(tex, &xsize, &ysize, &zsize, &wsize);
cache = cacheFileCreateAccessor("atmo-br", "cache", tag, xsize, ysize, zsize, wsize, order);
if (cacheFileIsWritable(cache))
CacheFile cache("atmo-br", "cache", tag, xsize, ysize, zsize, wsize, order);
if (cache.isWritable())
{
PackStream stream;
stream.bindToFile(cacheFileGetPath(cache));
texture4DSave(&stream, tex);
stream.bindToFile(cache.getPath());
tex->save(&stream);
}
cacheFileDeleteAccessor(cache);
}
static void _saveDebug4D(Texture4D* tex, const char* tag, int order)
{
CacheFile* cache;
int xsize, ysize, zsize, wsize;
tex->getSize(&xsize, &ysize, &zsize, &wsize);
texture4DGetSize(tex, &xsize, &ysize, &zsize, &wsize);
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, zsize, wsize, order);
if (cacheFileIsWritable(cache))
CacheFile cache("atmo-br", "png", tag, xsize, ysize, zsize, wsize, order);
if (cache.isWritable())
{
texture4DSaveToFile(tex, cacheFileGetPath(cache));
tex->saveToFile(cache.getPath());
}
cacheFileDeleteAccessor(cache);
}
/*********************** Public methods ***********************/
@ -1059,9 +1046,9 @@ int brunetonInit()
assert(_inscatterTexture == NULL);
/* TODO Deletes */
_transmittanceTexture = texture2DCreate(TRANSMITTANCE_W, TRANSMITTANCE_H);
_irradianceTexture = texture2DCreate(SKY_W, SKY_H);
_inscatterTexture = texture4DCreate(RES_MU, RES_MU_S, RES_NU, RES_R);
_transmittanceTexture = new Texture2D(TRANSMITTANCE_W, TRANSMITTANCE_H);
_irradianceTexture = new Texture2D(SKY_W, SKY_H);
_inscatterTexture = new Texture4D(RES_MU, RES_MU_S, RES_NU, RES_R);
/* try loading from cache */
if (_tryLoadCache2D(_transmittanceTexture, "transmittance", 0)
@ -1071,10 +1058,10 @@ int brunetonInit()
return 1;
}
Texture2D* _deltaETexture = texture2DCreate(SKY_W, SKY_H);
Texture4D* _deltaSMTexture = texture4DCreate(RES_MU, RES_MU_S, RES_NU, RES_R);
Texture4D* _deltaSRTexture = texture4DCreate(RES_MU, RES_MU_S, RES_NU, RES_R);
Texture4D* _deltaJTexture = texture4DCreate(RES_MU, RES_MU_S, RES_NU, RES_R);
Texture2D* _deltaETexture = new Texture2D(SKY_W, SKY_H);
Texture4D* _deltaSMTexture = new Texture4D(RES_MU, RES_MU_S, RES_NU, RES_R);
Texture4D* _deltaSRTexture = new Texture4D(RES_MU, RES_MU_S, RES_NU, RES_R);
Texture4D* _deltaJTexture = new Texture4D(RES_MU, RES_MU_S, RES_NU, RES_R);
/* computes transmittance texture T (line 1 in algorithm 4.1) */
_precomputeTransmittanceTexture();
@ -1095,7 +1082,7 @@ int brunetonInit()
/* copies deltaE into irradiance texture E (line 4 in algorithm 4.1) */
/* ??? all black texture (k=0.0) ??? */
texture2DFill(_irradianceTexture, COLOR_BLACK);
_irradianceTexture->fill(COLOR_BLACK);
/* copies deltaS into inscatter texture S (line 5 in algorithm 4.1) */
for (x = 0; x < RES_MU; x++)
@ -1106,10 +1093,10 @@ int brunetonInit()
{
for (w = 0; w < RES_R; w++)
{
Color result = texture4DGetPixel(_deltaSRTexture, x, y, z, w);
Color mie = texture4DGetPixel(_deltaSMTexture, x, y, z, w);
Color result = _deltaSRTexture->getPixel(x, y, z, w);
Color mie = _deltaSMTexture->getPixel(x, y, z, w);
result.a = mie.r;
texture4DSetPixel(_inscatterTexture, x, y, z, w, result);
_inscatterTexture->setPixel(x, y, z, w, result);
}
}
}
@ -1137,7 +1124,7 @@ int brunetonInit()
delete work;
/* adds deltaE into irradiance texture E (line 10 in algorithm 4.1) */
texture2DAdd(_deltaETexture, _irradianceTexture);
_irradianceTexture->add(_deltaETexture);
_saveDebug2D(_irradianceTexture, "irradiance", order);
/* adds deltaS into inscatter texture S (line 11 in algorithm 4.1) */
@ -1152,10 +1139,10 @@ int brunetonInit()
_saveCache2D(_irradianceTexture, "irradiance", 0);
_saveCache4D(_inscatterTexture, "inscatter", 0);
texture2DDelete(_deltaETexture);
texture4DDelete(_deltaSMTexture);
texture4DDelete(_deltaSRTexture);
texture4DDelete(_deltaJTexture);
delete _deltaETexture;
delete _deltaSMTexture;
delete _deltaSRTexture;
delete _deltaJTexture;
return 1;
}

View file

@ -6,7 +6,7 @@
#include "CameraDefinition.h"
#include "SoftwareRenderer.h"
#include "Thread.h"
#include "PictureFile.h"
#include "PictureWriter.h"
struct RenderFragment
{
@ -721,16 +721,25 @@ void RenderArea::postProcess(int nbchunks)
callback_update(1.0);
}
static unsigned int _getPicturePixel(void* data, int x, int y)
class RenderWriter:public PictureWriter
{
Color result = _getFinalPixel((RenderArea*)data, x, y);
public:
RenderWriter(RenderArea *area): area(area) {}
virtual unsigned int getPixel(int x, int y) override
{
Color result = _getFinalPixel(area, x, y);
result.normalize();
return result.to32BitBGRA();
}
}
private:
RenderArea *area;
};
int RenderArea::saveToFile(const char* path)
int RenderArea::saveToFile(const std::string &path)
{
return systemSavePictureFile(path, _getPicturePixel, this, params.width, params.height);
RenderWriter writer(this);
return writer.save(path, params.width, params.height);
}
void RenderArea::setPreviewCallbacks(RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)

View file

@ -42,7 +42,7 @@ public:
Color getPixel(int x, int y);
void postProcess(int nbchunks);
int saveToFile(const char* path);
int saveToFile(const std::string &path);
void setPreviewCallbacks(RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update);
void setAllDirty();

View file

@ -9,19 +9,12 @@ DEFINES += RENDERING_LIBRARY
include(../common.pri)
SOURCES += main.cpp \
tools/texture.cpp \
tools/data.cpp \
tools/cache.cpp \
RenderingScenery.cpp
tools/data.cpp
HEADERS += \
main.h \
shared/types.h \
tools/texture.h \
tools/data.h \
tools/cache.h \
rendering_global.h \
RenderingScenery.h
rendering_global.h
win32:CONFIG(release, debug|release): LIBS += -L$$OUT_PWD/../system/release/ -lpaysages_system
else:win32:CONFIG(debug, debug|release): LIBS += -L$$OUT_PWD/../system/debug/ -lpaysages_system

View file

@ -1,18 +0,0 @@
#ifndef _PAYSAGES_TYPES_H_
#define _PAYSAGES_TYPES_H_
#include "rendering_global.h"
#include "Color.h"
#include "Vector3.h"
typedef void* (*FuncObjectCreate)();
typedef void (*FuncObjectDelete)(void* object);
typedef void (*FuncObjectBind)(void* base, void* sub);
typedef struct {
FuncObjectCreate create;
FuncObjectDelete destroy;
FuncObjectBind bind;
} StandardRenderer;
#endif

View file

@ -1,82 +0,0 @@
#include "cache.h"
#include <cstdio>
#include <cstdlib>
struct CacheFile
{
char* datapath;
char* filepath;
};
CacheFile* cacheFileCreateAccessor(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4, int tag5, int tag6)
{
CacheFile* result;
result = new CacheFile;
result->datapath = (char*)malloc(sizeof(char) * 501);
result->filepath = (char*)malloc(sizeof(char) * 501);
snprintf(result->datapath, 500, "/usr/share/paysages3d/%s-%s-%d-%d-%d-%d-%d.%s", module, tag1, tag2, tag3, tag4, tag5, tag6, ext);
snprintf(result->filepath, 500, "./cache/%s-%s-%d-%d-%d-%d-%d.%s", module, tag1, tag2, tag3, tag4, tag5, tag6, ext);
return result;
}
void cacheFileDeleteAccessor(CacheFile* cache)
{
free(cache->datapath);
free(cache->filepath);
delete cache;
}
int cacheFileIsReadable(CacheFile* cache)
{
FILE* f = fopen(cache->filepath, "rb");
if (f)
{
fclose(f);
return 1;
}
else
{
FILE* f = fopen(cache->datapath, "rb");
if (f)
{
fclose(f);
return 1;
}
else
{
return 0;
}
}
}
int cacheFileIsWritable(CacheFile*)
{
FILE* f = fopen("./cache/.test", "wb");
if (f)
{
fclose(f);
return 1;
}
else
{
return 0;
}
}
const char* cacheFileGetPath(CacheFile* cache)
{
FILE* f = fopen(cache->datapath, "rb");
if (f)
{
fclose(f);
return cache->datapath;
}
else
{
return cache->filepath;
}
}

View file

@ -1,18 +0,0 @@
#ifndef _PAYSAGES_TOOLS_CACHE_H_
#define _PAYSAGES_TOOLS_CACHE_H_
/*
* Cache management.
*/
#include "../rendering_global.h"
typedef struct CacheFile CacheFile;
RENDERINGSHARED_EXPORT CacheFile* cacheFileCreateAccessor(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4, int tag5, int tag6);
RENDERINGSHARED_EXPORT void cacheFileDeleteAccessor(CacheFile* cache);
RENDERINGSHARED_EXPORT int cacheFileIsReadable(CacheFile* cache);
RENDERINGSHARED_EXPORT int cacheFileIsWritable(CacheFile* cache);
RENDERINGSHARED_EXPORT const char* cacheFileGetPath(CacheFile* cache);
#endif

View file

@ -1,628 +0,0 @@
#include "texture.h"
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include "System.h"
#include "PackStream.h"
#include "PictureFile.h"
struct Texture2D
{
int xsize;
int ysize;
Color* data;
};
struct Texture3D
{
int xsize;
int ysize;
int zsize;
Color* data;
};
struct Texture4D
{
int xsize;
int ysize;
int zsize;
int wsize;
Color* data;
};
static inline Color _lerp(Color c1, Color c2, double d)
{
Color result;
result.r = c1.r * (1.0 - d) + c2.r * d;
result.g = c1.g * (1.0 - d) + c2.g * d;
result.b = c1.b * (1.0 - d) + c2.b * d;
result.a = c1.a * (1.0 - d) + c2.a * d;
return result;
}
Texture2D* texture2DCreate(int xsize, int ysize)
{
Texture2D* result;
assert(xsize > 0 && ysize > 0);
result = new Texture2D;
result->xsize = xsize;
result->ysize = ysize;
result->data = new Color[xsize * ysize];
return result;
}
void texture2DDelete(Texture2D* tex)
{
delete[] tex->data;
delete tex;
}
void texture2DGetSize(Texture2D* tex, int* xsize, int* ysize)
{
*xsize = tex->xsize;
*ysize = tex->ysize;
}
void texture2DSetPixel(Texture2D* tex, int x, int y, Color col)
{
assert(x >= 0 && x < tex->xsize);
assert(y >= 0 && y < tex->ysize);
tex->data[y * tex->xsize + x] = col;
}
Color texture2DGetPixel(Texture2D* tex, int x, int y)
{
assert(x >= 0 && x < tex->xsize);
assert(y >= 0 && y < tex->ysize);
return tex->data[y * tex->xsize + x];
}
Color texture2DGetNearest(Texture2D* tex, double dx, double dy)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
int ix = (int)(dx * (double)(tex->xsize - 1));
int iy = (int)(dy * (double)(tex->ysize - 1));
assert(ix >= 0 && ix < tex->xsize);
assert(iy >= 0 && iy < tex->ysize);
return tex->data[iy * tex->xsize + ix];
}
Color texture2DGetLinear(Texture2D* tex, double dx, double dy)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
dx *= (double)(tex->xsize - 1);
dy *= (double)(tex->ysize - 1);
int ix = (int)floor(dx);
if (ix == tex->xsize - 1)
{
ix--;
}
int iy = (int)floor(dy);
if (iy == tex->ysize - 1)
{
iy--;
}
dx -= (double)ix;
dy -= (double)iy;
Color* data = tex->data + iy * tex->xsize + ix;
Color c1 = _lerp(*data, *(data + 1), dx);
Color c2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
return _lerp(c1, c2, dy);
}
Color texture2DGetCubic(Texture2D* tex, double dx, double dy)
{
/* TODO */
return texture2DGetLinear(tex, dx, dy);
}
void texture2DFill(Texture2D* tex, Color col)
{
int i, n;
n = tex->xsize * tex->ysize;
for (i = 0; i < n; i++)
{
tex->data[i] = col;
}
}
void texture2DAdd(Texture2D* source, Texture2D* destination)
{
int i, n;
assert(source->xsize == destination->xsize);
assert(source->ysize == destination->ysize);
n = source->xsize * source->ysize;
for (i = 0; i < n; i++)
{
destination->data[i].r += source->data[i].r;
destination->data[i].g += source->data[i].g;
destination->data[i].b += source->data[i].b;
/* destination->data[i].a += source->data[i].a; */
}
}
void texture2DSave(PackStream* stream, Texture2D* tex)
{
int i, n;
stream->write(&tex->xsize);
stream->write(&tex->ysize);
n = tex->xsize * tex->ysize;
for (i = 0; i < n; i++)
{
colorSave(stream, tex->data + i);
}
}
void texture2DLoad(PackStream* stream, Texture2D* tex)
{
int i, n;
stream->read(&tex->xsize);
stream->read(&tex->ysize);
n = tex->xsize * tex->ysize;
delete[] tex->data;
tex->data = new Color[n];
for (i = 0; i < n; i++)
{
colorLoad(stream, tex->data + i);
}
}
void texture2DSaveToFile(Texture2D* tex, const char* filepath)
{
systemSavePictureFile(filepath, (PictureCallbackSavePixel)texture2DGetPixel, tex, tex->xsize, tex->ysize);
}
Texture3D* texture3DCreate(int xsize, int ysize, int zsize)
{
Texture3D* result;
assert(xsize > 0 && ysize > 0 && zsize > 0);
result = new Texture3D;
result->xsize = xsize;
result->ysize = ysize;
result->zsize = zsize;
result->data = new Color[xsize * ysize * zsize];
return result;
}
void texture3DDelete(Texture3D* tex)
{
delete[] tex->data;
delete tex;
}
void texture3DGetSize(Texture3D* tex, int* xsize, int* ysize, int* zsize)
{
*xsize = tex->xsize;
*ysize = tex->ysize;
*zsize = tex->zsize;
}
void texture3DSetPixel(Texture3D* tex, int x, int y, int z, Color col)
{
assert(x >= 0 && x < tex->xsize);
assert(y >= 0 && y < tex->ysize);
assert(z >= 0 && z < tex->ysize);
tex->data[z * tex->xsize * tex->ysize + y * tex->xsize + x] = col;
}
Color texture3DGetPixel(Texture3D* tex, int x, int y, int z)
{
assert(x >= 0 && x < tex->xsize);
assert(y >= 0 && y < tex->ysize);
assert(z >= 0 && z < tex->zsize);
return tex->data[z * tex->xsize * tex->ysize + y * tex->xsize + x];
}
Color texture3DGetNearest(Texture3D* tex, double dx, double dy, double dz)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
int ix = (int)(dx * (double)(tex->xsize - 1));
int iy = (int)(dy * (double)(tex->ysize - 1));
int iz = (int)(dz * (double)(tex->zsize - 1));
assert(ix >= 0 && ix < tex->xsize);
assert(iy >= 0 && iy < tex->ysize);
assert(iz >= 0 && iz < tex->zsize);
return tex->data[iz * tex->xsize * tex->ysize + iy * tex->xsize + ix];
}
Color texture3DGetLinear(Texture3D* tex, double dx, double dy, double dz)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
dx *= (double)(tex->xsize - 1);
dy *= (double)(tex->ysize - 1);
dz *= (double)(tex->zsize - 1);
int ix = (int)floor(dx);
if (ix == tex->xsize - 1)
{
ix--;
}
int iy = (int)floor(dy);
if (iy == tex->ysize - 1)
{
iy--;
}
int iz = (int)floor(dz);
if (iz == tex->zsize - 1)
{
iz--;
}
dx -= (double)ix;
dy -= (double)iy;
dz -= (double)iz;
Color* data = tex->data + iz * tex->xsize * tex->ysize + iy * tex->xsize + ix;
Color cx1 = _lerp(*data, *(data + 1), dx);
Color cx2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
Color cy1 = _lerp(cx1, cx2, dy);
data += tex->xsize * tex->ysize;
cx1 = _lerp(*(data), *(data + 1), dx);
cx2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
Color cy2 = _lerp(cx1, cx2, dy);
return _lerp(cy1, cy2, dz);
}
Color texture3DGetCubic(Texture3D* tex, double dx, double dy, double dz)
{
/* TODO */
return texture3DGetLinear(tex, dx, dy, dz);
}
void texture3DFill(Texture3D* tex, Color col)
{
int i, n;
n = tex->xsize * tex->ysize * tex->zsize;
for (i = 0; i < n; i++)
{
tex->data[i] = col;
}
}
void texture3DAdd(Texture3D* source, Texture3D* destination)
{
int i, n;
assert(source->xsize == destination->xsize);
assert(source->ysize == destination->ysize);
assert(source->zsize == destination->zsize);
n = source->xsize * source->ysize * source->zsize;
for (i = 0; i < n; i++)
{
destination->data[i].r += source->data[i].r;
destination->data[i].g += source->data[i].g;
destination->data[i].b += source->data[i].b;
/* destination->data[i].a += source->data[i].a; */
}
}
void texture3DSave(PackStream* stream, Texture3D* tex)
{
int i, n;
stream->write(&tex->xsize);
stream->write(&tex->ysize);
stream->write(&tex->zsize);
n = tex->xsize * tex->ysize * tex->zsize;
for (i = 0; i < n; i++)
{
colorSave(stream, tex->data + i);
}
}
void texture3DLoad(PackStream* stream, Texture3D* tex)
{
int i, n;
stream->read(&tex->xsize);
stream->read(&tex->ysize);
stream->read(&tex->zsize);
n = tex->xsize * tex->ysize * tex->zsize;
delete[] tex->data;
tex->data = new Color[n];
for (i = 0; i < n; i++)
{
colorLoad(stream, tex->data + i);
}
}
static Color _callbackTex3dSave(Texture3D* tex, int x, int y)
{
int z = y / tex->ysize;
y = y % tex->ysize;
assert(x >= 0 && x < tex->xsize);
assert(y >= 0 && y < tex->ysize);
assert(z >= 0 && z < tex->zsize);
return tex->data[z * tex->xsize * tex->ysize + y * tex->xsize + x];
}
void texture3DSaveToFile(Texture3D* tex, const char* filepath)
{
systemSavePictureFile(filepath, (PictureCallbackSavePixel)_callbackTex3dSave, tex, tex->xsize, tex->ysize * tex->zsize);
}
Texture4D* texture4DCreate(int xsize, int ysize, int zsize, int wsize)
{
Texture4D* result;
assert(xsize > 0 && ysize > 0 && zsize > 0 && wsize > 0);
result = new Texture4D;
result->xsize = xsize;
result->ysize = ysize;
result->zsize = zsize;
result->wsize = wsize;
result->data = new Color[xsize * ysize * zsize * wsize];
return result;
}
void texture4DDelete(Texture4D* tex)
{
delete[] tex->data;
delete tex;
}
void texture4DGetSize(Texture4D* tex, int* xsize, int* ysize, int* zsize, int* wsize)
{
*xsize = tex->xsize;
*ysize = tex->ysize;
*zsize = tex->zsize;
*wsize = tex->wsize;
}
void texture4DSetPixel(Texture4D* tex, int x, int y, int z, int w, Color col)
{
assert(x >= 0 && x < tex->xsize);
assert(y >= 0 && y < tex->ysize);
assert(z >= 0 && z < tex->zsize);
assert(w >= 0 && w < tex->wsize);
tex->data[w * tex->xsize * tex->ysize * tex->zsize + z * tex->xsize * tex->ysize + y * tex->xsize + x] = col;
}
Color texture4DGetPixel(Texture4D* tex, int x, int y, int z, int w)
{
assert(x >= 0 && x < tex->xsize);
assert(y >= 0 && y < tex->ysize);
assert(z >= 0 && z < tex->zsize);
assert(w >= 0 && w < tex->wsize);
return tex->data[w * tex->xsize * tex->ysize * tex->zsize + z * tex->xsize * tex->ysize + y * tex->xsize + x];
}
Color texture4DGetNearest(Texture4D* tex, double dx, double dy, double dz, double dw)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
if (dw < 0.0) dw = 0.0;
if (dw > 1.0) dw = 1.0;
int ix = (int)(dx * (double)(tex->xsize - 1));
int iy = (int)(dy * (double)(tex->ysize - 1));
int iz = (int)(dz * (double)(tex->zsize - 1));
int iw = (int)(dw * (double)(tex->wsize - 1));
assert(ix >= 0 && ix < tex->xsize);
assert(iy >= 0 && iy < tex->ysize);
assert(iz >= 0 && iz < tex->zsize);
assert(iw >= 0 && iw < tex->wsize);
return tex->data[iw * tex->xsize * tex->ysize * tex->zsize + iz * tex->xsize * tex->ysize + iy * tex->xsize + ix];
}
Color texture4DGetLinear(Texture4D* tex, double dx, double dy, double dz, double dw)
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
if (dw < 0.0) dw = 0.0;
if (dw > 1.0) dw = 1.0;
dx *= (double)(tex->xsize - 1);
dy *= (double)(tex->ysize - 1);
dz *= (double)(tex->zsize - 1);
dw *= (double)(tex->wsize - 1);
int ix = (int)floor(dx);
if (ix == tex->xsize - 1)
{
ix--;
}
int iy = (int)floor(dy);
if (iy == tex->ysize - 1)
{
iy--;
}
int iz = (int)floor(dz);
if (iz == tex->zsize - 1)
{
iz--;
}
int iw = (int)floor(dw);
if (iw == tex->wsize - 1)
{
iw--;
}
dx -= (double)ix;
dy -= (double)iy;
dz -= (double)iz;
dw -= (double)iw;
Color* data = tex->data + iw * tex->xsize * tex->ysize * tex->zsize + iz * tex->xsize * tex->ysize + iy * tex->xsize + ix;
Color cz1, cz2;
Color cx1 = _lerp(*data, *(data + 1), dx);
Color cx2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
Color cy1 = _lerp(cx1, cx2, dy);
data += tex->xsize * tex->ysize;
cx1 = _lerp(*(data), *(data + 1), dx);
cx2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
Color cy2 = _lerp(cx1, cx2, dy);
data += tex->xsize * tex->ysize * tex->zsize;
cz1 = _lerp(cy1, cy2, dz);
cx1 = _lerp(*data, *(data + 1), dx);
cx2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
cy1 = _lerp(cx1, cx2, dy);
cx1 = _lerp(*(data), *(data + 1), dx);
cx2 = _lerp(*(data + tex->xsize), *(data + tex->xsize + 1), dx);
cy2 = _lerp(cx1, cx2, dy);
cz2 = _lerp(cy1, cy2, dz);
return _lerp(cz1, cz2, dw);
}
Color texture4DGetCubic(Texture4D* tex, double dx, double dy, double dz, double dw)
{
/* TODO */
return texture4DGetLinear(tex, dx, dy, dz, dw);
}
void texture4DFill(Texture4D* tex, Color col)
{
int i, n;
n = tex->xsize * tex->ysize * tex->zsize * tex->wsize;
for (i = 0; i < n; i++)
{
tex->data[i] = col;
}
}
void texture4DAdd(Texture4D* source, Texture4D* destination)
{
int i, n;
assert(source->xsize == destination->xsize);
assert(source->ysize == destination->ysize);
assert(source->zsize == destination->zsize);
assert(source->wsize == destination->wsize);
n = source->xsize * source->ysize * source->zsize * source->wsize;
for (i = 0; i < n; i++)
{
destination->data[i].r += source->data[i].r;
destination->data[i].g += source->data[i].g;
destination->data[i].b += source->data[i].b;
/* destination->data[i].a += source->data[i].a; */
}
}
void texture4DSave(PackStream* stream, Texture4D* tex)
{
int i, n;
stream->write(&tex->xsize);
stream->write(&tex->ysize);
stream->write(&tex->zsize);
stream->write(&tex->wsize);
n = tex->xsize * tex->ysize * tex->zsize * tex->wsize;
for (i = 0; i < n; i++)
{
colorSave(stream, tex->data + i);
}
}
void texture4DLoad(PackStream* stream, Texture4D* tex)
{
int i, n;
stream->read(&tex->xsize);
stream->read(&tex->ysize);
stream->read(&tex->zsize);
stream->read(&tex->wsize);
n = tex->xsize * tex->ysize * tex->zsize * tex->wsize;
delete[] tex->data;
tex->data = new Color[n];
for (i = 0; i < n; i++)
{
colorLoad(stream, tex->data + i);
}
}
static Color _callbackTex4dSave(Texture4D* tex, int x, int y)
{
int w = x / tex->xsize;
x = x % tex->xsize;
int z = y / tex->ysize;
y = y % tex->ysize;
assert(x >= 0 && x < tex->xsize);
assert(y >= 0 && y < tex->ysize);
assert(z >= 0 && z < tex->zsize);
assert(w >= 0 && w < tex->wsize);
return tex->data[w * tex->xsize * tex->ysize * tex->zsize + z * tex->xsize * tex->ysize + y * tex->xsize + x];
}
void texture4DSaveToFile(Texture4D* tex, const char* filepath)
{
systemSavePictureFile(filepath, (PictureCallbackSavePixel)_callbackTex4dSave, tex, tex->xsize * tex->wsize, tex->ysize * tex->zsize);
}

View file

@ -1,58 +0,0 @@
#ifndef _PAYSAGES_TOOLS_TEXTURE_H_
#define _PAYSAGES_TOOLS_TEXTURE_H_
/*
* Pixel based textures.
*/
#include "../rendering_global.h"
#include "Color.h"
typedef struct Texture2D Texture2D;
typedef struct Texture3D Texture3D;
typedef struct Texture4D Texture4D;
RENDERINGSHARED_EXPORT Texture2D* texture2DCreate(int xsize, int ysize);
RENDERINGSHARED_EXPORT void texture2DDelete(Texture2D* tex);
RENDERINGSHARED_EXPORT void texture2DGetSize(Texture2D* tex, int* xsize, int* ysize);
RENDERINGSHARED_EXPORT void texture2DSetPixel(Texture2D* tex, int x, int y, Color col);
RENDERINGSHARED_EXPORT Color texture2DGetPixel(Texture2D* tex, int x, int y);
RENDERINGSHARED_EXPORT Color texture2DGetNearest(Texture2D* tex, double dx, double dy);
RENDERINGSHARED_EXPORT Color texture2DGetLinear(Texture2D* tex, double dx, double dy);
RENDERINGSHARED_EXPORT Color texture2DGetCubic(Texture2D* tex, double dx, double dy);
RENDERINGSHARED_EXPORT void texture2DFill(Texture2D* tex, Color col);
RENDERINGSHARED_EXPORT void texture2DAdd(Texture2D* source, Texture2D* destination);
RENDERINGSHARED_EXPORT void texture2DSave(PackStream* stream, Texture2D* tex);
RENDERINGSHARED_EXPORT void texture2DLoad(PackStream* stream, Texture2D* tex);
RENDERINGSHARED_EXPORT void texture2DSaveToFile(Texture2D* tex, const char* filepath);
RENDERINGSHARED_EXPORT Texture3D* texture3DCreate(int xsize, int ysize, int zsize);
RENDERINGSHARED_EXPORT void texture3DDelete(Texture3D* tex);
RENDERINGSHARED_EXPORT void texture3DGetSize(Texture3D* tex, int* xsize, int* ysize, int* zsize);
RENDERINGSHARED_EXPORT void texture3DSetPixel(Texture3D* tex, int x, int y, int z, Color col);
RENDERINGSHARED_EXPORT Color texture3DGetPixel(Texture3D* tex, int x, int y, int z);
RENDERINGSHARED_EXPORT Color texture3DGetNearest(Texture3D* tex, double dx, double dy, double dz);
RENDERINGSHARED_EXPORT Color texture3DGetLinear(Texture3D* tex, double dx, double dy, double dz);
RENDERINGSHARED_EXPORT Color texture3DGetCubic(Texture3D* tex, double dx, double dy, double dz);
RENDERINGSHARED_EXPORT void texture3DFill(Texture3D* tex, Color col);
RENDERINGSHARED_EXPORT void texture3DAdd(Texture3D* source, Texture3D* destination);
RENDERINGSHARED_EXPORT void texture3DSave(PackStream* stream, Texture3D* tex);
RENDERINGSHARED_EXPORT void texture3DLoad(PackStream* stream, Texture3D* tex);
RENDERINGSHARED_EXPORT void texture3DSaveToFile(Texture3D* tex, const char* filepath);
RENDERINGSHARED_EXPORT Texture4D* texture4DCreate(int xsize, int ysize, int zsize, int wsize);
RENDERINGSHARED_EXPORT void texture4DDelete(Texture4D* tex);
RENDERINGSHARED_EXPORT void texture4DGetSize(Texture4D* tex, int* xsize, int* ysize, int* zsize, int* wsize);
RENDERINGSHARED_EXPORT void texture4DSetPixel(Texture4D* tex, int x, int y, int z, int w, Color col);
RENDERINGSHARED_EXPORT Color texture4DGetPixel(Texture4D* tex, int x, int y, int z, int w);
RENDERINGSHARED_EXPORT Color texture4DGetNearest(Texture4D* tex, double dx, double dy, double dz, double dw);
RENDERINGSHARED_EXPORT Color texture4DGetLinear(Texture4D* tex, double dx, double dy, double dz, double dw);
RENDERINGSHARED_EXPORT Color texture4DGetCubic(Texture4D* tex, double dx, double dy, double dz, double dw);
RENDERINGSHARED_EXPORT void texture4DFill(Texture4D* tex, Color col);
RENDERINGSHARED_EXPORT void texture4DAdd(Texture4D* source, Texture4D* destination);
RENDERINGSHARED_EXPORT void texture4DSave(PackStream* stream, Texture4D* tex);
RENDERINGSHARED_EXPORT void texture4DLoad(PackStream* stream, Texture4D* tex);
RENDERINGSHARED_EXPORT void texture4DSaveToFile(Texture4D* tex, const char* filepath);
#endif

67
src/system/CacheFile.cpp Normal file
View file

@ -0,0 +1,67 @@
#include "CacheFile.h"
CacheFile::CacheFile(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4, int tag5, int tag6)
{
datapath = (char*)malloc(sizeof(char) * 501);
filepath = (char*)malloc(sizeof(char) * 501);
snprintf(datapath, 500, "/usr/share/paysages3d/%s-%s-%d-%d-%d-%d-%d.%s", module, tag1, tag2, tag3, tag4, tag5, tag6, ext);
snprintf(filepath, 500, "./cache/%s-%s-%d-%d-%d-%d-%d.%s", module, tag1, tag2, tag3, tag4, tag5, tag6, ext);
}
CacheFile::~CacheFile()
{
free(datapath);
free(filepath);
}
bool CacheFile::isReadable()
{
FILE* f = fopen(filepath, "rb");
if (f)
{
fclose(f);
return true;
}
else
{
FILE* f = fopen(datapath, "rb");
if (f)
{
fclose(f);
return true;
}
else
{
return false;
}
}
}
bool CacheFile::isWritable()
{
FILE* f = fopen("./cache/.test", "wb");
if (f)
{
fclose(f);
return true;
}
else
{
return false;
}
}
const char* CacheFile::getPath()
{
FILE* f = fopen(datapath, "rb");
if (f)
{
fclose(f);
return datapath;
}
else
{
return filepath;
}
}

27
src/system/CacheFile.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef CACHEFILE_H
#define CACHEFILE_H
#include "system_global.h"
namespace paysages {
namespace system {
class SYSTEMSHARED_EXPORT CacheFile
{
public:
CacheFile(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4, int tag5, int tag6);
~CacheFile();
bool isReadable();
bool isWritable();
const char* getPath();
private:
char* datapath;
char* filepath;
};
}
}
#endif // CACHEFILE_H

View file

@ -1,25 +0,0 @@
#include "PictureFile.h"
#include <QImage>
#include <QColor>
PictureFile::PictureFile()
{
}
// Transitional C-API
int systemSavePictureFile(const char* filepath, PictureCallbackSavePixel callback_pixel, void* data, int width, int height)
{
QImage result(width, height, QImage::Format_ARGB32);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
result.setPixel(x, height - 1 - y, callback_pixel(data, x, y));
}
}
return result.save(filepath);
}

View file

@ -1,26 +0,0 @@
#ifndef PICTUREFILE_H
#define PICTUREFILE_H
#include "system_global.h"
namespace paysages
{
namespace system
{
class SYSTEMSHARED_EXPORT PictureFile
{
public:
PictureFile();
};
}
}
// Transitional C-API
// Les pixels doivent être fournis en BGRA
typedef unsigned int (*PictureCallbackSavePixel)(void* data, int x, int y);
SYSTEMSHARED_EXPORT int systemSavePictureFile(const char* filepath, PictureCallbackSavePixel callback_pixel, void* data, int width, int height);
#endif // PICTUREFILE_H

View file

@ -0,0 +1,18 @@
#include "PictureWriter.h"
#include <QImage>
bool PictureWriter::save(const std::string &filepath, int width, int height)
{
QImage result(width, height, QImage::Format_ARGB32);
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
result.setPixel(x, height - 1 - y, getPixel(x, y));
}
}
return result.save(QString::fromStdString(filepath));
}

View file

@ -0,0 +1,27 @@
#ifndef PICTUREWRITER_H
#define PICTUREWRITER_H
#include "system_global.h"
namespace paysages {
namespace system {
class SYSTEMSHARED_EXPORT PictureWriter
{
public:
/**
* @brief Start saving the picture in a file.
*/
bool save(const std::string &filepath, int width, int height);
protected:
/**
* @brief Get the (x, y) pixel, in BGRA format
*/
virtual unsigned int getPixel(int x, int y) = 0;
};
}
}
#endif // PICTUREWRITER_H

View file

@ -14,7 +14,6 @@ DEFINES += SYSTEM_LIBRARY
include(../common.pri)
SOURCES += \
PictureFile.cpp \
Thread.cpp \
Mutex.cpp \
System.cpp \
@ -22,11 +21,12 @@ SOURCES += \
RandomGenerator.cpp \
Memory.cpp \
ParallelWork.cpp \
ParallelQueue.cpp
ParallelQueue.cpp \
CacheFile.cpp \
PictureWriter.cpp
HEADERS += \
system_global.h \
PictureFile.h \
Thread.h \
Mutex.h \
System.h \
@ -34,7 +34,9 @@ HEADERS += \
RandomGenerator.h \
Memory.h \
ParallelWork.h \
ParallelQueue.h
ParallelQueue.h \
CacheFile.h \
PictureWriter.h
unix:!symbian {
maemo5 {