Optimized camera projection and scanlines

This commit is contained in:
Michaël Lemaire 2013-12-10 23:41:33 +01:00
parent 09c6ce6e58
commit 5354087244
5 changed files with 37 additions and 25 deletions

1
.gitignore vendored
View file

@ -5,6 +5,7 @@
/gmon.out
/nbproject/
/output/
/perf.*
*.pro.user
*.pro.user.*
qrc_*.cpp

View file

@ -1,6 +1,6 @@
BUILDMODE=release
BUILDPATH=./build/${BUILDMODE}
LIBRARY_PATH=${BUILDPATH}/rendering:${BUILDPATH}/exploring:${BUILDPATH}/system:${BUILDPATH}/basics:${BUILDPATH}/definition:${BUILDPATH}/render/opengl:${BUILDPATH}/render/software:${BUILDPATH}/tests/googletest
LIBRARY_PATH=${BUILDPATH}/rendering:${BUILDPATH}/exploring:${BUILDPATH}/system:${BUILDPATH}/basics:${BUILDPATH}/definition:${BUILDPATH}/render/opengl:${BUILDPATH}/render/software:${BUILDPATH}/render/preview:${BUILDPATH}/tests/googletest
BUILD_SPEC=linux-g++
all:build
@ -46,15 +46,15 @@ run_cli:build
run:build
LD_LIBRARY_PATH=$(LIBRARY_PATH) ${RUNNER} ${BUILDPATH}/interface/desktop/paysages-gui
profile:debug
profile:build
LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g fp ${BUILDPATH}/interface/desktop/paysages-gui
perf report -g
profile_cli:debug
profile_cli:build
LD_LIBRARY_PATH=${LIBRARY_PATH} perf record -g fp ${BUILDPATH}/interface/commandline/paysages-cli
perf report -g
package:release
package:build
rm -rf paysages3d-linux
rm -f paysages3d-linux.tar.bz2
mkdir paysages3d-linux

View file

@ -58,8 +58,6 @@ void CameraDefinition::copy(BaseDefinition* _destination) const
void CameraDefinition::validate()
{
Matrix4 rotation;
if (location.y > 300.0)
{
location.y = 300.0;
@ -75,7 +73,7 @@ void CameraDefinition::validate()
up.y = 1.0;
up.z = 0.0;
rotation = Matrix4::newRotateEuler(direction.phi, direction.theta, roll);
Matrix4 rotation = Matrix4::newRotateEuler(direction.phi, direction.theta, roll);
forward = rotation.multPoint(forward);
right = rotation.multPoint(right);
@ -83,16 +81,17 @@ void CameraDefinition::validate()
target = location.add(direction);
projector = Matrix4::newPerspective(perspective.yfov, perspective.xratio, perspective.znear, perspective.zfar).mult(Matrix4::newLookAt(location, target, up));
Matrix4 mperspective = Matrix4::newPerspective(perspective.yfov, perspective.xratio, perspective.znear, perspective.zfar);
unperspective = mperspective.inversed();
projector = mperspective.mult(Matrix4::newLookAt(location, target, up));
unprojector = projector.inversed();
}
double CameraDefinition::getRealDepth(const Vector3 &projected) const
{
/* TODO Optimize this */
Matrix4 m = Matrix4::newPerspective(perspective.yfov, perspective.xratio, perspective.znear, perspective.zfar);
Vector3 v(projected.x / (0.5 * width) - 1.0, -(projected.y / (0.5 * height) - 1.0), projected.z);
return m.inversed().transform(v).z;
return unperspective.transform(v).z;
}
void CameraDefinition::setLocation(const Vector3 &location)

View file

@ -82,6 +82,7 @@ private:
Vector3 up;
Matrix4 projector;
Matrix4 unprojector;
Matrix4 unperspective;
};
}

View file

@ -352,27 +352,44 @@ static void _pushScanPoint(RenderArea* area, RenderScanlines* scanlines, ScanPoi
if (point->x < 0 || point->x >= area->params.width * area->params.antialias)
{
// Point outside scanline range
return;
}
if (point->x > scanlines->right)
else if (scanlines->right < 0)
{
// First point pushed
scanlines->left = point->x;
scanlines->right = point->x;
scanlines->up[scanlines->right] = *point;
scanlines->down[scanlines->right] = *point;
if (point->x < scanlines->left)
scanlines->up[point->x] = *point;
scanlines->down[point->x] = *point;
}
else if (point->x > scanlines->right)
{
// Grow scanlines to right
for (int x = scanlines->right + 1; x < point->x; x++)
{
scanlines->left = point->x;
scanlines->up[x].y = -1;
scanlines->down[x].y = area->params.height * area->params.antialias;
}
scanlines->right = point->x;
scanlines->up[point->x] = *point;
scanlines->down[point->x] = *point;
}
else if (point->x < scanlines->left)
{
// Grow scanlines to left
for (int x = point->x + 1; x < scanlines->left; x++)
{
scanlines->up[x].y = -1;
scanlines->down[x].y = area->params.height * area->params.antialias;
}
scanlines->left = point->x;
scanlines->up[scanlines->left] = *point;
scanlines->down[scanlines->left] = *point;
scanlines->up[point->x] = *point;
scanlines->down[point->x] = *point;
}
else
{
// Expand existing scanline
if (point->y > scanlines->up[point->x].y)
{
scanlines->up[point->x] = *point;
@ -534,12 +551,6 @@ void RenderArea::pushTriangle(Vector3 pixel1, Vector3 pixel2, Vector3 pixel3, Ve
scanlines.right = -1;
scanlines.up = new ScanPoint[width];
scanlines.down = new ScanPoint[width];
for (x = 0; x < width; x++)
{
/* TODO Do not initialize whole width each time, init only when needed on point push */
scanlines.up[x].y = -1;
scanlines.down[x].y = params.height * params.antialias;
}
/* Render edges in scanlines */
_pushScanLineEdge(this, &scanlines, &point1, &point2);