paysages: Refactored rendering to use a RenderArea.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@252 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-01-29 21:45:58 +00:00 committed by ThunderK
parent e5a64ebf9f
commit 878614e13c
29 changed files with 481 additions and 531 deletions

2
TODO
View file

@ -1,7 +1,7 @@
- Restore render interrupt and progress
- Clouds are lighted without filtering from ground (clouds lighted at night !)
- Camera should respect ratio aspect of render area.
- All noises should use the same entropy pool (saved separately), and avoid reallocs.
- Implement light multi-sampling (mainly for skydome).
- Remove all global variables (render_quality, render_width...), it should all be set in Renderer.
- Implement scaling and scrolling on previews.
- Water and terrain LOD moves with the camera, fix it like in the wanderer.

View file

@ -3,16 +3,17 @@
#include <string.h>
#include "../lib_paysages/auto.h"
#include "../lib_paysages/main.h"
#include "../lib_paysages/render.h"
#include "../lib_paysages/scenery.h"
void startRender(Renderer* renderer, char* outputpath)
void startRender(Renderer* renderer, char* outputpath, int width, int height, int quality)
{
printf("\rRendering %s ... \n", outputpath);
autoRenderSceneTwoPass(renderer, 0);
rendererStart(renderer, width, height, quality);
printf("\rSaving %s ... \n", outputpath);
remove(outputpath);
renderSaveToFile(outputpath);
renderSaveToFile(renderer->render_area, outputpath);
}
void displayHelp()
@ -97,19 +98,20 @@ int main(int argc, char** argv)
printf("Initializing ...\n");
paysagesInit();
renderer = sceneryGetStandardRenderer(conf_render_quality);
renderSetSize(conf_render_width, conf_render_height);
renderSetPreviewCallbacks(NULL, NULL, NULL, _previewUpdate);
renderer = sceneryCreateStandardRenderer();
rendererSetPreviewCallbacks(&renderer, NULL, NULL, _previewUpdate);
for (outputcount = 0; outputcount < conf_nb_pictures; outputcount++)
{
autoSetDaytimeFraction(conf_daytime_start);
sprintf(outputpath, "output/pic%05d.png", outputcount);
startRender(&renderer, outputpath);
startRender(&renderer, outputpath, conf_render_width, conf_render_height, conf_render_quality);
conf_daytime_start += conf_daytime_step;
}
rendererDelete(&renderer);
printf("\rDone. \n");

View file

@ -4,46 +4,21 @@
#include <QImage>
#include <QColor>
#include <QPainter>
#include "tools.h"
#include "../lib_paysages/render.h"
#include "../lib_paysages/scenery.h"
#include "../lib_paysages/auto.h"
class RenderThread:public QThread
{
public:
RenderThread(Renderer* renderer):QThread()
{
_renderer = renderer;
}
void run()
{
autoRenderSceneTwoPass(_renderer, 0);
}
private:
Renderer* _renderer;
};
static DialogRender* _current_dialog;
static void _renderResize(int width, int height)
static void _renderStart(int width, int height, Color background)
{
delete _current_dialog->pixbuf;
_current_dialog->pixbuf = new QImage(width, height, QImage::Format_ARGB32);
_current_dialog->area->setMinimumSize(width, height);
_current_dialog->area->setMaximumSize(width, height);
_current_dialog->area->resize(width, height);
_current_dialog->scroll->setMinimumSize(width > 800 ? 850 : width + 50, height > 600 ? 650 : height + 50);
}
static void _renderClear(Color col)
{
_current_dialog->pixbuf->fill(QColor(col.r * 255.0, col.g * 255.0, col.b * 255.0).rgb());
_current_dialog->pixbuf->fill(colorToQColor(background).rgb());
}
static void _renderDraw(int x, int y, Color col)
{
_current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, QColor(col.r * 255.0, col.g * 255.0, col.b * 255.0).rgb());
_current_dialog->pixbuf->setPixel(x, _current_dialog->pixbuf->height() - 1 - y, colorToQColor(col).rgb());
}
static void _renderUpdate(double progress)
@ -52,6 +27,27 @@ static void _renderUpdate(double progress)
_current_dialog->progress_value = progress * 1000.0;
}
class RenderThread:public QThread
{
public:
RenderThread(Renderer* renderer, int width, int height, int quality):QThread()
{
_renderer = renderer;
_width = width;
_height = height;
_quality = quality;
}
void run()
{
rendererStart(_renderer, _width, _height, _quality);
}
private:
Renderer* _renderer;
int _width;
int _height;
int _quality;
};
class RenderArea:public QWidget
{
public:
@ -76,6 +72,7 @@ DialogRender::DialogRender(QWidget *parent):
pixbuf = new QImage(1, 1, QImage::Format_ARGB32);
_current_dialog = this;
render_thread = NULL;
renderer = sceneryCreateStandardRenderer();
setModal(true);
setWindowTitle("Paysages 3D - Render");
@ -99,23 +96,29 @@ DialogRender::~DialogRender()
{
if (render_thread)
{
renderInterrupt();
rendererInterrupt(&renderer);
render_thread->wait();
renderSetPreviewCallbacks(NULL, NULL, NULL, NULL);
rendererSetPreviewCallbacks(&renderer, NULL, NULL, NULL);
delete render_thread;
}
rendererDelete(&renderer);
delete pixbuf;
}
void DialogRender::startRender(int quality, int width, int height)
{
renderer = sceneryGetStandardRenderer(quality);
renderSetSize(width, height);
renderSetPreviewCallbacks(_renderResize, _renderClear, _renderDraw, _renderUpdate);
delete pixbuf;
pixbuf = new QImage(width, height, QImage::Format_ARGB32);
area->setMinimumSize(width, height);
area->setMaximumSize(width, height);
area->resize(width, height);
scroll->setMinimumSize(width > 800 ? 850 : width + 50, height > 600 ? 650 : height + 50);
rendererSetPreviewCallbacks(&renderer, _renderStart, _renderDraw, _renderUpdate);
render_thread = new RenderThread(&renderer);
render_thread = new RenderThread(&renderer, width, height, quality);
render_thread->start();
exec();
@ -124,7 +127,7 @@ void DialogRender::startRender(int quality, int width, int height)
void DialogRender::loadLastRender()
{
progress->hide();
renderSetPreviewCallbacks(_renderResize, _renderClear, _renderDraw, _renderUpdate);
//renderSetPreviewCallbacks(_renderStart, _renderDraw, _renderUpdate);
exec();
}

View file

@ -74,7 +74,7 @@ void FormRender::saveRender()
filepath = QFileDialog::getSaveFileName(this, "Choose a filename to save the last render");
if (!filepath.isNull())
{
renderSaveToFile((char*)filepath.toStdString().c_str());
//renderSaveToFile((char*)filepath.toStdString().c_str());
QMessageBox::information(this, "Message", "The picture " + filepath + " has been saved.");
}
}

View file

@ -20,7 +20,7 @@ public:
PreviewEast(QWidget* parent):
Preview(parent)
{
_renderer = rendererGetFake();
_renderer = rendererCreate();
_preview_definition = skyCreateDefinition();
}
protected:
@ -50,7 +50,7 @@ public:
PreviewWest(QWidget* parent):
Preview(parent)
{
_renderer = rendererGetFake();
_renderer = rendererCreate();
_preview_definition = skyCreateDefinition();
}
protected:

View file

@ -40,7 +40,7 @@ class PreviewTerrainColor:public Preview
public:
PreviewTerrainColor(QWidget* parent):Preview(parent)
{
_renderer = rendererGetFake();
_renderer = rendererCreate();
_renderer.applyTextures = _applyTextures;
_renderer.getTerrainHeight = _getTerrainHeight;
/*_renderer.applyLightingToSurface = _applyLightingToSurface;*/

View file

@ -72,7 +72,7 @@ public:
lightingAddLight(&_lighting, light);
lightingValidateDefinition(&_lighting);
_renderer = rendererGetFake();
_renderer = rendererCreate();
_renderer.rayWalking = _rayWalking;
_renderer.applyLightingToSurface = _applyLightingToSurface;
_renderer.customData[0] = &_water;

View file

@ -6,7 +6,6 @@
#include "shared/types.h"
#include "shared/constants.h"
#include "shared/globals.h"
#include "clouds.h"
#include "color.h"
#include "lighting.h"
@ -20,8 +19,6 @@
#include "water.h"
#include "zone.h"
static int _is_rendering = 0;
void autoSetDaytime(int hour, int minute)
{
autoSetDaytimeFraction((double)hour / 24.0 + (double)minute / 1440.0);
@ -231,66 +228,3 @@ void autoGenRealisticLandscape(int seed)
scenerySetAtmosphere(&atmosphere);
atmosphereDeleteDefinition(&atmosphere);
}
void* _renderFirstPass(void* data)
{
sceneryRenderFirstPass((Renderer*)data);
_is_rendering = 0;
return NULL;
}
void autoRenderSceneTwoPass(Renderer* renderer, int postonly)
{
Thread* thread;
int loops;
if (!postonly)
{
renderClear();
_is_rendering = 1;
thread = threadCreate(_renderFirstPass, renderer);
loops = 0;
while (_is_rendering)
{
timeSleepMs(100);
if (++loops >= 10)
{
renderUpdate();
loops = 0;
}
}
threadJoin(thread);
}
sceneryRenderSecondPass(renderer);
}
static int _postProcessRayTracingOverlay(RenderFragment* fragment)
{
Vector3 terrain_hit, look;
// 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()
{
// TODO
/*renderClear();
cameraPushOverlay(COLOR_RED, _postProcessRayTracingOverlay);
renderUpdate();
if (renderSetNextProgressStep(0.0, 1.0))
{
renderPostProcess(_cpu_count);
}*/
}

View file

@ -10,8 +10,6 @@ extern "C" {
void autoSetDaytime(int hour, int minute);
void autoSetDaytimeFraction(double daytime);
void autoGenRealisticLandscape(int seed);
void autoRenderSceneTwoPass(Renderer* renderer, int postonly);
void autoRenderSceneRayTracing();
#ifdef __cplusplus
}

View file

@ -5,7 +5,6 @@
#include "euclid.h"
#include "render.h"
#include "shared/types.h"
#include "shared/globals.h"
#include "shared/constants.h"
#include "scenery.h"
#include "tools.h"
@ -211,25 +210,25 @@ void cameraRotateRoll(CameraDefinition* camera, double value)
cameraValidateDefinition(camera, 0);
}
Vector3 cameraProject(CameraDefinition* camera, Vector3 point)
Vector3 cameraProject(CameraDefinition* camera, Renderer* renderer, Vector3 point)
{
point = m4Transform(camera->project, point);
point.x = (point.x + 1.0) * 0.5 * (double)render_width;
point.y = (-point.y + 1.0) * 0.5 * (double)render_height;
point.x = (point.x + 1.0) * 0.5 * (double)renderer->render_width;
point.y = (-point.y + 1.0) * 0.5 * (double)renderer->render_height;
return point;
}
Vector3 cameraUnproject(CameraDefinition* camera, Vector3 point)
Vector3 cameraUnproject(CameraDefinition* camera, Renderer* renderer, Vector3 point)
{
point.x = (point.x / (0.5 * (double)render_width) - 1.0);
point.y = -(point.y / (0.5 * (double)render_height) - 1.0);
point.x = (point.x / (0.5 * (double)renderer->render_width) - 1.0);
point.y = -(point.y / (0.5 * (double)renderer->render_height) - 1.0);
return m4Transform(camera->unproject, point);
}
void cameraProjectToFragment(CameraDefinition* camera, double x, double y, double z, RenderFragment* result)
void cameraProjectToFragment(CameraDefinition* camera, Renderer* renderer, double x, double y, double z, RenderFragment* result)
{
Vector3 point = {x, y, z};
point = cameraProject(camera, point);
point = cameraProject(camera, renderer, point);
result->x = lround(point.x);
result->y = lround(point.y);
result->z = point.z;
@ -242,9 +241,9 @@ void cameraProjectToFragment(CameraDefinition* camera, double x, double y, doubl
* @param col Color of the polygon.
* @param callback Post-processing callback.
*/
void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCallback callback)
/*void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCallback callback)
{
/*Vertex v1, v2, v3, v4;
Vertex v1, v2, v3, v4;
Vector3 v;
v.x = 0.0;
@ -275,5 +274,5 @@ void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCall
v4.color = col;
v4.callback = callback;
renderPushQuad(&v1, &v2, &v3, &v4);*/
}
renderPushQuad(&v1, &v2, &v3, &v4);
}*/

View file

@ -1,8 +1,9 @@
#ifndef _PAYSAGES_CAMERA_H_
#define _PAYSAGES_CAMERA_H_
#include "shared/types.h"
#include <stdio.h>
#include "shared/types.h"
#include "renderer.h"
#ifdef __cplusplus
extern "C" {
@ -48,10 +49,10 @@ void cameraRotateYaw(CameraDefinition* camera, double value);
void cameraRotatePitch(CameraDefinition* camera, double value);
void cameraRotateRoll(CameraDefinition* camera, double value);
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);
Vector3 cameraProject(CameraDefinition* camera, Renderer* renderer, Vector3 point);
Vector3 cameraUnproject(CameraDefinition* camera, Renderer* renderer, Vector3 point);
void cameraProjectToFragment(CameraDefinition* camera, Renderer* renderer, double x, double y, double z, RenderFragment* result);
/*void cameraPushOverlay(CameraDefinition* camera, Color col, f_RenderFragmentCallback callback);*/
#ifdef __cplusplus
}

View file

@ -8,7 +8,6 @@
#include "tools.h"
#include "shared/types.h"
#include "shared/constants.h"
#include "shared/globals.h"
typedef struct
{

View file

@ -7,7 +7,6 @@
#include "shared/types.h"
#include "shared/constants.h"
#include "shared/globals.h"
#include "color.h"
#include "euclid.h"
#include "renderer.h"

View file

@ -6,7 +6,6 @@
#include "shared/types.h"
#include "shared/constants.h"
#include "shared/globals.h"
#include "auto.h"
#include "system.h"

View file

@ -11,164 +11,145 @@
#include "color.h"
#include "system.h"
int render_width;
int render_height;
int render_quality;
static int _pixel_count;
static Array* render_zone = NULL;
static RenderFragment* scanline_up;
static RenderFragment* scanline_down;
static int scanline_left;
static int scanline_right;
static Color background_color;
static volatile int _dirty_left;
static volatile int _dirty_right;
static volatile int _dirty_up;
static volatile int _dirty_down;
static volatile int _dirty_count;
static Mutex* _lock;
static volatile int _interrupt = 0;
static volatile int _progress_pixels;
static volatile double _progress = 0.0;
static volatile double _progress_step_start = 0.0;
static volatile double _progress_step_length = 1.0;
struct RenderArea
{
int width;
int height;
int pixel_count;
Array* pixels;
RenderFragment* scanline_up;
RenderFragment* scanline_down;
int scanline_left;
int scanline_right;
Color background_color;
volatile int dirty_left;
volatile int dirty_right;
volatile int dirty_up;
volatile int dirty_down;
volatile int dirty_count;
Mutex* lock;
RenderCallbackStart callback_start;
RenderCallbackDraw callback_draw;
RenderCallbackUpdate callback_update;
};
/*#define RENDER_INVERSE 1*/
#define RENDER_WIREFRAME 1
static void _previewResize(int width, int height) {}
static void _previewClear(Color col) {}
static void _previewDraw(int x, int y, Color col) {}
static void _previewUpdate(double progress) {}
static PreviewCallbackResize _cb_preview_resize = _previewResize;
static PreviewCallbackClear _cb_preview_clear = _previewClear;
static PreviewCallbackDraw _cb_preview_draw = _previewDraw;
static PreviewCallbackUpdate _cb_preview_update = _previewUpdate;
void renderSave(FILE* f)
{
}
void renderLoad(FILE* f)
{
}
static void _callbackStart(int width, int height, Color background) {}
static void _callbackDraw(int x, int y, Color col) {}
static void _callbackUpdate(double progress) {}
void renderInit()
{
_lock = mutexCreate();
renderSetBackgroundColor(&COLOR_BLACK);
}
void renderSetSize(int width, int height)
RenderArea* renderCreateArea()
{
RenderArea* result;
result = malloc(sizeof(RenderArea));
result->width = 1;
result->height = 1;
result->pixel_count = 1;
result->pixels = malloc(sizeof(Array));
arrayCreate(result->pixels, sizeof(RenderFragment));
result->scanline_up = malloc(sizeof(RenderFragment));
result->scanline_down = malloc(sizeof(RenderFragment));
result->scanline_left = 0;
result->scanline_right = 0;
result->background_color = COLOR_TRANSPARENT;
result->dirty_left = 1;
result->dirty_right = -1;
result->dirty_down = 1;
result->dirty_up = -1;
result->dirty_count = 0;
result->lock = mutexCreate();
result->callback_start = _callbackStart;
result->callback_draw = _callbackDraw;
result->callback_update = _callbackUpdate;
return result;
}
void renderDeleteArea(RenderArea* area)
{
mutexDestroy(area->lock);
arrayDelete(area->pixels);
free(area->scanline_up);
free(area->scanline_down);
free(area);
}
void renderSetSize(RenderArea* area, int width, int height)
{
int x;
int y;
if (render_zone != NULL)
for (x = 0; x < area->width; x++)
{
/* Delete previous render zone */
for (x = 0; x < render_width; x++)
for (y = 0; y < area->height; y++)
{
for (y = 0; y < render_height; y++)
{
arrayDelete(render_zone + (y * render_width + x));
}
arrayDelete(area->pixels + (y * area->width + x));
}
free(render_zone);
free(scanline_up);
free(scanline_down);
}
render_width = width;
render_height = height;
render_zone = malloc(sizeof(Array) * width * height);
area->width = width;
area->height = height;
area->pixels = realloc(area->pixels, sizeof(Array) * width * height);
area->pixel_count = width * height;
scanline_left = 0;
scanline_right = render_width - 1;
scanline_up = malloc(sizeof(RenderFragment) * width);
scanline_down = malloc(sizeof(RenderFragment) * width);
area->scanline_left = 0;
area->scanline_right = width - 1;
area->scanline_up = realloc(area->scanline_up, sizeof(RenderFragment) * width);
area->scanline_down = realloc(area->scanline_down, sizeof(RenderFragment) * width);
_dirty_left = render_width;
_dirty_right = -1;
_dirty_down = render_height;
_dirty_up = -1;
_dirty_count = 0;
_pixel_count = render_width * render_height;
area->dirty_left = width;
area->dirty_right = -1;
area->dirty_down = height;
area->dirty_up = -1;
area->dirty_count = 0;
for (y = 0; y < height; y++)
{
for (x = 0; x < width; x++)
{
arrayCreate(render_zone + (y * width + x), sizeof(RenderFragment));
arrayCreate(area->pixels + (y * width + x), sizeof(RenderFragment));
}
}
_cb_preview_resize(render_width, render_height);
_cb_preview_clear(background_color);
}
int renderSetQuality(int quality)
void renderSetBackgroundColor(RenderArea* area, Color* col)
{
if (quality < 1)
{
render_quality = 1;
}
else if (quality > 10)
{
render_quality = 10;
}
else
{
render_quality = quality;
}
return render_quality;
area->background_color = *col;
}
void renderClear()
void renderClear(RenderArea* area)
{
int x;
int y;
for (x = 0; x < render_width; x++)
for (x = 0; x < area->width; x++)
{
for (y = 0; y < render_height; y++)
for (y = 0; y < area->height; y++)
{
arrayClear(render_zone + (y * render_width + x));
arrayClear(area->pixels + (y * area->width + x));
}
}
scanline_left = 0;
scanline_right = render_width - 1;
area->scanline_left = 0;
area->scanline_right = area->width - 1;
_progress = 0.0;
_progress_step_start = 0.0;
_progress_step_length = 0.0;
_interrupt = 0;
area->callback_start(area->width, area->height, area->background_color);
_cb_preview_clear(background_color);
_cb_preview_update(_progress * _progress_step_length + _progress_step_start);
_dirty_left = render_width;
_dirty_right = -1;
_dirty_down = render_height;
_dirty_up = -1;
_dirty_count = 0;
area->dirty_left = area->width;
area->dirty_right = -1;
area->dirty_down = area->height;
area->dirty_up = -1;
area->dirty_count = 0;
}
void renderInterrupt()
{
_interrupt = 1;
}
void renderSetBackgroundColor(Color* col)
{
background_color = *col;
}
int _sortRenderFragment(void const* a, void const* b)
/*static int _sortRenderFragment(void const* a, void const* b)
{
double za, zb;
za = ((RenderFragment*)a)->z;
@ -185,12 +166,11 @@ int _sortRenderFragment(void const* a, void const* b)
{
return 0;
}
}
}*/
static Color _getPixelColor(Array* pixel_data)
static Color _getPixelColor(Color base, Array* pixel_data)
{
RenderFragment* fragment;
Color result = background_color;
int i;
if (pixel_data->length > 0)
@ -198,84 +178,91 @@ static Color _getPixelColor(Array* pixel_data)
for (i = 0; i < pixel_data->length; i++)
{
fragment = ((RenderFragment*)pixel_data->data) + i;
colorMask(&result, &(fragment->vertex.color));
colorMask(&base, &(fragment->vertex.color));
}
}
return result;
return base;
}
static inline void _setDirtyPixel(Array* pixel_data, int x, int y)
static inline void _setDirtyPixel(RenderArea* area, Array* pixel_data, int x, int y)
{
pixel_data->dirty = 1;
if (x < _dirty_left)
if (x < area->dirty_left)
{
_dirty_left = x;
area->dirty_left = x;
}
if (x > _dirty_right)
if (x > area->dirty_right)
{
_dirty_right = x;
area->dirty_right = x;
}
if (y < _dirty_down)
if (y < area->dirty_down)
{
_dirty_down = y;
area->dirty_down = y;
}
if (y > _dirty_up)
if (y > area->dirty_up)
{
_dirty_up = y;
area->dirty_up = y;
}
_dirty_count++;
area->dirty_count++;
}
static void _processDirtyPixels()
static void _processDirtyPixels(RenderArea* area)
{
Color col;
Array* pixel_data;
int x, y;
for (y = _dirty_down; y <= _dirty_up; y++)
for (y = area->dirty_down; y <= area->dirty_up; y++)
{
for (x = _dirty_left; x <= _dirty_right; x++)
for (x = area->dirty_left; x <= area->dirty_right; x++)
{
pixel_data = render_zone + y * render_width + x;
pixel_data = area->pixels + y * area->width + x;
if (pixel_data->dirty)
{
col = _getPixelColor(pixel_data);
_cb_preview_draw(x, y, col);
col = _getPixelColor(area->background_color, pixel_data);
area->callback_draw(x, y, col);
pixel_data->dirty = 0;
}
}
}
_cb_preview_update(_progress * _progress_step_length + _progress_step_start);
area->callback_update(0.0);
_dirty_left = render_width;
_dirty_right = -1;
_dirty_down = render_height;
_dirty_up = -1;
_dirty_count = 0;
area->dirty_left = area->width;
area->dirty_right = -1;
area->dirty_down = area->height;
area->dirty_up = -1;
area->dirty_count = 0;
}
static void _setAllDirty()
void renderUpdate(RenderArea* area)
{
mutexAcquire(area->lock);
_processDirtyPixels(area);
mutexRelease(area->lock);
}
static void _setAllDirty(RenderArea* area)
{
int x, y;
_dirty_left = 0;
_dirty_right = render_width - 1;
_dirty_down = 0;
_dirty_up = render_height - 1;
area->dirty_left = 0;
area->dirty_right = area->width - 1;
area->dirty_down = 0;
area->dirty_up = area->height - 1;
for (y = _dirty_down; y <= _dirty_up; y++)
for (y = area->dirty_down; y <= area->dirty_up; y++)
{
for (x = _dirty_left; x <= _dirty_right; x++)
for (x = area->dirty_left; x <= area->dirty_right; x++)
{
(render_zone + y * render_width + x)->dirty = 1;
(area->pixels + y * area->width + x)->dirty = 1;
}
}
}
void renderAddFragment(RenderFragment* fragment)
void renderAddFragment(RenderArea* area, RenderFragment* fragment)
{
Array* pixel_data;
int x = fragment->x;
@ -287,9 +274,9 @@ void renderAddFragment(RenderFragment* fragment)
RenderFragment* fragments;
dirty = 0;
if (x >= 0 && x < render_width && y >= 0 && y < render_height && z > 1.0)
if (x >= 0 && x < area->width && y >= 0 && y < area->height && z > 1.0)
{
pixel_data = render_zone + (y * render_width + x);
pixel_data = area->pixels + (y * area->width + x);
fragments = (RenderFragment*)pixel_data->data;
fragments_count = pixel_data->length;
@ -336,12 +323,12 @@ void renderAddFragment(RenderFragment* fragment)
if (dirty)
{
_setDirtyPixel(pixel_data, x, y);
_setDirtyPixel(area, pixel_data, x, y);
}
}
}
void renderPushFragment(int x, int y, double z, Vertex* vertex)
void renderPushFragment(RenderArea* area, int x, int y, double z, Vertex* vertex)
{
RenderFragment fragment;
@ -350,7 +337,7 @@ void renderPushFragment(int x, int y, double z, Vertex* vertex)
fragment.z = z;
fragment.vertex = *vertex;
renderAddFragment(&fragment);
renderAddFragment(area, &fragment);
}
static void __vertexGetDiff(Vertex* v1, Vertex* v2, Vertex* result)
@ -385,43 +372,43 @@ static void __vertexInterpolate(Vertex* v1, Vertex* diff, double value, Vertex*
result->callback_data = v1->callback_data;
}
static void __pushScanLinePoint(RenderFragment point)
static void __pushScanLinePoint(RenderArea* area, RenderFragment point)
{
if (point.x < 0 || point.x >= render_width)
if (point.x < 0 || point.x >= area->width)
{
return;
}
if (point.x > scanline_right)
if (point.x > area->scanline_right)
{
scanline_right = point.x;
scanline_up[scanline_right] = point;
scanline_down[scanline_right] = point;
if (point.x < scanline_left)
area->scanline_right = point.x;
area->scanline_up[area->scanline_right] = point;
area->scanline_down[area->scanline_right] = point;
if (point.x < area->scanline_left)
{
scanline_left = point.x;
area->scanline_left = point.x;
}
}
else if (point.x < scanline_left)
else if (point.x < area->scanline_left)
{
scanline_left = point.x;
scanline_up[scanline_left] = point;
scanline_down[scanline_left] = point;
area->scanline_left = point.x;
area->scanline_up[area->scanline_left] = point;
area->scanline_down[area->scanline_left] = point;
}
else
{
if (point.y > scanline_up[point.x].y)
if (point.y > area->scanline_up[point.x].y)
{
scanline_up[point.x] = point;
area->scanline_up[point.x] = point;
}
if (point.y < scanline_down[point.x].y)
if (point.y < area->scanline_down[point.x].y)
{
scanline_down[point.x] = point;
area->scanline_down[point.x] = point;
}
}
}
static void __pushScanLineEdge(Vector3 v1, Vector3 v2, Vertex* vertex1, Vertex* vertex2)
static void __pushScanLineEdge(RenderArea* area, Vector3 v1, Vector3 v2, Vertex* vertex1, Vertex* vertex2)
{
double dx, dy, dz, fx;
Vertex diff;
@ -432,9 +419,9 @@ static void __pushScanLineEdge(Vector3 v1, Vector3 v2, Vertex* vertex1, Vertex*
if (endx < startx)
{
__pushScanLineEdge(v2, v1, vertex2, vertex1);
__pushScanLineEdge(area, v2, v1, vertex2, vertex1);
}
else if (endx < 0 || startx >= render_width)
else if (endx < 0 || startx >= area->width)
{
return;
}
@ -445,14 +432,14 @@ static void __pushScanLineEdge(Vector3 v1, Vector3 v2, Vertex* vertex1, Vertex*
fragment.z = v1.z;
fragment.vertex = *vertex1;
__pushScanLinePoint(fragment);
__pushScanLinePoint(area, fragment);
fragment.x = endx;
fragment.y = lround(v2.y);
fragment.z = v2.z;
fragment.vertex = *vertex2;
__pushScanLinePoint(fragment);
__pushScanLinePoint(area, fragment);
}
else
{
@ -460,9 +447,9 @@ static void __pushScanLineEdge(Vector3 v1, Vector3 v2, Vertex* vertex1, Vertex*
{
startx = 0;
}
if (endx >= render_width)
if (endx >= area->width)
{
endx = render_width - 1;
endx = area->width - 1;
}
dx = v2.x - v1.x;
@ -486,41 +473,41 @@ static void __pushScanLineEdge(Vector3 v1, Vector3 v2, Vertex* vertex1, Vertex*
fragment.z = v1.z + dz * fx / dx;
__vertexInterpolate(vertex1, &diff, fx / dx, &(fragment.vertex));
__pushScanLinePoint(fragment);
__pushScanLinePoint(area, fragment);
}
}
}
static void __clearScanLines()
static void __clearScanLines(RenderArea* area)
{
int x;
for (x = scanline_left; x <= scanline_right; x++)
for (x = area->scanline_left; x <= area->scanline_right; x++)
{
scanline_up[x].y = -1;
scanline_down[x].y = render_height;
area->scanline_up[x].y = -1;
area->scanline_down[x].y = area->height;
}
scanline_left = render_width;
scanline_right = -1;
area->scanline_left = area->width;
area->scanline_right = -1;
}
static void __renderScanLines()
static void __renderScanLines(RenderArea* area)
{
int x, starty, endy, cury;
Vertex diff;
double dy, dz, fy;
RenderFragment up, down, current;
if (scanline_right > 0)
if (area->scanline_right > 0)
{
for (x = scanline_left; x <= scanline_right; x++)
for (x = area->scanline_left; x <= area->scanline_right; x++)
{
up = scanline_up[x];
down = scanline_down[x];
up = area->scanline_up[x];
down = area->scanline_down[x];
starty = down.y;
endy = up.y;
if (endy < 0 || starty >= render_height)
if (endy < 0 || starty >= area->height)
{
continue;
}
@ -529,9 +516,9 @@ static void __renderScanLines()
{
starty = 0;
}
if (endy >= render_height)
if (endy >= area->height)
{
endy = render_height - 1;
endy = area->height - 1;
}
dy = (double)(up.y - down.y);
@ -554,21 +541,16 @@ static void __renderScanLines()
}
#endif
renderAddFragment(&current);
renderAddFragment(area, &current);
}
}
}
}
void renderPushTriangle(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3)
void renderPushTriangle(RenderArea* area, Vertex* v1, Vertex* v2, Vertex* v3, Vector3 p1, Vector3 p2, Vector3 p3)
{
Vector3 p1, p2, p3;
double limit_width = (double)(render_width - 1);
double limit_height = (double)(render_height - 1);
p1 = renderer->projectPoint(renderer, v1->location);
p2 = renderer->projectPoint(renderer, v2->location);
p3 = renderer->projectPoint(renderer, v3->location);
double limit_width = (double)(area->width - 1);
double limit_height = (double)(area->height - 1);
/* Filter if outside screen */
if (p1.z < 1.0 || p2.z < 1.0 || p3.z < 1.0 || (p1.x < 0.0 && p2.x < 0.0 && p3.x < 0.0) || (p1.y < 0.0 && p2.y < 0.0 && p3.y < 0.0) || (p1.x > limit_width && p2.x > limit_width && p3.x > limit_width) || (p1.y > limit_height && p2.y > limit_height && p3.y > limit_height))
@ -576,19 +558,13 @@ void renderPushTriangle(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3)
return;
}
__clearScanLines();
__pushScanLineEdge(p1, p2, v1, v2);
__pushScanLineEdge(p2, p3, v2, v3);
__pushScanLineEdge(p3, p1, v3, v1);
mutexAcquire(_lock);
__renderScanLines();
mutexRelease(_lock);
}
void renderPushQuad(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3, Vertex* v4)
{
renderPushTriangle(renderer, v2, v3, v1);
renderPushTriangle(renderer, v4, v1, v3);
__clearScanLines(area);
__pushScanLineEdge(area, p1, p2, v1, v2);
__pushScanLineEdge(area, p2, p3, v2, v3);
__pushScanLineEdge(area, p3, p1, v3, v1);
mutexAcquire(area->lock);
__renderScanLines(area);
mutexRelease(area->lock);
}
typedef struct {
@ -599,6 +575,7 @@ typedef struct {
int finished;
int interrupt;
Thread* thread;
RenderArea* area;
Renderer* renderer;
} RenderChunk;
@ -618,7 +595,7 @@ void* _renderPostProcessChunk(void* data)
{
for (x = chunk->startx; x <= chunk->endx; x++)
{
pixel_data = render_zone + (y * render_width + x);
pixel_data = chunk->area->pixels + (y * chunk->area->width + x);
fragments = (RenderFragment*)pixel_data->data;
dirty = 0;
for (i = 0; i < pixel_data->length; i++)
@ -627,7 +604,6 @@ void* _renderPostProcessChunk(void* data)
{
if (fragments[i].vertex.callback(fragments + i, chunk->renderer, fragments[i].vertex.callback_data))
{
/* TODO Store over-exposure */
colorNormalize(&fragments[i].vertex.color);
dirty = 1;
}
@ -635,11 +611,11 @@ void* _renderPostProcessChunk(void* data)
}
if (dirty)
{
mutexAcquire(_lock);
_setDirtyPixel(pixel_data, x, y);
mutexRelease(_lock);
mutexAcquire(chunk->area->lock);
_setDirtyPixel(chunk->area, pixel_data, x, y);
mutexRelease(chunk->area->lock);
}
_progress_pixels++;
/* chunk->area->progress_pixels++; */
}
if (chunk->interrupt)
{
@ -652,12 +628,13 @@ void* _renderPostProcessChunk(void* data)
}
#define MAX_CHUNKS 8
void renderPostProcess(Renderer* renderer, int nbchunks)
void renderPostProcess(RenderArea* area, Renderer* renderer, int nbchunks)
{
volatile RenderChunk chunks[MAX_CHUNKS];
int i;
int x, y, dx, dy, nx, ny;
int loops, running;
int _interrupt = 0; /* TEMP */
if (nbchunks > MAX_CHUNKS)
{
@ -670,15 +647,16 @@ void renderPostProcess(Renderer* renderer, int nbchunks)
nx = 10;
ny = 10;
dx = render_width / nx;
dy = render_height / ny;
dx = area->width / nx;
dy = area->height / ny;
x = 0;
y = 0;
_progress_pixels = 0;
/*_progress_pixels = 0;*/
for (i = 0; i < nbchunks; i++)
{
chunks[i].thread = NULL;
chunks[i].area = area;
chunks[i].renderer = renderer;
}
@ -711,7 +689,7 @@ void renderPostProcess(Renderer* renderer, int nbchunks)
chunks[i].startx = x * dx;
if (x == nx)
{
chunks[i].endx = render_width - 1;
chunks[i].endx = area->width - 1;
}
else
{
@ -720,7 +698,7 @@ void renderPostProcess(Renderer* renderer, int nbchunks)
chunks[i].starty = y * dy;
if (y == ny)
{
chunks[i].endy = render_height - 1;
chunks[i].endy = area->height - 1;
}
else
{
@ -740,27 +718,20 @@ void renderPostProcess(Renderer* renderer, int nbchunks)
if (++loops >= 10)
{
mutexAcquire(_lock);
_progress = (double)_progress_pixels / (double)_pixel_count;
_processDirtyPixels();
mutexRelease(_lock);
mutexAcquire(area->lock);
/*_progress = (double)_progress_pixels / (double)_pixel_count;*/
_processDirtyPixels(area);
mutexRelease(area->lock);
loops = 0;
}
}
_progress = 1.0;
_processDirtyPixels();
/*_progress = 1.0;*/
_processDirtyPixels(area);
}
void renderUpdate()
{
mutexAcquire(_lock);
_processDirtyPixels();
mutexRelease(_lock);
}
void renderSaveToFile(const char* path)
void renderSaveToFile(RenderArea* area, const char* path)
{
ILuint image_id;
ilGenImages(1, &image_id);
@ -768,22 +739,22 @@ void renderSaveToFile(const char* path)
Color result;
ILuint x, y;
ILuint rgba;
ILuint data[render_height * render_width];
ILuint data[area->height * area->width];
ILenum error;
Array* pixel_data;
for (y = 0; y < render_height; y++)
for (y = 0; y < area->height; y++)
{
for (x = 0; x < render_width; x++)
for (x = 0; x < area->width; x++)
{
pixel_data = render_zone + (y * render_width + x);
result = _getPixelColor(pixel_data);
pixel_data = area->pixels + (y * area->width + x);
result = _getPixelColor(area->background_color, pixel_data);
rgba = colorTo32BitRGBA(&result);
data[y * render_width + x] = rgba;
data[y * area->width + x] = rgba;
}
}
ilTexImage((ILuint)render_width, (ILuint)render_height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, data);
ilTexImage((ILuint)area->width, (ILuint)area->height, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE, data);
ilSaveImage(path);
ilDeleteImages(1, &image_id);
@ -794,46 +765,16 @@ void renderSaveToFile(const char* path)
}
}
void renderSetPreviewCallbacks(PreviewCallbackResize resize, PreviewCallbackClear clear, PreviewCallbackDraw draw, PreviewCallbackUpdate update)
void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
{
_cb_preview_resize = resize ? resize : _previewResize;
_cb_preview_clear = clear ? clear : _previewClear;
_cb_preview_draw = draw ? draw : _previewDraw;
_cb_preview_update = update ? update : _previewUpdate;
area->callback_start = start ? start : _callbackStart;
area->callback_draw = draw ? draw : _callbackDraw;
area->callback_update = update ? update : _callbackUpdate;
_cb_preview_resize(render_width, render_height);
_cb_preview_clear(background_color);
area->callback_start(area->width, area->height, area->background_color);
_setAllDirty();
_processDirtyPixels();
_setAllDirty(area);
_processDirtyPixels(area);
_cb_preview_update(1.0);
}
int renderSetNextProgressStep(double start, double end)
{
if (_interrupt)
{
return 0;
}
else
{
_progress = 0.0;
_progress_step_start = start;
_progress_step_length = end - start;
return 1;
}
}
int renderTellProgress(double progress)
{
if (_interrupt)
{
return 0;
}
else
{
_progress = progress;
return 1;
}
area->callback_update(0.0);
}

View file

@ -10,23 +10,21 @@ extern "C" {
#endif
void renderInit();
void renderSave(FILE* f);
void renderLoad(FILE* f);
void renderSetSize(int width, int height);
int renderSetQuality(int quality);
void renderClear();
void renderUpdate();
void renderInterrupt();
void renderSetBackgroundColor(Color* col);
void renderAddFragment(RenderFragment* fragment);
void renderPushFragment(int x, int y, double z, Vertex* vertex);
void renderPushTriangle(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3);
void renderPushQuad(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3, Vertex* v4);
void renderPostProcess(Renderer* renderer, int nbchunks);
void renderSaveToFile(const char* path);
void renderSetPreviewCallbacks(PreviewCallbackResize resize, PreviewCallbackClear clear, PreviewCallbackDraw draw, PreviewCallbackUpdate update);
int renderSetNextProgressStep(double start, double end);
int renderTellProgress(double progress);
RenderArea* renderCreateArea();
void renderDeleteArea(RenderArea* area);
void renderSetSize(RenderArea* area, int width, int height);
void renderSetBackgroundColor(RenderArea* area, Color* col);
void renderClear(RenderArea* area);
void renderUpdate(RenderArea* area);
void renderAddFragment(RenderArea* area, RenderFragment* fragment);
void renderPushFragment(RenderArea* area, int x, int y, double z, Vertex* vertex);
void renderPushTriangle(RenderArea* area, Vertex* v1, Vertex* v2, Vertex* v3, Vector3 p1, Vector3 p2, Vector3 p3);
void renderPostProcess(RenderArea* area, Renderer* renderer, int nbchunks);
void renderSaveToFile(RenderArea* area, const char* path);
void renderSetPreviewCallbacks(RenderArea* area, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update);
#ifdef __cplusplus

View file

@ -1,10 +1,59 @@
#include "renderer.h"
#include "shared/constants.h"
#include "lighting.h"
#include "system.h"
#include "render.h"
#include "scenery.h"
RayCastingResult _RAYCASTING_NULL = {0};
HeightInfo _WATER_HEIGHT_INFO = {-1000000.0, -1000000.0, -1000000.0};
static void* _renderFirstPass(void* data)
{
Renderer* renderer = (Renderer*)data;
sceneryRenderFirstPass(renderer);
renderer->is_rendering = 0;
return NULL;
}
static int _addRenderProgress(Renderer* renderer, double progress)
{
return 1;
}
static double _getPrecision(Renderer* renderer, Vector3 location)
{
return 0.001;
}
static Vector3 _projectPoint(Renderer* renderer, Vector3 point)
{
return point;
}
static Vector3 _unprojectPoint(Renderer* renderer, Vector3 point)
{
return point;
}
static void _pushTriangle(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3)
{
Vector3 p1, p2, p3;
p1 = renderer->projectPoint(renderer, v1->location);
p2 = renderer->projectPoint(renderer, v2->location);
p3 = renderer->projectPoint(renderer, v3->location);
renderPushTriangle(renderer->render_area, v1, v2, v3, p1, p2, p3);
}
static void _pushQuad(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3, Vertex* v4)
{
renderer->pushTriangle(renderer, v2, v3, v1);
renderer->pushTriangle(renderer, v4, v1, v3);
}
static Color _filterLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
{
return light_color;
@ -50,40 +99,88 @@ static Color _applyClouds(Renderer* renderer, Color base, Vector3 start, Vector3
return base;
}
static Vector3 _projectPoint(Renderer* renderer, Vector3 point)
{
return point;
}
static Vector3 _unprojectPoint(Renderer* renderer, Vector3 point)
{
return point;
}
static double _getPrecision(Renderer* renderer, Vector3 location)
{
return 0.001;
}
Renderer rendererGetFake()
Renderer rendererCreate()
{
Renderer result;
result.render_quality = 5;
result.render_width = 1;
result.render_height = 1;
result.render_interrupt = 0;
result.render_progress = 0.0;
result.is_rendering = 0;
result.camera_location = VECTOR_ZERO;
result.render_area = renderCreateArea();
renderSetSize(result.render_area, 1, 1);
result.addRenderProgress = _addRenderProgress;
result.getPrecision = _getPrecision;
result.projectPoint = _projectPoint;
result.unprojectPoint = _unprojectPoint;
result.pushTriangle = _pushTriangle;
result.pushQuad = _pushQuad;
result.filterLight = _filterLight;
result.maskLight = _maskLight;
result.applyLightingToSurface = _applyLightingToSurface;
result.rayWalking = _rayWalking;
result.getTerrainHeight = _getTerrainHeight;
result.getWaterHeightInfo = _getWaterHeightInfo;
result.applyTextures = _applyTextures;
result.applyAtmosphere = _applyAtmosphere;
result.applyClouds = _applyClouds;
result.projectPoint = _projectPoint;
result.unprojectPoint = _unprojectPoint;
result.getPrecision = _getPrecision;
result.filterLight = _filterLight;
result.maskLight = _maskLight;
result.applyLightingToSurface = _applyLightingToSurface;
return result;
}
void rendererDelete(Renderer* renderer)
{
renderDeleteArea(renderer->render_area);
}
void rendererSetPreviewCallbacks(Renderer* renderer, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update)
{
renderSetPreviewCallbacks(renderer->render_area, start, draw, update);
}
void rendererStart(Renderer* renderer, int width, int height, int quality)
{
Thread* thread;
int loops;
int core_count = systemGetCoreCount();
renderer->render_quality = quality;
renderer->render_width = width;
renderer->render_height = height;
renderer->render_interrupt = 0;
renderer->render_progress = 0.0;
renderSetBackgroundColor(renderer->render_area, &COLOR_BLACK);
renderSetSize(renderer->render_area, width, height);
renderClear(renderer->render_area);
renderer->is_rendering = 1;
thread = threadCreate(_renderFirstPass, renderer);
loops = 0;
while (renderer->is_rendering)
{
timeSleepMs(100);
if (++loops >= 10)
{
renderUpdate(renderer->render_area);
loops = 0;
}
}
threadJoin(thread);
renderer->is_rendering = 1;
renderPostProcess(renderer->render_area, renderer, core_count);
renderer->is_rendering = 0;
}
void rendererInterrupt(Renderer* renderer)
{
}

View file

@ -11,14 +11,23 @@ typedef struct Renderer Renderer;
struct Renderer
{
/* Quality configuration */
/* Render base configuration */
int render_quality;
int render_width;
int render_height;
Vector3 camera_location;
/* Render related */
RenderArea* render_area;
double render_progress;
int render_interrupt;
int is_rendering;
double (*getPrecision)(Renderer* renderer, Vector3 location);
Vector3 (*projectPoint)(Renderer* renderer, Vector3 point);
Vector3 (*unprojectPoint)(Renderer* renderer, Vector3 point);
int (*addRenderProgress)(Renderer* renderer, double progress);
void (*pushTriangle)(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3);
void (*pushQuad)(Renderer* renderer, Vertex* v1, Vertex* v2, Vertex* v3, Vertex* v4);
/* Scenery related */
RayCastingResult (*rayWalking)(Renderer* renderer, Vector3 location, Vector3 direction, int terrain, int water, int sky, int clouds);
@ -37,7 +46,11 @@ struct Renderer
void* customData[10];
};
Renderer rendererGetFake();
Renderer rendererCreate();
void rendererDelete(Renderer* renderer);
void rendererSetPreviewCallbacks(Renderer* renderer, RenderCallbackStart start, RenderCallbackDraw draw, RenderCallbackUpdate update);
void rendererStart(Renderer* renderer, int width, int height, int quality);
void rendererInterrupt(Renderer* renderer);
#ifdef __cplusplus
}

View file

@ -177,29 +177,21 @@ void sceneryGetWater(WaterDefinition* water)
void sceneryRenderFirstPass(Renderer* renderer)
{
if (!renderSetNextProgressStep(0.0, 0.01))
/*if (!renderSetNextProgressStep(0.0, 0.01))
{
return;
}
skyRender(&_sky, renderer, renderTellProgress);
if (!renderSetNextProgressStep(0.01, 0.085))
}*/
skyRender(&_sky, renderer);
/*if (!renderSetNextProgressStep(0.01, 0.085))
{
return;
}
terrainRender(&_terrain, renderer, renderTellProgress);
if (!renderSetNextProgressStep(0.085, 0.1))
}*/
terrainRender(&_terrain, renderer);
/*if (!renderSetNextProgressStep(0.085, 0.1))
{
return;
}
waterRender(&_water, renderer, renderTellProgress);
}
void sceneryRenderSecondPass(Renderer* renderer)
{
if (renderSetNextProgressStep(0.1, 1.0))
{
renderPostProcess(renderer, systemGetCoreCount());
}
}*/
waterRender(&_water, renderer);
}
@ -277,34 +269,32 @@ static Color _applyClouds(Renderer* renderer, Color base, Vector3 start, Vector3
static Vector3 _projectPoint(Renderer* renderer, Vector3 point)
{
return cameraProject(&_camera, point);
return cameraProject(&_camera, renderer, point);
}
static Vector3 _unprojectPoint(Renderer* renderer, Vector3 point)
{
return cameraUnproject(&_camera, point);
return cameraUnproject(&_camera, renderer, point);
}
static double _getPrecision(Renderer* renderer, Vector3 location)
{
Vector3 projected;
projected = cameraProject(&_camera, location);
projected = cameraProject(&_camera, renderer, location);
projected.x += 1.0;
//projected.y += 1.0;
return v3Norm(v3Sub(cameraUnproject(&_camera, projected), location)); // / (double)render_quality;
return v3Norm(v3Sub(cameraUnproject(&_camera, renderer, projected), location)); // / (double)render_quality;
}
Renderer sceneryGetStandardRenderer(int quality)
Renderer sceneryCreateStandardRenderer()
{
Renderer result;
quality = (quality > 10) ? 10 : quality;
quality = (quality < 1) ? 1 : quality;
result = rendererCreate();
result.camera_location = _camera.location;
result.render_quality = quality;
result.filterLight = _filterLight;
result.maskLight = _maskLight;

View file

@ -51,9 +51,8 @@ void sceneryGetTextures(TexturesDefinition* textures);
void scenerySetWater(WaterDefinition* water);
void sceneryGetWater(WaterDefinition* water);
Renderer sceneryGetStandardRenderer(int quality);
Renderer sceneryCreateStandardRenderer();
void sceneryRenderFirstPass(Renderer* renderer);
void sceneryRenderSecondPass(Renderer* renderer);
#ifdef __cplusplus
}

View file

@ -1,18 +0,0 @@
#ifndef _PAYSAGES_GLOBALS_H_
#define _PAYSAGES_GLOBALS_H_
#include "types.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int render_width;
extern int render_height;
extern int render_quality;
#ifdef __cplusplus
}
#endif
#endif

View file

@ -100,11 +100,11 @@ typedef struct
typedef struct Zone Zone;
typedef void (*PreviewCallbackResize)(int width, int height);
typedef void (*PreviewCallbackClear)(Color col);
typedef void (*PreviewCallbackDraw)(int x, int y, Color col);
typedef void (*PreviewCallbackUpdate)(double progress);
typedef int (*RenderProgressCallback)(double progress);
typedef void (*RenderCallbackStart)(int width, int height, Color background);
typedef void (*RenderCallbackDraw)(int x, int y, Color col);
typedef void (*RenderCallbackUpdate)(double progress);
typedef struct RenderArea RenderArea;
typedef struct
{

View file

@ -4,7 +4,6 @@
#include <math.h>
#include "shared/types.h"
#include "shared/globals.h"
#include "shared/constants.h"
#include "color.h"
#include "clouds.h"
@ -182,7 +181,7 @@ static int _postProcessFragment(RenderFragment* fragment, Renderer* renderer, vo
return 1;
}
void skyRender(SkyDefinition* definition, Renderer* renderer, RenderProgressCallback callback)
void skyRender(SkyDefinition* definition, Renderer* renderer)
{
int res_i, res_j;
int i, j;
@ -203,7 +202,7 @@ void skyRender(SkyDefinition* definition, Renderer* renderer, RenderProgressCall
for (j = 0; j < res_j; j++)
{
if (!callback((double)j / (double)(res_j - 1)))
if (!renderer->addRenderProgress(renderer, 0.0))
{
return;
}
@ -251,7 +250,7 @@ void skyRender(SkyDefinition* definition, Renderer* renderer, RenderProgressCall
vertex4.callback_data = definition;
/* TODO Triangles at poles */
renderPushQuad(renderer, &vertex1, &vertex4, &vertex3, &vertex2);
renderer->pushQuad(renderer, &vertex1, &vertex4, &vertex3, &vertex2);
}
}
}

View file

@ -32,7 +32,7 @@ void skyValidateDefinition(SkyDefinition* definition);
int skyGetLights(SkyDefinition* sky, LightDefinition* lights, int max_lights);
Color skyGetColor(SkyDefinition* definition, Renderer* renderer, Vector3 eye, Vector3 look);
void skyRender(SkyDefinition* definition, Renderer* renderer, RenderProgressCallback callback);
void skyRender(SkyDefinition* definition, Renderer* renderer);
#ifdef __cplusplus
}

View file

@ -6,7 +6,6 @@
#include <assert.h>
#include "shared/types.h"
#include "shared/globals.h"
#include "shared/constants.h"
#include "euclid.h"
#include "render.h"
@ -322,7 +321,7 @@ static void _renderQuad(TerrainDefinition* definition, Renderer* renderer, doubl
if (v1.location.y > water_height || v2.location.y > water_height || v3.location.y > water_height || v4.location.y > water_height)
{
renderPushQuad(renderer, &v1, &v2, &v3, &v4);
renderer->pushQuad(renderer, &v1, &v2, &v3, &v4);
}
}
@ -349,7 +348,7 @@ Color terrainGetColor(TerrainDefinition* definition, Renderer* renderer, double
return _getColor(definition, renderer, point, detail);
}
void terrainRender(TerrainDefinition* definition, Renderer* renderer, RenderProgressCallback callback)
void terrainRender(TerrainDefinition* definition, Renderer* renderer)
{
int chunk_factor, chunk_count, i;
double cx = renderer->camera_location.x;
@ -371,7 +370,7 @@ void terrainRender(TerrainDefinition* definition, Renderer* renderer, RenderProg
while (radius_ext < 1000.0)
{
if (!callback(radius_ext / 1000.0))
if (!renderer->addRenderProgress(renderer, 0.0))
{
return;
}

View file

@ -41,7 +41,7 @@ int terrainProjectRay(TerrainDefinition* definition, Renderer* renderer, Vector3
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);
void terrainRender(TerrainDefinition* definition, Renderer* renderer);
#ifdef __cplusplus
}

View file

@ -7,7 +7,6 @@
#include "shared/types.h"
#include "shared/constants.h"
#include "shared/globals.h"
#include "color.h"
#include "euclid.h"
#include "lighting.h"

View file

@ -2,7 +2,6 @@
#include "shared/types.h"
#include "shared/constants.h"
#include "shared/globals.h"
#include "color.h"
#include "euclid.h"
#include "render.h"
@ -266,10 +265,10 @@ static void _renderQuad(WaterDefinition* definition, Renderer* renderer, double
v2 = _getFirstPassVertex(definition, x, z + size, size);
v3 = _getFirstPassVertex(definition, x + size, z + size, size);
v4 = _getFirstPassVertex(definition, x + size, z, size);
renderPushQuad(renderer, &v1, &v2, &v3, &v4);
renderer->pushQuad(renderer, &v1, &v2, &v3, &v4);
}
void waterRender(WaterDefinition* definition, Renderer* renderer, RenderProgressCallback callback)
void waterRender(WaterDefinition* definition, Renderer* renderer)
{
int chunk_factor, chunk_count, i;
double cx = renderer->camera_location.x;
@ -286,7 +285,7 @@ void waterRender(WaterDefinition* definition, Renderer* renderer, RenderProgress
while (radius_ext < 1000.0)
{
if (!callback(radius_ext / 1000.0))
if (!renderer->addRenderProgress(renderer, 0.0))
{
return;
}

View file

@ -47,7 +47,7 @@ HeightInfo waterGetHeightInfo(WaterDefinition* definition);
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);
void waterRender(WaterDefinition* definition, Renderer* renderer);
#ifdef __cplusplus
}