/*
* =====================================================================================
*
* Filename: viewer.cpp
*
* Description: View multi-z-buffer views
*
* Version: 1.0
* Created: 23/02/2011 08:31:52
* Revision: none
* Compiler: gcc
*
* Author: John Ryland (jryland), jryland@xiaofrog.com
* Company: InvertedLogic
*
* =====================================================================================
*/
#include <viewer.h>
#include <QMatrix4x4>
Viewer::Viewer(QWidget *parent) : QWidget(parent)
{
for (int f = 0; f < 6; f++)
{
QImage img(QString("side_%1_.png").arg(f));
unsigned int *data = (unsigned int *)img.bits();
for (int j = 0; j < 256; j++)
{
for (int i = 0; i < 256; i++)
{
//if ( data[j*256+i] & 0x00ffffff )
{
switch ( f )
{
case 0:
face[f][(255-j)*256+(255-i)] = data[j*256+i] & 0xff;
break;
case 1:
face[f][(255-j)*256+i] = 255 - data[j*256+i] & 0xff;
break;
case 2:
face[f][(255-j)*256+i] = data[j*256+i] & 0xff;
break;
case 3:
face[f][j*256+i] = data[j*256+i] & 0xff;
break;
case 4:
face[f][(255-j)*256+i] = 255 - data[j*256+i] & 0xff;
break;
case 5:
face[f][(255-j)*256+(255-i)] = 255 - data[j*256+i] & 0xff;
break;
/*
case 1:
face[f][j*256+i] = 255 - (data[j*256+i] & 0xff);
break;
case 4:
face[f][j*256+i] = 255 - (data[j*256+i] & 0xff);
break;
case 5:
face[f][j*256+i] = 255 - (data[j*256+i] & 0xff);
break;
*/
default:
face[f][j*256+i] = data[j*256+i] & 0xff;
break;
}
}
//else
{
//face[f][j*256+i] = 0xff;
}
}
}
for (int i = 0; i < 256*256; i++)
{
face2[0][i] = (face[3][i] << 16) | face[1][i];
face2[1][i] = (face[0][i] << 24) | (face[4][i] << 16) |
(face[2][i] << 8) | face[5][i];
face2[2][i] = (face[2][i] << 8) | face[5][i];
// Should generate some mip levels
}
}
angle = 0;
startTimer(1);
}
Viewer::~Viewer()
{
}
void Viewer::timerEvent(QTimerEvent *event)
{
repaint();
}
#include <time.h>
float calcFPS()
{
static unsigned lastTick = clock();
unsigned currTick = clock();
unsigned tickDiff=currTick-lastTick;
lastTick = currTick;
return (float)(CLOCKS_PER_SEC) / (float)(tickDiff); // Inverse
}
void Viewer::paintEvent(QPaintEvent *pe)
{
QPainter p(this);
angle += 15;
QImage output( 256, 256, QImage::Format_ARGB32 );
unsigned int *data = (unsigned int *)output.bits();
/*
int sideX[6];
int sideY[6];
int sideZ[6];
int sideDX[6];
int sideDY[6];
int sideDZ[6];
int sideIncX[6];
int sideIncY[6];
int sideIncZ[6];
sideX[0] = 128;
sideY[0] = 0;
sideZ[0] = -128;
sideDX[0] = -1;
sideDY[0] = 0;
sideDZ[0] = 1;
sideIncX[0] = 1;
sideIncY[0] = 0;
sideIncZ[0] = 1;
// y = y
sideX[1] = 128;
sideZ[1] = -128;
sideDX[1] = -1;
sideDZ[1] = 1;
sideIncX[1] = 1;
sideIncZ[1] = 1;
sideX[2] = 128;
sideZ[2] = -128;
sideDX[2] = -1;
sideDZ[2] = 1;
sideIncX[2] = 1;
sideIncZ[2] = 1;
sideX[3] = 128;
sideZ[3] = -128;
sideDX[3] = -1;
sideDZ[3] = 1;
sideIncX[3] = 1;
sideIncZ[3] = 1;
sideX[4] = 128;
sideZ[4] = -128;
sideDX[4] = -1;
sideDZ[4] = 1;
sideIncX[4] = 1;
sideIncZ[4] = 1;
sideX[5] = 128;
sideZ[5] = -128;
sideDX[5] = -1;
sideDZ[5] = 1;
sideIncX[5] = 1;
sideIncZ[5] = 1;
*/
// At the moment this is orthographic, but shouldn't be hard to modify that
QMatrix4x4 invViewSpace;
invViewSpace.translate( 128, 128, 128 );
invViewSpace.rotate( angle, 0, 1, 0 );
invViewSpace.rotate( angle + 30, 1, 0, 0 );
invViewSpace.rotate( angle - 30, 0, 0, 1 );
invViewSpace.translate( -128, -128, -128 );
for (int y = 0; y < 256; y++)
{
QVector3D pntA(0, y, -10);
pntA = invViewSpace.map(pntA);
QVector3D pntB(256, y, -10);
pntB = invViewSpace.map(pntB);
QVector3D dxpnt1 = (pntB - pntA) / 256.0f;
QVector3D pntC(0, y, 256);
pntC = invViewSpace.map(pntC);
QVector3D pntD(256, y, 256);
pntD = invViewSpace.map(pntD);
QVector3D dxpnt2 = (pntD - pntC) / 256.0f;
int ipntA[3];
int ipntC[3];
short int idPntA[3];
short int idPntC[3];
const float scaleUp = 256.0f;//65536.0f;
const int iScaleUp = 256;//65536;
// const int shiftDown = 8;//16;
#define shiftDown 8
ipntA[0] = pntA.x() * scaleUp;
ipntA[1] = pntA.y() * scaleUp;
ipntA[2] = pntA.z() * scaleUp;
ipntC[0] = pntC.x() * scaleUp;
ipntC[1] = pntC.y() * scaleUp;
ipntC[2] = pntC.z() * scaleUp;
idPntA[0] = dxpnt1.x() * scaleUp;
idPntA[1] = dxpnt1.y() * scaleUp;
idPntA[2] = dxpnt1.z() * scaleUp;
idPntC[0] = dxpnt2.x() * scaleUp;
idPntC[1] = dxpnt2.y() * scaleUp;
idPntC[2] = dxpnt2.z() * scaleUp;
for (int x = 0; x < 256; x++)
{
data[y*256+x] = 0xff000000;
bool inside = false;
int ipnt[3];
int ipnt2[3];
short int idpnt[3];
for (int i = 0; i < 3; i++)
{
ipnt[i] = ipntA[i];
ipnt2[i] = ipntC[i];
ipntA[i] += idPntA[i];
ipntC[i] += idPntC[i];
idpnt[i] = (ipnt2[i] - ipnt[i]) / 256;
}
int px, py, pz;
int c = -10;
for (int j = 0; j < 3; j++)
{
int cnt = 1;
if ( ipnt[j] < 0 )
{
if ( idpnt[j] > 0 ) {
cnt = -ipnt[j] / idpnt[j];
}
}
else if ( ipnt[j] > 256*iScaleUp )
{
if ( idpnt[j] < 0 ) {
cnt = (ipnt[j] - 256*iScaleUp) / -idpnt[j];
}
}
for (int i = 0; i < 3; i++)
ipnt[i] += (cnt - 1) * idpnt[i];
c += cnt - 1;
}
int iterations = 512;
for (int j = 0; j < 3; j++)
{
if ( idpnt[j] > 0 )
{
int its = (256*iScaleUp - ipnt[j]) / idpnt[j];
if ( its < 512 )
{
iterations = its;
}
}
else if ( idpnt[j] < 0 )
{
int its = ipnt[j] / -idpnt[j];
if ( its < 512 )
{
iterations = its;
}
}
}
int z = 0;
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
/*
face2[0][i] = (face[3][i] << 16) | face[1][i];
face2[1][i] = (face[0][i] << 16) | face[4][i];
face2[2][i] = (face[2][i] << 16) | face[5][i];
*/
/*
face2[1][i] = (face[0][i] << 24) | (face[4][i] << 16) |
(face[2][i] << 8) | face[5][i];
while ( z <= iterations
&&
( (ipnt[1] & 0xFF00) <= ( (face2[0][(ipnt[2] & 0xFF00) | (ipnt[0] >> 8)] >> 8) & 0xFF00 )
|| (ipnt[1] & 0xFF00) > ( (face2[0][(ipnt[2] & 0xFF00) | (ipnt[0] >> 8)] << 8) & 0xFF00 )
|| (ipnt[0] & 0xFF00) <= ( (face2[1][(ipnt[1] & 0xFF00) | (ipnt[2] >> 8)] >> 16) & 0xFF00 )
|| (ipnt[0] & 0xFF00) > ( (face2[1][(ipnt[1] & 0xFF00) | (ipnt[2] >> 8)] >> 8) & 0xFF00 )
|| (ipnt[2] & 0xFF00) <= ( (face2[1][(ipnt[1] & 0xFF00) | (ipnt[0] >> 8)] >> 0) & 0xFF00 )
|| (ipnt[2] & 0xFF00) > ( (face2[1][(ipnt[1] & 0xFF00) | (ipnt[0] >> 8)] << 8) & 0xFF00 ) ) )
*/
while ( z <= iterations
&&
( py <= face[3][(pz << 8) | px]
|| py > face[1][(pz << 8) | px]
|| px <= face[0][(py << 8) | pz]
|| px > face[4][(py << 8) | pz]
|| pz <= face[2][(py << 8) | px]
|| pz > face[5][(py << 8) | px] ) )
{
for (int i = 0; i < 3; i++)
ipnt[i] += idpnt[i];
px = ipnt[0] >> shiftDown;// / 65536;
py = ipnt[1] >> shiftDown;// / 65536;
pz = ipnt[2] >> shiftDown;/// 65536;
z++;
}
if ( z <= iterations )
{
int col = z + c;//128;
data[(y<<8)+x] = 0xff000000 | (col << 16) | (col << 8) | col;
}
}
}
/*
for (int i = 0; i < 256*256; i++)
{
unsigned char z = face[0][i];
data[i] = 0xff000000 | (z << 16) | (z << 8) | z;
}
*/
p.drawImage(0, 0, output);
p.setPen( Qt::green );
p.drawText( 10, 30, QString("fps: %1").arg(calcFPS()) );
}
void Viewer::mouseMoveEvent(QMouseEvent *me)
{
}
void Viewer::mouseClickEvent(QMouseEvent *me)
{
}