paysages : Fixed maximum memory size for render area.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@349 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
parent
ee86e2d251
commit
5deb2fdced
5 changed files with 27 additions and 154 deletions
|
@ -110,7 +110,7 @@ FormRender::FormRender(QWidget *parent) :
|
||||||
addInput(new InputCamera(this, tr("Camera"), &_camera));
|
addInput(new InputCamera(this, tr("Camera"), &_camera));
|
||||||
addInputInt(tr("Quality"), &_params.quality, 1, 10, 1, 1);
|
addInputInt(tr("Quality"), &_params.quality, 1, 10, 1, 1);
|
||||||
addInputInt(tr("Image width"), &_params.width, 100, 2000, 10, 100);
|
addInputInt(tr("Image width"), &_params.width, 100, 2000, 10, 100);
|
||||||
addInputInt(tr("Image height"), &_params.height, 100, 2000, 10, 100);
|
addInputInt(tr("Image height"), &_params.height, 100, 1200, 10, 100);
|
||||||
addInputInt(tr("Anti aliasing"), &_params.antialias, 1, 4, 1, 1);
|
addInputInt(tr("Anti aliasing"), &_params.antialias, 1, 4, 1, 1);
|
||||||
|
|
||||||
button = addButton(tr("Start new render"));
|
button = addButton(tr("Start new render"));
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#include "IL/ilu.h"
|
#include "IL/ilu.h"
|
||||||
|
|
||||||
#include "shared/types.h"
|
#include "shared/types.h"
|
||||||
#include "array.h"
|
|
||||||
#include "color.h"
|
#include "color.h"
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
|
@ -15,7 +14,7 @@ struct RenderArea
|
||||||
{
|
{
|
||||||
RenderParams params;
|
RenderParams params;
|
||||||
int pixel_count;
|
int pixel_count;
|
||||||
Array* pixels;
|
RenderFragment* pixels;
|
||||||
RenderFragment* scanline_up;
|
RenderFragment* scanline_up;
|
||||||
RenderFragment* scanline_down;
|
RenderFragment* scanline_down;
|
||||||
int scanline_left;
|
int scanline_left;
|
||||||
|
@ -57,8 +56,7 @@ RenderArea* renderCreateArea()
|
||||||
result->params.antialias = 1;
|
result->params.antialias = 1;
|
||||||
result->params.quality = 5;
|
result->params.quality = 5;
|
||||||
result->pixel_count = 1;
|
result->pixel_count = 1;
|
||||||
result->pixels = malloc(sizeof(Array));
|
result->pixels = malloc(sizeof(RenderFragment));
|
||||||
arrayCreate(result->pixels, sizeof(RenderFragment));
|
|
||||||
result->scanline_up = malloc(sizeof(RenderFragment));
|
result->scanline_up = malloc(sizeof(RenderFragment));
|
||||||
result->scanline_down = malloc(sizeof(RenderFragment));
|
result->scanline_down = malloc(sizeof(RenderFragment));
|
||||||
result->scanline_left = 0;
|
result->scanline_left = 0;
|
||||||
|
@ -79,17 +77,6 @@ RenderArea* renderCreateArea()
|
||||||
|
|
||||||
void renderDeleteArea(RenderArea* area)
|
void renderDeleteArea(RenderArea* area)
|
||||||
{
|
{
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
|
|
||||||
for (x = 0; x < area->params.width * area->params.antialias; x++)
|
|
||||||
{
|
|
||||||
for (y = 0; y < area->params.height * area->params.antialias; y++)
|
|
||||||
{
|
|
||||||
arrayDelete(area->pixels + (y * area->params.width * area->params.antialias + x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mutexDestroy(area->lock);
|
mutexDestroy(area->lock);
|
||||||
free(area->pixels);
|
free(area->pixels);
|
||||||
free(area->scanline_up);
|
free(area->scanline_up);
|
||||||
|
@ -99,22 +86,13 @@ void renderDeleteArea(RenderArea* area)
|
||||||
|
|
||||||
void renderSetParams(RenderArea* area, RenderParams params)
|
void renderSetParams(RenderArea* area, RenderParams params)
|
||||||
{
|
{
|
||||||
int x, y;
|
|
||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
width = params.width * params.antialias;
|
width = params.width * params.antialias;
|
||||||
height = params.height * params.antialias;
|
height = params.height * params.antialias;
|
||||||
|
|
||||||
for (x = 0; x < area->params.width * area->params.antialias; x++)
|
|
||||||
{
|
|
||||||
for (y = 0; y < area->params.height * area->params.antialias; y++)
|
|
||||||
{
|
|
||||||
arrayDelete(area->pixels + (y * area->params.width * area->params.antialias + x));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
area->params = params;
|
area->params = params;
|
||||||
area->pixels = realloc(area->pixels, sizeof(Array) * width * height);
|
area->pixels = realloc(area->pixels, sizeof(RenderFragment) * width * height);
|
||||||
area->pixel_count = width * height;
|
area->pixel_count = width * height;
|
||||||
|
|
||||||
area->scanline_left = 0;
|
area->scanline_left = 0;
|
||||||
|
@ -128,13 +106,7 @@ void renderSetParams(RenderArea* area, RenderParams params)
|
||||||
area->dirty_up = -1;
|
area->dirty_up = -1;
|
||||||
area->dirty_count = 0;
|
area->dirty_count = 0;
|
||||||
|
|
||||||
for (y = 0; y < height; y++)
|
renderClear(area);
|
||||||
{
|
|
||||||
for (x = 0; x < width; x++)
|
|
||||||
{
|
|
||||||
arrayCreate(area->pixels + (y * width + x), sizeof(RenderFragment));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderSetBackgroundColor(RenderArea* area, Color* col)
|
void renderSetBackgroundColor(RenderArea* area, Color* col)
|
||||||
|
@ -144,6 +116,7 @@ void renderSetBackgroundColor(RenderArea* area, Color* col)
|
||||||
|
|
||||||
void renderClear(RenderArea* area)
|
void renderClear(RenderArea* area)
|
||||||
{
|
{
|
||||||
|
RenderFragment* pixel;
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
|
|
||||||
|
@ -151,7 +124,9 @@ void renderClear(RenderArea* area)
|
||||||
{
|
{
|
||||||
for (y = 0; y < area->params.height * area->params.antialias; y++)
|
for (y = 0; y < area->params.height * area->params.antialias; y++)
|
||||||
{
|
{
|
||||||
arrayClear(area->pixels + (y * area->params.width * area->params.antialias + x));
|
pixel = area->pixels + (y * area->params.width * area->params.antialias + x);
|
||||||
|
pixel->z = -100000000.0;
|
||||||
|
pixel->vertex.color = area->background_color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,26 +161,8 @@ void renderClear(RenderArea* area)
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
static Color _getPixelColor(Color base, Array* pixel_data)
|
static inline void _setDirtyPixel(RenderArea* area, RenderFragment* fragment, int x, int y)
|
||||||
{
|
{
|
||||||
RenderFragment* fragment;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (pixel_data->length > 0)
|
|
||||||
{
|
|
||||||
for (i = 0; i < pixel_data->length; i++)
|
|
||||||
{
|
|
||||||
fragment = ((RenderFragment*)pixel_data->data) + i;
|
|
||||||
colorMask(&base, &(fragment->vertex.color));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void _setDirtyPixel(RenderArea* area, Array* pixel_data, int x, int y)
|
|
||||||
{
|
|
||||||
pixel_data->dirty = 1;
|
|
||||||
if (x < area->dirty_left)
|
if (x < area->dirty_left)
|
||||||
{
|
{
|
||||||
area->dirty_left = x;
|
area->dirty_left = x;
|
||||||
|
@ -230,7 +187,7 @@ static inline Color _getFinalPixel(RenderArea* area, int x, int y)
|
||||||
{
|
{
|
||||||
Color result, col;
|
Color result, col;
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
Array* pixel_data;
|
RenderFragment* pixel_data;
|
||||||
|
|
||||||
result.r = result.g = result.b = 0.0;
|
result.r = result.g = result.b = 0.0;
|
||||||
result.a = 1.0;
|
result.a = 1.0;
|
||||||
|
@ -239,14 +196,10 @@ static inline Color _getFinalPixel(RenderArea* area, int x, int y)
|
||||||
for (sy = 0; sy < area->params.antialias; sy++)
|
for (sy = 0; sy < area->params.antialias; sy++)
|
||||||
{
|
{
|
||||||
pixel_data = area->pixels + (y * area->params.antialias + sy) * area->params.width * area->params.antialias + (x * area->params.antialias + sx);
|
pixel_data = area->pixels + (y * area->params.antialias + sy) * area->params.width * area->params.antialias + (x * area->params.antialias + sx);
|
||||||
if (1 || pixel_data->dirty)
|
col = pixel_data->vertex.color;
|
||||||
{
|
|
||||||
col = _getPixelColor(area->background_color, pixel_data);
|
|
||||||
result.r += col.r / (float)(area->params.antialias * area->params.antialias);
|
result.r += col.r / (float)(area->params.antialias * area->params.antialias);
|
||||||
result.g += col.g / (float)(area->params.antialias * area->params.antialias);
|
result.g += col.g / (float)(area->params.antialias * area->params.antialias);
|
||||||
result.b += col.b / (float)(area->params.antialias * area->params.antialias);
|
result.b += col.b / (float)(area->params.antialias * area->params.antialias);
|
||||||
pixel_data->dirty = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,83 +242,26 @@ void renderUpdate(RenderArea* area)
|
||||||
|
|
||||||
static void _setAllDirty(RenderArea* area)
|
static void _setAllDirty(RenderArea* area)
|
||||||
{
|
{
|
||||||
int x, y;
|
|
||||||
|
|
||||||
area->dirty_left = 0;
|
area->dirty_left = 0;
|
||||||
area->dirty_right = area->params.width * area->params.antialias - 1;
|
area->dirty_right = area->params.width * area->params.antialias - 1;
|
||||||
area->dirty_down = 0;
|
area->dirty_down = 0;
|
||||||
area->dirty_up = area->params.height * area->params.antialias - 1;
|
area->dirty_up = area->params.height * area->params.antialias - 1;
|
||||||
|
|
||||||
for (y = area->dirty_down; y <= area->dirty_up; y++)
|
|
||||||
{
|
|
||||||
for (x = area->dirty_left; x <= area->dirty_right; x++)
|
|
||||||
{
|
|
||||||
(area->pixels + y * area->params.width * area->params.antialias + x)->dirty = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderAddFragment(RenderArea* area, RenderFragment* fragment)
|
void renderAddFragment(RenderArea* area, RenderFragment* fragment)
|
||||||
{
|
{
|
||||||
Array* pixel_data;
|
RenderFragment* pixel_data;
|
||||||
int x = fragment->x;
|
int x = fragment->x;
|
||||||
int y = fragment->y;
|
int y = fragment->y;
|
||||||
float z = fragment->z;
|
float z = fragment->z;
|
||||||
|
|
||||||
int i, dirty;
|
|
||||||
int fragments_count;
|
|
||||||
RenderFragment* fragments;
|
|
||||||
|
|
||||||
dirty = 0;
|
|
||||||
if (x >= 0 && x < area->params.width * area->params.antialias && y >= 0 && y < area->params.height * area->params.antialias && z > 1.0)
|
if (x >= 0 && x < area->params.width * area->params.antialias && y >= 0 && y < area->params.height * area->params.antialias && z > 1.0)
|
||||||
{
|
{
|
||||||
pixel_data = area->pixels + (y * area->params.width * area->params.antialias + x);
|
pixel_data = area->pixels + (y * area->params.width * area->params.antialias + x);
|
||||||
fragments = (RenderFragment*)pixel_data->data;
|
|
||||||
fragments_count = pixel_data->length;
|
|
||||||
|
|
||||||
if (fragments_count == 0)
|
if (z > pixel_data->z)
|
||||||
{
|
|
||||||
arrayAppend(pixel_data, fragment);
|
|
||||||
dirty = 1;
|
|
||||||
}
|
|
||||||
else if (fragments[0].z > z)
|
|
||||||
{
|
|
||||||
if (fragments[0].vertex.color.a < 1.0)
|
|
||||||
{
|
|
||||||
arrayInsert(pixel_data, fragment, 0);
|
|
||||||
dirty = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (i = 1; i <= fragments_count; i++)
|
|
||||||
{
|
|
||||||
if ((i == fragments_count) || (fragments[i].z > z))
|
|
||||||
{
|
|
||||||
if (fragment->vertex.color.a > 0.999999)
|
|
||||||
{
|
|
||||||
if (i > 1)
|
|
||||||
{
|
|
||||||
arrayLStrip(pixel_data, i - 1);
|
|
||||||
}
|
|
||||||
arrayReplace(pixel_data, fragment, 0);
|
|
||||||
}
|
|
||||||
else if (i == fragments_count)
|
|
||||||
{
|
|
||||||
arrayAppend(pixel_data, fragment);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
arrayInsert(pixel_data, fragment, i);
|
|
||||||
}
|
|
||||||
dirty = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dirty)
|
|
||||||
{
|
{
|
||||||
|
*pixel_data = *fragment;
|
||||||
_setDirtyPixel(area, pixel_data, x, y);
|
_setDirtyPixel(area, pixel_data, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -388,9 +284,6 @@ static void __vertexGetDiff(Vertex* v1, Vertex* v2, Vertex* result)
|
||||||
result->location.x = v2->location.x - v1->location.x;
|
result->location.x = v2->location.x - v1->location.x;
|
||||||
result->location.y = v2->location.y - v1->location.y;
|
result->location.y = v2->location.y - v1->location.y;
|
||||||
result->location.z = v2->location.z - v1->location.z;
|
result->location.z = v2->location.z - v1->location.z;
|
||||||
result->normal.x = v2->normal.x - v1->normal.x;
|
|
||||||
result->normal.y = v2->normal.y - v1->normal.y;
|
|
||||||
result->normal.z = v2->normal.z - v1->normal.z;
|
|
||||||
result->color.r = v2->color.r - v1->color.r;
|
result->color.r = v2->color.r - v1->color.r;
|
||||||
result->color.g = v2->color.g - v1->color.g;
|
result->color.g = v2->color.g - v1->color.g;
|
||||||
result->color.b = v2->color.b - v1->color.b;
|
result->color.b = v2->color.b - v1->color.b;
|
||||||
|
@ -404,9 +297,6 @@ static void __vertexInterpolate(Vertex* v1, Vertex* diff, float value, Vertex* r
|
||||||
result->location.x = v1->location.x + diff->location.x * value;
|
result->location.x = v1->location.x + diff->location.x * value;
|
||||||
result->location.y = v1->location.y + diff->location.y * value;
|
result->location.y = v1->location.y + diff->location.y * value;
|
||||||
result->location.z = v1->location.z + diff->location.z * value;
|
result->location.z = v1->location.z + diff->location.z * value;
|
||||||
result->normal.x = v1->normal.x + diff->normal.x * value;
|
|
||||||
result->normal.y = v1->normal.y + diff->normal.y * value;
|
|
||||||
result->normal.z = v1->normal.z + diff->normal.z * value;
|
|
||||||
result->color.r = v1->color.r + diff->color.r * value;
|
result->color.r = v1->color.r + diff->color.r * value;
|
||||||
result->color.g = v1->color.g + diff->color.g * value;
|
result->color.g = v1->color.g + diff->color.g * value;
|
||||||
result->color.b = v1->color.b + diff->color.b * value;
|
result->color.b = v1->color.b + diff->color.b * value;
|
||||||
|
@ -624,10 +514,8 @@ typedef struct {
|
||||||
|
|
||||||
void* _renderPostProcessChunk(void* data)
|
void* _renderPostProcessChunk(void* data)
|
||||||
{
|
{
|
||||||
int x, y, i;
|
int x, y;
|
||||||
int dirty;
|
RenderFragment* fragment;
|
||||||
Array* pixel_data;
|
|
||||||
RenderFragment* fragments;
|
|
||||||
RenderChunk* chunk = (RenderChunk*)data;
|
RenderChunk* chunk = (RenderChunk*)data;
|
||||||
|
|
||||||
#ifdef RENDER_INVERSE
|
#ifdef RENDER_INVERSE
|
||||||
|
@ -638,26 +526,15 @@ void* _renderPostProcessChunk(void* data)
|
||||||
{
|
{
|
||||||
for (x = chunk->startx; x <= chunk->endx; x++)
|
for (x = chunk->startx; x <= chunk->endx; x++)
|
||||||
{
|
{
|
||||||
pixel_data = chunk->area->pixels + (y * chunk->area->params.width * chunk->area->params.antialias + x);
|
fragment = chunk->area->pixels + (y * chunk->area->params.width * chunk->area->params.antialias + x);
|
||||||
fragments = (RenderFragment*)pixel_data->data;
|
if (fragment->vertex.callback)
|
||||||
dirty = 0;
|
|
||||||
for (i = 0; i < pixel_data->length; i++)
|
|
||||||
{
|
{
|
||||||
if (fragments[i].vertex.callback)
|
if (fragment->vertex.callback(fragment, chunk->renderer, fragment->vertex.callback_data))
|
||||||
{
|
{
|
||||||
if (fragments[i].vertex.callback(fragments + i, chunk->renderer, fragments[i].vertex.callback_data))
|
colorNormalize(&fragment->vertex.color);
|
||||||
{
|
_setDirtyPixel(chunk->area, fragment, x, y);
|
||||||
colorNormalize(&fragments[i].vertex.color);
|
|
||||||
dirty = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (dirty)
|
|
||||||
{
|
|
||||||
mutexAcquire(chunk->area->lock);
|
|
||||||
_setDirtyPixel(chunk->area, pixel_data, x, y);
|
|
||||||
mutexRelease(chunk->area->lock);
|
|
||||||
}
|
|
||||||
/* chunk->area->progress_pixels++; */
|
/* chunk->area->progress_pixels++; */
|
||||||
}
|
}
|
||||||
if (chunk->interrupt)
|
if (chunk->interrupt)
|
||||||
|
@ -784,7 +661,6 @@ int renderSaveToFile(RenderArea* area, const char* path)
|
||||||
ILuint rgba;
|
ILuint rgba;
|
||||||
ILuint data[area->params.height * area->params.width];
|
ILuint data[area->params.height * area->params.width];
|
||||||
ILenum error;
|
ILenum error;
|
||||||
Array* pixel_data;
|
|
||||||
int error_count;
|
int error_count;
|
||||||
|
|
||||||
for (y = 0; y < area->params.height; y++)
|
for (y = 0; y < area->params.height; y++)
|
||||||
|
|
|
@ -19,7 +19,6 @@ typedef int(*f_RenderFragmentCallback)(struct RenderFragment*, struct Renderer*
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
Vector3 location;
|
Vector3 location;
|
||||||
Vector3 normal;
|
|
||||||
Color color;
|
Color color;
|
||||||
f_RenderFragmentCallback callback;
|
f_RenderFragmentCallback callback;
|
||||||
void* callback_data;
|
void* callback_data;
|
||||||
|
@ -27,8 +26,8 @@ typedef struct
|
||||||
|
|
||||||
typedef struct RenderFragment
|
typedef struct RenderFragment
|
||||||
{
|
{
|
||||||
int x;
|
short int x;
|
||||||
int y;
|
short int y;
|
||||||
float z;
|
float z;
|
||||||
Vertex vertex;
|
Vertex vertex;
|
||||||
} RenderFragment;
|
} RenderFragment;
|
||||||
|
|
|
@ -345,7 +345,6 @@ static Vertex _getFirstPassVertex(TerrainDefinition* definition, float x, float
|
||||||
result.color.g = value;
|
result.color.g = value;
|
||||||
result.color.b = value;
|
result.color.b = value;
|
||||||
result.color.a = 1.0;
|
result.color.a = 1.0;
|
||||||
result.normal.x = result.normal.y = result.normal.z = 0.0;
|
|
||||||
result.callback = _postProcessFragment;
|
result.callback = _postProcessFragment;
|
||||||
result.callback_data = definition;
|
result.callback_data = definition;
|
||||||
|
|
||||||
|
|
|
@ -256,7 +256,6 @@ static Vertex _getFirstPassVertex(WaterDefinition* definition, float x, float z,
|
||||||
result.color.g = value;
|
result.color.g = value;
|
||||||
result.color.b = value;
|
result.color.b = value;
|
||||||
result.color.a = 1.0;
|
result.color.a = 1.0;
|
||||||
result.normal.x = result.normal.y = result.normal.z = 0.0;
|
|
||||||
result.callback = _postProcessFragment;
|
result.callback = _postProcessFragment;
|
||||||
result.callback_data = definition;
|
result.callback_data = definition;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue