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 <QTranslator>
|
||||||
#include <QLocale>
|
#include <QLocale>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QSplashScreen>
|
||||||
|
|
||||||
#include "basepreview.h"
|
#include "basepreview.h"
|
||||||
#include "formclouds.h"
|
#include "formclouds.h"
|
||||||
|
@ -31,12 +32,14 @@
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
MainWindow* window;
|
MainWindow* window;
|
||||||
|
QSplashScreen* splash;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
paysagesInit();
|
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
splash = new QSplashScreen(QPixmap("images/logo_256.png"));
|
||||||
|
splash->show();
|
||||||
|
|
||||||
QTranslator qtTranslator;
|
QTranslator qtTranslator;
|
||||||
QTranslator myTranslator;
|
QTranslator myTranslator;
|
||||||
|
|
||||||
|
@ -53,10 +56,17 @@ int main(int argc, char** argv)
|
||||||
app.installTranslator(&qtTranslator);
|
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();
|
BasePreview::initDrawers();
|
||||||
|
|
||||||
window = new MainWindow();
|
window = new MainWindow();
|
||||||
window->show();
|
window->show();
|
||||||
|
splash->finish(window);
|
||||||
|
|
||||||
|
delete splash;
|
||||||
|
|
||||||
result = app.exec();
|
result = app.exec();
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,10 @@
|
||||||
#if 1
|
#if 1
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "../system.h"
|
#include "../system.h"
|
||||||
|
#include "../tools/cache.h"
|
||||||
#include "../tools/texture.h"
|
#include "../tools/texture.h"
|
||||||
|
|
||||||
/*********************** Constants ***********************/
|
/*********************** Constants ***********************/
|
||||||
|
@ -400,13 +402,10 @@ static void _getMuMuSNu(double x, double y, double r, Color dhdH, double* mu, do
|
||||||
|
|
||||||
/*********************** Texture precomputing ***********************/
|
/*********************** Texture precomputing ***********************/
|
||||||
|
|
||||||
static Texture2D* _precomputeTransmittanceTexture()
|
static void _precomputeTransmittanceTexture()
|
||||||
{
|
{
|
||||||
Texture2D* result;
|
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
result = texture2DCreate(TRANSMITTANCE_W, TRANSMITTANCE_H);
|
|
||||||
|
|
||||||
for (x = 0; x < TRANSMITTANCE_W; x++)
|
for (x = 0; x < TRANSMITTANCE_W; x++)
|
||||||
{
|
{
|
||||||
for (y = 0; y < TRANSMITTANCE_H; y++)
|
for (y = 0; y < TRANSMITTANCE_H; y++)
|
||||||
|
@ -420,20 +419,15 @@ static Texture2D* _precomputeTransmittanceTexture()
|
||||||
trans.g = exp(-(betaR.g * depth1 + betaMEx.y * depth2));
|
trans.g = exp(-(betaR.g * depth1 + betaMEx.y * depth2));
|
||||||
trans.b = exp(-(betaR.b * depth1 + betaMEx.z * depth2));
|
trans.b = exp(-(betaR.b * depth1 + betaMEx.z * depth2));
|
||||||
trans.a = 1.0;
|
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;
|
int x, y;
|
||||||
|
|
||||||
result = texture2DCreate(SKY_W, SKY_H);
|
|
||||||
|
|
||||||
/* Irradiance program */
|
/* Irradiance program */
|
||||||
for (x = 0; x < SKY_W; x++)
|
for (x = 0; x < SKY_W; x++)
|
||||||
{
|
{
|
||||||
|
@ -452,11 +446,9 @@ static Texture2D* _precomputeIrrDeltaETexture()
|
||||||
irr.b = trans.b * max(muS, 0.0);
|
irr.b = trans.b * max(muS, 0.0);
|
||||||
irr.a = 1.0;
|
irr.a = 1.0;
|
||||||
|
|
||||||
texture2DSetPixel(result, x, y, irr);
|
texture2DSetPixel(_irrDeltaETexture, x, y, irr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _setLayer(int layer)
|
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 ***********************/
|
/*********************** Public methods ***********************/
|
||||||
|
|
||||||
void brunetonInit()
|
void brunetonInit()
|
||||||
{
|
{
|
||||||
int layer, x, y, z;
|
int layer, x, y, z, order;
|
||||||
|
|
||||||
if (_transmittanceTexture == NULL) /* TEMP */
|
if (_transmittanceTexture == NULL) /* TEMP */
|
||||||
{
|
{
|
||||||
/* TODO Deletes */
|
/* TODO Deletes */
|
||||||
|
|
||||||
/* computes transmittance texture T (line 1 in algorithm 4.1) */
|
/* computes transmittance texture T (line 1 in algorithm 4.1) */
|
||||||
_transmittanceTexture = _precomputeTransmittanceTexture();
|
_transmittanceTexture = texture2DCreate(TRANSMITTANCE_W, TRANSMITTANCE_H);
|
||||||
|
if (!_tryLoadCache2D(_transmittanceTexture, "transmittance"))
|
||||||
|
{
|
||||||
|
_precomputeTransmittanceTexture();
|
||||||
|
_saveCache2D(_transmittanceTexture, "transmittance");
|
||||||
|
}
|
||||||
|
|
||||||
/* computes irradiance texture deltaE (line 2 in algorithm 4.1) */
|
/* 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)
|
/* computes single scattering texture deltaS (line 3 in algorithm 4.1)
|
||||||
* Rayleigh and Mie separated in deltaSR + deltaSM */
|
* Rayleigh and Mie separated in deltaSR + deltaSM */
|
||||||
_deltaSRTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
_deltaSRTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
||||||
_deltaSMTexture = 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);
|
for (layer = 0; layer < RES_R; ++layer)
|
||||||
_setLayer(layer);
|
{
|
||||||
_inscatter1Prog(_deltaSRTexture, _deltaSMTexture);
|
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) */
|
/* 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) */
|
/* copies deltaS into inscatter texture S (line 5 in algorithm 4.1) */
|
||||||
_inscatterTexture = texture3DCreate(RES_MU_S * RES_NU, RES_MU, RES_R);
|
_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);
|
for (z = 0; z < RES_R; z++)
|
||||||
Color mie = texture3DGetPixel(_deltaSMTexture, x, y, z);
|
{
|
||||||
result.a = mie.r;
|
Color result = texture3DGetPixel(_deltaSRTexture, x, y, z);
|
||||||
texture3DSetPixel(_inscatterTexture, x, y, z, result);
|
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) */
|
/* 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) */
|
/* computes deltaJ (line 7 in algorithm 4.1) */
|
||||||
/*glFramebufferTextureEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, deltaJTexture, 0);
|
/*glFramebufferTextureEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, deltaJTexture, 0);
|
||||||
|
@ -848,11 +929,6 @@ void brunetonInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DEBUG */
|
/* DEBUG */
|
||||||
texture2DSaveToFile(_transmittanceTexture, "transmittance.png");
|
|
||||||
texture2DSaveToFile(_irrDeltaETexture, "irrdeltae.png");
|
|
||||||
texture3DSaveToFile(_deltaSRTexture, "deltasr.png");
|
|
||||||
texture3DSaveToFile(_deltaSMTexture, "deltasm.png");
|
|
||||||
texture3DSaveToFile(_inscatterTexture, "inscatter.png");
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,8 @@ void systemInit()
|
||||||
_core_count = _getCoreCount();
|
_core_count = _getCoreCount();
|
||||||
ilInit();
|
ilInit();
|
||||||
iluInit();
|
iluInit();
|
||||||
|
ilOriginFunc(IL_ORIGIN_LOWER_LEFT);
|
||||||
|
ilEnable(IL_ORIGIN_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
int systemGetCoreCount()
|
int systemGetCoreCount()
|
||||||
|
@ -117,7 +119,10 @@ int systemLoadPictureFile(const char* filepath, PictureCallbackLoadStarted callb
|
||||||
{
|
{
|
||||||
width = ilGetInteger(IL_IMAGE_WIDTH);
|
width = ilGetInteger(IL_IMAGE_WIDTH);
|
||||||
height = ilGetInteger(IL_IMAGE_HEIGHT);
|
height = ilGetInteger(IL_IMAGE_HEIGHT);
|
||||||
callback_start(data, width, height);
|
if (callback_start)
|
||||||
|
{
|
||||||
|
callback_start(data, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
pixels = malloc(sizeof(ILuint) * width * height);
|
pixels = malloc(sizeof(ILuint) * width * height);
|
||||||
ilCopyPixels(0, 0, 0, width, height, 1, IL_RGBA, IL_UNSIGNED_BYTE, pixels);
|
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;
|
Texture2D* result;
|
||||||
|
|
||||||
|
assert(xsize > 0 && ysize > 0);
|
||||||
|
|
||||||
result = (Texture2D*)malloc(sizeof(Texture2D));
|
result = (Texture2D*)malloc(sizeof(Texture2D));
|
||||||
result->xsize = xsize;
|
result->xsize = xsize;
|
||||||
result->ysize = ysize;
|
result->ysize = ysize;
|
||||||
|
@ -40,6 +42,12 @@ void texture2DDelete(Texture2D* tex)
|
||||||
free(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)
|
void texture2DSetPixel(Texture2D* tex, int x, int y, Color col)
|
||||||
{
|
{
|
||||||
assert(x >= 0 && x < tex->xsize);
|
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);
|
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;
|
Texture3D* result;
|
||||||
|
|
||||||
|
assert(xsize > 0 && ysize > 0 && zsize > 0);
|
||||||
|
|
||||||
result = (Texture3D*)malloc(sizeof(Texture3D));
|
result = (Texture3D*)malloc(sizeof(Texture3D));
|
||||||
result->xsize = xsize;
|
result->xsize = xsize;
|
||||||
result->ysize = ysize;
|
result->ysize = ysize;
|
||||||
|
@ -111,6 +134,13 @@ void texture3DDelete(Texture3D* tex)
|
||||||
free(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)
|
void texture3DSetPixel(Texture3D* tex, int x, int y, int z, Color col)
|
||||||
{
|
{
|
||||||
assert(x >= 0 && x < tex->xsize);
|
assert(x >= 0 && x < tex->xsize);
|
||||||
|
@ -167,9 +197,9 @@ static Color _callbackTex3dSave(Texture3D* tex, int x, int y)
|
||||||
y = y % tex->ysize;
|
y = y % tex->ysize;
|
||||||
|
|
||||||
assert(x >= 0 && x < tex->xsize);
|
assert(x >= 0 && x < tex->xsize);
|
||||||
assert(y >= 0 && y < tex->xsize);
|
assert(y >= 0 && y < tex->ysize);
|
||||||
assert(z >= 0 && z < tex->xsize);
|
assert(z >= 0 && z < tex->zsize);
|
||||||
|
|
||||||
return tex->data[z * tex->xsize * tex->ysize + y * tex->xsize + x];
|
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);
|
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_
|
#ifndef _PAYSAGES_TOOLS_TEXTURE_H_
|
||||||
#define _PAYSAGES_TOOLS_TEXTURE_H_
|
#define _PAYSAGES_TOOLS_TEXTURE_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pixel based textures.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -12,21 +16,25 @@ typedef struct Texture3D Texture3D;
|
||||||
|
|
||||||
Texture2D* texture2DCreate(int xsize, int ysize);
|
Texture2D* texture2DCreate(int xsize, int ysize);
|
||||||
void texture2DDelete(Texture2D* tex);
|
void texture2DDelete(Texture2D* tex);
|
||||||
|
void texture2DGetSize(Texture2D* tex, int* xsize, int* ysize);
|
||||||
void texture2DSetPixel(Texture2D* tex, int x, int y, Color col);
|
void texture2DSetPixel(Texture2D* tex, int x, int y, Color col);
|
||||||
Color texture2DGetPixel(Texture2D* tex, int x, int y);
|
Color texture2DGetPixel(Texture2D* tex, int x, int y);
|
||||||
Color texture2DGetNearest(Texture2D* tex, double dx, double dy);
|
Color texture2DGetNearest(Texture2D* tex, double dx, double dy);
|
||||||
Color texture2DGetLinear(Texture2D* tex, double dx, double dy);
|
Color texture2DGetLinear(Texture2D* tex, double dx, double dy);
|
||||||
Color texture2DGetCubic(Texture2D* tex, double dx, double dy);
|
Color texture2DGetCubic(Texture2D* tex, double dx, double dy);
|
||||||
void texture2DSaveToFile(Texture2D* tex, const char* filepath);
|
void texture2DSaveToFile(Texture2D* tex, const char* filepath);
|
||||||
|
void texture2DLoadFromFile(Texture2D* tex, const char* filepath);
|
||||||
|
|
||||||
Texture3D* texture3DCreate(int xsize, int ysize, int zsize);
|
Texture3D* texture3DCreate(int xsize, int ysize, int zsize);
|
||||||
void texture3DDelete(Texture3D* tex);
|
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);
|
void texture3DSetPixel(Texture3D* tex, int x, int y, int z, Color col);
|
||||||
Color texture3DGetPixel(Texture3D* tex, int x, int y, int z);
|
Color texture3DGetPixel(Texture3D* tex, int x, int y, int z);
|
||||||
Color texture3DGetNearest(Texture3D* tex, double dx, double dy, double dz);
|
Color texture3DGetNearest(Texture3D* tex, double dx, double dy, double dz);
|
||||||
Color texture3DGetLinear(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);
|
Color texture3DGetCubic(Texture3D* tex, double dx, double dy, double dz);
|
||||||
void texture3DSaveToFile(Texture3D* tex, const char* filepath);
|
void texture3DSaveToFile(Texture3D* tex, const char* filepath);
|
||||||
|
void texture3DLoadFromFile(Texture3D* tex, const char* filepath);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue