paysages: Big big refactoring for scenery and renderer (WIP - All broken).

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@232 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-01-23 23:45:33 +00:00 committed by ThunderK
parent 0685f21716
commit 48ea553f49
50 changed files with 1190 additions and 4734 deletions

View file

@ -1,21 +1,16 @@
all:
@+cd lib_paysages && make
@+cd cli && make
@+cd gui_gtk && make
@+cd gui_qt && qmake && make
clean:
cd lib_paysages && make clean
cd cli && make clean
cd gui_gtk && make clean
cd gui_qt && make clean && rm -f paysages-qt
run_cli:
LD_LIBRARY_PATH=lib_paysages ./cli/paysages-cli
run_gtk:
LD_LIBRARY_PATH=lib_paysages ./gui_gtk/paysages-gtk
run_qt:
LD_LIBRARY_PATH=lib_paysages ./gui_qt/paysages-qt

12
TODO Normal file
View file

@ -0,0 +1,12 @@
- Create a 'scenery' module that will, for each component :
- Hold definitions
- Setup standard Renderer
- Regroup load/save/render (from auto)
- Merge all Quality and Environment, as one Renderer.
- No more _definition, _quality, _environment in components.
- All component methods become custom.
- Refactor fog in a new 'atmosphere' module.
- In GUI, revertConfig should lock the previews while reverting.
- All Save and Load methods should have same signature : void ...Save(FILE*, ...*)
- All noises should use the same entropy pool (saved separately), and avoid reallocs.
- Remove all global variables (render_quality, render_width...), it should all be set in Renderer.

View file

@ -1,21 +0,0 @@
SOURCES=$(wildcard *.c)
OBJECTS=${SOURCES:.c=.o}
HEADERS=$(wildcard ../lib_paysages/shared/*.h ../lib_paysages/*.h *.h)
RESULT=paysages-gtk
CC_FLAGS=-g -pg -Wall $(shell pkg-config --cflags gtk+-3.0) -I..
CC_LDFLAGS=$(shell pkg-config --libs gtk+-3.0) -L../lib_paysages/ -lpaysages
all:${RESULT}
clean:
rm -f ${OBJECTS}
rm -f ${RESULT}
%.o:%.c ${HEADERS}
${CC} -c ${CC_FLAGS} $< -o $@
${RESULT}:${OBJECTS}
${CC} $^ ${CC_LDFLAGS} -o $@
.PHONY:all clean

View file

@ -1,55 +0,0 @@
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "lib_paysages/shared/types.h"
#include <stdio.h>
typedef void (*GuiNoiseChangedCallback)(NoiseGenerator* generator);
typedef struct SmallPreview SmallPreview;
typedef Color (*SmallPreviewCallback)(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling);
extern GtkBuilder* gui_definition;
static inline GtkWidget* _get_widget(const char* name, const char* file, int line)
{
GtkWidget* result;
result = (GtkWidget*)gtk_builder_get_object(gui_definition, (name));
if (result == NULL)
{
printf("Widget not found (%s:%d) : %s\n", file, line, name);
}
return result;
}
#define GET_WIDGET(_name_) (_get_widget(_name_, __FILE__, __LINE__))
void guiUpdate();
void guiTerrainInit();
void guiWaterInit();
void guiWaterUpdate();
void guiSkyInit();
void guiSkyUpdate();
void guiCloudsInit();
void guiCloudsUpdate();
void guiRenderInit();
void guiNoiseInit();
void guiNoiseEdit(NoiseGenerator* generator, GuiNoiseChangedCallback callback);
void guiPreviewStart();
void guiPreviewRedraw(SmallPreview* preview);
void guiPreviewRedrawAll();
SmallPreview* guiPreviewNew(GtkImage* image);
void guiPreviewSetTerrainHeight(SmallPreview* preview);
void guiPreviewSetTerrainColor(SmallPreview* preview);
void guiPreviewSetNoise1D(SmallPreview* preview, NoiseGenerator* generator);
void guiPreviewConfigScrolling(SmallPreview* preview, double xmin, double xmax, double ymin, double ymax);
void guiPreviewConfigScaling(SmallPreview* preview, double min, double max, double step);
void guiPreviewSetRenderer(SmallPreview* preview, SmallPreviewCallback renderer);
void guiPreviewSetViewport(SmallPreview* preview, double xoffset, double yoffset, double scaling);

View file

@ -1,218 +0,0 @@
/* Noise editor dialog */
#include "common.h"
#include "lib_paysages/shared/functions.h"
#include "lib_paysages/shared/constants.h"
static GtkWidget* _dialog;
static SmallPreview* _preview;
static GtkTreeView* _level_list;
static GtkListStore* _level_list_model;
static NoiseGenerator* _generator;
static GuiNoiseChangedCallback _callback;
static int _current_mode;
static Color _cbPreview1DRenderPixel(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
{
if (y > noiseGet1DTotal(_generator, x))
{
return COLOR_WHITE;
}
else
{
return COLOR_BLACK;
}
}
static Color _cbPreview2DRenderPixel(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
{
Color col;
double max_value;
/* TODO Cache this value */
max_value = noiseGetMaxValue(_generator);
col.r = col.g = col.b = (noiseGet2DTotal(_generator, x, y) / max_value) * 0.5 + 0.5;
col.a = 1.0;
return col;
}
static void _setPreviewMode(int mode)
{
GtkButton* button;
double max_value;
max_value = noiseGetMaxValue(_generator);
button = GTK_BUTTON(GET_WIDGET("noise_editor_preview_mode"));
if (mode == 1)
{
_current_mode = 1;
guiPreviewSetRenderer(_preview, _cbPreview1DRenderPixel);
gtk_button_set_label(button, "1D");
guiPreviewConfigScrolling(_preview, -max_value * 100.0, max_value * 100.0, -max_value, max_value);
}
else if (mode == 2)
{
_current_mode = 2;
guiPreviewSetRenderer(_preview, _cbPreview2DRenderPixel);
gtk_button_set_label(button, "2D");
guiPreviewConfigScrolling(_preview, -max_value * 100.0, max_value * 100.0, -max_value * 100.0, max_value * 100.0);
}
guiPreviewConfigScaling(_preview, max_value * 0.001, max_value * 0.1, max_value * 0.001);
guiPreviewSetViewport(_preview, 0.0, 0.0, max_value * 0.01);
}
static void _redrawPreview()
{
guiPreviewRedraw(_preview);
}
static void _resetPreview()
{
_setPreviewMode(_current_mode);
_redrawPreview();
}
static void _applyLayerParams()
{
GtkTreePath* path;
GtkTreeViewColumn* column;
GtkTreeIter row;
int* indices;
double height, scale;
gtk_tree_view_get_cursor(_level_list, &path, &column);
indices = gtk_tree_path_get_indices(path);
if (indices)
{
height = (double)gtk_spin_button_get_value(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_height")));
scale = (double)gtk_spin_button_get_value(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_scale")));
noiseSetLevelSimple(_generator, indices[0], scale, height);
gtk_tree_model_get_iter(GTK_TREE_MODEL(_level_list_model), &row, path);
gtk_list_store_set(_level_list_model, &row, 0, height, 1, scale, -1);
}
_redrawPreview();
}
static void _cbGenerateClicked(GtkButton* button, gpointer user_data)
{
noiseGenerateBaseNoise(_generator, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_base_size"))));
_redrawPreview();
}
static void _cbPreviewModeClicked(GtkButton* button, gpointer user_data)
{
if (_current_mode == 1)
{
_setPreviewMode(2);
}
else
{
_setPreviewMode(1);
}
_redrawPreview();
}
static void _cbPreviewResetClicked(GtkButton* button, gpointer user_data)
{
_resetPreview();
}
static void _cbApplyClicked(GtkButton* button, gpointer user_data)
{
gtk_widget_hide(_dialog);
_callback(_generator);
}
static void _cbCancelClicked(GtkButton* button, gpointer user_data)
{
gtk_widget_hide(_dialog);
}
static void _cbLevelParamChanged(GtkWidget* widget, gpointer user_data)
{
_applyLayerParams();
}
static void _cbRowSelected(GtkTreeView* tree_view, gpointer user_data)
{
GtkTreePath* path;
GtkTreeViewColumn* column;
int* indices;
NoiseLevel params;
gtk_tree_view_get_cursor(tree_view, &path, &column);
indices = gtk_tree_path_get_indices(path);
if (indices)
{
if (noiseGetLevel(_generator, indices[0], &params))
{
gtk_spin_button_set_value(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_height")), params.height);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_scale")), params.scaling);
}
}
}
void guiNoiseInit()
{
_dialog = GET_WIDGET("dialog_noise");
_level_list = GTK_TREE_VIEW(GET_WIDGET("noise_editor_levels"));
_level_list_model = GTK_LIST_STORE(gtk_tree_view_get_model(_level_list));
_generator = noiseCreateGenerator();
gtk_spin_button_set_range(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_base_size")), 1, 4000000);
gtk_spin_button_set_increments(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_base_size")), 100, 100000);
gtk_spin_button_set_range(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_scale")), 0.0001, 100.0);
gtk_spin_button_set_increments(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_scale")), 0.0001, 0.1);
gtk_spin_button_set_range(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_height")), 0.0, 100.0);
gtk_spin_button_set_increments(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_height")), 0.0001, 0.1);
_preview = guiPreviewNew(GTK_IMAGE(GET_WIDGET("noise_editor_preview")));
_resetPreview();
g_signal_connect(_dialog, "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), NULL);
g_signal_connect(GET_WIDGET("noise_editor_generate"), "clicked", G_CALLBACK(_cbGenerateClicked), NULL);
g_signal_connect(GET_WIDGET("noise_editor_preview_reset"), "clicked", G_CALLBACK(_cbPreviewResetClicked), NULL);
g_signal_connect(GET_WIDGET("noise_editor_preview_mode"), "clicked", G_CALLBACK(_cbPreviewModeClicked), NULL);
g_signal_connect(GET_WIDGET("noise_editor_apply"), "clicked", G_CALLBACK(_cbApplyClicked), NULL);
g_signal_connect(GET_WIDGET("noise_editor_cancel"), "clicked", G_CALLBACK(_cbCancelClicked), NULL);
g_signal_connect(_level_list, "cursor-changed", G_CALLBACK(_cbRowSelected), NULL);
g_signal_connect(GET_WIDGET("noise_editor_height"), "value-changed", G_CALLBACK(_cbLevelParamChanged), NULL);
g_signal_connect(GET_WIDGET("noise_editor_scale"), "value-changed", G_CALLBACK(_cbLevelParamChanged), NULL);
}
void guiNoiseEdit(NoiseGenerator* generator, GuiNoiseChangedCallback callback)
{
int i, n;
NoiseLevel level;
GtkTreeIter row;
_callback = callback;
noiseCopy(generator, _generator);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(GET_WIDGET("noise_editor_base_size")), noiseGetBaseSize(_generator));
gtk_list_store_clear(_level_list_model);
n = noiseGetLevelCount(_generator);
for (i = 0 ; i < n; i++)
{
noiseGetLevel(_generator, i, &level);
gtk_list_store_append(_level_list_model, &row);
gtk_list_store_set(_level_list_model, &row, 0, level.height, 1, level.scaling, -1);
}
_setPreviewMode(1);
_resetPreview();
gtk_widget_show(_dialog);
}

View file

@ -1,116 +0,0 @@
#include <stdlib.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "lib_paysages/shared/functions.h"
#include "lib_paysages/shared/constants.h"
#include "common.h"
GtkBuilder* gui_definition;
static GtkWindow* _main_window;
static void _cbQuit(GtkWidget* widget, gpointer data)
{
gtk_main_quit();
exit(0);
}
static void _cbLoad(GtkWidget* widget, gpointer data)
{
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new("Load File",
_main_window,
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
paysagesLoad(filename);
g_free(filename);
}
/* Update all GUI */
guiUpdate();
gtk_widget_destroy(dialog);
}
static void _cbSaveAs(GtkWidget* widget, gpointer data)
{
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new("Save File",
_main_window,
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
{
char *filename;
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
paysagesSave(filename);
g_free(filename);
}
gtk_widget_destroy(dialog);
}
void guiInit()
{
GError* p_err = NULL;
int argc = 0;
char** argv = NULL;
gtk_init(&argc, &argv);
gui_definition = gtk_builder_new();
gtk_builder_add_from_file(gui_definition, "gui_gtk/gui.glade", &p_err);
_main_window = GTK_WINDOW(GET_WIDGET("main_window"));
g_signal_connect(_main_window, "delete_event", G_CALLBACK(_cbQuit), NULL);
/* Menu bar */
g_signal_connect(GET_WIDGET("menu_quit"), "activate", G_CALLBACK(_cbQuit), NULL);
g_signal_connect(GET_WIDGET("menu_load"), "activate", G_CALLBACK(_cbLoad), NULL);
g_signal_connect(GET_WIDGET("menu_saveas"), "activate", G_CALLBACK(_cbSaveAs), NULL);
/* Dialogs */
guiNoiseInit();
/* Tabs */
guiRenderInit();
guiTerrainInit();
guiWaterInit();
guiCloudsInit();
guiSkyInit();
}
void guiStart()
{
guiPreviewStart();
guiUpdate();
gtk_widget_show_all(GTK_WIDGET(_main_window));
gtk_main();
}
void guiUpdate()
{
guiWaterUpdate();
guiCloudsUpdate();
guiSkyUpdate();
guiPreviewRedrawAll();
}
int main(int argc, char** argv)
{
paysagesInit();
guiInit();
guiStart();
return 0;
}

File diff suppressed because it is too large Load diff

View file

@ -1,431 +0,0 @@
/* Small preview management */
#include <string.h>
#include <math.h>
#include "common.h"
#include "lib_paysages/shared/types.h"
#include "lib_paysages/shared/functions.h"
#include "lib_paysages/shared/constants.h"
#include "lib_paysages/shared/system.h"
#define MAX_PREVIEWS 30
struct SmallPreview
{
double conf_scroll_xmin;
double conf_scroll_xmax;
double conf_scroll_ymin;
double conf_scroll_ymax;
double conf_scale_min;
double conf_scale_max;
double conf_scale_step;
double xoffset;
double yoffset;
double scaling;
Mutex* lock;
GdkPixbuf* pixbuf;
GtkImage* image;
int mousex;
int mousey;
int need_rerender;
int need_render;
int need_update;
SmallPreviewCallback renderer;
};
static int _previews_count = 0;
static SmallPreview _preview[MAX_PREVIEWS];
static Thread* _thread_update;
static inline void _forceRender(SmallPreview* preview)
{
gdk_pixbuf_fill(preview->pixbuf, 0x00000000);
preview->need_rerender = 0;
preview->need_render = 1;
}
static inline void _updateImage(SmallPreview* preview)
{
gtk_image_set_from_pixbuf(preview->image, preview->pixbuf);
}
static inline void _renderPixbuf(SmallPreview* preview)
{
int x, y, done;
Color col;
void* pixels = gdk_pixbuf_get_pixels(preview->pixbuf);
guint32* pixel;
int rowstride = gdk_pixbuf_get_rowstride(preview->pixbuf);
/* TODO Use pixbuf size */
for (x = 0; x < 256; x++)
{
mutexAcquire(preview->lock);
if (preview->need_rerender)
{
mutexRelease(preview->lock);
break;
}
done = 0;
for (y = 0; y < 256; y++)
{
pixel = (guint32*)(pixels + y * rowstride + x * 4);
if (!*pixel)
{
col = preview->renderer(preview, (double)(x - 128) * preview->scaling + preview->xoffset, (double)(y - 128) * preview->scaling + preview->yoffset, preview->xoffset, preview->yoffset, preview->scaling);
*pixel = (guint32)colorTo32BitRGBA(&col);
done = 1;
}
}
if (done)
{
preview->need_update = 1;
}
mutexRelease(preview->lock);
}
}
static void* _doRenders(void* data)
{
int i;
SmallPreview* preview;
while (1)
{
for (i = 0; i < _previews_count; i++)
{
preview = _preview + i;
if (preview->need_rerender)
{
_forceRender(preview);
}
if (preview->need_render)
{
preview->need_render = 0;
_renderPixbuf(preview);
}
}
timeSleepMs(100);
}
return NULL;
}
static int _doUpdates(void* data)
{
int i;
SmallPreview* preview;
for (i = 0; i < _previews_count; i++)
{
preview = _preview + i;
if (preview->need_update)
{
preview->need_update = 0;
_updateImage(preview);
}
}
return 1;
}
static void _scrollPixbuf(SmallPreview* preview, int dx, int dy)
{
int xstart, ystart, xsize, ysize, y;
void* pixels = gdk_pixbuf_get_pixels(preview->pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(preview->pixbuf);
preview->xoffset -= (double)dx * preview->scaling;
preview->yoffset -= (double)dy * preview->scaling;
/* TODO Use pixbuf size */
if (dx == 0 && dy == 0)
{
return;
}
else if (dx <= -256 || dx >= 256 || dy <= -256 || dy >= 256)
{
_forceRender(preview);
}
else
{
if (dx < 0)
{
xstart = -dx;
xsize = 256 + dx;
}
else
{
xstart = 0;
xsize = 256 - dx;
}
if (dy < 0)
{
ystart = -dy;
ysize = 256 + dy;
}
else
{
ystart = 0;
ysize = 256 - dy;
}
memmove(pixels + (ystart + dy) * rowstride + (xstart + dx) * 4, pixels + ystart * rowstride + xstart * 4, (ysize - 1) * rowstride + xsize * 4);
if (dy < 0)
{
memset(pixels + (256 + dy) * rowstride, 0, (-dy - 1) * rowstride + 256 * 4);
}
else if (dy > 0)
{
memset(pixels, 0, (dy - 1) * rowstride + 256 * 4);
}
if (dx < 0)
{
for (y = ystart + dy; y < ystart + dy + ysize; y++)
{
memset(pixels + y * rowstride + xsize * 4, 0, -dx * 4);
}
}
else if (dx > 0)
{
for (y = ystart + dy; y < ystart + dy + ysize; y++)
{
memset(pixels + y * rowstride, 0, dx * 4);
}
}
preview->need_render = 1;
}
}
static inline int _fixScroll(SmallPreview* preview, int dx, int dy, int* new_dx, int* new_dy)
{
*new_dx = dx;
*new_dy = dy;
if (preview->xoffset - dx * preview->scaling > preview->conf_scroll_xmax)
{
*new_dx = (int)floor((preview->conf_scroll_xmax - preview->xoffset) / preview->scaling);
}
if (preview->xoffset - dx * preview->scaling < preview->conf_scroll_xmin)
{
*new_dx = (int)floor((preview->conf_scroll_xmin - preview->xoffset) / preview->scaling);
}
if (preview->yoffset - dy * preview->scaling > preview->conf_scroll_ymax)
{
*new_dy = (int)floor((preview->conf_scroll_ymax - preview->yoffset) / preview->scaling);
}
if (preview->yoffset - dy * preview->scaling < preview->conf_scroll_ymin)
{
*new_dy = (int)floor((preview->conf_scroll_ymin - preview->yoffset) / preview->scaling);
}
return (*new_dx == 0 && *new_dy == 0) ? 0 : 1;
}
static inline int _fixScaling(SmallPreview* preview, double scaling, double* new_scaling)
{
double old_scaling = preview->scaling;
*new_scaling = scaling;
if (scaling < preview->conf_scale_min)
{
*new_scaling = preview->conf_scale_min;
}
if (scaling > preview->conf_scale_max)
{
*new_scaling = preview->conf_scale_max;
}
return (old_scaling == *new_scaling) ? 0 : 1;
}
static int _cbMouseScroll(GtkEventBox* image, GdkEventScroll* event, gpointer data)
{
SmallPreview* preview = (SmallPreview*)data;
/* TODO Center the zoom on the cursor */
if (event->direction == GDK_SCROLL_UP)
{
mutexAcquire(preview->lock);
if (_fixScaling(preview, preview->scaling - preview->conf_scale_step, &preview->scaling))
{
preview->need_rerender = 1;
}
mutexRelease(preview->lock);
}
else if (event->direction == GDK_SCROLL_DOWN)
{
mutexAcquire(preview->lock);
if (_fixScaling(preview, preview->scaling + preview->conf_scale_step, &preview->scaling))
{
preview->need_rerender = 1;
}
mutexRelease(preview->lock);
}
return 1;
}
static int _cbMouseButtonPressed(GtkEventBox* image, GdkEventButton* event, gpointer data)
{
SmallPreview* preview = (SmallPreview*)data;
if (event->button == 1)
{
preview->mousex = (int)event->x;
preview->mousey = (int)event->y;
}
return 1;
}
static int _cbMouseMove(GtkEventBox* image, GdkEventMotion* event, gpointer data)
{
SmallPreview* preview = (SmallPreview*)data;
int dx, dy;
if (event->state & GDK_BUTTON1_MASK)
{
mutexAcquire(preview->lock);
dx = (int)event->x - preview->mousex;
dy = (int)event->y - preview->mousey;
if (_fixScroll(preview, dx, dy, &dx, &dy))
{
_scrollPixbuf(preview, dx, dy);
}
preview->mousex = (int)event->x;
preview->mousey = (int)event->y;
mutexRelease(preview->lock);
}
return 1;
}
static Color _renderNone(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
{
return COLOR_BLACK;
}
void guiPreviewStart()
{
_thread_update = threadCreate(_doRenders, NULL);
g_timeout_add(200, _doUpdates, NULL);
}
void guiPreviewRedraw(SmallPreview* preview)
{
mutexAcquire(preview->lock);
preview->need_rerender = 1;
mutexRelease(preview->lock);
}
void guiPreviewRedrawAll()
{
int i;
for (i = 0; i < _previews_count; i++)
{
guiPreviewRedraw(_preview + i);
}
}
SmallPreview* guiPreviewNew(GtkImage* image)
{
GtkWidget* parent = gtk_widget_get_parent(GTK_WIDGET(image));
SmallPreview* preview;
/* TODO Check the parent can receive events (or is a GtkEventBox) */
if (_previews_count < MAX_PREVIEWS)
{
preview = _preview + _previews_count;
preview->lock = mutexCreate();
preview->conf_scroll_xmin = 0.0;
preview->conf_scroll_xmax = 0.0;
preview->conf_scroll_ymin = 0.0;
preview->conf_scroll_ymax = 0.0;
preview->conf_scale_min = 1.0;
preview->conf_scale_max = 1.0;
preview->conf_scale_step = 0.0;
preview->scaling = 1.0;
preview->xoffset = 0.0;
preview->yoffset = 0.0;
/* TODO Get size from GtkImage */
preview->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 1, 8, 256, 256);
preview->image = image;
preview->need_rerender = 0;
preview->need_render = 0;
preview->need_update = 0;
preview->renderer = _renderNone;
gtk_image_clear(image);
_forceRender(preview);
g_signal_connect(parent, "scroll-event", G_CALLBACK(_cbMouseScroll), (gpointer)preview);
g_signal_connect(parent, "button-press-event", G_CALLBACK(_cbMouseButtonPressed), (gpointer)preview);
g_signal_connect(parent, "motion-notify-event", G_CALLBACK(_cbMouseMove), (gpointer)preview);
_previews_count++;
return preview;
}
else
{
/* TODO Return fake preview */
return NULL;
}
}
void guiPreviewConfigScrolling(SmallPreview* preview, double xmin, double xmax, double ymin, double ymax)
{
mutexAcquire(preview->lock);
preview->conf_scroll_xmin = xmin;
preview->conf_scroll_xmax = xmax;
preview->conf_scroll_ymin = ymin;
preview->conf_scroll_ymax = ymax;
preview->need_rerender = 1;
mutexRelease(preview->lock);
}
void guiPreviewConfigScaling(SmallPreview* preview, double min, double max, double step)
{
mutexAcquire(preview->lock);
preview->conf_scale_min = min;
preview->conf_scale_max = max;
preview->conf_scale_step = step;
preview->need_rerender = 1;
mutexRelease(preview->lock);
}
void guiPreviewSetRenderer(SmallPreview* preview, SmallPreviewCallback renderer)
{
mutexAcquire(preview->lock);
preview->renderer = renderer;
preview->need_rerender = 1;
mutexRelease(preview->lock);
}
void guiPreviewSetViewport(SmallPreview* preview, double xoffset, double yoffset, double scaling)
{
mutexAcquire(preview->lock);
preview->xoffset = xoffset;
preview->yoffset = yoffset;
preview->scaling = scaling;
preview->need_rerender = 1;
mutexRelease(preview->lock);
}
void guiPreviewSetTerrainHeight(SmallPreview* preview)
{
/*preview->conf_scroll_x = 1;
preview->conf_scroll_y = 1;
preview->conf_zoom = 1;
preview->init_scaling = preview->scaling = 0.1;
preview->init_xoffset = preview->xoffset = 0.0;
preview->init_yoffset = preview->yoffset = 0.0;
preview->renderer = _renderTopDownHeight;*/
guiPreviewRedraw(preview);
}

View file

@ -1,128 +0,0 @@
/* Terrain tab */
#include "common.h"
#include "lib_paysages/shared/functions.h"
#include "lib_paysages/shared/constants.h"
#include "lib_paysages/clouds.h"
#include <math.h>
static SmallPreview* _preview;
static CloudsDefinition _definition;
static int _current_layer;
static GtkTreeView* _list_layers;
static GtkListStore* _list_layers_model;
/***** Internal functions *****/
static void _revertCurrentLayer()
{
if (_current_layer >= 0)
{
cloudsCopyDefinition(cloudsGetDefinition(_current_layer), &_definition);
}
/* TODO Revert layer from config */
guiPreviewRedraw(_preview);
}
/*static void _applyCurrentLayer()
{
guiUpdate();
}*/
static void _revertAll()
{
int i, n;
CloudsDefinition layer;
GtkTreeIter row;
gtk_list_store_clear(_list_layers_model);
n = cloudsGetLayerCount();
for (i = 0 ; i < n; i++)
{
layer = cloudsGetDefinition(i);
gtk_list_store_append(_list_layers_model, &row);
gtk_list_store_set(_list_layers_model, &row, 0, layer.ymin, 1, layer.ymax - layer.ymin, -1);
}
if (_current_layer < 0 || _current_layer >= n)
{
_current_layer = -1;
}
_revertCurrentLayer();
}
/***** Preview callbacks *****/
static Color _cbPreviewPixel(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
{
Color result, layer_color;
Vector3 start, end;
if (_current_layer < 0)
{
return COLOR_BLACK;
}
else
{
start.x = end.x = x;
start.z = end.z = y;
start.y = _definition.ymin;
end.y = _definition.ymax;
result.r = 0.3;
result.g = 0.5;
result.b = 0.8;
result.a = 1.0;
layer_color = cloudsGetColorCustom(start, end, &_definition, NULL, NULL);
colorMask(&result, &layer_color);
return result;
}
}
/***** Config callbacks *****/
static void _cbLayerSelected(GtkTreeView* tree_view, gpointer user_data)
{
GtkTreePath* path;
GtkTreeViewColumn* column;
int* indices;
gtk_tree_view_get_cursor(tree_view, &path, &column);
indices = gtk_tree_path_get_indices(path);
if (indices)
{
_current_layer = 0;
}
else
{
_current_layer = -1;
}
_revertCurrentLayer();
}
/***** Public functions *****/
void guiCloudsInit()
{
_list_layers = GTK_TREE_VIEW(GET_WIDGET("clouds_layers"));
_list_layers_model = GTK_LIST_STORE(gtk_tree_view_get_model(_list_layers));
_definition = cloudsCreateDefinition();
_preview = guiPreviewNew(GTK_IMAGE(GET_WIDGET("clouds_preview")));
guiPreviewConfigScaling(_preview, 1.0, 100.0, 1.0);
guiPreviewConfigScrolling(_preview, -10000.0, 10000.0, -10000.0, 10000.0);
guiPreviewSetViewport(_preview, 0.0, 0.0, 10.0);
guiPreviewSetRenderer(_preview, _cbPreviewPixel);
g_signal_connect(_list_layers, "cursor-changed", G_CALLBACK(_cbLayerSelected), NULL);
guiCloudsUpdate();
}
void guiCloudsUpdate()
{
_revertAll();
}

View file

@ -1,172 +0,0 @@
/* Terrain tab */
#include "common.h"
#include "lib_paysages/shared/functions.h"
#include "lib_paysages/shared/constants.h"
#include "lib_paysages/shared/globals.h"
#include "lib_paysages/shared/system.h"
static GtkImage* _render_final;
static GdkPixbuf* _render_buffer = NULL;
static guchar* _render_buffer_pixels = NULL;
static int _render_buffer_ymax = 0;
static int _render_buffer_rowstride = 0;
static int _rendering = 0;
static void _previewResize(int width, int height)
{
if (_render_buffer)
{
gdk_pixbuf_unref(_render_buffer);
}
_render_buffer = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 1, 8, width, height);
_render_buffer_pixels = gdk_pixbuf_get_pixels(_render_buffer);
_render_buffer_rowstride = gdk_pixbuf_get_rowstride(_render_buffer);
_render_buffer_ymax = height - 1;
}
static void _previewClear(Color col)
{
gdk_pixbuf_fill(_render_buffer, (guint32)colorTo32BitARGB(&col));
}
static void _previewDraw(int x, int y, Color col)
{
guint32* pixels = (guint32*)(_render_buffer_pixels + (_render_buffer_ymax - y) * _render_buffer_rowstride + x * 4);
*pixels = (guint32)colorTo32BitRGBA(&col);
}
static void _previewUpdate(double progress)
{
gtk_image_set_from_pixbuf(_render_final, _render_buffer);
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(GET_WIDGET("render_progress")), progress);
}
static void* _threadRender(void* data)
{
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(GET_WIDGET("render_mode_raytracing"))))
{
autoRenderSceneRayTracing();
}
else
{
autoRenderSceneTwoPass(0);
}
_rendering = 0;
return NULL;
}
static void _cbStartRender(GtkWidget* widget, gpointer data)
{
Thread* thread;
/* Prepare render */
renderSetSize(gtk_spin_button_get_value(GTK_SPIN_BUTTON(GET_WIDGET("render_width"))), gtk_spin_button_get_value(GTK_SPIN_BUTTON(GET_WIDGET("render_height"))));
autoSetRenderQuality((int)gtk_range_get_value(GTK_RANGE(GET_WIDGET("render_quality"))));
gtk_widget_set_size_request(GET_WIDGET("render_preview"), render_width, render_height);
gtk_image_clear(GTK_IMAGE(GET_WIDGET("render_preview")));
renderSetPreviewCallbacks(_previewResize, _previewClear, _previewDraw, _previewUpdate);
/* Open render dialog */
gtk_window_set_deletable(GTK_WINDOW(GET_WIDGET("dialog_render")), 0);
gtk_widget_show(GET_WIDGET("dialog_render"));
gtk_widget_set_sensitive(GET_WIDGET("render_stop"), 1);
gtk_widget_set_sensitive(GET_WIDGET("render_close"), 0);
/* Do the render */
_rendering = 1;
thread = threadCreate(_threadRender, NULL);
while (_rendering)
{
timeSleepMs(100);
while (gtk_events_pending())
{
gtk_main_iteration();
}
}
threadJoin(thread);
/* Clean up */
renderSetPreviewCallbacks(NULL, NULL, NULL, NULL);
gtk_widget_set_sensitive(GET_WIDGET("render_stop"), 0);
gtk_widget_set_sensitive(GET_WIDGET("render_close"), 1);
}
static void _cbStopRender(GtkWidget* widget, gpointer data)
{
if (_rendering)
{
renderInterrupt();
}
}
static void _cbCloseRender(GtkWidget* widget, gpointer data)
{
gtk_widget_hide(GET_WIDGET("dialog_render"));
}
static void _cbShowRender(GtkWidget* widget, gpointer data)
{
gtk_widget_show(GET_WIDGET("dialog_render"));
}
static void _cbSaveRender(GtkWidget* widget, gpointer data)
{
GtkWidget *dialog;
char *filename;
dialog = gtk_file_chooser_dialog_new("Save last render",
GTK_WINDOW(GET_WIDGET("main_window")),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
NULL);
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(dialog), TRUE);
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "render.png");
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
{
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
renderSaveToFile(filename);
g_free(filename);
}
gtk_widget_destroy(dialog);
}
static int _cbWindowClosed(GtkWidget* widget, GdkEvent* event, gpointer data)
{
gtk_widget_hide(widget);
if (_rendering)
{
renderInterrupt();
}
return 1;
}
void guiRenderInit()
{
_render_final = GTK_IMAGE(GET_WIDGET("render_preview"));
_previewResize(800, 600);
_previewClear(COLOR_BLACK);
_previewUpdate(0.0);
g_signal_connect(GET_WIDGET("render_show"), "clicked", G_CALLBACK(_cbShowRender), NULL);
g_signal_connect(GET_WIDGET("render_save"), "clicked", G_CALLBACK(_cbSaveRender), NULL);
g_signal_connect(GET_WIDGET("render_start"), "clicked", G_CALLBACK(_cbStartRender), NULL);
g_signal_connect(GET_WIDGET("render_stop"), "clicked", G_CALLBACK(_cbStopRender), NULL);
g_signal_connect(GET_WIDGET("render_close"), "clicked", G_CALLBACK(_cbCloseRender), NULL);
g_signal_connect(GET_WIDGET("dialog_render"), "delete-event", G_CALLBACK(_cbWindowClosed), NULL);
gtk_range_set_range(GTK_RANGE(GET_WIDGET("render_quality")), 1, 10);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("render_quality")), 5);
gtk_spin_button_set_range(GTK_SPIN_BUTTON(GET_WIDGET("render_width")), 100, 4000);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(GET_WIDGET("render_width")), 1200);
gtk_spin_button_set_increments(GTK_SPIN_BUTTON(GET_WIDGET("render_width")), 10, 100);
gtk_spin_button_set_range(GTK_SPIN_BUTTON(GET_WIDGET("render_height")), 100, 4000);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(GET_WIDGET("render_height")), 900);
gtk_spin_button_set_increments(GTK_SPIN_BUTTON(GET_WIDGET("render_height")), 10, 100);
}

View file

@ -1,133 +0,0 @@
/* Terrain tab */
#include "common.h"
#include "lib_paysages/shared/functions.h"
#include "lib_paysages/shared/constants.h"
#include "lib_paysages/sky.h"
#include <math.h>
static SmallPreview* _preview_horizon;
static SkyDefinition _definition;
static Color _cbPreviewHorizon(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
{
Vector3 eye = {0.0, 0.0, 0.0};
Vector3 look;
look.x = cos(M_PI * (x / 1.28 + 0.5)) * cos(M_PI * (y / 2.56));
look.y = -sin(M_PI * (y / 2.56));
look.z = sin(M_PI * (x / 1.28 + 0.5)) * cos(M_PI * (y / 2.56));
return skyGetColorCustom(eye, look, &_definition, NULL, NULL);
}
static inline void _updatePreview()
{
skyValidateDefinition(&_definition);
guiPreviewRedraw(_preview_horizon);
}
static void _redrawColorGradation(GtkImage* image, ColorGradation* gradation)
{
GdkPixbuf* pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, 1, 8, 200, 30);
void* pixels = gdk_pixbuf_get_pixels(pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(pixbuf);
int x, y;
guint32* pixel;
Color col;
for (x = 0; x < 200; x++)
{
for (y = 0; y < 30; y++)
{
pixel = (guint32*)(pixels + y * rowstride + x * 4);
col = colorGradationGet(gradation, (double)x / 200.0);
*pixel = (guint32)colorTo32BitRGBA(&col);
}
}
gtk_image_set_from_pixbuf(image, pixbuf);
gdk_pixbuf_unref(pixbuf);
}
static void _cbDaytimeChanged(GtkRange* range, gpointer data)
{
_definition.daytime = gtk_range_get_value(range);
_updatePreview();
}
static void _cbSunSizeChanged(GtkRange* range, gpointer data)
{
_definition.sun_radius = gtk_range_get_value(range);
_updatePreview();
}
static void _cbHazeHeightChanged(GtkRange* range, gpointer data)
{
_definition.haze_height = gtk_range_get_value(range);
_updatePreview();
}
static void _cbHazeSmoothingChanged(GtkRange* range, gpointer data)
{
_definition.haze_smoothing = gtk_range_get_value(range);
_updatePreview();
}
static void _cbRevertConfig(GtkWidget* widget, gpointer data)
{
skyCopyDefinition(skyGetDefinition(), &_definition);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("sky_daytime")), _definition.daytime);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("sky_sun_size")), _definition.sun_radius);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("sky_haze_height")), _definition.haze_height);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("sky_haze_smoothing")), _definition.haze_smoothing);
_redrawColorGradation(GTK_IMAGE(GET_WIDGET("sky_colorgradient_sun")), &_definition.sun_color);
_redrawColorGradation(GTK_IMAGE(GET_WIDGET("sky_colorgradient_zenith")),& _definition.zenith_color);
_redrawColorGradation(GTK_IMAGE(GET_WIDGET("sky_colorgradient_haze")), &_definition.haze_color);
_updatePreview();
}
static void _cbApplyConfig(GtkWidget* widget, gpointer data)
{
skySetDefinition(_definition);
guiUpdate();
}
void guiSkyInit()
{
_definition = skyCreateDefinition();
/* Buttons */
g_signal_connect(GET_WIDGET("sky_apply"), "clicked", G_CALLBACK(_cbApplyConfig), NULL);
g_signal_connect(GET_WIDGET("sky_revert"), "clicked", G_CALLBACK(_cbRevertConfig), NULL);
/* Configs */
gtk_range_set_range(GTK_RANGE(GET_WIDGET("sky_daytime")), 0.0, 1.0);
gtk_range_set_range(GTK_RANGE(GET_WIDGET("sky_sun_size")), 0.0, 0.3);
gtk_range_set_range(GTK_RANGE(GET_WIDGET("sky_haze_height")), 0.0, 1.0);
gtk_range_set_range(GTK_RANGE(GET_WIDGET("sky_haze_smoothing")), 0.0, 1.0);
/* Config signals */
g_signal_connect(GET_WIDGET("sky_daytime"), "value-changed", G_CALLBACK(_cbDaytimeChanged), NULL);
g_signal_connect(GET_WIDGET("sky_sun_size"), "value-changed", G_CALLBACK(_cbSunSizeChanged), NULL);
g_signal_connect(GET_WIDGET("sky_haze_height"), "value-changed", G_CALLBACK(_cbHazeHeightChanged), NULL);
g_signal_connect(GET_WIDGET("sky_haze_smoothing"), "value-changed", G_CALLBACK(_cbHazeSmoothingChanged), NULL);
/* Previews */
_preview_horizon = guiPreviewNew(GTK_IMAGE(GET_WIDGET("sky_preview_horizon")));
guiPreviewConfigScaling(_preview_horizon, 0.01, 0.01, 0.0);
guiPreviewConfigScrolling(_preview_horizon, 0.0, 0.0, 0.0, 0.0);
guiPreviewSetViewport(_preview_horizon, 0.0, 0.0, 0.01);
guiPreviewSetRenderer(_preview_horizon, _cbPreviewHorizon);
guiSkyUpdate();
}
void guiSkyUpdate()
{
_cbRevertConfig(NULL, NULL);
}

View file

@ -1,45 +0,0 @@
/* Terrain tab */
#include "common.h"
#include "lib_paysages/shared/functions.h"
#include "lib_paysages/terrain.h"
#include "lib_paysages/textures.h"
static SmallPreview* _preview;
static TerrainDefinition _definition;
static Color _cbPreviewRenderPixel(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
{
Color result;
result.r = result.g = result.b = terrainGetHeightNormalized(x, y);
result.a = 1.0;
return result;
}
static void _cbEditNoiseDone(NoiseGenerator* generator)
{
noiseCopy(generator, _definition.height_noise);
terrainSetDefinition(_definition);
/* TODO Redraw only affected by terrain */
guiPreviewRedrawAll();
}
static void _cbEditNoise(GtkWidget* widget, gpointer data)
{
guiNoiseEdit(_definition.height_noise, _cbEditNoiseDone);
}
void guiTerrainInit()
{
g_signal_connect(GET_WIDGET("terrain_noise_edit"), "clicked", G_CALLBACK(_cbEditNoise), NULL);
_preview = guiPreviewNew(GTK_IMAGE(GET_WIDGET("terrain_preview")));
guiPreviewConfigScaling(_preview, 0.01, 1.0, 0.05);
guiPreviewConfigScrolling(_preview, -1000.0, 1000.0, -1000.0, 1000.0);
guiPreviewSetViewport(_preview, 0.0, 0.0, 0.2);
guiPreviewSetRenderer(_preview, _cbPreviewRenderPixel);
}

View file

@ -1,234 +0,0 @@
/* Terrain tab */
#include "common.h"
#include "lib_paysages/shared/functions.h"
#include "lib_paysages/shared/constants.h"
#include "lib_paysages/water.h"
#include "lib_paysages/terrain.h"
#include <math.h>
static SmallPreview* _preview_coverage;
static SmallPreview* _preview_render;
static WaterDefinition _definition;
static RayCastingResult _rayCastFromWater(Vector3 start, Vector3 direction)
{
RayCastingResult result;
double x, y;
result.hit = 1;
if (direction.z < 0.0001)
{
result.hit_color = COLOR_WHITE;
}
else
{
x = start.x + direction.x * (0.0 - start.z) / direction.z;
y = start.y + direction.y * (0.0 - start.z) / direction.z;
if (((int)ceil(x * 0.2) % 2 == 0) ^ ((int)ceil(y * 0.2 - 0.5) % 2 == 0))
{
result.hit_color = COLOR_WHITE;
}
else
{
result.hit_color = COLOR_GREY;
}
}
/* TODO hit_location */
return result;
}
static Color _cbPreviewCoverage(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
{
Color result;
double height;
height = terrainGetHeight(x, y);
if (height <= _definition.height)
{
return _definition.main_color;
}
else
{
result.r = result.g = result.b = terrainGetHeightNormalized(x, y);
result.a = 1.0;
return result;
}
}
static Color _cbPreviewRender(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
{
Vector3 eye, look, location;
WaterDefinition definition;
WaterEnvironment environment;
WaterQuality quality;
eye.x = 0.0;
eye.y = scaling;
eye.z = -10.0 * scaling;
look.x = x * 0.01 / scaling;
look.y = -y * 0.01 / scaling - 0.3;
look.z = 1.0;
look = v3Normalize(look);
if (look.y > -0.0001)
{
return _rayCastFromWater(eye, look).hit_color;
}
location.x = eye.x - look.x * eye.y / look.y;
location.y = 0.0;
location.z = eye.z - look.z * eye.y / look.y;
if (location.z > 0.0)
{
return _rayCastFromWater(eye, look).hit_color;
}
definition = _definition;
definition.height = 0.0;
environment.reflection_function = _rayCastFromWater;
environment.refraction_function = _rayCastFromWater;
environment.toggle_fog = 0;
quality.force_detail = 0.0001;
return waterGetColorCustom(location, look, &definition, &quality, &environment).final;
}
static void _cbEditNoiseDone(NoiseGenerator* generator)
{
noiseCopy(generator, _definition.waves_noise);
guiPreviewRedraw(_preview_render);
}
static void _cbEditNoise(GtkWidget* widget, gpointer data)
{
guiNoiseEdit(_definition.waves_noise, _cbEditNoiseDone);
}
static void _cbHeightChanged(GtkRange* range, gpointer data)
{
_definition.height = gtk_range_get_value(range);
guiPreviewRedraw(_preview_coverage);
}
static void _cbTransparencyChanged(GtkRange* range, gpointer data)
{
_definition.transparency = gtk_range_get_value(range);
guiPreviewRedraw(_preview_render);
}
static void _cbReflectionChanged(GtkRange* range, gpointer data)
{
_definition.reflection = gtk_range_get_value(range);
guiPreviewRedraw(_preview_render);
}
static void _cbTransparencyDepthChanged(GtkRange* range, gpointer data)
{
_definition.transparency_depth = gtk_range_get_value(range);
guiPreviewRedraw(_preview_render);
}
static void _cbColorChanged(GtkColorButton* colorbutton, gpointer data)
{
GdkColor col;
gtk_color_button_get_color(colorbutton, &col);
_definition.main_color.r = (double)col.red / 65535.0;
_definition.main_color.g = (double)col.green / 65535.0;
_definition.main_color.b = (double)col.blue / 65535.0;
_definition.main_color.a = 1.0;
guiPreviewRedraw(_preview_render);
guiPreviewRedraw(_preview_coverage);
}
static void _cbColorDepthChanged(GtkColorButton* colorbutton, gpointer data)
{
GdkColor col;
gtk_color_button_get_color(colorbutton, &col);
_definition.depth_color.r = (double)col.red / 65535.0;
_definition.depth_color.g = (double)col.green / 65535.0;
_definition.depth_color.b = (double)col.blue / 65535.0;
_definition.depth_color.a = 1.0;
guiPreviewRedraw(_preview_render);
guiPreviewRedraw(_preview_coverage);
}
static void _cbRevertConfig(GtkWidget* widget, gpointer data)
{
GdkColor col;
waterCopyDefinition(waterGetDefinition(), &_definition);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("water_height")), _definition.height);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("water_transparency")), _definition.transparency);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("water_reflection")), _definition.reflection);
gtk_range_set_value(GTK_RANGE(GET_WIDGET("water_transparency_depth")), _definition.transparency_depth);
col.red = _definition.main_color.r * 65535.0;
col.green = _definition.main_color.g * 65535.0;
col.blue = _definition.main_color.b * 65535.0;
gtk_color_button_set_color(GTK_COLOR_BUTTON(GET_WIDGET("water_color")), &col);
col.red = _definition.depth_color.r * 65535.0;
col.green = _definition.depth_color.g * 65535.0;
col.blue = _definition.depth_color.b * 65535.0;
gtk_color_button_set_color(GTK_COLOR_BUTTON(GET_WIDGET("water_color_depth")), &col);
guiPreviewRedraw(_preview_render);
guiPreviewRedraw(_preview_coverage);
}
static void _cbApplyConfig(GtkWidget* widget, gpointer data)
{
waterSetDefinition(_definition);
guiUpdate();
}
void guiWaterInit()
{
_definition = waterCreateDefinition();
/* Buttons */
g_signal_connect(GET_WIDGET("water_noise_edit"), "clicked", G_CALLBACK(_cbEditNoise), NULL);
g_signal_connect(GET_WIDGET("water_apply"), "clicked", G_CALLBACK(_cbApplyConfig), NULL);
g_signal_connect(GET_WIDGET("water_revert"), "clicked", G_CALLBACK(_cbRevertConfig), NULL);
/* Configs */
gtk_range_set_range(GTK_RANGE(GET_WIDGET("water_height")), -20.0, 20.0);
gtk_range_set_range(GTK_RANGE(GET_WIDGET("water_transparency")), 0.0, 1.0);
gtk_range_set_range(GTK_RANGE(GET_WIDGET("water_reflection")), 0.0, 1.0);
gtk_range_set_range(GTK_RANGE(GET_WIDGET("water_transparency_depth")), 0.0, 100.0);
/* Config signals */
g_signal_connect(GET_WIDGET("water_height"), "value-changed", G_CALLBACK(_cbHeightChanged), NULL);
g_signal_connect(GET_WIDGET("water_transparency"), "value-changed", G_CALLBACK(_cbTransparencyChanged), NULL);
g_signal_connect(GET_WIDGET("water_transparency_depth"), "value-changed", G_CALLBACK(_cbTransparencyDepthChanged), NULL);
g_signal_connect(GET_WIDGET("water_reflection"), "value-changed", G_CALLBACK(_cbReflectionChanged), NULL);
g_signal_connect(GET_WIDGET("water_color"), "color-set", G_CALLBACK(_cbColorChanged), NULL);
g_signal_connect(GET_WIDGET("water_color_depth"), "color-set", G_CALLBACK(_cbColorDepthChanged), NULL);
/* Previews */
_preview_coverage = guiPreviewNew(GTK_IMAGE(GET_WIDGET("water_preview_coverage")));
guiPreviewConfigScaling(_preview_coverage, 0.01, 1.0, 0.05);
guiPreviewConfigScrolling(_preview_coverage, -1000.0, 1000.0, -1000.0, 1000.0);
guiPreviewSetViewport(_preview_coverage, 0.0, 0.0, 0.2);
guiPreviewSetRenderer(_preview_coverage, _cbPreviewCoverage);
_preview_render = guiPreviewNew(GTK_IMAGE(GET_WIDGET("water_preview_render")));
guiPreviewConfigScaling(_preview_render, 0.1, 1.0, 0.1);
guiPreviewConfigScrolling(_preview_render, -10.0, 10.0, -10.0, 10.0);
guiPreviewSetViewport(_preview_render, 0.0, 0.0, 0.5);
guiPreviewSetRenderer(_preview_render, _cbPreviewRender);
guiWaterUpdate();
}
void guiWaterUpdate()
{
_cbRevertConfig(NULL, NULL);
}

View file

@ -80,6 +80,7 @@ void BaseForm::revertConfig()
void BaseForm::applyConfig()
{
revertConfig();
}
void BaseForm::addPreview(Preview* preview, QString label)

View file

@ -6,6 +6,7 @@
#include "preview.h"
#include "baseinput.h"
#include "../lib_paysages/shared/types.h"
#include "../lib_paysages/noise.h"
class BaseForm:public QWidget
{

View file

@ -9,8 +9,6 @@
#include <QScrollArea>
#include <QPushButton>
#include "../lib_paysages/shared/functions.h"
/**************** Previews ****************/
class PreviewLevel:public Preview
{

View file

@ -5,7 +5,7 @@
#include <QListWidget>
#include "preview.h"
#include "../lib_paysages/shared/types.h"
#include "../lib_paysages/noise.h"
class DialogNoise : public QDialog
{
@ -13,7 +13,7 @@ class DialogNoise : public QDialog
public:
explicit DialogNoise(QWidget* parent, NoiseGenerator* noise);
~DialogNoise();
static bool getNoise(QWidget* parent, NoiseGenerator* noise);
public slots:
@ -32,7 +32,7 @@ private slots:
void levelChanged(int row);
void heightChanged(int value);
void scalingChanged(int value);
private:
NoiseGenerator* _base;
NoiseGenerator* _current;

View file

@ -24,7 +24,7 @@ protected:
{
double height;
height = terrainGetHeightNormalized(x, y);
height = terrainGetHeightNormalizedCustom(x, y, &_definition);
return QColor((int)(255.0 * height), (int)(255.0 * height), (int)(255.0 * height));
}
};
@ -35,7 +35,11 @@ public:
PreviewTerrainColor(QWidget* parent):
Preview(parent)
{
_lighting_environment.filter = NULL;
_environment.toggle_fog = 0;
_environment.lighting_definition = NULL;
_environment.lighting_environment = &_lighting_environment;
}
protected:
QColor getColor(double x, double y)
@ -43,6 +47,7 @@ protected:
return colorToQColor(terrainGetColorCustom(x, y, scaling, &_definition, NULL, &_environment));
}
private:
LightingEnvironment _lighting_environment;
TerrainEnvironment _environment;
};
@ -54,10 +59,12 @@ FormTerrain::FormTerrain(QWidget *parent):
previewHeight = new PreviewTerrainHeight(this);
previewColor = new PreviewTerrainColor(this);
addPreview(previewHeight, QString("Height preview"));
addPreview(previewColor, QString("Color preview"));
addPreview(previewHeight, QString("Height preview (normalized)"));
addPreview(previewColor, QString("Textured preview (no shadow)"));
addInputNoise("Height", _definition.height_noise);
addInputNoise("Noise", _definition.height_noise);
addInputDouble("Height", &_definition.height_factor, 0.0, 20.0, 0.1, 1.0);
addInputDouble("Scaling", &_definition.scaling, 1.0, 20.0, 0.1, 1.0);
revertConfig();
}
@ -73,3 +80,9 @@ void FormTerrain::applyConfig()
terrainSetDefinition(_definition);
BaseForm::applyConfig();
}
void FormTerrain::applyConfigPreview()
{
terrainValidateDefinition(&_definition);
BaseForm::applyConfigPreview();
}

View file

@ -16,6 +16,9 @@ public slots:
virtual void revertConfig();
virtual void applyConfig();
protected slots:
virtual void applyConfigPreview();
private:
Preview* previewHeight;
Preview* previewColor;

View file

@ -51,6 +51,7 @@ protected:
Vector3 eye, look, location;
WaterDefinition definition;
WaterEnvironment environment;
LightingEnvironment lighting_environment;
WaterQuality quality;
Color result;
@ -80,11 +81,12 @@ protected:
definition = _definition;
definition.height = 0.0;
lighting_environment.filter = NULL;
environment.reflection_function = (RayCastingFunction)(&this->rayCastFromWater);
environment.refraction_function = (RayCastingFunction)(&this->rayCastFromWater);
environment.toggle_fog = 0;
environment.lighting_definition = NULL;
environment.lighting_environment = NULL;
environment.lighting_environment = &lighting_environment;
quality.force_detail = 0.0001;
quality.detail_boost = 1.0;

View file

@ -4,7 +4,7 @@
#include <QWidget>
#include "baseinput.h"
#include "../lib_paysages/shared/types.h"
#include "../lib_paysages/noise.h"
class InputNoise:public BaseInput
{

View file

@ -2,7 +2,9 @@
#include <QApplication>
#include <QMenuBar>
#include <QMenu>
#include <QFileDialog>
#include <QTabWidget>
#include "formterrain.h"
#include "formwater.h"

View file

@ -16,6 +16,7 @@
#include "terrain.h"
#include "textures.h"
#include "lighting.h"
#include "scenery.h"
#ifdef WIN32
#include <windows.h>
@ -80,53 +81,25 @@ void autoSetDaytimeFraction(double daytime)
sun = colorGradationGet(&grad_sun, daytime);
lightingSetSunColor(sun);*/
sky = skyGetDefinition();
sky = skyCreateDefinition();
sceneryGetSky(&sky);
sky.daytime = daytime;
skySetDefinition(sky);
lightingValidateDefinition(NULL);
scenerySetSky(&sky);
skyDeleteDefinition(&sky);
fogSetColor(colorGradationGet(&sky.haze_color, daytime));
}
void autoSetRenderQuality(int quality)
{
TerrainQuality terrain;
WaterQuality water;
CloudsQuality clouds;
if (quality < 1)
{
quality = 1;
}
if (quality > 10)
{
quality = 10;
}
renderSetQuality(quality);
terrain.min_chunk_size = 0.1 / (double)render_quality;
terrain.visible_chunk_size = 0.05 / (double)render_quality;
terrainSetQuality(terrain);
water.detail_boost = 5.0;
water.force_detail = 0.0;
waterSetQuality(water);
clouds.precision = 3.3 - 0.3 * (double)render_quality;
cloudsSetQuality(clouds);
}
void autoGenRealisticLandscape(int seed)
{
TerrainDefinition terrain;
WaterDefinition water;
CloudsDefinition cloud;
CloudsDefinition clouds;
CloudsLayerDefinition* cloud;
SkyDefinition sky;
TextureDefinition texture;
TexturesDefinition textures;
TextureLayerDefinition* texture;
LightingDefinition lighting;
int layer;
HeightModifier* mod;
Zone* zone;
@ -137,33 +110,34 @@ void autoGenRealisticLandscape(int seed)
srand(seed);
/* Cloud layer */
cloud = cloudsCreateDefinition();
cloud.ymin = 10.0;
cloud.ycenter = 40.0;
cloud.ymax = 100.0;
cloud.color = COLOR_WHITE;
cloud.color.a = 0.1;
cloud.scaling = 50.0;
cloud.coverage = 0.5;
noiseGenerateBaseNoise(cloud.noise, 262144);
noiseAddLevelSimple(cloud.noise, 50.0, 0.3);
noiseAddLevelSimple(cloud.noise, 50.0 / 2.0, 0.2);
noiseAddLevelSimple(cloud.noise, 50.0 / 4.0, 0.1);
noiseAddLevelSimple(cloud.noise, 50.0 / 10.0, 0.05);
noiseAddLevelSimple(cloud.noise, 50.0 / 20.0, 0.03);
noiseAddLevelSimple(cloud.noise, 50.0 / 40.0, 0.02);
noiseAddLevelSimple(cloud.noise, 50.0 / 60.0, 0.01);
noiseAddLevelSimple(cloud.noise, 50.0 / 80.0, 0.005);
noiseAddLevelSimple(cloud.noise, 50.0 / 100.0, 0.02);
noiseAddLevelSimple(cloud.noise, 50.0 / 150.0, 0.005);
noiseAddLevelSimple(cloud.noise, 50.0 / 200.0, 0.003);
noiseAddLevelSimple(cloud.noise, 50.0 / 400.0, 0.008);
noiseAddLevelSimple(cloud.noise, 50.0 / 800.0, 0.001);
noiseAddLevelSimple(cloud.noise, 50.0 / 1000.0, 0.0005);
layer = cloudsAddLayer();
cloudsSetDefinition(layer, cloud);
clouds = cloudsCreateDefinition();
cloud = cloudsGetLayer(&clouds, cloudsAddLayer(&clouds));
cloud->ymin = 10.0;
cloud->ycenter = 40.0;
cloud->ymax = 100.0;
cloud->color = COLOR_WHITE;
cloud->color.a = 0.1;
cloud->scaling = 50.0;
cloud->coverage = 0.5;
noiseGenerateBaseNoise(cloud->noise, 262144);
noiseAddLevelSimple(cloud->noise, 50.0, 0.3);
noiseAddLevelSimple(cloud->noise, 50.0 / 2.0, 0.2);
noiseAddLevelSimple(cloud->noise, 50.0 / 4.0, 0.1);
noiseAddLevelSimple(cloud->noise, 50.0 / 10.0, 0.05);
noiseAddLevelSimple(cloud->noise, 50.0 / 20.0, 0.03);
noiseAddLevelSimple(cloud->noise, 50.0 / 40.0, 0.02);
noiseAddLevelSimple(cloud->noise, 50.0 / 60.0, 0.01);
noiseAddLevelSimple(cloud->noise, 50.0 / 80.0, 0.005);
noiseAddLevelSimple(cloud->noise, 50.0 / 100.0, 0.02);
noiseAddLevelSimple(cloud->noise, 50.0 / 150.0, 0.005);
noiseAddLevelSimple(cloud->noise, 50.0 / 200.0, 0.003);
noiseAddLevelSimple(cloud->noise, 50.0 / 400.0, 0.008);
noiseAddLevelSimple(cloud->noise, 50.0 / 800.0, 0.001);
noiseAddLevelSimple(cloud->noise, 50.0 / 1000.0, 0.0005);
scenerySetClouds(&clouds);
/* Water */
water = waterCreateDefinition();
water.height = 0.0;
water.transparency = 0.5;
water.reflection = 0.3;
@ -176,28 +150,25 @@ void autoGenRealisticLandscape(int seed)
water.depth_color.g = 0.2;
water.depth_color.b = 0.3;
water.depth_color.a = 1.0;
water.waves_noise = noiseCreateGenerator();
water.waves_noise_height = 0.015;
water.waves_noise_scale = 0.2;
noiseGenerateBaseNoise(water.waves_noise, 262144);
noiseAddLevelsSimple(water.waves_noise, 2, 1.0, 1.0);
noiseAddLevelsSimple(water.waves_noise, 3, 0.15, 0.1);
waterSetDefinition(water);
noiseDeleteGenerator(water.waves_noise);
scenerySetWater(&water);
waterDeleteDefinition(&water);
/* Sky */
sky.sun_color = colorGradationCreate();
sky = skyCreateDefinition();
colorGradationAddRgba(&sky.sun_color, 0.3, 1.0, 0.91, 0.8, 1.0);
colorGradationAddRgba(&sky.sun_color, 0.5, 1.0, 0.95, 0.9, 1.0);
colorGradationAddRgba(&sky.sun_color, 0.7, 1.0, 0.91, 0.8, 1.0);
sky.zenith_color = colorGradationCreate();
colorGradationAddRgba(&sky.zenith_color, 0.2, 0.03, 0.03, 0.05, 1.0);
colorGradationAddRgba(&sky.zenith_color, 0.25, 0.25, 0.33, 0.37, 1.0);
colorGradationAddRgba(&sky.zenith_color, 0.35, 0.52, 0.63, 0.8, 1.0);
colorGradationAddRgba(&sky.zenith_color, 0.65, 0.52, 0.63, 0.8, 1.0);
colorGradationAddRgba(&sky.zenith_color, 0.75, 0.25, 0.33, 0.37, 1.0);
colorGradationAddRgba(&sky.zenith_color, 0.8, 0.03, 0.03, 0.05, 1.0);
sky.haze_color = colorGradationCreate();
colorGradationAddRgba(&sky.haze_color, 0.2, 0.05, 0.05, 0.08, 1.0);
colorGradationAddRgba(&sky.haze_color, 0.25, 0.55, 0.42, 0.42, 1.0);
colorGradationAddRgba(&sky.haze_color, 0.3, 0.6, 0.6, 0.6, 1.0);
@ -210,18 +181,21 @@ void autoGenRealisticLandscape(int seed)
sky.haze_height = 0.75;
sky.haze_smoothing = 0.3;
sky.sun_radius = 0.02;
skySetDefinition(sky);
scenerySetSky(&sky);
skyDeleteDefinition(&sky);
/* Lighting */
lighting = lightingCreateDefinition();
lighting.autosetfromsky = 1;
lightingSetDefinition(lighting);
scenerySetLighting(&lighting);
lightingDeleteDefinition(&lighting);
/* Terrain */
terrain = terrainCreateDefinition();
noiseGenerateBaseNoise(terrain.height_noise, 1048576);
noiseAddLevelsSimple(terrain.height_noise, 10, 10.0, 1.0);
noiseNormalizeHeight(terrain.height_noise, -12.0, 12.0, 0);
noiseAddLevelsSimple(terrain.height_noise, 10, 1.0, 1.0);
terrain.height_factor = 12.0 / noiseGetMaxValue(terrain.height_noise);
terrain.scaling = 10.0;
/* DEBUG */
mod = modifierCreate();
zone = modifierGetZone(mod);
@ -241,42 +215,36 @@ void autoGenRealisticLandscape(int seed)
modifierActionFixValue(mod, -8.0);
terrainAddModifier(&terrain, mod);
/* DEBUG */
terrainSetDefinition(terrain);
terrainDeleteDefinition(terrain);
scenerySetTerrain(&terrain);
terrainDeleteDefinition(&terrain);
/* Textures */
layer = texturesAddLayer();
texture = texturesCreateDefinition();
noiseGenerateBaseNoise(texture.bump_noise, 102400);
noiseAddLevelsSimple(texture.bump_noise, 6, 0.01, 0.01);
texture.color.r = 0.6;
texture.color.g = 0.55;
texture.color.b = 0.57;
texturesSetDefinition(layer, texture);
texturesDeleteDefinition(texture);
layer = texturesAddLayer();
texture = texturesCreateDefinition();
zoneAddHeightRange(texture.zone, 1.0, -1.0, 0.0, 3.0, 15.0);
zoneAddSteepnessRange(texture.zone, 1.0, 0.0, 0.0, 0.3, 0.4);
noiseGenerateBaseNoise(texture.bump_noise, 102400);
noiseAddLevelsSimple(texture.bump_noise, 6, 0.02, 0.008);
texture.color.r = 0.2;
texture.color.g = 0.24;
texture.color.b = 0.05;
texturesSetDefinition(layer, texture);
texturesDeleteDefinition(texture);
/*layer = texturesAddLayer();
texture = texturesCreateDefinition();
zoneAddHeightRange(texture.zone, 1.0, 3.0, 4.0, 100.0, 100.0);
noiseGenerateBaseNoise(texture.bump_noise, 102400);
noiseAddLevelsSimple(texture.bump_noise, 6, 0.04, 0.003);
texture.color.r = 1.0;
texture.color.g = 1.0;
texture.color.b = 1.0;
textures = texturesCreateDefinition();
texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
noiseGenerateBaseNoise(texture->bump_noise, 102400);
noiseAddLevelsSimple(texture->bump_noise, 6, 0.01, 0.01);
texture->color.r = 0.6;
texture->color.g = 0.55;
texture->color.b = 0.57;
texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
zoneAddHeightRange(texture->zone, 1.0, -1.0, 0.0, 3.0, 15.0);
zoneAddSteepnessRange(texture->zone, 1.0, 0.0, 0.0, 0.3, 0.4);
noiseGenerateBaseNoise(texture->bump_noise, 102400);
noiseAddLevelsSimple(texture->bump_noise, 6, 0.02, 0.008);
texture->color.r = 0.2;
texture->color.g = 0.24;
texture->color.b = 0.05;
/*texture = texturesGetLayer(&textures, texturesAddLayer(&textures));
zoneAddHeightRange(texture->zone, 1.0, 3.0, 4.0, 100.0, 100.0);
noiseGenerateBaseNoise(texture->bump_noise, 102400);
noiseAddLevelsSimple(texture->bump_noise, 6, 0.04, 0.003);
texture->color.r = 1.0;
texture->color.g = 1.0;
texture->color.b = 1.0;
texturesSetDefinition(layer, texture);
texturesDeleteDefinition(texture);*/
scenerySetTextures(&textures);
texturesDeleteDefinition(&textures);
/* Fog */
fogSetDistance(20.0, 100.0);
@ -342,23 +310,25 @@ static int _postProcessRayTracingOverlay(RenderFragment* fragment)
{
Vector3 terrain_hit, look;
look = v3Sub(fragment->vertex.location, camera_location);
// TODO
/*look = v3Sub(fragment->vertex.location, camera_location);
if (!terrainProjectRay(camera_location, look, &terrain_hit, &fragment->vertex.color))
{
fragment->vertex.color = skyProjectRay(camera_location, look);
}
}*/
return 1;
}
void autoRenderSceneRayTracing()
{
renderClear();
// TODO
/*renderClear();
cameraPushOverlay(COLOR_RED, _postProcessRayTracingOverlay);
renderUpdate();
if (renderSetNextProgressStep(0.0, 1.0))
{
renderPostProcess(_cpu_count);
}
}*/
}

View file

@ -1,3 +1,5 @@
#include "camera.h"
#include <stdlib.h>
#include <math.h>
@ -6,71 +8,102 @@
#include "shared/constants.h"
#include "shared/functions.h"
Vector3 camera_location;
static Vector3 camera_target;
static Vector3 camera_up;
static Matrix4 matrix_project;
static Matrix4 matrix_project_inverse;
void cameraInit()
{
}
static void __updateMatrix()
void cameraSave(FILE* f, CameraDefinition* camera)
{
v3Save(camera->location, f);
v3Save(camera->target, f);
}
void cameraLoad(FILE* f, CameraDefinition* camera)
{
camera->location = v3Load(f);
camera->target = v3Load(f);
cameraValidateDefinition(camera);
}
CameraDefinition cameraCreateDefinition()
{
CameraDefinition definition;
definition.location.x = -1.0;
definition.location.y = 0.0;
definition.location.z = 0.0;
definition.target.x = 0.0;
definition.target.y = 0.0;
definition.target.z = 0.0;
cameraValidateDefinition(&definition);
return definition;
}
void cameraDeleteDefinition(CameraDefinition* definition)
{
}
void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination)
{
*destination = *source;
}
void cameraValidateDefinition(CameraDefinition* definition)
{
/* TODO Recompute up vector */
camera_up.x = 0.0;
camera_up.y = 1.0;
camera_up.z = 0.0;
definition->up.x = 0.0;
definition->up.y = 1.0;
definition->up.z = 0.0;
matrix_project = m4Mult(m4NewPerspective(1.57, 1.333333, 1.0, 1000.0), m4NewLookAt(VECTOR_ZERO, v3Sub(camera_target, camera_location), camera_up));
matrix_project_inverse = m4Inverse(matrix_project);
definition->project = m4Mult(m4NewPerspective(1.57, 1.333333, 1.0, 1000.0), m4NewLookAt(VECTOR_ZERO, v3Sub(definition->target, definition->location), definition->up));
definition->unproject = m4Inverse(definition->project);
}
void cameraSave(FILE* f)
void cameraSetLocation(CameraDefinition* camera, double x, double y, double z)
{
camera->location.x = x;
camera->location.y = y;
camera->location.z = z;
cameraValidateDefinition(camera);
}
void cameraLoad(FILE* f)
void cameraSetTarget(CameraDefinition* camera, double x, double y, double z)
{
camera->target.x = x;
camera->target.y = y;
camera->target.z = z;
cameraValidateDefinition(camera);
}
void cameraSetLocation(double x, double y, double z)
{
camera_location.x = x;
camera_location.y = y;
camera_location.z = z;
__updateMatrix();
}
void cameraSetTarget(double x, double y, double z)
{
camera_target.x = x;
camera_target.y = y;
camera_target.z = z;
__updateMatrix();
}
void cameraSetAngle(double angle)
void cameraSetAngle(CameraDefinition* camera, double angle)
{
/* TODO */
}
Vector3 cameraProject(Vector3 point)
Vector3 cameraProject(CameraDefinition* camera, Vector3 point)
{
point = m4Transform(matrix_project, v3Sub(point, camera_location));
point = m4Transform(camera->project, v3Sub(point, camera->location));
point.x = (-point.x + 1.0) * 0.5 * (double)render_width;
point.y = (-point.y + 1.0) * 0.5 * (double)render_height;
return point;
}
Vector3 cameraUnproject(Vector3 point)
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point)
{
point.x = -(point.x / (0.5 * (double)render_width) - 1.0);
point.y = -(point.y / (0.5 * (double)render_height) - 1.0);
return v3Add(m4Transform(matrix_project_inverse, point), camera_location);
return v3Add(m4Transform(camera->unproject, point), camera->location);
}
void cameraProjectToFragment(double x, double y, double z, RenderFragment* result)
void cameraProjectToFragment(CameraDefinition* camera, double x, double y, double z, RenderFragment* result)
{
Vector3 point = {x, y, z};
point = m4Transform(matrix_project, v3Sub(point, camera_location));
point = m4Transform(camera->project, v3Sub(point, camera->location));
result->x = lround((-point.x + 1.0) * 0.5 * (double)render_width);
result->y = lround((-point.y + 1.0) * 0.5 * (double)render_height);
result->z = point.z;
@ -79,42 +112,42 @@ void cameraProjectToFragment(double x, double y, double z, RenderFragment* resul
/**
* Render a quad that will fill the view in front of the camera.
* This quad can be used for post-processing.
*
*
* @param col Color of the polygon.
* @param callback Post-processing callback.
*/
void cameraPushOverlay(Color col, f_RenderFragmentCallback callback)
void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCallback callback)
{
Vertex v1, v2, v3, v4;
Vector3 v;
v.x = 0.0;
v.y = 0.0;
v.z = 10.0;
v1.location = cameraUnproject(v);
v1.location = cameraUnproject(camera, v);
v1.color = col;
v1.callback = callback;
v.x = 0.0;
v.y = (double)render_height;
v.z = 10.0;
v2.location = cameraUnproject(v);
v2.location = cameraUnproject(camera, v);
v2.color = col;
v2.callback = callback;
v.x = (double)render_width;
v.y = (double)render_height;
v.z = 10.0;
v3.location = cameraUnproject(v);
v3.location = cameraUnproject(camera, v);
v3.color = col;
v3.callback = callback;
v.x = (double)render_width;
v.y = 0.0;
v.z = 10.0;
v4.location = cameraUnproject(v);
v4.location = cameraUnproject(camera, v);
v4.color = col;
v4.callback = callback;
renderPushQuad(&v1, &v2, &v3, &v4);
}

41
lib_paysages/camera.h Normal file
View file

@ -0,0 +1,41 @@
#ifndef _PAYSAGES_CAMERA_H_
#define _PAYSAGES_CAMERA_H_
#include "shared/types.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
Vector3 location;
Vector3 target;
Vector3 up;
Matrix4 project;
Matrix4 unproject;
} CameraDefinition;
void cameraInit();
void cameraSave(FILE* f, CameraDefinition* camera);
void cameraLoad(FILE* f, CameraDefinition* camera);
CameraDefinition cameraCreateDefinition();
void cameraDeleteDefinition(CameraDefinition* definition);
void cameraCopyDefinition(CameraDefinition* source, CameraDefinition* destination);
void cameraValidateDefinition(CameraDefinition* definition);
void cameraSetLocation(CameraDefinition* camera, double x, double y, double z);
void cameraSetTarget(CameraDefinition* camera, double x, double y, double z);
void cameraSetAngle(CameraDefinition* camera, double angle);
Vector3 cameraProject(CameraDefinition* camera, Vector3 point);
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point);
void cameraProjectToFragment(CameraDefinition* camera, double x, double y, double z, RenderFragment* result);
void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCallback callback);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -9,13 +9,6 @@
#include "shared/constants.h"
#include "shared/globals.h"
#define MAX_LAYERS 10
static int _layers_count = 0;
static CloudsDefinition _layers[MAX_LAYERS];
static CloudsQuality _quality;
static CloudsEnvironment _environment;
typedef struct
{
Vector3 start;
@ -23,22 +16,23 @@ typedef struct
double length;
} CloudSegment;
static CloudsLayerDefinition NULL_LAYER;
void cloudsInit()
{
_layers_count = 0;
_quality.precision = 0.5;
NULL_LAYER.noise = noiseCreateGenerator();
NULL_LAYER.coverage = 0.0;
}
void cloudsSave(FILE* f)
void cloudsSave(FILE* f, CloudsDefinition* definition)
{
int i;
CloudsDefinition* layer;
CloudsLayerDefinition* layer;
toolsSaveInt(f, _layers_count);
for (i = 0; i < _layers_count; i++)
toolsSaveInt(f, definition->nblayers);
for (i = 0; i < definition->nblayers; i++)
{
layer = _layers + i;
layer = definition->layers + i;
toolsSaveDouble(f, layer->ycenter);
toolsSaveDouble(f, layer->ymin);
toolsSaveDouble(f, layer->ymax);
@ -49,20 +43,20 @@ void cloudsSave(FILE* f)
}
}
void cloudsLoad(FILE* f)
void cloudsLoad(FILE* f, CloudsDefinition* definition)
{
int i, n;
CloudsDefinition* layer;
CloudsLayerDefinition* layer;
while (_layers_count > 0)
while (definition->nblayers > 0)
{
cloudsDeleteLayer(0);
cloudsDeleteLayer(definition, 0);
}
n = toolsLoadInt(f);
for (i = 0; i < n; i++)
{
layer = _layers + cloudsAddLayer();
layer = definition->layers + cloudsAddLayer(definition);
layer->ycenter = toolsLoadDouble(f);
layer->ymin = toolsLoadDouble(f);
@ -74,107 +68,139 @@ void cloudsLoad(FILE* f)
}
}
int cloudsGetLayerCount()
{
return _layers_count;
}
int cloudsAddLayer()
{
CloudsDefinition* layer;
if (_layers_count < MAX_LAYERS)
{
layer = _layers + _layers_count;
layer->noise = noiseCreateGenerator();
layer->coverage = 0.0;
return _layers_count++;
}
else
{
return _layers_count - 1;
}
}
void cloudsDeleteLayer(int layer)
{
if (layer >= 0 && layer < _layers_count)
{
noiseDeleteGenerator(_layers[layer].noise);
if (_layers_count > 1 && layer < _layers_count - 1)
{
memmove(_layers + layer, _layers + layer + 1, sizeof(CloudsDefinition) * (_layers_count - layer - 1));
}
_layers_count--;
}
}
CloudsDefinition cloudsCreateDefinition()
{
CloudsDefinition result;
result.color = COLOR_WHITE;
result.coverage = 0.0;
result.noise = noiseCreateGenerator();
result.scaling = 1.0;
result.ymin = 0.0;
result.ycenter = 0.0;
result.ymax = 0.0;
result.nblayers = 0;
return result;
}
void cloudsDeleteDefinition(CloudsDefinition definition)
void cloudsDeleteDefinition(CloudsDefinition* definition)
{
noiseDeleteGenerator(definition.noise);
while (definition->nblayers > 0)
{
cloudsDeleteLayer(definition, 0);
}
}
void cloudsCopyDefinition(CloudsDefinition source, CloudsDefinition* destination)
void cloudsCopyDefinition(CloudsDefinition* source, CloudsDefinition* destination)
{
CloudsLayerDefinition* layer;
int i;
while (destination->nblayers > 0)
{
cloudsDeleteLayer(destination, 0);
}
for (i = 0; i < source->nblayers; i++)
{
layer = cloudsGetLayer(destination, cloudsAddLayer(destination));
cloudsLayerCopyDefinition(source->layers + i, layer);
}
}
void cloudsValidateDefinition(CloudsDefinition* definition)
{
int i;
for (i = 0; i < definition->nblayers; i++)
{
cloudsLayerValidateDefinition(&definition->layers[i]);
}
}
CloudsLayerDefinition cloudsLayerCreateDefinition()
{
CloudsLayerDefinition result;
result.color = COLOR_BLACK;
result.coverage = 0.0;
result.noise = noiseCreateGenerator();
result.scaling = 1.0;
result.ymin = 0.0;
result.ycenter = 0.5;
result.ymax = 1.0;
return result;
}
void cloudsLayerDeleteDefinition(CloudsLayerDefinition* definition)
{
noiseDeleteGenerator(definition->noise);
}
void cloudsLayerCopyDefinition(CloudsLayerDefinition* source, CloudsLayerDefinition* destination)
{
NoiseGenerator* noise;
noise = destination->noise;
*destination = source;
*destination = *source;
destination->noise = noise;
noiseCopy(source.noise, destination->noise);
noiseCopy(source->noise, destination->noise);
}
void cloudsSetDefinition(int layer, CloudsDefinition definition)
void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition)
{
CloudsDefinition* destination;
if (layer >= 0 && layer < _layers_count)
if (definition->coverage < 0.5)
{
destination = _layers + layer;
cloudsCopyDefinition(definition, destination);
if (destination->coverage < 0.5)
{
noiseNormalizeHeight(destination->noise, -1.0, destination->coverage * 2.0, 0);
}
else
{
noiseNormalizeHeight(destination->noise, -(1.0 - destination->coverage) * 2.0, 1.0, 0);
}
noiseNormalizeHeight(definition->noise, -1.0, definition->coverage * 2.0, 0);
}
else
{
noiseNormalizeHeight(definition->noise, -(1.0 - definition->coverage) * 2.0, 1.0, 0);
}
}
CloudsDefinition cloudsGetDefinition(int layer)
int cloudsGetLayerCount(CloudsDefinition* definition)
{
return _layers[layer];
return definition->nblayers;
}
void cloudsSetQuality(CloudsQuality quality)
CloudsLayerDefinition* cloudsGetLayer(CloudsDefinition* definition, int layer)
{
_quality = quality;
if (layer >= 0 && layer < definition->nblayers)
{
return definition->layers + layer;
}
else
{
return &NULL_LAYER;
}
}
CloudsQuality cloudsGetQuality()
int cloudsAddLayer(CloudsDefinition* definition)
{
return _quality;
CloudsLayerDefinition* layer;
if (definition->nblayers < CLOUDS_MAX_LAYERS)
{
layer = definition->layers + definition->nblayers;
layer->noise = noiseCreateGenerator();
layer->coverage = 0.0;
return definition->nblayers++;
}
else
{
return -1;
}
}
static inline double _getDistanceToBorder(CloudsDefinition* layer, Vector3 position, double detail)
void cloudsDeleteLayer(CloudsDefinition* definition, int layer)
{
if (layer >= 0 && layer < definition->nblayers)
{
cloudsLayerDeleteDefinition(definition->layers + layer);
if (definition->nblayers > 1 && layer < definition->nblayers - 1)
{
memmove(definition->layers + layer, definition->layers + layer + 1, sizeof(CloudsLayerDefinition) * (definition->nblayers - layer - 1));
}
definition->nblayers--;
}
}
static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3 position, double detail)
{
double val, min;
@ -192,7 +218,7 @@ static inline double _getDistanceToBorder(CloudsDefinition* layer, Vector3 posit
return (val - min) * layer->scaling;
}
static inline Vector3 _getNormal(CloudsDefinition* layer, Vector3 position, double detail)
static inline Vector3 _getNormal(CloudsLayerDefinition* layer, Vector3 position, double detail)
{
Vector3 result = {0.0, 0.0, 0.0};
double val, dval;
@ -217,7 +243,7 @@ static inline Vector3 _getNormal(CloudsDefinition* layer, Vector3 position, doub
dval = val - noiseGet3DDetail(layer->noise, position.x, position.y, position.z - detail, detail);
result.z -= dval;
return result;
return v3Normalize(result);
}
/**
@ -228,7 +254,7 @@ static inline Vector3 _getNormal(CloudsDefinition* layer, Vector3 position, doub
* @param end End of the search to optimize
* @return 0 if the search is useless
*/
static int _optimizeSearchLimits(CloudsDefinition* layer, Vector3* start, Vector3* end)
static int _optimizeSearchLimits(CloudsLayerDefinition* layer, Vector3* start, Vector3* end)
{
Vector3 diff;
@ -285,7 +311,7 @@ static int _optimizeSearchLimits(CloudsDefinition* layer, Vector3* start, Vector
* Go through the cloud layer to find segments (parts of the lookup that are inside the cloud).
*
* @param definition The cloud layer
* @param quality Render quality
* @param renderer The renderer environment
* @param start Start position of the lookup (already optimized)
* @param direction Normalized direction of the lookup
* @param detail Level of noise detail required
@ -297,34 +323,37 @@ static int _optimizeSearchLimits(CloudsDefinition* layer, Vector3* start, Vector
* @param out_segments Allocated space to fill found segments
* @return Number of segments found
*/
static int _findSegments(CloudsDefinition* definition, CloudsQuality* quality, Vector3 start, Vector3 direction, double detail, int max_segments, double max_inside_length, double max_total_length, double* inside_length, double* total_length, CloudSegment* out_segments)
static int _findSegments(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, double detail, int max_segments, double max_inside_length, double max_total_length, double* inside_length, double* total_length, CloudSegment* out_segments)
{
int inside, segment_count;
double current_total_length, current_inside_length;
double step_length, segment_length, remaining_length;
double noise_distance, last_noise_distance;
Vector3 walker, step, segment_start;
double render_precision;
if (max_segments <= 0)
{
return 0;
}
render_precision = 3.3 - 0.3 * (double)renderer->render_quality;
segment_count = 0;
current_total_length = 0.0;
current_inside_length = 0.0;
segment_length = 0.0;
walker = start;
noise_distance = _getDistanceToBorder(definition, start, detail) * quality->precision;
noise_distance = _getDistanceToBorder(definition, start, detail) * render_precision;
inside = (noise_distance > 0.0) ? 1 : 0;
step = v3Scale(direction, quality->precision);
step = v3Scale(direction, render_precision);
do
{
walker = v3Add(walker, step);
step_length = v3Norm(step);
last_noise_distance = noise_distance;
noise_distance = _getDistanceToBorder(definition, walker, detail) * quality->precision;
noise_distance = _getDistanceToBorder(definition, walker, detail) * render_precision;
current_total_length += step_length;
if (noise_distance > 0.0)
@ -334,7 +363,7 @@ static int _findSegments(CloudsDefinition* definition, CloudsQuality* quality, V
// inside the cloud
segment_length += step_length;
current_inside_length += step_length;
step = v3Scale(direction, (noise_distance < quality->precision) ? quality->precision : noise_distance);
step = v3Scale(direction, (noise_distance < render_precision) ? render_precision : noise_distance);
}
else
{
@ -343,7 +372,7 @@ static int _findSegments(CloudsDefinition* definition, CloudsQuality* quality, V
segment_length = step_length * noise_distance / (noise_distance - last_noise_distance);
segment_start = v3Add(walker, v3Scale(direction, -segment_length));
current_inside_length += segment_length;
step = v3Scale(direction, quality->precision);
step = v3Scale(direction, render_precision);
}
}
else
@ -365,12 +394,12 @@ static int _findSegments(CloudsDefinition* definition, CloudsQuality* quality, V
}
inside = 0;
step = v3Scale(direction, quality->precision);
step = v3Scale(direction, render_precision);
}
else
{
// searching for a cloud
step = v3Scale(direction, (noise_distance > -quality->precision) ? quality->precision : -noise_distance);
step = v3Scale(direction, (noise_distance > -render_precision) ? render_precision : -noise_distance);
}
}
} while (inside || (walker.y <= definition->ymax + 0.001 && walker.y >= definition->ymin - 0.001 && current_total_length < max_total_length && current_inside_length < max_inside_length));
@ -380,25 +409,16 @@ static int _findSegments(CloudsDefinition* definition, CloudsQuality* quality, V
return segment_count;
}
typedef struct
{
CloudsDefinition* definition;
CloudsQuality* quality;
Color base;
double detail;
} LightFilterData;
static Color _lightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
/*static Color _lightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
{
double inside_depth, total_depth;
CloudSegment segments[20];
Color result;
LightFilterData data;
data = *((LightFilterData*)custom_data);
data.detail = (data.detail < 0.1) ? 0.1 : data.detail;
/* FIXME Dont hard-code max_total_length */
// FIXME Dont hard-code max_total_length
_findSegments(data.definition, data.quality, location, direction_to_light, data.detail, 20, 50.0, 300.0, &inside_depth, &total_depth, segments);
inside_depth *= 0.02;
@ -407,29 +427,30 @@ static Color _lightFilter(Color light, Vector3 location, Vector3 light_location,
inside_depth = 1.0;
}
result.r = data.base.r * - 0.2 * inside_depth;
result.g = data.base.g * - 0.2 * inside_depth;
result.b = data.base.b * - 0.2 * inside_depth;
light.r = light.r * (1.0 - 0.2 * inside_depth);
light.g = light.g * (1.0 - 0.2 * inside_depth);
light.b = light.b * (1.0 - 0.2 * inside_depth);
return result;
}
return light;
}*/
static Color _applyLayerLighting(CloudsDefinition* definition, CloudsQuality* quality, Vector3 position, Color base, double detail)
static Color _applyLayerLighting(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 position, Color base, double detail)
{
Vector3 normal;
return base;
/*Vector3 normal;
ReceiverMaterial material;
LightingEnvironment lighting_environment;
LightFilterData data;
normal = _getNormal(definition, position, 0.5);
normal = v3Add(normal, _getNormal(definition, position, 0.2));
normal = v3Add(normal, _getNormal(definition, position, 0.1));
//normal = v3Normalize(normal);
normal = v3Scale(_getNormal(definition, position, 1.0), 0.25);
normal = v3Add(normal, v3Scale(_getNormal(definition, position, 0.5), 0.25));
normal = v3Add(normal, v3Scale(_getNormal(definition, position, 0.2), 0.25));
normal = v3Add(normal, v3Scale(_getNormal(definition, position, 0.1), 0.25));
normal = v3Normalize(normal);
data.definition = definition;
data.quality = quality;
data.detail = detail;
data.base = base;
lighting_environment.filter = _lightFilter;
lighting_environment.custom_data = &data;
@ -438,10 +459,10 @@ static Color _applyLayerLighting(CloudsDefinition* definition, CloudsQuality* qu
material.reflection = 0.3;
material.shininess = 0.1;
return lightingApplyCustom(position, normal, material, NULL, NULL, &lighting_environment);
return lightingApplyCustom(position, normal, material, NULL, NULL, &lighting_environment);*/
}
Color cloudsGetColorCustom(Vector3 start, Vector3 end, CloudsDefinition* definition, CloudsQuality* quality, CloudsEnvironment* environment)
Color cloudsGetLayerColor(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 start, Vector3 end)
{
int i, segment_count;
double max_length, detail, total_length, inside_length;
@ -449,15 +470,6 @@ Color cloudsGetColorCustom(Vector3 start, Vector3 end, CloudsDefinition* definit
Color result, col;
CloudSegment segments[20];
if (quality == NULL)
{
quality = &_quality;
}
if (environment == NULL)
{
environment = &_environment;
}
if (!_optimizeSearchLimits(definition, &start, &end))
{
return COLOR_TRANSPARENT;
@ -471,35 +483,35 @@ Color cloudsGetColorCustom(Vector3 start, Vector3 end, CloudsDefinition* definit
/* TODO Flexible precision */
detail = renderGetPrecision(start) / definition->scaling;
segment_count = _findSegments(definition, quality, start, direction, detail, 20, 60.0, max_length, &inside_length, &total_length, segments);
segment_count = _findSegments(definition, renderer, start, direction, detail, 20, 60.0, max_length, &inside_length, &total_length, segments);
for (i = 0; i < segment_count; i++)
{
col = _applyLayerLighting(definition, quality, segments[i].start, definition->color, detail);
col = _applyLayerLighting(definition, renderer, segments[i].start, definition->color, detail);
col.a = (segments[i].length >= 50.0) ? 1.0 : (segments[i].length / 50.0);
colorMask(&result, &col);
}
return result;
}
Color cloudsGetColor(Vector3 start, Vector3 end)
Color cloudsGetColor(CloudsDefinition* definition, Renderer* renderer, Vector3 start, Vector3 end)
{
int i;
Color layer_color, result;
if (end.y < start.y)
{
return cloudsGetColor(end, start);
return cloudsGetColor(definition, renderer, end, start);
}
if (_layers_count < 1 || end.y - start.y < 0.001)
if (definition->nblayers < 1 || end.y - start.y < 0.001)
{
return COLOR_TRANSPARENT;
}
result = COLOR_TRANSPARENT;
for (i = 0; i < _layers_count; i++)
for (i = 0; i < definition->nblayers; i++)
{
layer_color = cloudsGetColorCustom(start, end, _layers + i, &_quality, &_environment);
layer_color = cloudsGetLayerColor(definition->layers + i, renderer, start, end);
if (layer_color.a > 0.0)
{
colorMask(&result, &layer_color);

View file

@ -2,12 +2,16 @@
#define _PAYSAGES_CLOUDS_H_
#include "shared/types.h"
#include "noise.h"
#include "renderer.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define CLOUDS_MAX_LAYERS 6
typedef struct
{
double ycenter;
@ -17,37 +21,35 @@ typedef struct
Color color;
double scaling;
double coverage;
} CloudsLayerDefinition;
typedef struct
{
int nblayers;
CloudsLayerDefinition layers[CLOUDS_MAX_LAYERS];
} CloudsDefinition;
typedef struct
{
double precision;
} CloudsQuality;
typedef struct
{
int unused;
} CloudsEnvironment;
void cloudsInit();
void cloudsSave(FILE* f);
void cloudsLoad(FILE* f);
int cloudsGetLayerCount();
int cloudsAddLayer();
void cloudsDeleteLayer(int layer);
void cloudsSave(FILE* f, CloudsDefinition* definition);
void cloudsLoad(FILE* f, CloudsDefinition* definition);
CloudsDefinition cloudsCreateDefinition();
void cloudsDeleteDefinition(CloudsDefinition definition);
void cloudsCopyDefinition(CloudsDefinition source, CloudsDefinition* destination);
void cloudsSetDefinition(int layer, CloudsDefinition definition);
CloudsDefinition cloudsGetDefinition(int layer);
void cloudsDeleteDefinition(CloudsDefinition* definition);
void cloudsCopyDefinition(CloudsDefinition* source, CloudsDefinition* destination);
void cloudsValidateDefinition(CloudsDefinition* definition);
void cloudsSetQuality(CloudsQuality quality);
CloudsQuality cloudsGetQuality();
CloudsLayerDefinition cloudsLayerCreateDefinition();
void cloudsLayerDeleteDefinition(CloudsLayerDefinition* definition);
void cloudsLayerCopyDefinition(CloudsLayerDefinition* source, CloudsLayerDefinition* destination);
void cloudsLayerValidateDefinition(CloudsLayerDefinition* definition);
Color cloudsGetColorCustom(Vector3 start, Vector3 end, CloudsDefinition* definition, CloudsQuality* quality, CloudsEnvironment* environment);
Color cloudsGetColor(Vector3 start, Vector3 end);
int cloudsGetLayerCount(CloudsDefinition* definition);
CloudsLayerDefinition* cloudsGetLayer(CloudsDefinition* definition, int layer);
int cloudsAddLayer(CloudsDefinition* definition);
void cloudsDeleteLayer(CloudsDefinition* definition, int layer);
Color cloudsGetLayerColor(CloudsLayerDefinition* definition, Renderer* renderer, Vector3 start, Vector3 end);
Color cloudsGetColor(CloudsDefinition* definition, Renderer* renderer, Vector3 start, Vector3 end);
#ifdef __cplusplus
}

View file

@ -27,10 +27,11 @@ void fogSetDistance(double near, double far)
Color fogApplyToLocation(Vector3 location, Color base)
{
Color mask = _col;
// TODO Don't use camera_location
/*Color mask = _col;
double distance = v3Norm(v3Sub(camera_location, location));
double value;
if (distance < _near)
{
return base;
@ -44,6 +45,6 @@ Color fogApplyToLocation(Vector3 location, Color base)
mask.a *= value;
colorMask(&base, &mask);
return base;
return base;*/
}

View file

@ -12,32 +12,13 @@
#include "sky.h"
#include "water.h"
#include "terrain.h"
static LightingDefinition _definition;
static LightingQuality _quality;
static LightingEnvironment _environment;
#include "renderer.h"
#include "scenery.h"
static LightDefinition _LIGHT_NULL;
static Color _standardFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
{
Color result;
result = waterLightFilter(light, location, light_location, direction_to_light, custom_data);
result = terrainLightFilter(result, location, light_location, direction_to_light, custom_data);
// TODO atmosphere filter
// TODO clouds filter
return result;
}
void lightingInit()
{
_definition = lightingCreateDefinition();
_environment.filter = _standardFilter;
_environment.custom_data = NULL;
_LIGHT_NULL.color = COLOR_BLACK;
_LIGHT_NULL.direction.x = 0.0;
_LIGHT_NULL.direction.y = 1.0;
@ -65,38 +46,25 @@ LightingDefinition lightingCreateDefinition()
return definition;
}
void lightingDeleteDefinition(LightingDefinition definition)
void lightingDeleteDefinition(LightingDefinition* definition)
{
}
void lightingCopyDefinition(LightingDefinition source, LightingDefinition* destination)
void lightingCopyDefinition(LightingDefinition* source, LightingDefinition* destination)
{
*destination = source;
}
void lightingSetDefinition(LightingDefinition definition)
{
lightingValidateDefinition(&definition);
lightingCopyDefinition(definition, &_definition);
}
LightingDefinition lightingGetDefinition()
{
return _definition;
*destination = *source;
}
void lightingValidateDefinition(LightingDefinition* definition)
{
if (!definition)
{
lightingValidateDefinition(&_definition);
return;
}
if (definition->autosetfromsky)
{
// TODO Get lights from sky
definition->_nbautolights = skyGetLights(definition->_autolights, MAX_LIGHTS);
SkyDefinition sky;
sky = skyCreateDefinition();
sceneryGetSky(&sky);
definition->_nbautolights = skyGetLights(&sky, definition->_autolights, LIGHTING_MAX_LIGHTS);
skyDeleteDefinition(&sky);
}
else
{
@ -123,7 +91,7 @@ LightDefinition lightingGetLight(LightingDefinition* definition, int light)
int lightingAddLight(LightingDefinition* definition, LightDefinition light)
{
if (definition->nblights < MAX_LIGHTS)
if (definition->nblights < LIGHTING_MAX_LIGHTS)
{
definition->lights[definition->nblights] = light;
return definition->nblights++;
@ -146,17 +114,7 @@ void lightingDeleteLight(LightingDefinition* definition, int light)
}
}
void lightingSetQuality(LightingQuality quality)
{
_quality = quality;
}
LightingQuality lightingGetQuality()
{
return _quality;
}
static Color _applyLightCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightDefinition* definition, LightingQuality* quality, LightingEnvironment* environment)
static Color _applyLightCustom(LightDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
{
Color result, light;
double diffuse, specular;
@ -165,14 +123,15 @@ static Color _applyLightCustom(Vector3 location, Vector3 normal, ReceiverMateria
light = definition->color;
direction_inv = v3Scale(definition->direction, -1.0);
light = environment->filter(light, location, v3Add(location, direction_inv), direction_inv, environment->custom_data);
light = renderer->filterLight(renderer, light, location, v3Add(location, direction_inv), direction_inv);
normal = v3Normalize(normal);
view = v3Normalize(v3Sub(location, camera_location)); // TODO Configurable
view = v3Normalize(v3Sub(location, renderer->camera_location));
reflect = v3Sub(v3Scale(normal, 2.0 * v3Dot(direction_inv, normal)), direction_inv);
diffuse = v3Dot(direction_inv, normal);
//diffuse = pow(diffuse * 0.5 + 0.5, 2.0);
diffuse = diffuse * 0.5 + 0.5;
if (diffuse > 0.0)
{
if (material.shininess > 0.0)
@ -198,38 +157,20 @@ static Color _applyLightCustom(Vector3 location, Vector3 normal, ReceiverMateria
return result;
}
Color lightingApplyCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightingDefinition* definition, LightingQuality* quality, LightingEnvironment* environment)
Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
{
Color result;
int i;
if (!definition)
{
definition = &_definition;
}
if (!quality)
{
quality = &_quality;
}
if (!environment)
{
environment = &_environment;
}
/* TODO Merge lights */
result = material.base;
for (i = 0; i < definition->nblights; i++)
{
result = _applyLightCustom(location, normal, material, definition->lights + i, quality, environment);
result = _applyLightCustom(definition->lights + i, renderer, location, normal, material);
}
for (i = 0; i < definition->_nbautolights; i++)
{
result = _applyLightCustom(location, normal, material, definition->_autolights + i, quality, environment);
result = _applyLightCustom(definition->_autolights + i, renderer, location, normal, material);
}
return result;
}
Color lightingApply(Vector3 location, Vector3 normal, ReceiverMaterial material)
{
return lightingApplyCustom(location, normal, material, &_definition, &_quality, &_environment);
}

View file

@ -2,13 +2,14 @@
#define _PAYSAGES_LIGHTING_H_
#include "shared/types.h"
#include "renderer.h"
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_LIGHTS 10
#define LIGHTING_MAX_LIGHTS 10
typedef struct
{
@ -21,40 +22,25 @@ typedef struct
{
int autosetfromsky;
int nblights;
LightDefinition lights[MAX_LIGHTS];
LightDefinition lights[LIGHTING_MAX_LIGHTS];
int _nbautolights;
LightDefinition _autolights[MAX_LIGHTS];
LightDefinition _autolights[LIGHTING_MAX_LIGHTS];
} LightingDefinition;
typedef struct
{
int unused;
} LightingQuality;
typedef Color (*LightFilter)(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data);
typedef struct
{
LightFilter filter;
void* custom_data;
} LightingEnvironment;
typedef struct
{
Color base;
double reflection;
double shininess;
} ReceiverMaterial;
} SurfaceMaterial;
void lightingInit();
void lightingSave(FILE* f);
void lightingLoad(FILE* f);
LightingDefinition lightingCreateDefinition();
void lightingDeleteDefinition(LightingDefinition definition);
void lightingCopyDefinition(LightingDefinition source, LightingDefinition* destination);
void lightingSetDefinition(LightingDefinition definition);
LightingDefinition lightingGetDefinition();
void lightingDeleteDefinition(LightingDefinition* definition);
void lightingCopyDefinition(LightingDefinition* source, LightingDefinition* destination);
void lightingValidateDefinition(LightingDefinition* definition);
int lightingGetLightCount(LightingDefinition* definition);
@ -62,11 +48,7 @@ LightDefinition lightingGetLight(LightingDefinition* definition, int light);
int lightingAddLight(LightingDefinition* definition, LightDefinition light);
void lightingDeleteLight(LightingDefinition* definition, int light);
void lightingSetQuality(LightingQuality quality);
LightingQuality lightingGetQuality();
Color lightingApplyCustom(Vector3 location, Vector3 normal, ReceiverMaterial material, LightingDefinition* definition, LightingQuality* quality, LightingEnvironment* environment);
Color lightingApply(Vector3 location, Vector3 normal, ReceiverMaterial material);
Color lightingApplyToSurface(LightingDefinition* definition, Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material);
#ifdef __cplusplus
}

View file

@ -23,17 +23,12 @@ void paysagesInit()
ilInit();
iluInit();
autoInit();
renderInit();
cameraSetLocation(-12.0, 5.0, 2.0);
cameraSetTarget(0.0, 5.0, 0.0);
autoInit();
skyInit();
terrainInit();
texturesInit();
waterInit();
lightingInit();
renderInit();
autoSetRenderQuality(5);
autoGenRealisticLandscape(0);
autoSetDaytime(8, 30);
@ -54,36 +49,10 @@ void paysagesInit()
void paysagesSave(char* filepath)
{
FILE* f = fopen(filepath, "wb");
cameraSave(f);
cloudsSave(f);
fogSave(f);
renderSave(f);
skySave(f);
terrainSave(f);
texturesSave(f);
waterSave(f);
lightingSave(f);
fclose(f);
scenerySaveToFile(filepath);
}
void paysagesLoad(char* filepath)
{
FILE* f = fopen(filepath, "rb");
cameraLoad(f);
cloudsLoad(f);
fogLoad(f);
renderLoad(f);
skyLoad(f);
terrainLoad(f);
texturesLoad(f);
waterLoad(f);
lightingLoad(f);
fclose(f);
sceneryLoadFromFile(filepath);
}

View file

@ -1,7 +1,6 @@
#ifndef _PAYSAGES_MODIFIERS_H_
#define _PAYSAGES_MODIFIERS_H_
#include "shared/types.h"
#include <stdio.h>
#ifdef __cplusplus

View file

@ -1,7 +1,3 @@
#include <stdlib.h>
#include <math.h>
#include <string.h>
struct NoiseLevel;
struct NoiseGenerator
@ -15,7 +11,12 @@ struct NoiseGenerator
struct NoiseLevel* levels;
};
#include "shared/types.h"
#include "noise.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "shared/functions.h"
static inline double _cubicInterpolate(double* p, double x)
@ -23,7 +24,6 @@ static inline double _cubicInterpolate(double* p, double x)
return p[1] + 0.5 * x * (p[2] - p[0] + x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
}
NoiseGenerator* noiseCreateGenerator()
{
NoiseGenerator* result;

54
lib_paysages/noise.h Normal file
View file

@ -0,0 +1,54 @@
#ifndef _PAYSAGES_NOISE_H_
#define _PAYSAGES_NOISE_H_
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
struct NoiseLevel
{
double scaling;
double height;
double xoffset;
double yoffset;
double zoffset;
};
typedef struct NoiseLevel NoiseLevel;
typedef struct NoiseGenerator NoiseGenerator;
NoiseGenerator* noiseCreateGenerator();
void noiseDeleteGenerator(NoiseGenerator* generator);
void noiseSave(NoiseGenerator* perlin, FILE* f);
void noiseLoad(NoiseGenerator* perlin, FILE* f);
void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination);
void noiseGenerateBaseNoise(NoiseGenerator* generator, int size);
int noiseGetBaseSize(NoiseGenerator* generator);
double noiseGetMaxValue(NoiseGenerator* generator);
int noiseGetLevelCount(NoiseGenerator* generator);
void noiseClearLevels(NoiseGenerator* generator);
void noiseAddLevel(NoiseGenerator* generator, NoiseLevel level);
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double height);
void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start_level, double scaling_factor, double height_factor, int randomize_offset);
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double height);
void noiseRemoveLevel(NoiseGenerator* generator, int level);
int noiseGetLevel(NoiseGenerator* generator, int level, NoiseLevel* params);
void noiseSetLevel(NoiseGenerator* generator, int level, NoiseLevel params);
void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, double height);
void noiseNormalizeHeight(NoiseGenerator* generator, double min_height, double max_height, int adjust_scaling);
double noiseGet1DLevel(NoiseGenerator* generator, int level, double x);
double noiseGet1DTotal(NoiseGenerator* generator, double x);
double noiseGet1DDetail(NoiseGenerator* generator, double x, double detail);
double noiseGet2DLevel(NoiseGenerator* generator, int level, double x, double y);
double noiseGet2DTotal(NoiseGenerator* generator, double x, double y);
double noiseGet2DDetail(NoiseGenerator* generator, double x, double y, double detail);
double noiseGet3DLevel(NoiseGenerator* generator, int level, double x, double y, double z);
double noiseGet3DTotal(NoiseGenerator* generator, double x, double y, double z);
double noiseGet3DDetail(NoiseGenerator* generator, double x, double y, double z, double detail);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -108,16 +108,21 @@ void renderSetSize(int width, int height)
_cb_preview_clear(background_color);
}
void renderSetQuality(int quality)
int renderSetQuality(int quality)
{
if (quality < 1)
{
render_quality = 1;
}
else if (quality > 10)
{
render_quality = 10;
}
else
{
render_quality = quality;
}
return render_quality;
}
void renderClear()

19
lib_paysages/renderer.c Normal file
View file

@ -0,0 +1,19 @@
#include "renderer.h"
#include "shared/constants.h"
static Color _fakeFilterLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
{
return light_color;
}
Renderer rendererGetFake()
{
Renderer result;
result.render_quality = 5;
result.camera_location = VECTOR_ZERO;
result.filterLight = _fakeFilterLight;
return result;
}

31
lib_paysages/renderer.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef _PAYSAGES_RENDERER_H_
#define _PAYSAGES_RENDERER_H_
#include "shared/types.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Renderer Renderer;
struct Renderer
{
/* Quality configuration */
int render_quality;
Vector3 camera_location;
/* Lighting related */
Color (*filterLight)(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light);
/* Custom data */
void* customData[10];
};
Renderer rendererGetFake();
#ifdef __cplusplus
}
#endif
#endif

197
lib_paysages/scenery.c Normal file
View file

@ -0,0 +1,197 @@
#include "scenery.h"
#include <stdio.h>
CameraDefinition _camera;
CloudsDefinition _clouds;
LightingDefinition _lighting;
SkyDefinition _sky;
TerrainDefinition _terrain;
TexturesDefinition _textures;
WaterDefinition _water;
static Color _filterLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
{
Color result;
result = waterLightFilter(&_water, renderer, light_color, at_location, light_location, direction_to_light);
result = terrainLightFilter(&_terrain, renderer, result, at_location, light_location, direction_to_light);
// TODO atmosphere filter
// TODO clouds filter
return result;
}
static RayCastingResult _reflectionFunction(Vector3 start, Vector3 direction)
{
RayCastingResult result;
if (!terrainProjectRay(start, direction, &result.hit_location, &result.hit_color))
{
result.hit_color = skyProjectRay(start, direction);
/* TODO hit_location */
}
result.hit = 1;
return result;
}
static RayCastingResult _refractionFunction(Vector3 start, Vector3 direction)
{
RayCastingResult result;
result.hit = terrainProjectRay(start, direction, &result.hit_location, &result.hit_color);
return result;
}
void sceneryInit()
{
cameraInit();
cloudsInit();
lightingInit();
skyInit();
terrainInit();
texturesInit();
waterInit();
_camera = cameraCreateDefinition();
_clouds = cloudsCreateDefinition();
_lighting = lightingCreateDefinition();
_sky = skyCreateDefinition();
_terrain = terrainCreateDefinition();
_textures = texturesCreateDefinition();
_water = waterCreateDefinition();
}
void scenerySaveToFile(char* filepath)
{
FILE* f = fopen(filepath, "wb");
cameraSave(f, &_camera);
cloudsSave(f, &_clouds);
lightingSave(f, &_lighting);
skySave(f, &_sky);
terrainSave(f, &_terrain);
texturesSave(f, &_textures);
waterSave(f, &_water);
fclose(f);
}
void sceneryLoadFromFile(char* filepath)
{
FILE* f = fopen(filepath, "rb");
/* TODO Use intermediary definitions ? */
cameraLoad(f, &_camera);
cameraValidateDefinition(&_camera);
cloudsLoad(f, &_clouds);
cloudsValidateDefinition(&_clouds);
lightingLoad(f, &_lighting);
lightingValidateDefinition(&_lighting);
skyLoad(f, &_sky);
skyValidateDefinition(&_sky);
terrainLoad(f, &_terrain);
terrainValidateDefinition(&_terrain);
texturesLoad(f, &_textures);
texturesValidateDefinition(&_textures);
waterLoad(f, &_water);
waterValidateDefinition(&_water);
fclose(f);
}
void scenerySetCamera(CameraDefinition* camera)
{
cameraCopyDefinition(camera, &_camera);
cameraValidateDefinition(&_camera);
}
void sceneryGetCamera(CameraDefinition* camera)
{
cameraCopyDefinition(&_camera, camera);
}
void scenerySetClouds(CloudsDefinition* clouds)
{
cloudsCopyDefinition(clouds, &_clouds);
cloudsValidateDefinition(&_clouds);
}
void sceneryGetClouds(CloudsDefinition* clouds)
{
cloudsCopyDefinition(_clouds, clouds);
}
void scenerySetLighting(LightingDefinition* lighting)
{
lightingCopyDefinition(lighting, &_lighting);
lightingValidateDefinition(&_lighting);
}
void sceneryGetLighting(LightingDefinition* lighting)
{
lightingCopyDefinition(&_lighting, lighting);
}
void scenerySetSky(SkyDefinition* sky)
{
skyCopyDefinition(sky, &_sky);
skyValidateDefinition(&_sky);
lightingValidateDefinition(&_lighting);
}
void sceneryGetSky(SkyDefinition* sky)
{
skyCopyDefinition(&_sky, sky);
}
void scenerySetTerrain(TerrainDefinition* terrain)
{
terrainCopyDefinition(terrain, &_terrain);
terrainValidateDefinition(&_terrain);
}
void sceneryGetTerrain(TerrainDefinition* terrain)
{
terrainCopyDefinition(&_terrain, terrain);
}
void scenerySetTextures(TexturesDefinition* textures)
{
texturesCopyDefinition(textures, &_textures);
texturesValidateDefinition(&_textures);
}
void sceneryGetTextures(TexturesDefinition* textures)
{
texturesCopyDefinition(&_textures, textures);
}
void scenerySetWater(WaterDefinition* water)
{
waterCopyDefinition(water, &_water);
waterValidateDefinition(&_water);
}
void sceneryGetWater(WaterDefinition* water)
{
waterCopyDefinition(&_water, water);
}
Renderer sceneryGetStandardRenderer()
{
}
void sceneryRender()
{
}

57
lib_paysages/scenery.h Normal file
View file

@ -0,0 +1,57 @@
#ifndef _PAYSAGES_SCENERY_H_
#define _PAYSAGES_SCENERY_H_
/*
* Scenery management.
*
* This module handles all scenery components (terrain, water...) definitions and maintains
* a standard renderer.
*/
#include "camera.h"
#include "clouds.h"
#include "lighting.h"
#include "sky.h"
#include "terrain.h"
#include "textures.h"
#include "water.h"
#include "renderer.h"
#ifdef __cplusplus
extern "C" {
#endif
void sceneryInit();
void scenerySaveToFile(char* filepath);
void sceneryLoadFromFile(char* filepath);
void scenerySetCamera(CameraDefinition* camera);
void sceneryGetCamera(CameraDefinition* camera);
void scenerySetClouds(CloudsDefinition* clouds);
void sceneryGetClouds(CloudsDefinition* clouds);
void scenerySetLighting(LightingDefinition* lighting);
void sceneryGetLighting(LightingDefinition* lighting);
void scenerySetSky(SkyDefinition* sky);
void sceneryGetSky(SkyDefinition* sky);
void scenerySetTerrain(TerrainDefinition* terrain);
void sceneryGetTerrain(TerrainDefinition* terrain);
void scenerySetTextures(TexturesDefinition* textures);
void sceneryGetTextures(TexturesDefinition* textures);
void scenerySetWater(WaterDefinition* water);
void sceneryGetWater(WaterDefinition* water);
Renderer sceneryGetStandardRenderer();
void sceneryRender();
#ifdef __cplusplus
}
#endif
#endif

View file

@ -25,22 +25,10 @@ void arrayClear(Array* array);
void autoInit();
void autoSetDaytime(int hour, int minute);
void autoSetDaytimeFraction(double daytime);
void autoSetRenderQuality(int quality);
void autoGenRealisticLandscape(int seed);
void autoRenderSceneTwoPass(int postonly);
void autoRenderSceneRayTracing();
/* camera.c */
void cameraSave(FILE* f);
void cameraLoad(FILE* f);
void cameraSetLocation(double x, double y, double z);
void cameraSetTarget(double x, double y, double z);
void cameraSetAngle(double angle);
Vector3 cameraProject(Vector3 point);
Vector3 cameraUnproject(Vector3 point);
void cameraProjectToFragment(double x, double y, double z, RenderFragment* result);
void cameraPushOverlay(Color col, f_RenderFragmentCallback callback);
/* color.c */
void colorSave(Color col, FILE* f);
Color colorLoad(FILE* f);
@ -97,42 +85,12 @@ void fogSetColor(Color col);
void fogSetDistance(double near, double far);
Color fogApplyToLocation(Vector3 location, Color base);
/* noise.c */
NoiseGenerator* noiseCreateGenerator();
void noiseDeleteGenerator(NoiseGenerator* generator);
void noiseSave(NoiseGenerator* perlin, FILE* f);
void noiseLoad(NoiseGenerator* perlin, FILE* f);
void noiseCopy(NoiseGenerator* source, NoiseGenerator* destination);
void noiseGenerateBaseNoise(NoiseGenerator* generator, int size);
int noiseGetBaseSize(NoiseGenerator* generator);
double noiseGetMaxValue(NoiseGenerator* generator);
int noiseGetLevelCount(NoiseGenerator* generator);
void noiseClearLevels(NoiseGenerator* generator);
void noiseAddLevel(NoiseGenerator* generator, NoiseLevel level);
void noiseAddLevelSimple(NoiseGenerator* generator, double scaling, double height);
void noiseAddLevels(NoiseGenerator* generator, int level_count, NoiseLevel start_level, double scaling_factor, double height_factor, int randomize_offset);
void noiseAddLevelsSimple(NoiseGenerator* generator, int level_count, double scaling, double height);
void noiseRemoveLevel(NoiseGenerator* generator, int level);
int noiseGetLevel(NoiseGenerator* generator, int level, NoiseLevel* params);
void noiseSetLevel(NoiseGenerator* generator, int level, NoiseLevel params);
void noiseSetLevelSimple(NoiseGenerator* generator, int level, double scaling, double height);
void noiseNormalizeHeight(NoiseGenerator* generator, double min_height, double max_height, int adjust_scaling);
double noiseGet1DLevel(NoiseGenerator* generator, int level, double x);
double noiseGet1DTotal(NoiseGenerator* generator, double x);
double noiseGet1DDetail(NoiseGenerator* generator, double x, double detail);
double noiseGet2DLevel(NoiseGenerator* generator, int level, double x, double y);
double noiseGet2DTotal(NoiseGenerator* generator, double x, double y);
double noiseGet2DDetail(NoiseGenerator* generator, double x, double y, double detail);
double noiseGet3DLevel(NoiseGenerator* generator, int level, double x, double y, double z);
double noiseGet3DTotal(NoiseGenerator* generator, double x, double y, double z);
double noiseGet3DDetail(NoiseGenerator* generator, double x, double y, double z, double detail);
/* render.c */
void renderInit();
void renderSave(FILE* f);
void renderLoad(FILE* f);
void renderSetSize(int width, int height);
void renderSetQuality(int quality);
int renderSetQuality(int quality);
void renderClear();
void renderUpdate();
void renderInterrupt();
@ -148,14 +106,6 @@ void renderSetPreviewCallbacks(PreviewCallbackResize resize, PreviewCallbackClea
int renderSetNextProgressStep(double start, double end);
int renderTellProgress(double progress);
/* sky.c */
void skySave(FILE* f);
void skyLoad(FILE* f);
Color skyGetColor(Vector3 start, Vector3 direction);
Color skyProjectRay(Vector3 start, Vector3 direction);
void skySetGradation(ColorGradation grad);
void skyRender(RenderProgressCallback callback);
/* tools.c */
double toolsRandom();
double toolsBicubicInterpolate(double stencil[16], double x, double y);

View file

@ -7,8 +7,6 @@
extern "C" {
#endif
extern Vector3 camera_location;
extern int render_width;
extern int render_height;
extern int render_quality;

View file

@ -87,17 +87,6 @@ typedef struct
void* data;
} Array;
struct NoiseLevel
{
double scaling;
double height;
double xoffset;
double yoffset;
double zoffset;
};
typedef struct NoiseLevel NoiseLevel;
typedef struct NoiseGenerator NoiseGenerator;
typedef struct Zone Zone;
typedef void (*PreviewCallbackResize)(int width, int height);

View file

@ -11,40 +11,32 @@
#define SPHERE_SIZE 1000.0
static SkyDefinition _definition;
static SkyQuality _quality;
static SkyEnvironment _environment;
void skyInit()
{
skySetDefinition(skyCreateDefinition());
}
void skySave(FILE* f)
void skySave(FILE* f, SkyDefinition* definition)
{
toolsSaveDouble(f, _definition.daytime);
colorGradationSave(f, _definition.sun_color);
toolsSaveDouble(f, _definition.sun_radius);
colorGradationSave(f, _definition.zenith_color);
colorGradationSave(f, _definition.haze_color);
toolsSaveDouble(f, _definition.haze_height);
toolsSaveDouble(f, _definition.haze_smoothing);
toolsSaveDouble(f, definition->daytime);
colorGradationSave(f, definition->sun_color);
toolsSaveDouble(f, definition->sun_radius);
colorGradationSave(f, definition->zenith_color);
colorGradationSave(f, definition->haze_color);
toolsSaveDouble(f, definition->haze_height);
toolsSaveDouble(f, definition->haze_smoothing);
}
void skyLoad(FILE* f)
void skyLoad(FILE* f, SkyDefinition* definition)
{
definition->daytime = toolsLoadDouble(f);
definition->sun_color = colorGradationLoad(f);
definition->sun_radius = toolsLoadDouble(f);
definition->zenith_color = colorGradationLoad(f);
definition->haze_color = colorGradationLoad(f);
definition->haze_height = toolsLoadDouble(f);
definition->haze_smoothing = toolsLoadDouble(f);
SkyDefinition def;
def.daytime = toolsLoadDouble(f);
def.sun_color = colorGradationLoad(f);
def.sun_radius = toolsLoadDouble(f);
def.zenith_color = colorGradationLoad(f);
def.haze_color = colorGradationLoad(f);
def.haze_height = toolsLoadDouble(f);
def.haze_smoothing = toolsLoadDouble(f);
skySetDefinition(def);
skyValidateDefinition(definition);
}
SkyDefinition skyCreateDefinition()
@ -64,13 +56,13 @@ SkyDefinition skyCreateDefinition()
return def;
}
void skyDeleteDefinition(SkyDefinition definition)
void skyDeleteDefinition(SkyDefinition* definition)
{
}
void skyCopyDefinition(SkyDefinition source, SkyDefinition* destination)
void skyCopyDefinition(SkyDefinition* source, SkyDefinition* destination)
{
*destination = source;
*destination = *source;
}
void skyValidateDefinition(SkyDefinition* definition)
@ -87,31 +79,20 @@ void skyValidateDefinition(SkyDefinition* definition)
colorGradationAdd(&definition->_sky_gradation, 1.0, &zenith);
}
void skySetDefinition(SkyDefinition definition)
{
skyValidateDefinition(&definition);
_definition = definition;
}
SkyDefinition skyGetDefinition()
{
return _definition;
}
int skyGetLights(LightDefinition* lights, int max_lights)
int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights)
{
double sun_angle;
Vector3 sun_direction;
int nblights = 0;
sun_angle = (_definition.daytime + 0.75) * M_PI * 2.0;
sun_angle = (sky->daytime + 0.75) * M_PI * 2.0;
sun_direction.x = cos(sun_angle);
sun_direction.y = sin(sun_angle);
sun_direction.z = 0.0;
if (max_lights > 0)
{
lights[0].color = colorGradationGet(&_definition.sun_color, _definition.daytime);
lights[0].color = colorGradationGet(sky->sun_color, sky->daytime);
lights[0].direction = v3Scale(sun_direction, -1.0);
lights[0].maxshadow = 1.0;
nblights = 1;
@ -120,25 +101,12 @@ int skyGetLights(LightDefinition* lights, int max_lights)
return nblights;
}
Color skyGetColorCustom(Vector3 eye, Vector3 look, SkyDefinition* definition, SkyQuality* quality, SkyEnvironment* environment)
Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Vector3 look)
{
double sun_angle, dist;
Vector3 sun_position;
Color sun_color, sky_color;
if (definition == NULL)
{
definition = &_definition;
}
if (quality == NULL)
{
quality = &_quality;
}
if (environment == NULL)
{
environment = &_environment;
}
sun_angle = (definition->daytime + 0.75) * M_PI * 2.0;
sun_position.x = cos(sun_angle);
sun_position.y = sin(sun_angle);
@ -169,28 +137,10 @@ Color skyGetColorCustom(Vector3 eye, Vector3 look, SkyDefinition* definition, Sk
}
}
Color skyGetColor(Vector3 eye, Vector3 look)
static int _postProcessFragment(RenderFragment* fragment, Renderer* renderer)
{
return skyGetColorCustom(eye, look, &_definition, &_quality, &_environment);
}
Color skyProjectRay(Vector3 start, Vector3 direction)
{
Color color_sky, color_clouds;
direction = v3Normalize(direction);
color_sky = skyGetColor(start, direction);
color_clouds = cloudsGetColor(start, v3Add(start, v3Scale(direction, SPHERE_SIZE)));
colorMask(&color_sky, &color_clouds);
return color_sky;
}
static int _postProcessFragment(RenderFragment* fragment)
{
Vector3 location, direction;
// TODO
/*Vector3 location, direction;
Color color_sky, color_clouds;
location = fragment->vertex.location;
@ -200,12 +150,12 @@ static int _postProcessFragment(RenderFragment* fragment)
color_clouds = cloudsGetColor(camera_location, v3Add(camera_location, v3Scale(direction, 10.0)));
colorMask(&color_sky, &color_clouds);
fragment->vertex.color = color_sky;
fragment->vertex.color = color_sky;*/
return 1;
}
void skyRender(RenderProgressCallback callback)
void skyRender(SkyDefinition* definition, Renderer* renderer, RenderProgressCallback callback)
{
int res_i, res_j;
int i, j;
@ -215,8 +165,8 @@ void skyRender(RenderProgressCallback callback)
Color col;
Vector3 direction;
res_i = render_quality * 40;
res_j = render_quality * 20;
res_i = renderer->render_quality * 40;
res_j = renderer->render_quality * 20;
step_i = M_PI * 2.0 / (double)res_i;
step_j = M_PI / (double)res_j;
@ -240,7 +190,7 @@ void skyRender(RenderProgressCallback callback)
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j);
direction.y = SPHERE_SIZE * sin(current_j);
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j);
vertex1.location = v3Add(camera_location, direction);
vertex1.location = v3Add(renderer->camera_location, direction);
col.b = sin(direction.x) * sin(direction.x) * cos(direction.z) * cos(direction.z);
vertex1.color = col;
vertex1.callback = _postProcessFragment;
@ -248,7 +198,7 @@ void skyRender(RenderProgressCallback callback)
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j);
direction.y = SPHERE_SIZE * sin(current_j);
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j);
vertex2.location = v3Add(camera_location, direction);
vertex2.location = v3Add(renderer->camera_location, direction);
col.b = sin(direction.x) * sin(direction.x) * cos(direction.z) * cos(direction.z);
vertex2.color = col;
vertex2.callback = _postProcessFragment;
@ -256,7 +206,7 @@ void skyRender(RenderProgressCallback callback)
direction.x = SPHERE_SIZE * cos(current_i + step_i) * cos(current_j + step_j);
direction.y = SPHERE_SIZE * sin(current_j + step_j);
direction.z = SPHERE_SIZE * sin(current_i + step_i) * cos(current_j + step_j);
vertex3.location = v3Add(camera_location, direction);
vertex3.location = v3Add(renderer->camera_location, direction);
col.b = sin(direction.x) * sin(direction.x) * cos(direction.z) * cos(direction.z);
vertex3.color = col;
vertex3.callback = _postProcessFragment;
@ -264,7 +214,7 @@ void skyRender(RenderProgressCallback callback)
direction.x = SPHERE_SIZE * cos(current_i) * cos(current_j + step_j);
direction.y = SPHERE_SIZE * sin(current_j + step_j);
direction.z = SPHERE_SIZE * sin(current_i) * cos(current_j + step_j);
vertex4.location = v3Add(camera_location, direction);
vertex4.location = v3Add(renderer->camera_location, direction);
col.b = sin(direction.x) * sin(direction.x) * cos(direction.z) * cos(direction.z);
vertex4.color = col;
vertex4.callback = _postProcessFragment;

View file

@ -21,37 +21,21 @@ typedef struct
ColorGradation _sky_gradation;
} SkyDefinition;
typedef struct
{
int unused;
} SkyQuality;
typedef struct
{
int unused;
} SkyEnvironment;
void skyInit();
void skySave(FILE* f);
void skyLoad(FILE* f);
void skySave(FILE* f, SkyDefinition* definition);
void skyLoad(FILE* f, SkyDefinition* definition);
SkyDefinition skyCreateDefinition();
void skyDeleteDefinition(SkyDefinition definition);
void skyCopyDefinition(SkyDefinition source, SkyDefinition* destination);
void skyDeleteDefinition(SkyDefinition* definition);
void skyCopyDefinition(SkyDefinition* source, SkyDefinition* destination);
void skyValidateDefinition(SkyDefinition* definition);
void skySetDefinition(SkyDefinition definition);
SkyDefinition skyGetDefinition();
void skySetQuality(SkyQuality quality);
SkyQuality skyGetQuality();
int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights);
int skyGetLights(LightDefinition* lights, int max_lights);
Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Vector3 look);
Color skyProjectRay(SkyDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction);
Color skyGetColorCustom(Vector3 eye, Vector3 look, SkyDefinition* definition, SkyQuality* quality, SkyEnvironment* environment);
Color skyGetColor(Vector3 eye, Vector3 look);
Color skyProjectRay(Vector3 start, Vector3 direction);
void skyRender(RenderProgressCallback callback);
void skyRender(SkyDefinition* definition, Renderer* renderer, RenderProgressCallback callback);
#ifdef __cplusplus
}

View file

@ -1,6 +1,9 @@
#include "terrain.h"
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include "shared/types.h"
#include "shared/functions.h"
@ -9,52 +12,49 @@
#include "textures.h"
#include "water.h"
#include "terrain.h"
static TerrainDefinition _definition;
static TerrainQuality _quality;
static TerrainEnvironment _environment;
static double _max_height = 1.0;
void terrainInit()
{
_definition = terrainCreateDefinition();
_max_height = noiseGetMaxValue(_definition.height_noise);
_environment.toggle_fog = 1;
_environment.lighting_definition = NULL;
_environment.lighting_environment = NULL;
}
void terrainSave(FILE* f)
void terrainSave(FILE* f, TerrainDefinition* definition)
{
int i;
noiseSave(_definition.height_noise, f);
toolsSaveInt(f, _definition.height_modifiers_count);
for (i = 0; i < _definition.height_modifiers_count; i++)
noiseSave(definition->height_noise, f);
toolsSaveDouble(f, definition->height_factor);
toolsSaveDouble(f, definition->scaling);
toolsSaveInt(f, definition->height_modifiers_count);
for (i = 0; i < definition->height_modifiers_count; i++)
{
modifierSave(_definition.height_modifiers[i], f);
modifierSave(definition->height_modifiers[i], f);
}
}
void terrainLoad(FILE* f)
void terrainLoad(FILE* f, TerrainDefinition* definition)
{
int i;
int i, n;
HeightModifier* modifier;
noiseLoad(_definition.height_noise, f);
_max_height = noiseGetMaxValue(_definition.height_noise);
noiseLoad(definition->height_noise, f);
definition->height_factor = toolsLoadDouble(f);
definition->scaling = toolsLoadDouble(f);
for (i = 0; i < _definition.height_modifiers_count; i++)
while (definition->height_modifiers_count > 0)
{
modifierDelete(_definition.height_modifiers[i]);
terrainDelModifier(definition, 0);
}
_definition.height_modifiers_count = toolsLoadInt(f);
for (i = 0; i < _definition.height_modifiers_count; i++)
n = toolsLoadInt(f);
for (i = 0; i < n; i++)
{
_definition.height_modifiers[i] = modifierCreate();
modifierLoad(_definition.height_modifiers[i], f);
modifier = modifierCreate();
modifierLoad(modifier, f);
terrainAddModifier(&definition, modifier);
modifierDelete(modifier);
}
terrainValidateDefinition(definition);
}
TerrainDefinition terrainCreateDefinition()
@ -62,54 +62,57 @@ TerrainDefinition terrainCreateDefinition()
TerrainDefinition definition;
definition.height_noise = noiseCreateGenerator();
definition.height_factor = 0.0;
definition.scaling = 1.0;
definition.height_modifiers_count = 0;
terrainValidateDefinition(&definition);
return definition;
}
void terrainDeleteDefinition(TerrainDefinition definition)
void terrainDeleteDefinition(TerrainDefinition* definition)
{
int i;
noiseDeleteGenerator(definition.height_noise);
for (i = 0; i < definition.height_modifiers_count; i++)
noiseDeleteGenerator(definition->height_noise);
for (i = 0; i < definition->height_modifiers_count; i++)
{
modifierDelete(definition.height_modifiers[i]);
modifierDelete(definition->height_modifiers[i]);
}
}
void terrainCopyDefinition(TerrainDefinition source, TerrainDefinition* destination)
void terrainCopyDefinition(TerrainDefinition* source, TerrainDefinition* destination)
{
int i;
noiseCopy(source.height_noise, destination->height_noise);
destination->height_factor = source->height_factor;
destination->scaling = source->scaling;
for (i = 0; i < destination->height_modifiers_count; i++)
{
modifierDelete(destination->height_modifiers[i]);
}
destination->height_modifiers_count = source.height_modifiers_count;
for (i = 0; i < destination->height_modifiers_count; i++)
destination->height_modifiers_count = 0;
for (i = 0; i < source->height_modifiers_count; i++)
{
destination->height_modifiers[i] = modifierCreateCopy(source.height_modifiers[i]);
terrainAddModifier(destination, source->height_modifiers[i]);
}
terrainValidateDefinition(destination);
}
void terrainSetDefinition(TerrainDefinition definition)
void terrainValidateDefinition(TerrainDefinition* definition)
{
terrainCopyDefinition(definition, &_definition);
_max_height = noiseGetMaxValue(_definition.height_noise);
definition->_max_height = noiseGetMaxValue(definition->height_noise) * definition->height_factor;
/* FIXME _max_height depends on modifiers */
}
TerrainDefinition terrainGetDefinition()
{
return _definition;
}
int terrainAddModifier(TerrainDefinition* definition, HeightModifier* modifier)
{
if (definition->height_modifiers_count < MAX_HEIGHT_MODIFIER_COUNT)
if (definition->height_modifiers_count < TERRAIN_MAX_MODIFIERS)
{
definition->height_modifiers[definition->height_modifiers_count] = modifierCreateCopy(modifier);
return definition->height_modifiers_count++;
@ -124,27 +127,22 @@ void terrainDelModifier(TerrainDefinition* definition, int modifier_position)
{
if (modifier_position >= 0 && modifier_position < definition->height_modifiers_count)
{
/* TODO */
modifierDelete(definition->height_modifiers[modifier_position]);
if (definition->height_modifiers_count > 1 && modifier_position < definition->height_modifiers_count - 1)
{
memmove(definition->height_modifiers + modifier_position, definition->height_modifiers + modifier_position + 1, sizeof(HeightModifier*) * (definition->height_modifiers_count - modifier_position - 1));
}
definition->height_modifiers_count--;
}
}
void terrainSetQuality(TerrainQuality quality)
{
_quality = quality;
}
TerrainQuality terrainGetQuality()
{
return _quality;
}
static inline double _getHeight(TerrainDefinition* definition, double x, double z, double detail)
{
Vector3 location;
int i;
location.x = x;
location.y = noiseGet2DDetail(definition->height_noise, x, z, detail);
location.y = noiseGet2DDetail(definition->height_noise, x / definition->scaling, z / definition->scaling, detail) * definition->height_factor;
location.z = z;
for (i = 0; i < definition->height_modifiers_count; i++)
@ -166,16 +164,16 @@ static inline Vector3 _getPoint(TerrainDefinition* definition, double x, double
return result;
}
Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
Color terrainLightFilter(TerrainDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light)
{
Vector3 inc_vector;
double inc_value, inc_base, inc_factor, height, diff, light_factor, smoothing, length;
direction_to_light = v3Normalize(direction_to_light);
inc_factor = (double)render_quality; // TODO Configurable
inc_factor = (double)renderer->render_quality;
inc_base = 1.0;
inc_value = inc_base / inc_factor;
smoothing = 0.03 * inc_factor;;
smoothing = 0.03 * inc_factor;
light_factor = 1.0;
length = 0.0;
@ -184,7 +182,7 @@ Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location,
inc_vector = v3Scale(direction_to_light, inc_value);
length += v3Norm(inc_vector);
location = v3Add(location, inc_vector);
height = _getHeight(&_definition, location.x, location.z, inc_value);
height = _getHeight(definition, location.x, location.z, inc_value);
diff = location.y - height;
if (diff < 0.0)
{
@ -203,7 +201,7 @@ Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location,
{
inc_value = diff;
}
} while (light_factor > 0.0 && length < 50.0 && location.y <= _max_height);
} while (light_factor > 0.0 && length < 50.0 && location.y <= definition._max_height);
if (light_factor <= 0.0)
{
@ -219,31 +217,29 @@ Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location,
}
}
static Color _getColor(TerrainDefinition* definition, TerrainEnvironment* environment, Vector3 point, double precision)
static Color _getColor(TerrainDefinition* definition, Renderer* renderer, Vector3 point, double precision)
{
Color color;
TextureEnvironment texenv;
texenv.lighting_definition = environment->lighting_definition;
texenv.lighting_environment = environment->lighting_environment;
color = texturesGetColorCustom(point, precision, NULL, &texenv);
if (environment->toggle_fog)
color = COLOR_RED;
//color = texturesGetColorCustom(point, precision, NULL, &texenv);
/*if (environment->toggle_fog)
{
color = fogApplyToLocation(point, color);
}
}*/
//color = cloudsApplySegmentResult(color, camera_location, point);
return color;
}
int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color)
int terrainProjectRay(TerrainDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color)
{
Vector3 inc_vector;
double inc_value, inc_base, inc_factor, height, diff, length;
direction = v3Normalize(direction);
inc_factor = (double)render_quality;
inc_factor = (double)renderer->render_quality;
inc_base = 1.0;
inc_value = inc_base / inc_factor;
@ -253,13 +249,13 @@ int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Colo
inc_vector = v3Scale(direction, inc_value);
length += v3Norm(inc_vector);
start = v3Add(start, inc_vector);
height = _getHeight(&_definition, start.x, start.z, inc_value);
height = _getHeight(definition, start.x, start.z, inc_value);
diff = start.y - height;
if (diff < 0.0)
{
start.y = height;
*hit_point = start;
*hit_color = _getColor(&_definition, &_environment, start, inc_value);
*hit_color = _getColor(definition, renderer, start, inc_value);
return 1;
}
@ -275,14 +271,14 @@ int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Colo
{
inc_value = diff;
}
} while (length < 50.0 && start.y <= _max_height);
} while (length < 50.0 && start.y <= definition._max_height);
return 0;
}
static int _postProcessFragment(RenderFragment* fragment)
{
Vector3 point;
/*Vector3 point;
double precision;
point = fragment->vertex.location;
@ -290,17 +286,17 @@ static int _postProcessFragment(RenderFragment* fragment)
point = _getPoint(&_definition, point.x, point.z, precision);
fragment->vertex.color = _getColor(&_definition, &_environment, point, precision);
fragment->vertex.color = _getColor(&_definition, &_environment, point, precision);*/
return 1;
}
static Vertex _getFirstPassVertex(double x, double z, double detail)
static Vertex _getFirstPassVertex(TerrainDefinition* definition, double x, double z, double detail)
{
Vertex result;
double value;
result.location = _getPoint(&_definition, x, z, 0.0);
result.location = _getPoint(definition, x, z, 0.0);
value = sin(x) * sin(x) * cos(z) * cos(z);
result.color.r = value;
result.color.g = value;
@ -312,63 +308,50 @@ static Vertex _getFirstPassVertex(double x, double z, double detail)
return result;
}
static void _renderQuad(double x, double z, double size)
static void _renderQuad(TerrainDefinition* definition, double x, double z, double size)
{
Vertex v1, v2, v3, v4;
v1 = _getFirstPassVertex(x, z, size);
v2 = _getFirstPassVertex(x, z + size, size);
v3 = _getFirstPassVertex(x + size, z + size, size);
v4 = _getFirstPassVertex(x + size, z, size);
v1 = _getFirstPassVertex(definition, x, z, size);
v2 = _getFirstPassVertex(definition, x, z + size, size);
v3 = _getFirstPassVertex(definition, x + size, z + size, size);
v4 = _getFirstPassVertex(definition, x + size, z, size);
renderPushQuad(&v1, &v2, &v3, &v4);
}
double terrainGetHeight(double x, double z)
double terrainGetHeight(TerrainDefinition* definition, double x, double z)
{
return _getHeight(&_definition, x, z, 0.0);
return _getHeight(definition, x, z, 0.0);
}
double terrainGetHeightNormalized(double x, double z)
double terrainGetHeightNormalized(TerrainDefinition* definition, double x, double z)
{
return 0.5 + _getHeight(&_definition, x, z, 0.0) / (_max_height * 2.0);
return 0.5 + _getHeight(definition, x, z, 0.0) / (definition->_max_height * 2.0);
}
Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition* definition, TerrainQuality* quality, TerrainEnvironment* environment)
Color terrainGetColor(TerrainDefinition* definition, Renderer* renderer, double x, double z, double detail)
{
if (!definition)
{
definition = &_definition;
}
if (!quality)
{
quality = &_quality;
}
if (!environment)
{
environment = &_environment;
}
Vector3 point = _getPoint(definition, x, z, detail);
return _getColor(definition, environment, point, detail);
return _getColor(definition, renderer, point, detail);
}
Color terrainGetColor(double x, double z, double detail)
{
return terrainGetColorCustom(x, z, detail, &_definition, &_quality, &_environment);
}
void terrainRender(RenderProgressCallback callback)
void terrainRender(TerrainDefinition* definition, Renderer* renderer, RenderProgressCallback callback)
{
int chunk_factor, chunk_count, i;
double cx = camera_location.x;
double cz = camera_location.z;
double cx = renderer->camera_location.x;
double cz = renderer->camera_location.z;
double min_chunk_size, visible_chunk_size;
double radius_int, radius_ext, chunk_size;
min_chunk_size = 0.1 / (double)renderer->render_quality;
visible_chunk_size = 0.05 / (double)renderer->render_quality;
chunk_factor = 1;
chunk_count = 2;
radius_int = 0.0;
radius_ext = _quality.min_chunk_size;
chunk_size = _quality.min_chunk_size;
radius_ext = min_chunk_size;
chunk_size = min_chunk_size;
while (radius_ext < 1000.0)
{
@ -379,20 +362,20 @@ void terrainRender(RenderProgressCallback callback)
for (i = 0; i < chunk_count - 1; i++)
{
_renderQuad(cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size);
_renderQuad(cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size);
_renderQuad(cx + radius_int - chunk_size * i, cz + radius_int, chunk_size);
_renderQuad(cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size);
_renderQuad(definition, cx - radius_ext + chunk_size * i, cz - radius_ext, chunk_size);
_renderQuad(definition, cx + radius_int, cz - radius_ext + chunk_size * i, chunk_size);
_renderQuad(definition, cx + radius_int - chunk_size * i, cz + radius_int, chunk_size);
_renderQuad(definition, cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size);
}
if (chunk_count % 64 == 0 && chunk_size / radius_int < _quality.visible_chunk_size)
if (chunk_count % 64 == 0 && chunk_size / radius_int < visible_chunk_size)
{
chunk_count /= 2;
chunk_factor *= 2;
/* TODO Fill in gaps with triangles */
}
chunk_count += 2;
chunk_size = _quality.min_chunk_size * chunk_factor;
chunk_size = min_chunk_size * chunk_factor;
radius_int = radius_ext;
radius_ext += chunk_size;
}

View file

@ -3,6 +3,7 @@
#include "shared/types.h"
#include "modifiers.h"
#include "noise.h"
#include "lighting.h"
#include <stdio.h>
@ -10,53 +11,37 @@
extern "C" {
#endif
#define MAX_HEIGHT_MODIFIER_COUNT 50
#define TERRAIN_MAX_MODIFIERS 50
typedef struct
{
NoiseGenerator* height_noise;
double height_factor;
double scaling;
int height_modifiers_count;
HeightModifier* height_modifiers[MAX_HEIGHT_MODIFIER_COUNT];
HeightModifier* height_modifiers[TERRAIN_MAX_MODIFIERS];
double _max_height;
} TerrainDefinition;
typedef struct
{
double min_chunk_size;
double visible_chunk_size;
} TerrainQuality;
typedef struct
{
int toggle_fog;
LightingDefinition* lighting_definition;
LightingEnvironment* lighting_environment;
} TerrainEnvironment;
void terrainInit();
void terrainSave(FILE* f);
void terrainLoad(FILE* f);
void terrainSave(FILE* f, TerrainDefinition* definition);
void terrainLoad(FILE* f, TerrainDefinition* definition);
TerrainDefinition terrainCreateDefinition();
void terrainDeleteDefinition(TerrainDefinition definition);
void terrainCopyDefinition(TerrainDefinition source, TerrainDefinition* destination);
void terrainSetDefinition(TerrainDefinition definition);
TerrainDefinition terrainGetDefinition();
void terrainDeleteDefinition(TerrainDefinition* definition);
void terrainCopyDefinition(TerrainDefinition* source, TerrainDefinition* destination);
void terrainValidateDefinition(TerrainDefinition* definition);
int terrainAddModifier(TerrainDefinition* definition, HeightModifier* modifier);
void terrainDelModifier(TerrainDefinition* definition, int modifier_position);
void terrainSetQuality(TerrainQuality quality);
TerrainQuality terrainGetQuality();
Color terrainLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data);
int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color);
double terrainGetHeightCustom(double x, double z, TerrainDefinition* definition);
double terrainGetHeight(double x, double z);
double terrainGetHeightNormalizedCustom(double x, double z, TerrainDefinition* definition);
double terrainGetHeightNormalized(double x, double z);
Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition* definition, TerrainQuality* quality, TerrainEnvironment* environment);
Color terrainGetColor(double x, double z, double detail);
void terrainRender(RenderProgressCallback callback);
Color terrainLightFilter(TerrainDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light);
int terrainProjectRay(TerrainDefinition* definition, Renderer* renderer, Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color);
double terrainGetHeight(TerrainDefinition* definition, double x, double z);
double terrainGetHeightNormalized(TerrainDefinition* definition, double x, double z);
Color terrainGetColor(TerrainDefinition* definition, Renderer* renderer, double x, double z, double detail);
void terrainRender(TerrainDefinition* definition, Renderer* renderer, RenderProgressCallback callback);
#ifdef __cplusplus
}

View file

@ -12,90 +12,94 @@
#include "terrain.h"
#include "lighting.h"
#define TEXTURES_MAX 50
static TextureQuality _quality;
static TextureEnvironment _environment;
static int _textures_count = 0;
static TextureDefinition _textures[TEXTURES_MAX];
static TextureLayerDefinition _NULL_LAYER;
void texturesInit()
{
_textures_count = 0;
_environment.lighting_definition = NULL;
_environment.lighting_environment = NULL;
_NULL_LAYER = texturesLayerCreateDefinition();
}
void texturesSave(FILE* f)
void texturesSave(FILE* f, TexturesDefinition* definition)
{
int i;
toolsSaveInt(f, _textures_count);
for (i = 0; i < _textures_count; i++)
toolsSaveInt(f, definition->nbtextures);
for (i = 0; i < definition->nbtextures; i++)
{
zoneSave(_textures[i].zone, f);
noiseSave(_textures[i].bump_noise, f);
colorSave(_textures[i].color, f);
zoneSave(definition->textures[i].zone, f);
noiseSave(definition->textures[i].bump_noise, f);
colorSave(definition->textures[i].color, f);
}
}
void texturesLoad(FILE* f)
void texturesLoad(FILE* f, TexturesDefinition* definition)
{
TextureLayerDefinition* layer;
int i, n;
TextureDefinition* texture;
while (_textures_count > 0)
while (definition->nbtextures > 0)
{
texturesDeleteLayer(0);
texturesDeleteLayer(definition, 0);
}
n = toolsLoadInt(f);
for (i = 0; i < n; i++)
{
texture = _textures + texturesAddLayer();
layer = definition->nbtextures + texturesAddLayer(definition);
zoneLoad(texture->zone, f);
noiseLoad(texture->bump_noise, f);
texture->color = colorLoad(f);
zoneLoad(layer->zone, f);
noiseLoad(layer->bump_noise, f);
layer->color = colorLoad(f);
}
texturesValidateDefinition(definition);
}
int texturesGetLayerCount()
TexturesDefinition texturesCreateDefinition()
{
return _textures_count;
TexturesDefinition result;
result.nbtextures = 0;
return result;
}
int texturesAddLayer()
void texturesDeleteDefinition(TexturesDefinition* definition)
{
if (_textures_count < TEXTURES_MAX)
while (definition->nbtextures > 0)
{
_textures[_textures_count] = texturesCreateDefinition();
return _textures_count++;
}
else
{
return -1;
texturesDeleteLayer(definition, 0);
}
}
void texturesDeleteLayer(int layer)
void texturesCopyDefinition(TexturesDefinition* source, TexturesDefinition* destination)
{
if (layer >= 0 && layer < _textures_count)
TextureLayerDefinition* layer;
int i;
while (destination->nbtextures > 0)
{
zoneDelete(_textures[layer].zone);
noiseDeleteGenerator(_textures[layer].bump_noise);
if (_textures_count > 1 && layer < _textures_count - 1)
{
memmove(_textures + layer, _textures + layer + 1, sizeof(TextureDefinition) * (_textures_count - layer - 1));
}
_textures_count--;
texturesDeleteLayer(destination, 0);
}
for (i = 0; i < source->nbtextures; i++)
{
layer = texturesGetLayer(destination, texturesAddLayer(destination));
texturesLayerCopyDefinition(source->textures + i, layer);
}
}
TextureDefinition texturesCreateDefinition()
void texturesValidateDefinition(TexturesDefinition* definition)
{
TextureDefinition result;
int i;
for (i = 0; i < definition->nbtextures; i++)
{
texturesLayerValidateDefinition(definition->textures + i);
}
}
TextureLayerDefinition texturesLayerCreateDefinition()
{
TextureLayerDefinition result;
result.zone = zoneCreate();
result.bump_noise = noiseCreateGenerator();
@ -104,49 +108,68 @@ TextureDefinition texturesCreateDefinition()
return result;
}
void texturesDeleteDefinition(TextureDefinition definition)
void texturesLayerDeleteDefinition(TextureLayerDefinition* definition)
{
zoneDelete(definition.zone);
noiseDeleteGenerator(definition.bump_noise);
}
void texturesCopyDefinition(TextureDefinition source, TextureDefinition* destination)
void texturesLayerCopyDefinition(TextureLayerDefinition* source, TextureLayerDefinition* destination)
{
destination->color = source.color;
noiseCopy(source.bump_noise, destination->bump_noise);
zoneCopy(source.zone, destination->zone);
}
void texturesSetDefinition(int layer, TextureDefinition definition)
void texturesLayerValidateDefinition(TextureLayerDefinition* definition)
{
TextureDefinition* destination;
}
if (layer >= 0 && layer < _textures_count)
int texturesGetLayerCount(TexturesDefinition* definition)
{
return definition->nbtextures;
}
TextureLayerDefinition* texturesGetLayer(TexturesDefinition* definition, int layer)
{
if (layer >= 0 && layer < definition->nbtextures)
{
destination = _textures + layer;
texturesCopyDefinition(definition, destination);
return definition->textures + layer;
}
else
{
return &_NULL_LAYER;
}
}
TextureDefinition texturesGetDefinition(int layer)
int texturesAddLayer(TexturesDefinition* definition)
{
assert(layer >= 0);
assert(layer < _textures_count);
if (definition->nbtextures < TEXTURES_MAX_LAYERS)
{
_textures[definition->nbtextures] = texturesCreateDefinition();
return _textures[layer];
return definition->nbtextures++;
}
else
{
return -1;
}
}
void texturesSetQuality(TextureQuality quality)
void texturesDeleteLayer(TexturesDefinition* definition, int layer)
{
_quality = quality;
if (layer >= 0 && layer < definition->nbtextures)
{
texturesLayerDeleteDefinition(definition->textures + layer);
if (definition->nbtextures > 1 && layer < definition->nbtextures - 1)
{
memmove(definition->textures + layer, definition->textures + layer + 1, sizeof(TextureLayerDefinition) * (definition->nbtextures - layer - 1));
}
definition->nbtextures--;
}
}
TextureQuality texturesGetQuality()
{
return _quality;
}
static inline Vector3 _getNormal(TextureDefinition* definition, Vector3 point, double scale)
static inline Vector3 _getNormal(TextureLayerDefinition* definition, Vector3 point, double scale)
{
Vector3 dpoint, ref, normal;
@ -183,12 +206,12 @@ static inline Vector3 _getNormal(TextureDefinition* definition, Vector3 point, d
return v3Normalize(normal);
}
Color texturesGetLayerColorCustom(Vector3 location, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment)
Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail)
{
Color result;
Vector3 normal;
double coverage;
ReceiverMaterial material;
SurfaceMaterial material;
result = COLOR_TRANSPARENT;
normal = _getNormal(definition, location, detail * 0.3);
@ -200,31 +223,22 @@ Color texturesGetLayerColorCustom(Vector3 location, double detail, TextureDefini
material.reflection = 0.1;
material.shininess = 0.1;
result = lightingApplyCustom(location, normal, material, environment->lighting_definition, NULL, environment->lighting_environment);
result = renderer->applyLightingToSurface(renderer, location, normal, material);
result.a = coverage;
}
return result;
}
Color texturesGetColorCustom(Vector3 location, double detail, TextureQuality* quality, TextureEnvironment* environment)
Color texturesGetColorCustom(TexturesDefinition* definition, Renderer* renderer, Vector3 location, double detail)
{
Color result, tex_color;
int i;
/*if (!quality)
{
quality = &_quality;
}
if (!environment)
{
environment = &_environment;
}*/
result = COLOR_GREEN;
for (i = 0; i < _textures_count; i++)
for (i = 0; i < definition->nbtextures; i++)
{
/* TODO Do not compute layers fully covered */
tex_color = texturesGetLayerColorCustom(location, detail, _textures + i, quality, environment);
tex_color = texturesGetLayerColor(_textures + i, renderer, location, detail);
if (tex_color.a > 0.0001)
{
colorMask(&result, &tex_color);
@ -233,8 +247,3 @@ Color texturesGetColorCustom(Vector3 location, double detail, TextureQuality* qu
return result;
}
Color texturesGetColor(Vector3 location)
{
return texturesGetColorCustom(location, renderGetPrecision(location), &_quality, &_environment);
}

View file

@ -2,6 +2,7 @@
#define _PAYSAGES_TEXTURES_H_
#include "shared/types.h"
#include "noise.h"
#include "lighting.h"
#include <stdio.h>
@ -9,44 +10,42 @@
extern "C" {
#endif
#define TEXTURES_MAX_LAYERS 50
typedef struct
{
Zone* zone;
NoiseGenerator* bump_noise;
Color color;
} TextureDefinition;
} TextureLayerDefinition;
typedef struct
{
int unused;
} TextureQuality;
typedef struct
{
LightingDefinition* lighting_definition;
LightingEnvironment* lighting_environment;
} TextureEnvironment;
int nbtextures;
TextureLayerDefinition textures[TEXTURES_MAX_LAYERS];
} TexturesDefinition;
void texturesInit();
void texturesSave(FILE* f);
void texturesLoad(FILE* f);
void texturesSave(FILE* f, TexturesDefinition* definition);
void texturesLoad(FILE* f, TexturesDefinition* definition);
int texturesGetLayerCount();
int texturesAddLayer();
void texturesDeleteLayer(int layer);
TexturesDefinition texturesCreateDefinition();
void texturesDeleteDefinition(TexturesDefinition* definition);
void texturesCopyDefinition(TexturesDefinition* source, TexturesDefinition* destination);
void texturesValidateDefinition(TexturesDefinition* definition);
TextureDefinition texturesCreateDefinition();
void texturesDeleteDefinition(TextureDefinition definition);
void texturesCopyDefinition(TextureDefinition source, TextureDefinition* destination);
void texturesSetDefinition(int layer, TextureDefinition definition);
TextureDefinition texturesGetDefinition(int layer);
TextureLayerDefinition texturesLayerCreateDefinition();
void texturesLayerDeleteDefinition(TextureLayerDefinition* definition);
void texturesLayerCopyDefinition(TextureLayerDefinition* source, TextureLayerDefinition* destination);
void texturesLayerValidateDefinition(TextureLayerDefinition* definition);
void texturesSetQuality(TextureQuality quality);
TextureQuality texturesGetQuality();
int texturesGetLayerCount(TexturesDefinition* definition);
TextureLayerDefinition* texturesGetLayer(TexturesDefinition* definition, int layer);
int texturesAddLayer(TexturesDefinition* definition);
void texturesDeleteLayer(TexturesDefinition* definition, int layer);
Color texturesGetLayerColorCustom(Vector3 location, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment);
Color texturesGetColorCustom(Vector3 location, double detail, TextureQuality* quality, TextureEnvironment* environment);
Color texturesGetColor(Vector3 location);
Color texturesGetLayerColor(TextureLayerDefinition* definition, Renderer* renderer, Vector3 location, double detail);
Color texturesGetColorCustom(TexturesDefinition* definition, Renderer* renderer, Vector3 location, double detail);
#ifdef __cplusplus
}

View file

@ -1,78 +1,45 @@
#include "water.h"
#include "shared/types.h"
#include "shared/functions.h"
#include "shared/constants.h"
#include "shared/globals.h"
#include "water.h"
#include "terrain.h"
#include "lighting.h"
#include <math.h>
static WaterDefinition _definition;
static WaterQuality _quality;
static WaterEnvironment _environment;
static RayCastingResult _reflectionFunction(Vector3 start, Vector3 direction)
{
RayCastingResult result;
if (!terrainProjectRay(start, direction, &result.hit_location, &result.hit_color))
{
result.hit_color = skyProjectRay(start, direction);
/* TODO hit_location */
}
result.hit = 1;
return result;
}
static RayCastingResult _refractionFunction(Vector3 start, Vector3 direction)
{
RayCastingResult result;
result.hit = terrainProjectRay(start, direction, &result.hit_location, &result.hit_color);
return result;
}
void waterInit()
{
_definition = waterCreateDefinition();
/* TODO quality */
_environment.reflection_function = _reflectionFunction;
_environment.refraction_function = _refractionFunction;
_environment.toggle_fog = 1;
_environment.lighting_definition = NULL;
_environment.lighting_environment = NULL;
}
void waterSave(FILE* f)
void waterSave(FILE* f, WaterDefinition* definition)
{
toolsSaveDouble(f, _definition.height);
colorSave(_definition.main_color, f);
colorSave(_definition.depth_color, f);
toolsSaveDouble(f, _definition.transparency_depth);
toolsSaveDouble(f, _definition.transparency);
toolsSaveDouble(f, _definition.reflection);
noiseSave(_definition.waves_noise, f);
toolsSaveDouble(f, _definition.waves_noise_height);
toolsSaveDouble(f, _definition.waves_noise_scale);
toolsSaveDouble(f, definition.height);
colorSave(definition->main_color, f);
colorSave(definition->depth_color, f);
toolsSaveDouble(f, definition->transparency_depth);
toolsSaveDouble(f, definition->transparency);
toolsSaveDouble(f, definition->reflection);
noiseSave(definition->waves_noise, f);
toolsSaveDouble(f, definition->waves_noise_height);
toolsSaveDouble(f, definition->waves_noise_scale);
}
void waterLoad(FILE* f)
void waterLoad(FILE* f, WaterDefinition* definition)
{
_definition.height = toolsLoadDouble(f);
_definition.main_color = colorLoad(f);
_definition.depth_color = colorLoad(f);
_definition.transparency_depth = toolsLoadDouble(f);
_definition.transparency = toolsLoadDouble(f);
_definition.reflection = toolsLoadDouble(f);
noiseLoad(_definition.waves_noise, f);
_definition.waves_noise_height = toolsLoadDouble(f);
_definition.waves_noise_scale = toolsLoadDouble(f);
definition->height = toolsLoadDouble(f);
definition->main_color = colorLoad(f);
definition->depth_color = colorLoad(f);
definition->transparency_depth = toolsLoadDouble(f);
definition->transparency = toolsLoadDouble(f);
definition->reflection = toolsLoadDouble(f);
noiseLoad(definition->waves_noise, f);
definition->waves_noise_height = toolsLoadDouble(f);
definition->waves_noise_scale = toolsLoadDouble(f);
waterValidateDefinition(definition);
}
WaterDefinition waterCreateDefinition()
@ -92,41 +59,23 @@ WaterDefinition waterCreateDefinition()
return result;
}
void waterDeleteDefinition(WaterDefinition definition)
void waterDeleteDefinition(WaterDefinition* definition)
{
noiseDeleteGenerator(definition.waves_noise);
noiseDeleteGenerator(definition->waves_noise);
}
void waterCopyDefinition(WaterDefinition source, WaterDefinition* destination)
void waterCopyDefinition(WaterDefinition* source, WaterDefinition* destination)
{
NoiseGenerator* noise;
noise = destination->waves_noise;
*destination = source;
destination->waves_noise = noise;
noiseCopy(source.waves_noise, destination->waves_noise);
noiseCopy(source->waves_noise, destination->waves_noise);
}
void waterSetDefinition(WaterDefinition config)
void waterValidateDefinition(WaterDefinition* definition)
{
waterCopyDefinition(config, &_definition);
}
WaterDefinition waterGetDefinition()
{
return _definition;
}
void waterSetQuality(WaterQuality quality)
{
_quality = quality;
_quality.detail_boost = (_quality.detail_boost < 0.1) ? 0.1 : _quality.detail_boost;
}
WaterQuality waterGetQuality()
{
return _quality;
}
static inline double _getHeight(WaterDefinition* definition, double x, double z, double detail)
@ -180,44 +129,56 @@ static inline Vector3 _refractRay(Vector3 incoming, Vector3 normal)
}
}
WaterResult waterGetColorCustom(Vector3 location, Vector3 look, WaterDefinition* definition, WaterQuality* quality, WaterEnvironment* environment)
Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light)
{
double factor;
if (location.y < definition->height)
{
if (direction_to_light.y > 0.00001)
{
factor = (definition->height - location.y) / (direction_to_light.y * 5.0); // TODO Configurable
if (factor > 1.0)
{
factor = 1.0;
}
factor = 1.0 - 0.8 * factor;
light.r *= factor;
light.g *= factor;
light.b *= factor;
return light;
}
else
{
return COLOR_BLACK;
}
}
else
{
return light;
}
}
WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer, Vector3 location, Vector3 look)
{
WaterResult result;
RayCastingResult refracted;
Vector3 normal;
Color color;
ReceiverMaterial material;
SurfaceMaterial material;
double detail, depth;
if (definition == NULL)
{
definition = &_definition;
}
if (quality == NULL)
{
quality = &_quality;
}
if (environment == NULL)
{
environment = &_environment;
}
if (quality->force_detail != 0.0)
{
detail = quality->force_detail;
}
else
{
detail = renderGetPrecision(location) / quality->detail_boost;
}
detail = renderer->getPrecision(renderer, location);
location.y = _getHeight(definition, location.x, location.z, detail);
result.location = location;
normal = _getNormal(definition, location, detail);
look = v3Normalize(look);
result.reflected = environment->reflection_function(location, _reflectRay(look, normal)).hit_color;
refracted = environment->refraction_function(location, _refractRay(look, normal));
result.reflected = renderer->rayWalking(renderer, location, _reflectRay(look, normal), 0).hit_color;
refracted = renderer->rayWalking(renderer, location, _refractRay(look, normal), 0);
depth = v3Norm(v3Sub(location, refracted.hit_location));
if (depth > definition->transparency_depth)
{
@ -240,11 +201,11 @@ WaterResult waterGetColorCustom(Vector3 location, Vector3 look, WaterDefinition*
material.base = color;
material.reflection = 0.8;
material.shininess = 0.6;
color = lightingApplyCustom(location, normal, material, environment->lighting_definition, NULL, environment->lighting_environment);
if (environment->toggle_fog)
color = renderer->applyLightingToSurface(renderer, location, normal, material);
/*if (environment->toggle_fog)
{
color = fogApplyToLocation(location, color);
}
}*/
result.base = definition->main_color;
result.final = color;
@ -252,14 +213,14 @@ WaterResult waterGetColorCustom(Vector3 location, Vector3 look, WaterDefinition*
return result;
}
Color waterGetColor(Vector3 location, Vector3 look)
Color waterGetColor(WaterDefinition* definition, Renderer* renderer, Vector3 location, Vector3 look)
{
return waterGetColorCustom(location, look, &_definition, &_quality, &_environment).final;
return waterGetColorDetail(definition, renderer, location, look).final;
}
static int _postProcessFragment(RenderFragment* fragment)
{
fragment->vertex.color = waterGetColor(fragment->vertex.location, v3Sub(fragment->vertex.location, camera_location));
/* fragment->vertex.color = waterGetColor(fragment->vertex.location, v3Sub(fragment->vertex.location, camera_location)); */
return 1;
}
@ -293,46 +254,14 @@ static void _renderQuad(double x, double z, double size)
renderPushQuad(&v1, &v2, &v3, &v4);
}
Color waterLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data)
{
double factor;
if (location.y < _definition.height)
{
if (direction_to_light.y > 0.00001)
{
factor = (_definition.height - location.y) / (direction_to_light.y * 5.0); // TODO Configurable
if (factor > 1.0)
{
factor = 1.0;
}
factor = 1.0 - 0.8 * factor;
light.r *= factor;
light.g *= factor;
light.b *= factor;
return light;
}
else
{
return COLOR_BLACK;
}
}
else
{
return light;
}
}
void waterRender(RenderProgressCallback callback)
void waterRender(WaterDefinition* definition, Renderer* renderer, RenderProgressCallback callback)
{
int chunk_factor, chunk_count, i;
double cx = camera_location.x;
double cz = camera_location.z;
double cx = renderer->camera_location.x;
double cz = renderer->camera_location.z;
double radius_int, radius_ext, base_chunk_size, chunk_size;
base_chunk_size = 2.0 / (double)render_quality;
base_chunk_size = 2.0 / (double)renderer->render_quality;
chunk_factor = 1;
chunk_count = 2;

View file

@ -2,7 +2,9 @@
#define _PAYSAGES_WATER_H_
#include "shared/types.h"
#include "renderer.h"
#include "lighting.h"
#include "noise.h"
#include <stdio.h>
#ifdef __cplusplus
@ -22,21 +24,6 @@ typedef struct
double waves_noise_scale;
} WaterDefinition;
typedef struct
{
double detail_boost;
double force_detail;
} WaterQuality;
typedef struct
{
RayCastingFunction reflection_function;
RayCastingFunction refraction_function;
int toggle_fog;
LightingDefinition* lighting_definition;
LightingEnvironment* lighting_environment;
} WaterEnvironment;
typedef struct
{
Vector3 location;
@ -47,21 +34,18 @@ typedef struct
} WaterResult;
void waterInit();
void waterSave(FILE* f);
void waterLoad(FILE* f);
void waterSave(FILE* f, WaterDefinition* definition);
void waterLoad(FILE* f, WaterDefinition* definition);
WaterDefinition waterCreateDefinition();
void waterDeleteDefinition(WaterDefinition definition);
void waterCopyDefinition(WaterDefinition source, WaterDefinition* destination);
void waterSetDefinition(WaterDefinition definition);
WaterDefinition waterGetDefinition();
void waterSetQuality(WaterQuality quality);
WaterQuality waterGetQuality();
void waterDeleteDefinition(WaterDefinition* definition);
void waterCopyDefinition(WaterDefinition* source, WaterDefinition* destination);
void waterValidateDefinition(WaterDefinition* definition);
Color waterLightFilter(Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light, void* custom_data);
WaterResult waterGetColorCustom(Vector3 location, Vector3 look, WaterDefinition* definition, WaterQuality* quality, WaterEnvironment* environment);
Color waterGetColor(Vector3 location, Vector3 look);
void waterRender(RenderProgressCallback callback);
Color waterLightFilter(WaterDefinition* definition, Renderer* renderer, Color light, Vector3 location, Vector3 light_location, Vector3 direction_to_light);
WaterResult waterGetColorDetail(WaterDefinition* definition, Renderer* renderer, Vector3 location, Vector3 look);
Color waterGetColor(WaterDefinition* definition, Renderer* renderer, Vector3 location, Vector3 look);
void waterRender(WaterDefinition* definition, Renderer* renderer, RenderProgressCallback callback);
#ifdef __cplusplus
}