Software rendering and Camera - problem

Started by
3 comments, last by Aliii 10 years, 11 months ago

I try apply software rendering to draw simple cube. I have matrix World, View, Projection:


My3DMatrix4x4 mWorld(
		1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 1, 0,
		0, 0, 0, 1);


My3DMatrix4x4 mView = m_pCamera->GetViewMatrix();

float fFov = 3.1415926f/4.0f;
float fAspect = 4.0f/3.0f;
float fZFar = 500.0;
float fZNear = 5.0f;

float    h, w, Q;

w = (1.0f/tan(fFov*0.5f))/fAspect;  
h = 1.0f/tan(fFov*0.5f);   
		
Q = fZFar/(fZFar - fZNear);

My3DMatrix4x4 mProj(
w, 0, 0, 0,
0, h, 0, 0,
0, 0, Q, 1,
0, 0, -Q*fZNear, 0);

Then I muptiply all this matrix and multiply all vert of my cube on this result matrix. For multiplication matrix I use DirectX func, and for vertices I use DirectX func D3DXTransformNormal(). Also my camera class use DirectX func for calculation and under original DirectX program my camera class works fine. In normal state my program rendering 3D cube.

Problem appears when I move camera closer to cube and try rotate camera left, right, up, down - error occur when angle > 45 degree. When I have distant from cube and rotate camera - all fine. But when I move camera closer to cube and try rotate it more then 45 degree - program fault. Sorry my English.

This is screenshot #1 when I rotate cube left:

56493896.jpg

This is scrennshot #2 when cube had rotatet more that 45 degree:

71811404.jpg

Also I am use back face culling and frustum clipping (its works fine in my native DirectX program).

My camera class works fine in native DirectX program:


void CFirstPersonCamera::FrameMove(float fTime, int delta)
{
POINT mousePos;
GetCursorPos(&mousePos);

SetCursorPos(nScreenWidth/2, nScreenHeight/2);

    
int nDeltaX=nScreenWidth/2-mousePos.x;
int nDeltaY=nScreenHeight/2-mousePos.y;
	

float m_fRotationScalerX = 0.04f;
float m_fRotationScalerY = 0.04f;

/*	
if(nDeltaY<0) m_fRotationScalerY = m_fRotationScalerY;
else if(nDeltaY>0) m_fRotationScalerY = -m_fRotationScalerY;
else if(nDeltaY==0) m_fRotationScalerY = 0;

My3DMatrix4x4 matRotRight = My3DMatrixRotationAxis(vRight , m_fRotationScalerY);
//My3DMatrix4x4 matRotY = My3DMatrixRotationX(m_fRotationScalerY);
vRight = My3DVec3TransformNormal(vRight, matRotRight);
vUp = My3DVec3TransformNormal(vUp, matRotRight);
vLook = My3DVec3TransformNormal(vLook, matRotRight);
*/


if(nDeltaX<0) m_fRotationScalerX = m_fRotationScalerX;
else if(nDeltaX>0) m_fRotationScalerX = -m_fRotationScalerX;
else if(nDeltaX==0) m_fRotationScalerX = 0;
/*
//My3DVector3 vUpTemp = My3DVector3( 0.0f, 1.0f, 0.0f );
//My3DMatrix4x4 matRotUp = My3DMatrixRotationAxis(vUpTemp , m_fRotationScalerX);
My3DMatrix4x4 matRotUp = My3DMatrixRotationY(m_fRotationScalerX);


	
	
vRight = My3DVec3TransformNormal(vRight, matRotUp);
vUp = My3DVec3TransformNormal(vUp, matRotUp);
vLook = My3DVec3TransformNormal(vLook, matRotUp);
*/	

	
	
D3DXMATRIX matRotUp;
D3DXMatrixRotationY(&matRotUp, m_fRotationScalerX);

D3DXVECTOR3 vR, vU, vL;
vR = D3DXVECTOR3(vRight.x, vRight.y, vRight.z);
vU = D3DXVECTOR3(vUp.x, vUp.y, vUp.z);
vL = D3DXVECTOR3(vLook.x, vLook.y, vLook.z);

D3DXVECTOR3 vOutR, vOutU, vOutL;
D3DXVec3TransformNormal(&vOutR, &vR, &matRotUp);
D3DXVec3TransformNormal(&vOutU, &vU, &matRotUp);
D3DXVec3TransformNormal(&vOutL, &vL, &matRotUp);

vRight = My3DVector3(vOutR.x, vOutR.y, vOutR.z);
vUp = My3DVector3(vOutU.x, vOutU.y, vOutU.z);
vLook = My3DVector3(vOutL.x, vOutL.y, vOutL.z);


float ratioMove = 150;
My3DVector3 temp = My3DVector3(0,0,0);;
My3DVector3 vAccel = My3DVector3(0,0,0);

	
if(GetAsyncKeyState('W')& 0xFF00) 
{
temp = My3DVector3(vLook.x,0,vLook.z);
temp = My3DVec3Dot(temp, ratioMove);
vAccel = My3DVec3Dot(temp, fTime);
vAccel.y = 0.0;
}
if(GetAsyncKeyState('S')& 0xFF00) 
{
temp = My3DVector3(vLook.x,0,vLook.z);
temp = My3DVec3Dot(temp, -ratioMove);
vAccel = My3DVec3Dot(temp, fTime);
}
if(GetAsyncKeyState('D')& 0xFF00) 
{
temp = My3DVector3(vRight.x,0,vRight.z);
temp = My3DVec3Dot(temp, ratioMove);
vAccel = My3DVec3Dot(temp, fTime);
}
if(GetAsyncKeyState('A')& 0xFF00) 
{
temp = My3DVector3(vRight.x,0,vRight.z);
temp = My3DVec3Dot(temp, -ratioMove);
vAccel = My3DVec3Dot(temp, fTime);
}

vAccel.y = 0.0;

vPos = My3DVec3Add(vPos,vAccel);

	
vRight = My3DVec3Normalize(vRight);
vLook = My3DVec3Normalize(vLook);
vUp = My3DVec3Cross(vLook,vRight);
vUp = My3DVec3Normalize(vUp);
vRight = My3DVec3Cross(vUp,vLook);
vRight = My3DVec3Normalize(vRight);
	
	
matView.r1c1 = vRight.x;
matView.r2c1 = vRight.y;
matView.r3c1 = vRight.z;

matView.r1c2 = vUp.x;
matView.r2c2 = vUp.y;
matView.r3c2 = vUp.z;

matView.r1c3 = vLook.x;
matView.r2c3 = vLook.y;
matView.r3c3 = vLook.z;

matView.r1c4 = 0.0;
matView.r2c4 = 0.0;
matView.r3c4 = 0.0;

	
matView.r4c1 =- My3DVec3Dot( vPos, vRight );
matView.r4c2 =- My3DVec3Dot( vPos, vUp    );
matView.r4c3 =- My3DVec3Dot( vPos, vLook  );
	
	
matView.r4c4 = 1.0;
	
}


My3DMatrix4x4 mRes(
1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);

mRes = My3DMatrixMultiply(mRes, mView);
mRes = My3DMatrixMultiply(mRes, mProj);

for( int i = 0; i < 12; i++)
{
pMy3DTriangle_Transformed.v1.tu = pMy3DTriangle_Original.v1.tu;
pMy3DTriangle_Transformed.v1.tv = pMy3DTriangle_Original.v1.tv;
pMy3DTriangle_Transformed.v2.tu = pMy3DTriangle_Original.v2.tu;
pMy3DTriangle_Transformed.v2.tv = pMy3DTriangle_Original.v2.tv;
pMy3DTriangle_Transformed.v3.tu = pMy3DTriangle_Original.v3.tu;
pMy3DTriangle_Transformed.v3.tv = pMy3DTriangle_Original.v3.tv;


D3DXMATRIX mResDX = D3DXMATRIX(mRes.r1c1, mRes.r1c2,mRes.r1c3,mRes.r1c4,
mRes.r2c1, mRes.r2c2,mRes.r2c3,mRes.r2c4,
mRes.r3c1, mRes.r3c2,mRes.r3c3,mRes.r3c4,
mRes.r4c1, mRes.r4c2,mRes.r4c3,mRes.r4c4);

D3DXVECTOR3 vt1 = D3DXVECTOR3(pMy3DTriangle_Original.v1.x, pMy3DTriangle_Original.v1.y, pMy3DTriangle_Original.v1.z);
D3DXVECTOR3 vt1_Out;
D3DXVec3TransformNormal(&vt1_Out, &vt1, &mResDX);

D3DXVECTOR3 vt2 = D3DXVECTOR3(pMy3DTriangle_Original.v2.x, pMy3DTriangle_Original.v2.y, pMy3DTriangle_Original.v2.z);
D3DXVECTOR3 vt2_Out;
D3DXVec3TransformNormal(&vt2_Out, &vt2, &mResDX);

D3DXVECTOR3 vt3 = D3DXVECTOR3(pMy3DTriangle_Original.v3.x, pMy3DTriangle_Original.v3.y, pMy3DTriangle_Original.v3.z);
D3DXVECTOR3 vt3_Out;
D3DXVec3TransformNormal(&vt3_Out, &vt3, &mResDX);

pMy3DTriangle_Transformed.v1.x = vt1_Out.x / vt1_Out.z;
pMy3DTriangle_Transformed.v1.y = vt1_Out.y / vt1_Out.z;
pMy3DTriangle_Transformed.v1.z = vt1_Out.z;

pMy3DTriangle_Transformed.v2.x = vt2_Out.x / vt2_Out.z;
pMy3DTriangle_Transformed.v2.y = vt2_Out.y / vt2_Out.z;
pMy3DTriangle_Transformed.v2.z = vt2_Out.z;

pMy3DTriangle_Transformed.v3.x = vt3_Out.x / vt3_Out.z;
pMy3DTriangle_Transformed.v3.y = vt3_Out.y / vt3_Out.z;
pMy3DTriangle_Transformed.v3.z = vt3_Out.z;
}

Please assist me. Thanks in advance.

Windows programming is like going to the dentist: You know it’s good for you, but no one likes doing it.- Andre LaMothe.
Advertisement
Could you describe better what the actual issue is? Meaning how does the actual output differ from the expected output. By "program fault" do you mean it crashes or that it just doesn't look right?

However, with what you have describe so far it seems like the problem is caused by a face with points both in front of and behind the camera. In that case I would look at your clipping algorithms to make sure they handle that case properly.
My current game project Platform RPG

What does "error occurs" mean? Crash? The debugger would give you the fastest answer I think.

+you also have a few division by zero candidates

pMy3DTriangle_Transformed.v1.x = vt1_Out.x / vt1_Out.z;
pMy3DTriangle_Transformed.v1.y = vt1_Out.y / vt1_Out.z;
pMy3DTriangle_Transformed.v1.z = vt1_Out.z;

pMy3DTriangle_Transformed.v2.x = vt2_Out.x / vt2_Out.z;
pMy3DTriangle_Transformed.v2.y = vt2_Out.y / vt2_Out.z;
pMy3DTriangle_Transformed.v2.z = vt2_Out.z;

pMy3DTriangle_Transformed.v3.x = vt3_Out.x / vt3_Out.z;
pMy3DTriangle_Transformed.v3.y = vt3_Out.y / vt3_Out.z;

Hi guys! Very thanks for you attention.

For example I have front poly of cube 1st tri:

2-3

| /

1

and second tri:

2

/ |

1-3

Then run program, and move cube left behind left edge of screen. My code write log file:








num_tri=1 : tri=0 : y1=-9.166122 : y2=9.166122 : y3=1.458612
num_tri=2 : tri=1 : y1=-9.166122 : y2=1.458612 : y3=-1.458612
num_tri=1 : tri=0 : y1=-9.166122 : y2=9.166122 : y3=1.458612
num_tri=2 : tri=1 : y1=-9.166122 : y2=1.458612 : y3=-1.458612
num_tri=1 : tri=0 : y1=-13.575529 : y2=13.575529 : y3=1.483807
num_tri=2 : tri=1 : y1=-13.575529 : y2=1.483807 : y3=-1.483807
num_tri=1 : tri=0 : y1=-26.473291 : y2=26.473291 : y3=1.513117
num_tri=2 : tri=1 : y1=-26.473291 : y2=1.513117 : y3=-1.513117
num_tri=1 : tri=0 : y1=-670.692383 : y2=670.692383 : y3=1.546930
num_tri=2 : tri=1 : y1=-670.692383 : y2=1.546930 : y3=-1.546930
num_tri=1 : tri=0 : y1=-670.692383 : y2=670.692383 : y3=1.546930
num_tri=2 : tri=1 : y1=-670.692383 : y2=1.546930 : y3=-1.546930
num_tri=1 : tri=0 : y1=-670.692383 : y2=670.692383 : y3=1.546930
num_tri=2 : tri=1 : y1=-670.692383 : y2=1.546930 : y3=-1.546930
num_tri=1 : tri=0 : y1=28.466400 : y2=-28.466400 : y3=1.585725
num_tri=2 : tri=1 : y1=28.466400 : y2=1.585725 : y3=-1.585725
num_tri=1 : tri=0 : y1=13.883531 : y2=-13.883531 : y3=1.630078


where num_tri = is count of triangle to draw presently, tri = number of triangle (front face cube tri 0 and 1) and y1, y2, y3 - is Y coord of vert 1,2,3. This records log file before fault. As you can see y1 coord was y1=-670.692383 (vert1 - y1 is located below screen and left) and next record abrupt y1 = y1=28.466400 (that means vert1- y1 is located in range screen).

I think my clipping OK because in rendering process draw only triangle 0 and 1 (front face of cuble) and this show log file. But code:








for(int i = 0; i < 12; i++)
{
My3DVector3 v1 = My3DVector3(pMy3DTriangle_Original.v1.x,
		pMy3DTriangle_Original.v1.y,
		pMy3DTriangle_Original.v1.z);

My3DVector3 v2 = My3DVector3(pMy3DTriangle_Original.v2.x,
		pMy3DTriangle_Original.v2.y,
		pMy3DTriangle_Original.v2.z);

My3DVector3 v3 = My3DVector3(pMy3DTriangle_Original.v3.x,
		pMy3DTriangle_Original.v3.y,
		pMy3DTriangle_Original.v3.z);


My3DVector3 m_BoundsMin, m_BoundsMax;

m_BoundsMin = My3DVector3( 999999.0f, 999999.0f, 999999.0f );
m_BoundsMax = My3DVector3( -999999.0f, -999999.0f, -999999.0f );

if ( v1.x < m_BoundsMin.x ) m_BoundsMin.x = v1.x;
if ( v1.y < m_BoundsMin.y ) m_BoundsMin.y = v1.y;
if ( v1.z < m_BoundsMin.z ) m_BoundsMin.z = v1.z;
if ( v1.x > m_BoundsMax.x ) m_BoundsMax.x = v1.x;
if ( v1.y > m_BoundsMax.y ) m_BoundsMax.y = v1.y;
if ( v1.z > m_BoundsMax.z ) m_BoundsMax.z = v1.z;

if ( v2.x < m_BoundsMin.x ) m_BoundsMin.x = v2.x;
if ( v2.y < m_BoundsMin.y ) m_BoundsMin.y = v2.y;
if ( v2.z < m_BoundsMin.z ) m_BoundsMin.z = v2.z;
if ( v2.x > m_BoundsMax.x ) m_BoundsMax.x = v2.x;
if ( v2.y > m_BoundsMax.y ) m_BoundsMax.y = v2.y;
if ( v2.z > m_BoundsMax.z ) m_BoundsMax.z = v2.z;

if ( v3.x < m_BoundsMin.x ) m_BoundsMin.x = v3.x;
if ( v3.y < m_BoundsMin.y ) m_BoundsMin.y = v3.y;
if ( v3.z < m_BoundsMin.z ) m_BoundsMin.z = v3.z;
if ( v3.x > m_BoundsMax.x ) m_BoundsMax.x = v3.x;
if ( v3.y > m_BoundsMax.y ) m_BoundsMax.y = v3.y;
if ( v3.z > m_BoundsMax.z ) m_BoundsMax.z = v3.z;

		
if (!BoundsInFrustum(m_BoundsMin, m_BoundsMax, mRes))
pMy3DTriangle_Transformed.TriState_Clipped = CLIPPED;	
else
pMy3DTriangle_Transformed.TriState_Clipped = NOTCLIPPED;
}

And render proc:








DDraw_Lock_Back_Surface();

myTRI = 0;
myNumTri = 0;
	
for ( int i = 0; i < 12; i++)
{
if(pMy3DTriangle_Transformed.TriState_Cull == CULL) continue;
if(pMy3DTriangle_Transformed.TriState_Clipped == CLIPPED) continue;
			
			
myTRI = i;
myNumTri++;

FILE *f;
f = fopen("log.txt", "at");
char szBuff[256];
sprintf_s(szBuff,256, "num_tri=%d : tri=%d : y1=%f : y2=%f : y3=%f\n", myNumTri,
myTRI, pMy3DTriangle_Transformed.v1.y, pMy3DTriangle_Transformed.v2.y, pMy3DTriangle_Transformed.v3.y);
fwrite((void*)szBuff, strlen(szBuff), 1, f);
fclose(f);

			
Draw_Textured_Triangle(pMy3DTriangle_Transformed, back_buffer, back_lpitch);
		}
DDraw_Unlock_Back_Surface();

DDraw_Flip();







void CMy3DApp::Draw_Textured_Triangle(My3DTriangle tri,
		UCHAR *dest_buffer,   // pointer to video buffer
		int mem_pitch)        // bytes per line, 320, 640 etc.
{
int side;
float x1, x2, x3;
float y1, y2, y3;
float iz1, uiz1, viz1, iz2, uiz2, viz2, iz3, uiz3, viz3;
float tempf;
int y1i, y2i, y3i;
float dxdy1, dxdy2, dxdy3;
float dy;
float dyl, dyr;

x1 = tri.vScreen1.x + 0.5f;
y1 = tri.vScreen1.y + 0.5f;
x2 = tri.vScreen2.x + 0.5f;
y2 = tri.vScreen2.y + 0.5f;
x3 = tri.vScreen3.x + 0.5f;
y3 = tri.vScreen3.y + 0.5f;

iz1 = 1.0f / tri.v1.z;
iz2 = 1.0f / tri.v2.z;
iz3 = 1.0f / tri.v3.z;

uiz1 = tri.v1.tu * iz1;
viz1 = tri.v1.tv * iz1;
uiz2 = tri.v2.tu * iz2;
viz2 = tri.v2.tv * iz2;
uiz3 = tri.v3.tu * iz3;
viz3 = tri.v3.tv * iz3;

#define swapfloat(x, y) tempf = x; x = y; y = tempf;

if (y1 > y2)
{
swapfloat(x1, x2);
swapfloat(y1, y2);
swapfloat(iz1, iz2);
swapfloat(uiz1, uiz2);
swapfloat(viz1, viz2);
}
if (y1 > y3)
{
swapfloat(x1, x3);
swapfloat(y1, y3);
swapfloat(iz1, iz3);
swapfloat(uiz1, uiz3);
swapfloat(viz1, viz3);
}
if (y2 > y3)
{
swapfloat(x2, x3);
swapfloat(y2, y3);
swapfloat(iz2, iz3);
swapfloat(uiz2, uiz3);
swapfloat(viz2, viz3);
}
	
#undef swapfloat

//variables for log file
myY1 = y1;
myY2 = y2;
myY3 = y3;
	

y1i = (int) y1;
y2i = (int) y2;
y3i = (int) y3;

if ((y1i == y2i && y1i == y3i) || ((int) x1 == (int) x2 && (int) x1 == (int) x3))
return;


dxdy1 = 0.0;
dxdy2 = 0.0;
dxdy3 = 0.0;

if (y2 > y1)
dxdy1 = (x2 - x1) / (y2 - y1);
if (y3 > y1)
dxdy2 = (x3 - x1) / (y3 - y1);
if (y3 > y2)
dxdy3 = (x3 - x2) / (y3 - y2);

// Determine which side of the poly the longer edge is on
	
side = dxdy2 > dxdy1;

if (y1 == y2)
side = x1 > x2;
if (y2 == y3)
	side = x3 > x2;

int nMinClipY = nViewY;
int nMaxClipY = nViewHeight;

int nMinClipX = nViewX;
int nMaxClipX = nViewWidth;
	
if(y1i> nMaxClipY) y1i = 599;
if(y2i> nMaxClipY) y2i = 599;
if(y3i> nMaxClipY) y3i = 599;

if(y1i< nMinClipY) y1i = 0;
if(y2i< nMinClipY) y2i = 0;
if(y3i< nMinClipY) y3i = 0;


if (!side)	// Longer edge is on the left side
{
	
dyl = y3 - y1;
dxdyl = (x3 - x1) / dyl;
dudyl = (uiz3 - uiz1) / dyl;
dvdyl = (viz3 - viz1) / dyl;
dzdyl = (iz3 - iz1) / dyl;
	
dy = 1 - (y1 - y1i);
xl = x1 + dy * dxdyl;
ul = uiz1 + dy * dudyl;
vl = viz1 + dy * dvdyl;
zl = iz1 + dy * dzdyl;

if(y1 < nMinClipY)
{
dy = nMinClipY - y1;
xl = x1 + dy * dxdyl;
ul = uiz1 + dy * dudyl;
vl = viz1 + dy * dvdyl;
zl = iz1 + dy * dzdyl;

}

if (y1 < y2)	// Draw upper segment if possibly visible
{
		
dyr = y2 - y1;
dxdyr = (x2 - x1) / dyr;
dudyr = (uiz2 - uiz1) / dyr;
dvdyr = (viz2 - viz1) / dyr;
dzdyr = (iz2 - iz1) / dyr;

xr = x1 + dy * dxdyr;
ur = uiz1 + dy * dudyr;
vr = viz1 + dy * dvdyr;
zr = iz1 + dy * dzdyr;

if(y1 < nMinClipY)
{
dy = nMinClipY - y1;
xr = x1 + dy * dxdyr;
ur = uiz1 + dy * dudyr;
vr = viz1 + dy * dvdyr;
zr = iz1 + dy * dzdyr;

}


Draw_Textured_Poly(y1i, y2i, back_buffer, back_lpitch);

}
if (y2 < y3)	// Draw lower segment if possibly visible
{

dyr = y3 - y2;
dxdyr = (x3 - x2) / dyr;
dudyr = (uiz3 - uiz2) / dyr;
dvdyr = (viz3 - viz2) / dyr;
dzdyr = (iz3 - iz2) / dyr;

xr = x2 + (1 - (y2 - y2i)) * dxdyr;
ur = uiz2 + (1 - (y2 - y2i)) * dudyr;
vr = viz2 + (1 - (y2 - y2i)) * dvdyr;
zr = iz2 + (1 - (y2 - y2i)) * dzdyr;

if(y2 < nMinClipY)
{
dy = nMinClipY - y2;
xr = x2 + dy * dxdyr;
ur = uiz2 + dy * dudyr;
vr = viz2 + dy * dvdyr;
zr = iz2 + dy * dzdyr;

}

Draw_Textured_Poly(y2i, y3i, back_buffer, back_lpitch);

}
}

else // Longer edge is on the right side
{
dyr = y3 - y1;
dxdyr = (x3 - x1) / dyr;
dudyr = (uiz3 - uiz1) / dyr;
dvdyr = (viz3 - viz1) / dyr;
dzdyr = (iz3 - iz1) / dyr;

dy = 1 - (y1 - y1i);
xr = x1 + dy * dxdyr;
ur = uiz1 + dy * dudyr;
vr = viz1 + dy * dvdyr;
zr = iz1 + dy * dzdyr;

if(y1 < nMinClipY)
{
dy = nMinClipY - y1;
xr = x1 + dy * dxdyr;
ur = uiz1 + dy * dudyr;
vr = viz1 + dy * dvdyr;
zr = iz1 + dy * dzdyr;
}

if (y1 < y2)	// Draw upper segment if possibly visible
{
dyl = y2 - y1;
dxdyl = (x2 - x1) / dyl;
dudyl = (uiz2 - uiz1) / dyl;
dvdyl = (viz2 - viz1) / dyl;
dzdyl = (iz2 - iz1) / dyl;

xl = x1 + dy * dxdyl;
ul = uiz1 + dy * dudyl;
vl = viz1 + dy * dvdyl;
zl = iz1 + dy * dzdyl;

if(y1 < nMinClipY)
{	
dy = nMinClipY - y1;
xl = x1 + dy * dxdyl;
ul = uiz1 + dy * dudyl;
vl = viz1 + dy * dvdyl;
zl = iz1 + dy * dzdyl;
}

Draw_Textured_Poly(y1i, y2i, back_buffer, back_lpitch);
			
}
if (y2 < y3)	// Draw lower segment if possibly visible
{
		
dyl = y3 - y2;
dxdyl = (x3 - x2) / dyl;
dudyl = (uiz3 - uiz2) / dyl;
dvdyl = (viz3 - viz2) / dyl;
dzdyl = (iz3 - iz2) / dyl;

			
dy = 1 - (y2 - y2i);
xl = x2 + dy * dxdyl;
ul = uiz2 + dy * dudyl;
vl = viz2 + dy * dvdyl;
zl = iz2 + dy * dzdyl;

if(y2 < nMinClipY)
{
dy = nMinClipY - y2;
xl = x2 + dy * dxdyl;
ul = uiz2 + dy * dudyl;
vl = viz2 + dy * dvdyl;
zl = iz2 + dy * dzdyl;

}

Draw_Textured_Poly(y2i, y3i, back_buffer, back_lpitch);

}
}

	
	
} // end Draw_Textured_Triangle

void CMy3DApp::Draw_Textured_Poly(int y1, int y2,
			UCHAR *dest_buffer,   
			int mem_pitch)        
{
int x1, x2;
int dx;
float ui, vi, zi;
float du, dv, dz;

int nMinClipX = nViewX;
int nMaxClipX = nViewWidth;
	

UCHAR *screen_ptr  = NULL;
screen_ptr = dest_buffer + (y1 * mem_pitch);
			
for (int yi = y1; yi<y2; yi++)
{
				
x1 = (int) xl;
x2   = (int) xr;

ui = ul;
vi = vl;
zi = zl;

if ((dx = (x2 - x1))>0)
{
du = (ur - ul)/dx;
dv = (vr - vl)/dx;
dz = (zr - zl)/dx;
}
else
{
du = (ur - ul);
dv = (vr - vl);
dz = (zr - zl);
}
				
if(x1 < nMinClipX)
{
dx = nMinClipX-x1;
ui+=dx * du;
vi+=dx * dv;
zi+=dx * dz;
x1 = nMinClipX;
}

				
if(x1 == 0 && x2 == 0) return;

if(x2> nMaxClipX) x2 = 799;

int indx =  x1 * 4;

for (int xi=x1; xi<x2; xi++)
{

float z = 1.0/zi;
float u = ui  * z;
float v = vi  * z;

int t = (int)u  + (((int)v) << 6);
					

t= t*3;

screen_ptr[indx] = pRes[t];
indx++;

screen_ptr[indx] = pRes[t+1];
indx++;

screen_ptr[indx] = pRes[t+2];
indx++;

screen_ptr[indx] = 0;
indx++;

ui+=du;
vi+=dv;
zi+=dz;
}

xl+=dxdyl;
ul+=dudyl;
vl+=dvdyl;
zl+=dzdyl;

xr+=dxdyr;
ur+=dudyr;
vr+=dvdyr;
zr+=dzdyr;

screen_ptr+=mem_pitch;

				
}
}

Run time error occurs in code:








int t = (int)u  + (((int)v) << 6);
					
t= t*3;

screen_ptr[indx] = pRes[t]; // HERE ERROR !!!!!!!!!!!!!!!!!!!!!!!!!!!!!
indx++;

screen_ptr[indx] = pRes[t+1];
indx++;

screen_ptr[indx] = pRes[t+2];
indx++;

screen_ptr[indx] = 0;
indx++;

And another screenshot. When I move whole cube behind left edge of screen appears this screenshot and next runtime error:

44766596.jpg

And in normal state without error (no moving, no rotation) cube render fine:

60259675.jpg

51864110.jpg

Windows programming is like going to the dentist: You know it’s good for you, but no one likes doing it.- Andre LaMothe.

Whats the question?

Why dont you try the debugger? ...its a good thing

This topic is closed to new replies.

Advertisement