paysages : Cache system for bruneton precomputations.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@480 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
d5dddf40e1
commit
9da260a5e8
7 changed files with 276 additions and 42 deletions
|
@ -10,6 +10,7 @@
|
|||
#include <QTranslator>
|
||||
#include <QLocale>
|
||||
#include <QMessageBox>
|
||||
#include <QSplashScreen>
|
||||
|
||||
#include "basepreview.h"
|
||||
#include "formclouds.h"
|
||||
|
@ -31,12 +32,14 @@
|
|||
int main(int argc, char** argv)
|
||||
{
|
||||
MainWindow* window;
|
||||
QSplashScreen* splash;
|
||||
int result;
|
||||
|
||||
paysagesInit();
|
||||
|
||||
QApplication app(argc, argv);
|
||||
|
||||
splash = new QSplashScreen(QPixmap("images/logo_256.png"));
|
||||
splash->show();
|
||||
|
||||
QTranslator qtTranslator;
|
||||
QTranslator myTranslator;
|
||||
|
||||
|
@ -53,10 +56,17 @@ int main(int argc, char** argv)
|
|||
app.installTranslator(&qtTranslator);
|
||||
}
|
||||
|
||||
splash->showMessage(app.tr("Preloading environment...\n(may take some time on the first launch)"), Qt::AlignCenter, Qt::white);
|
||||
app.processEvents();
|
||||
|
||||
paysagesInit();
|
||||
BasePreview::initDrawers();
|
||||
|
||||
window = new MainWindow();
|
||||
window->show();
|
||||
splash->finish(window);
|
||||
|
||||
delete splash;
|
||||
|
||||
result = app.exec();
|
||||
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
#if 1
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../system.h"
|
||||
#include "../tools/cache.h"
|
||||
#include "../tools/texture.h"
|
||||
|
||||
/*********************** Constants ***********************/
|
||||
|
@ -400,13 +402,10 @@ static void _getMuMuSNu(double x, double y, double r, Color dhdH, double* mu, do
|
|||
|
||||
/*********************** Texture precomputing ***********************/
|
||||
|
||||
static Texture2D* _precomputeTransmittanceTexture()
|
||||
static void _precomputeTransmittanceTexture()
|
||||
{
|
||||
Texture2D* result;
|
||||
int x, y;
|
||||
|
||||
result = texture2DCreate(TRANSMITTANCE_W, TRANSMITTANCE_H);
|
||||
|
||||
for (x = 0; x < TRANSMITTANCE_W; x++)
|
||||
{
|
||||
for (y = 0; y < TRANSMITTANCE_H; y++)
|
||||
|
@ -420,20 +419,15 @@ static Texture2D* _precomputeTransmittanceTexture()
|
|||
trans.g = exp(-(betaR.g * depth1 + betaMEx.y * depth2));
|
||||
trans.b = exp(-(betaR.b * depth1 + betaMEx.z * depth2));
|
||||
trans.a = 1.0;
|
||||
texture2DSetPixel(result, x, y, trans); /* Eq (5) */
|
||||
texture2DSetPixel(_transmittanceTexture, x, y, trans); /* Eq (5) */
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static Texture2D* _precomputeIrrDeltaETexture()
|
||||
static void _precomputeIrrDeltaETexture()
|
||||
{
|
||||
Texture2D* result;
|
||||
int x, y;
|
||||
|
||||
result = texture2DCreate(SKY_W, SKY_H);
|
||||
|
||||
/* Irradiance program */
|
||||
for (x = 0; x < SKY_W; x++)
|
||||
{
|
||||
|
@ -452,11 +446,9 @@ static Texture2D* _precomputeIrrDeltaETexture()
|
|||
irr.b = trans.b * max(muS, 0.0);
|
||||
irr.a = 1.0;
|
||||
|
||||
texture2DSetPixel(result, x, y, irr);
|
||||
texture2DSetPixel(_irrDeltaETexture, x, y, irr);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _setLayer(int layer)
|
||||
|
@ -735,31 +727,116 @@ static Color _sunColor(Vector3 x, double t, Vector3 v, Vector3 s, double r, doub
|
|||
}
|
||||
}
|
||||
|
||||
/*********************** Cache methods ***********************/
|
||||
|
||||
static int _tryLoadCache2D(Texture2D* tex, const char* tag)
|
||||
{
|
||||
CacheFile* cache;
|
||||
int xsize, ysize;
|
||||
|
||||
texture2DGetSize(tex, &xsize, &ysize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, 0);
|
||||
if (cacheFileIsReadable(cache))
|
||||
{
|
||||
texture2DLoadFromFile(tex, cacheFileGetPath(cache));
|
||||
cacheFileDeleteAccessor(cache);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheFileDeleteAccessor(cache);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void _saveCache2D(Texture2D* tex, const char* tag)
|
||||
{
|
||||
CacheFile* cache;
|
||||
int xsize, ysize;
|
||||
|
||||
texture2DGetSize(tex, &xsize, &ysize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, 0);
|
||||
if (cacheFileIsWritable(cache))
|
||||
{
|
||||
texture2DSaveToFile(tex, cacheFileGetPath(cache));
|
||||
}
|
||||
cacheFileDeleteAccessor(cache);
|
||||
}
|
||||
|
||||
static int _tryLoadCache3D(Texture3D* tex, const char* tag)
|
||||
{
|
||||
CacheFile* cache;
|
||||
int xsize, ysize, zsize;
|
||||
|
||||
texture3DGetSize(tex, &xsize, &ysize, &zsize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, zsize);
|
||||
if (cacheFileIsReadable(cache))
|
||||
{
|
||||
texture3DLoadFromFile(tex, cacheFileGetPath(cache));
|
||||
cacheFileDeleteAccessor(cache);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cacheFileDeleteAccessor(cache);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void _saveCache3D(Texture3D* tex, const char* tag)
|
||||
{
|
||||
CacheFile* cache;
|
||||
int xsize, ysize, zsize;
|
||||
|
||||
texture3DGetSize(tex, &xsize, &ysize, &zsize);
|
||||
cache = cacheFileCreateAccessor("atmo-br", "png", tag, xsize, ysize, zsize);
|
||||
if (cacheFileIsWritable(cache))
|
||||
{
|
||||
texture3DSaveToFile(tex, cacheFileGetPath(cache));
|
||||
}
|
||||
cacheFileDeleteAccessor(cache);
|
||||
}
|
||||
|
||||
/*********************** Public methods ***********************/
|
||||
|
||||
void brunetonInit()
|
||||
{
|
||||
int layer, x, y, z;
|
||||
int layer, x, y, z, order;
|
||||
|
||||
if (_transmittanceTexture == NULL) /* TEMP */
|
||||
{
|
||||
/* TODO Deletes */
|
||||
/* TODO Deletes */
|
||||
|
||||
/* computes transmittance texture T (line 1 in algorithm 4.1) */
|
||||
_transmittanceTexture = _precomputeTransmittanceTexture();
|
||||
/* computes transmittance texture T (line 1 in algorithm 4.1) */
|
||||
_transmittanceTexture = texture2DCreate(TRANSMITTANCE_W, TRANSMITTANCE_H);
|
||||
if (!_tryLoadCache2D(_transmittanceTexture, "transmittance"))
|
||||
{
|
||||
_precomputeTransmittanceTexture();
|
||||
_saveCache2D(_transmittanceTexture, "transmittance");
|
||||
}
|
||||
|
||||
/* computes irradiance texture deltaE (line 2 in algorithm 4.1) */
|
||||
_irrDeltaETexture = _precomputeIrrDeltaETexture();
|
||||
_irrDeltaETexture = texture2DCreate(SKY_W, SKY_H);
|
||||
if (!_tryLoadCache2D(_irrDeltaETexture, "irradianceDeltaE"))
|
||||
{
|
||||
_precomputeIrrDeltaETexture();
|
||||
_saveCache2D(_irrDeltaETexture, "irradianceDeltaE");
|
||||
}
|
||||
|
||||
/* computes single scattering texture deltaS (line 3 in algorithm 4.1)
|
||||
* Rayleigh and Mie separated in deltaSR + deltaSM */
|
||||
_deltaSRTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
||||
_deltaSMTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
||||
for (layer = 0; layer < RES_R; ++layer)
|
||||
if (!_tryLoadCache3D(_deltaSRTexture, "deltaSR") || !_tryLoadCache3D(_deltaSMTexture, "deltaSM"))
|
||||
{
|
||||
printf("%d\n", layer);
|
||||
_setLayer(layer);
|
||||
_inscatter1Prog(_deltaSRTexture, _deltaSMTexture);
|
||||
for (layer = 0; layer < RES_R; ++layer)
|
||||
{
|
||||
printf("%d\n", layer);
|
||||
_setLayer(layer);
|
||||
_inscatter1Prog(_deltaSRTexture, _deltaSMTexture);
|
||||
}
|
||||
_saveCache3D(_deltaSRTexture, "deltaSR");
|
||||
_saveCache3D(_deltaSMTexture, "deltaSM");
|
||||
}
|
||||
|
||||
/* copies deltaE into irradiance texture E (line 4 in algorithm 4.1) */
|
||||
|
@ -769,22 +846,26 @@ void brunetonInit()
|
|||
|
||||
/* copies deltaS into inscatter texture S (line 5 in algorithm 4.1) */
|
||||
_inscatterTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
||||
for (x = 0; x < RES_MU_S * RES_NU; x++)
|
||||
if (!_tryLoadCache3D(_inscatterTexture, "inscatter"))
|
||||
{
|
||||
for (y = 0; y < RES_MU; y++)
|
||||
for (x = 0; x < RES_MU_S * RES_NU; x++)
|
||||
{
|
||||
for (z = 0; z < RES_R; z++)
|
||||
for (y = 0; y < RES_MU; y++)
|
||||
{
|
||||
Color result = texture3DGetPixel(_deltaSRTexture, x, y, z);
|
||||
Color mie = texture3DGetPixel(_deltaSMTexture, x, y, z);
|
||||
result.a = mie.r;
|
||||
texture3DSetPixel(_inscatterTexture, x, y, z, result);
|
||||
for (z = 0; z < RES_R; z++)
|
||||
{
|
||||
Color result = texture3DGetPixel(_deltaSRTexture, x, y, z);
|
||||
Color mie = texture3DGetPixel(_deltaSMTexture, x, y, z);
|
||||
result.a = mie.r;
|
||||
texture3DSetPixel(_inscatterTexture, x, y, z, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
_saveCache3D(_inscatterTexture, "inscatter");
|
||||
}
|
||||
|
||||
/* loop for each scattering order (line 6 in algorithm 4.1) */
|
||||
for (int order = 2; order <= 4; ++order) {
|
||||
for (order = 2; order <= 4; ++order) {
|
||||
|
||||
/* computes deltaJ (line 7 in algorithm 4.1) */
|
||||
/*glFramebufferTextureEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, deltaJTexture, 0);
|
||||
|
@ -848,11 +929,6 @@ void brunetonInit()
|
|||
}
|
||||
|
||||
/* DEBUG */
|
||||
texture2DSaveToFile(_transmittanceTexture, "transmittance.png");
|
||||
texture2DSaveToFile(_irrDeltaETexture, "irrdeltae.png");
|
||||
texture3DSaveToFile(_deltaSRTexture, "deltasr.png");
|
||||
texture3DSaveToFile(_deltaSMTexture, "deltasm.png");
|
||||
texture3DSaveToFile(_inscatterTexture, "inscatter.png");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@ void systemInit()
|
|||
_core_count = _getCoreCount();
|
||||
ilInit();
|
||||
iluInit();
|
||||
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
|
||||
ilEnable(IL_ORIGIN_SET);
|
||||
}
|
||||
|
||||
int systemGetCoreCount()
|
||||
|
@ -117,7 +119,10 @@ int systemLoadPictureFile(const char* filepath, PictureCallbackLoadStarted callb
|
|||
{
|
||||
width = ilGetInteger(IL_IMAGE_WIDTH);
|
||||
height = ilGetInteger(IL_IMAGE_HEIGHT);
|
||||
callback_start(data, width, height);
|
||||
if (callback_start)
|
||||
{
|
||||
callback_start(data, width, height);
|
||||
}
|
||||
|
||||
pixels = malloc(sizeof(ILuint) * width * height);
|
||||
ilCopyPixels(0, 0, 0, width, height, 1, IL_RGBA, IL_UNSIGNED_BYTE, pixels);
|
||||
|
|
65
lib_paysages/tools/cache.c
Normal file
65
lib_paysages/tools/cache.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "cache.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../tools.h"
|
||||
|
||||
struct CacheFile
|
||||
{
|
||||
char* filepath;
|
||||
};
|
||||
|
||||
CacheFile* cacheFileCreateAccessor(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4)
|
||||
{
|
||||
CacheFile* result;
|
||||
|
||||
result = (CacheFile*)malloc(sizeof(CacheFile));
|
||||
result->filepath = malloc(sizeof(char) * 501);
|
||||
|
||||
snprintf(result->filepath, 500, "./cache/%s-%s-%d-%d-%d.%s", module, tag1, tag2, tag3, tag4, ext);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void cacheFileDeleteAccessor(CacheFile* cache)
|
||||
{
|
||||
free(cache->filepath);
|
||||
free(cache);
|
||||
}
|
||||
|
||||
int cacheFileIsReadable(CacheFile* cache)
|
||||
{
|
||||
FILE* f = fopen(cache->filepath, "rb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int cacheFileIsWritable(CacheFile* cache)
|
||||
{
|
||||
UNUSED(cache);
|
||||
|
||||
FILE* f = fopen("./cache/.test", "wb");
|
||||
if (f)
|
||||
{
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
const char* cacheFileGetPath(CacheFile* cache)
|
||||
{
|
||||
return cache->filepath;
|
||||
}
|
24
lib_paysages/tools/cache.h
Normal file
24
lib_paysages/tools/cache.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
#ifndef _PAYSAGES_TOOLS_CACHE_H_
|
||||
#define _PAYSAGES_TOOLS_CACHE_H_
|
||||
|
||||
/*
|
||||
* Cache management.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct CacheFile CacheFile;
|
||||
|
||||
CacheFile* cacheFileCreateAccessor(const char* module, const char* ext, const char* tag1, int tag2, int tag3, int tag4);
|
||||
void cacheFileDeleteAccessor(CacheFile* cache);
|
||||
int cacheFileIsReadable(CacheFile* cache);
|
||||
int cacheFileIsWritable(CacheFile* cache);
|
||||
const char* cacheFileGetPath(CacheFile* cache);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -26,6 +26,8 @@ Texture2D* texture2DCreate(int xsize, int ysize)
|
|||
{
|
||||
Texture2D* result;
|
||||
|
||||
assert(xsize > 0 && ysize > 0);
|
||||
|
||||
result = (Texture2D*)malloc(sizeof(Texture2D));
|
||||
result->xsize = xsize;
|
||||
result->ysize = ysize;
|
||||
|
@ -40,6 +42,12 @@ void texture2DDelete(Texture2D* tex)
|
|||
free(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);
|
||||
|
@ -89,6 +97,19 @@ void texture2DSaveToFile(Texture2D* tex, const char* filepath)
|
|||
systemSavePictureFile(filepath, (PictureCallbackSavePixel)texture2DGetPixel, tex, tex->xsize, tex->ysize);
|
||||
}
|
||||
|
||||
static void _callbackTex2dLoad(Texture2D* tex, int x, int y, Color col)
|
||||
{
|
||||
if (x >= 0 && x < tex->xsize && y >= 0 && y < tex->ysize)
|
||||
{
|
||||
tex->data[y * tex->xsize + x] = col;
|
||||
}
|
||||
}
|
||||
|
||||
void texture2DLoadFromFile(Texture2D* tex, const char* filepath)
|
||||
{
|
||||
systemLoadPictureFile(filepath, NULL, (PictureCallbackLoadPixel)_callbackTex2dLoad, tex);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -96,6 +117,8 @@ Texture3D* texture3DCreate(int xsize, int ysize, int zsize)
|
|||
{
|
||||
Texture3D* result;
|
||||
|
||||
assert(xsize > 0 && ysize > 0 && zsize > 0);
|
||||
|
||||
result = (Texture3D*)malloc(sizeof(Texture3D));
|
||||
result->xsize = xsize;
|
||||
result->ysize = ysize;
|
||||
|
@ -111,6 +134,13 @@ void texture3DDelete(Texture3D* tex)
|
|||
free(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);
|
||||
|
@ -167,9 +197,9 @@ static Color _callbackTex3dSave(Texture3D* tex, int x, int y)
|
|||
y = y % tex->ysize;
|
||||
|
||||
assert(x >= 0 && x < tex->xsize);
|
||||
assert(y >= 0 && y < tex->xsize);
|
||||
assert(z >= 0 && z < 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];
|
||||
}
|
||||
|
||||
|
@ -177,3 +207,19 @@ void texture3DSaveToFile(Texture3D* tex, const char* filepath)
|
|||
{
|
||||
systemSavePictureFile(filepath, (PictureCallbackSavePixel)_callbackTex3dSave, tex, tex->xsize, tex->ysize * tex->zsize);
|
||||
}
|
||||
|
||||
static void _callbackTex3dLoad(Texture3D* tex, int x, int y, Color col)
|
||||
{
|
||||
int z = y / tex->ysize;
|
||||
y = y % tex->ysize;
|
||||
|
||||
if (x >= 0 && x < tex->xsize && y >= 0 && y < tex->ysize && z >= 0 && z < tex->zsize)
|
||||
{
|
||||
tex->data[z * tex->xsize * tex->ysize + y * tex->xsize + x] = col;
|
||||
}
|
||||
}
|
||||
|
||||
void texture3DLoadFromFile(Texture3D* tex, const char* filepath)
|
||||
{
|
||||
systemLoadPictureFile(filepath, NULL, (PictureCallbackLoadPixel)_callbackTex3dLoad, tex);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _PAYSAGES_TOOLS_TEXTURE_H_
|
||||
#define _PAYSAGES_TOOLS_TEXTURE_H_
|
||||
|
||||
/*
|
||||
* Pixel based textures.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -12,21 +16,25 @@ typedef struct Texture3D Texture3D;
|
|||
|
||||
Texture2D* texture2DCreate(int xsize, int ysize);
|
||||
void texture2DDelete(Texture2D* tex);
|
||||
void texture2DGetSize(Texture2D* tex, int* xsize, int* ysize);
|
||||
void texture2DSetPixel(Texture2D* tex, int x, int y, Color col);
|
||||
Color texture2DGetPixel(Texture2D* tex, int x, int y);
|
||||
Color texture2DGetNearest(Texture2D* tex, double dx, double dy);
|
||||
Color texture2DGetLinear(Texture2D* tex, double dx, double dy);
|
||||
Color texture2DGetCubic(Texture2D* tex, double dx, double dy);
|
||||
void texture2DSaveToFile(Texture2D* tex, const char* filepath);
|
||||
void texture2DLoadFromFile(Texture2D* tex, const char* filepath);
|
||||
|
||||
Texture3D* texture3DCreate(int xsize, int ysize, int zsize);
|
||||
void texture3DDelete(Texture3D* tex);
|
||||
void texture3DGetSize(Texture3D* tex, int* xsize, int* ysize, int* zsize);
|
||||
void texture3DSetPixel(Texture3D* tex, int x, int y, int z, Color col);
|
||||
Color texture3DGetPixel(Texture3D* tex, int x, int y, int z);
|
||||
Color texture3DGetNearest(Texture3D* tex, double dx, double dy, double dz);
|
||||
Color texture3DGetLinear(Texture3D* tex, double dx, double dy, double dz);
|
||||
Color texture3DGetCubic(Texture3D* tex, double dx, double dy, double dz);
|
||||
void texture3DSaveToFile(Texture3D* tex, const char* filepath);
|
||||
void texture3DLoadFromFile(Texture3D* tex, const char* filepath);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue