Making Software rasterization similar to Directx Issues.

Started by
7 comments, last by AzharulHaque 12 years, 8 months ago
Hi,

I have an issue with implementing the rasterization that operates completly in CPU. Actually i wanted to behave exactly similar to the DirectX.

Forget about the Shading and Texturing and optimizing the code. :)
Right now i just wanted to make it look similar to the DirectX.

Here is the sample code of my software rasterization.

http://www.mediafire.com/?mpd4caua80z4atk

and here is the sample code of same triangles rendered above in directx.

http://www.mediafire.com/?ffe62nfqjpgvxp5

I appreciate for your time and really need your help to sort it out. As i am also involved with modelling works so cant give much time on it.

Thanks.

Advertisement
ok i have uploaded the images. Please check it out.

In DirectX

http://imageshack.us/photo/my-images/94/directxnv.jpg/

directxnv.jpg

Uploaded with ImageShack.us

In my own version of software rasterization

http://imageshack.us/photo/my-images/10/softwarer.jpg/

softwarer.jpg

Uploaded with ImageShack.us
Hi,

you aren't exactly explaining the issue it seems that you are missing z-buffering?

Cheers!
looks like clipping to me,

one of the vertices of the blue triangle appears to be behind the near plane... so you will need to clip it. or it will spaz out like that.

that what is going on?
I think he might be missing near plane clipping too.
Does blue triangle originates from behind the camera?

EDIT: We've posted at the same time.
i am not doing near and far plane clipping here..
ok here is the sample code for software rasterization

// ChildView.h : interface of the CChildView class
//


#pragma once

enum { TOP = 0x1, BOTTOM = 0x2, RIGHT = 0x4, LEFT = 0x8 };
typedef unsigned int outcode;

// CChildView window
class CChildView : public CWnd
{
// Construction
public:
CChildView();

// Attributes
public:

// Operations
public:
void Transform(D3DXVECTOR3 &v);

void clipEdgeTop(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, std::vector<D3DXVECTOR3> &triListOut);
void clipEdgeBottom(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, std::vector<D3DXVECTOR3> &triListOut);
void clipEdgeLeft(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, std::vector<D3DXVECTOR3> &triListOut);
void clipEdgeRight(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, std::vector<D3DXVECTOR3> &triListOut);
void ClipTriangle(std::vector<D3DXVECTOR3> &triListIn);


void ScanTriangleA(CPaintDC &dc, D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, D3DXVECTOR3 &v3);
inline void CreateEdge(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, int &e1x, int &e1y, int &e2x, int &e2y);
void DrawSpansBetweenEdges( CPaintDC &dc, int e1x1, int e1y1, int e1x2, int e1y2,
int e2x1, int e2y1, int e2x2, int e2y2);

// Overrides
protected:
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);

// Implementation
public:
virtual ~CChildView();

// Generated message map functions
RECT m_ScreenRect;
UINT m_dwScreenWidth, m_dwScreenHeight;
float m_fFarDist;
float *m_fZBuffer;

float A, B, C, D, dz;
COLORREF m_dwColor;

protected:
afx_msg void OnPaint();
DECLARE_MESSAGE_MAP()
};

// ChildView.cpp : implementation of the CChildView class
//

#include "stdafx.h"
#include "TriangleScan.h"
#include "ChildView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CChildView

CChildView::CChildView()
{
m_fFarDist = 150;
m_fZBuffer = NULL;
dz = 0;
}

CChildView::~CChildView()
{
if(m_fZBuffer)
{
delete[] (m_fZBuffer);
m_fZBuffer = NULL;
}
}


BEGIN_MESSAGE_MAP(CChildView, CWnd)
ON_WM_PAINT()
END_MESSAGE_MAP()



// CChildView message handlers

BOOL CChildView::PreCreateWindow(CREATESTRUCT& cs)
{
if (!CWnd::PreCreateWindow(cs))
return FALSE;

cs.dwExStyle |= WS_EX_CLIENTEDGE;
cs.style &= ~WS_BORDER;
cs.lpszClass = AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS,
::LoadCursor(NULL, IDC_ARROW), reinterpret_cast<HBRUSH>(COLOR_WINDOW+1), NULL);

return TRUE;
}

void CChildView::Transform(D3DXVECTOR3 &v)
{
// We shouldn't perform division by zero, no ?
if(v.z >= -0.0001f && v.z <= 0.0001f) v.z = 1.0f;

// Project the point
float inv = m_fFarDist / v.z;

v.x = v.x * inv + (m_dwScreenWidth >> 1);
v.y = -v.y * inv + (m_dwScreenHeight >> 1);
}

bool BackFaceCull(D3DXVECTOR3 &v, D3DXVECTOR3 &n, D3DXVECTOR3 &e)
{
//return(dot(e-v1, n)<=0);
return false;
}

void CChildView::clipEdgeTop(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, std::vector<D3DXVECTOR3> &triListOut)
{
if (v1.y >= m_ScreenRect.top && v2.y >= m_ScreenRect.top)
triListOut.push_back(v1);
else if(v1.y >= m_ScreenRect.top && v2.y < m_ScreenRect.top)
{
float m = (float)(m_ScreenRect.top - v1.y) / (v2.y - v1.y);
D3DXVECTOR3 v;
v.x = v1.x + (v2.x - v1.x) * m;
v.y = m_ScreenRect.top;
v.z = v1.z + (v2.z - v1.z) * m;
triListOut.push_back(v1);
triListOut.push_back(v);
}
else if(v1.y < m_ScreenRect.top && v2.y >= m_ScreenRect.top)
{
float m = (float)(m_ScreenRect.top - v1.y) / (v2.y - v1.y);
D3DXVECTOR3 v;
v.x = v1.x + (v2.x - v1.x) * m;
v.y = m_ScreenRect.top;
v.z = v1.z + (v2.z - v1.z) * m;
triListOut.push_back(v);
}
}
void CChildView::clipEdgeBottom(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, std::vector<D3DXVECTOR3> &triListOut)
{
if (v1.y <= m_ScreenRect.bottom && v2.y <= m_ScreenRect.bottom)
triListOut.push_back(v1);
else if(v1.y <= m_ScreenRect.bottom && v2.y > m_ScreenRect.bottom)
{
float m = (float)(m_ScreenRect.bottom - v1.y) / (v2.y - v1.y);
D3DXVECTOR3 v;
v.x = v1.x + (v2.x - v1.x) * m;
v.y = m_ScreenRect.bottom;
v.z = v1.z + (v2.z - v1.z) * m;
triListOut.push_back(v1);
triListOut.push_back(v);
}
else if(v1.y > m_ScreenRect.bottom && v2.y <= m_ScreenRect.bottom)
{
float m = (float)(m_ScreenRect.bottom - v1.y) / (v2.y - v1.y);
D3DXVECTOR3 v;
v.x = v1.x + (v2.x - v1.x) * m;
v.y = m_ScreenRect.bottom;
v.z = v1.z + (v2.z - v1.z) * m;
triListOut.push_back(v);
}
}
void CChildView::clipEdgeLeft(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, std::vector<D3DXVECTOR3> &triListOut)
{
if (v1.x >= m_ScreenRect.left && v2.x >= m_ScreenRect.left)
triListOut.push_back(v1);
else if(v1.x >= m_ScreenRect.left && v2.x < m_ScreenRect.left)
{
D3DXVECTOR3 v;
float m = (float)(m_ScreenRect.left - v1.x) / (v2.x - v1.x);
v.y = v1.y + (v2.y - v1.y) * m;
v.x = m_ScreenRect.left;
v.z = v1.z + (v2.z - v1.z) * m;
triListOut.push_back(v1);
triListOut.push_back(v);
}
else if(v1.x < m_ScreenRect.left && v2.x >= m_ScreenRect.left)
{
D3DXVECTOR3 v;
float m = (float)(m_ScreenRect.left - v1.x) / (v2.x - v1.x);
v.y = v1.y + (v2.y - v1.y) * m;
v.x = m_ScreenRect.left;
v.z = v1.z + (v2.z - v1.z) * m;
triListOut.push_back(v);
}
}
void CChildView::clipEdgeRight(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, std::vector<D3DXVECTOR3> &triListOut)
{
if (v1.x <= m_ScreenRect.right && v2.x <= m_ScreenRect.right)
triListOut.push_back(v1);
else if(v1.x <= m_ScreenRect.right && v2.x > m_ScreenRect.right)
{
D3DXVECTOR3 v;
float m = (float)(m_ScreenRect.right - v1.x) / (v2.x - v1.x);
v.y = v1.y + (v2.y - v1.y) * m;
v.x = m_ScreenRect.right;
v.z = v1.z + (v2.z - v1.z) * m;
triListOut.push_back(v1);
triListOut.push_back(v);
}
else if(v1.x > m_ScreenRect.right && v2.x <= m_ScreenRect.right)
{
D3DXVECTOR3 v;
float m = (float)(m_ScreenRect.right - v1.x) / (v2.x - v1.x);
v.y = v1.y + (v2.y - v1.y) * m;
v.x = m_ScreenRect.right;
v.z = v1.z + (v2.z - v1.z) * m;
triListOut.push_back(v);
}
}
void CChildView::ClipTriangle(std::vector<D3DXVECTOR3> &triListIn)
{
std::vector<D3DXVECTOR3> triListTemp;

UINT nLoopCount = triListIn.size();
UINT i,j;
for(i=0; i<nLoopCount; i++)
{
j=i+1;
if (j == nLoopCount)j = 0;
clipEdgeTop(triListIn, triListIn[j], triListTemp);
}

triListIn.clear();
nLoopCount = triListTemp.size();
for(i=0; i<nLoopCount; i++)
{
j=i+1;
if (j == nLoopCount)j = 0;
clipEdgeLeft(triListTemp, triListTemp[j], triListIn);
}
triListTemp.clear();
nLoopCount = triListIn.size();
for(i=0; i<nLoopCount; i++)
{
j=i+1;
if (j == nLoopCount)j = 0;
clipEdgeBottom(triListIn, triListIn[j], triListTemp);
}
triListIn.clear();
nLoopCount = triListTemp.size();
for(i=0; i<nLoopCount; i++)
{
j=i+1;
if (j == nLoopCount)j = 0;
clipEdgeRight(triListTemp, triListTemp[j], triListIn);
}
triListTemp.clear();
}

void CChildView::CreateEdge(D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, int &e1x, int &e1y, int &e2x, int &e2y)
{
if(v1.y < v2.y)
{
e1x = v1.x;
e1y = v1.y;
e2x = v2.x;
e2y = v2.y;
}
else
{
e1x = v2.x;
e1y = v2.y;
e2x = v1.x;
e2y = v1.y;
}
}
void CChildView::ScanTriangleA(CPaintDC &dc, D3DXVECTOR3 &v1, D3DXVECTOR3 &v2, D3DXVECTOR3 &v3)
{
//Collect Triangle Edges
int ex1[3], ey1[3], ex2[3], ey2[3];
CreateEdge(v1, v2, ex1[0], ey1[0], ex2[0], ey2[0]);
CreateEdge(v2, v3, ex1[1], ey1[1], ex2[1], ey2[1]);
CreateEdge(v3, v1, ex1[2], ey1[2], ex2[2], ey2[2]);

int maxLength = 0;
short longEdge = 0;
int length = 0;

// find edge with the greatest length in the y axis
// find edge with the greatest length in the y axis
for(short i = 0; i < 3; i++) {
length = ey2 - ey1;
if(length > maxLength) {
maxLength = length;
longEdge = i;
}
}

short shortEdge1 = (longEdge + 1) % 3;
short shortEdge2 = (longEdge + 2) % 3;

// draw spans between edges; the long edge can be drawn
// with the shorter edges to draw the full triangle
DrawSpansBetweenEdges(dc, ex1[longEdge], ey1[longEdge], ex2[longEdge], ey2[longEdge], ex1[shortEdge1], ey1[shortEdge1], ex2[shortEdge1], ey2[shortEdge1]);
DrawSpansBetweenEdges(dc, ex1[longEdge], ey1[longEdge], ex2[longEdge], ey2[longEdge], ex1[shortEdge2], ey1[shortEdge2], ex2[shortEdge2], ey2[shortEdge2]);
}


void CChildView::DrawSpansBetweenEdges( CPaintDC &dc, int e1x1, int e1y1, int e1x2, int e1y2,
int e2x1, int e2y1, int e2x2, int e2y2)
{
// calculate difference between the y coordinates
// of the first edge and return if 0
const int e1ydiff = e1y2 - e1y1;
if(e1ydiff == 0x0)
return;

// calculate difference between the y coordinates
// of the second edge and return if 0
const int e2ydiff = e2y2 - e2y1;
if(e2ydiff == 0x0)
return;

// calculate differences between the x coordinates
const float e1xdiff = (float)(e1x2 - e1x1);
const float e2xdiff = (float)(e2x2 - e2x1);

// calculate factors to use for interpolation
// with the edges and the step values to increase
// them by after drawing each span
const float factorStep1 = e1xdiff / e1ydiff;
const float factorStep2 = e2xdiff / e2ydiff;

// loop through the lines between the edges and draw spans
int x, xdiff, coord, iX1, iX2;
float X1 = (float)e1x1 + factorStep1 * (e2y1 - e1y1), X2 = e2x1, z;

for(int y = e2y1; y < e2y2; y++)
{
// calculate initial z-value for edges
z = ((-D)- B*y)/C;

iX1 = (int)X1;
iX2 = (int)X2;
// create and draw span
xdiff = iX2 - iX1;
if(xdiff == 0x0)
{
// increase factors
X1 = X1 + factorStep1;
X2 = X2 + factorStep2;
continue;
}
if (iX1 > iX2)
{
// draw each pixel in the span
for(x = iX2; x < iX1; x++)
{
coord = y*m_dwScreenWidth+x;
if(z >= m_fZBuffer[coord])
{
m_fZBuffer[coord] = z;
SetPixel(dc, x, y, m_dwColor);
}
z += dz;
}
}
else
{
// draw each pixel in the span
for(x = iX1; x < iX2; x++)
{
coord = y*m_dwScreenWidth+x;
if(z >= m_fZBuffer[coord])
{
m_fZBuffer[coord] = z;
SetPixel(dc, x, y, m_dwColor);
}
z += dz;
}
}
// increase factors
X1 = X1 + factorStep1;
X2 = X2 + factorStep2;
}
}

void CChildView::OnPaint()
{
CPaintDC dc(this); // device context for painting
GetWindowRect(&m_ScreenRect);

m_ScreenRect.left = 0;
m_ScreenRect.top = 0;
m_ScreenRect.right = 1000;
m_ScreenRect.bottom = 400;

m_dwScreenHeight = m_ScreenRect.bottom - m_ScreenRect.top;
m_dwScreenWidth= m_ScreenRect.right - m_ScreenRect.left;

dc.Rectangle(m_ScreenRect.left, m_ScreenRect.top, m_ScreenRect.right, m_ScreenRect.bottom);

if(m_fZBuffer)
{
delete[] (m_fZBuffer);
}
UINT nSize = m_dwScreenWidth*m_dwScreenHeight;
m_fZBuffer = new float[nSize];
ZeroMemory(m_fZBuffer, sizeof(float)*nSize);
float fTime = timeGetTime();

D3DXVECTOR3 v1, v2, v3;

v1.x = 0;
v1.y = 0;
v1.z = 0.5f;

v2.x = -2;
v2.y = 2;
v2.z = -2;

v3.x = 4;
v3.y = 1;
v3.z = 5;

D3DXMATRIXA16 m_mWorld, m_mView, m_mProj, m_mWorldViewProj;
D3DXMatrixIdentity(&m_mWorld);
D3DXVECTOR3 vEyeAt(0, 3, -5), vLookAt(0,0,0), vUp(0,0,1);
D3DXMatrixLookAtLH( &m_mView, &vEyeAt, &vLookAt, &vUp );
D3DXMatrixPerspectiveFovLH( &m_mProj, D3DX_PI/4, 1.0f, 1.0f, 100);

m_mWorldViewProj = m_mWorld * m_mView * m_mProj;

//Transform here
D3DXVECTOR4 vA, vB, vC;
D3DXVec3Transform(&vA, &v1, &m_mWorldViewProj);
D3DXVec3Transform(&vB, &v2, &m_mWorldViewProj);
D3DXVec3Transform(&vC, &v3, &m_mWorldViewProj);
v1 = D3DXVECTOR3(vA.x, vA.y, vA.z)/vA.w;
v2 = D3DXVECTOR3(vB.x, vB.y, vB.z)/vB.w;
v3 = D3DXVECTOR3(vC.x, vC.y, vC.z)/vC.w;

//convert 3d cubic(range -1 to 1)point into 2d screen space point
v1.x = (1+v1.x)*m_dwScreenWidth*0.5f;
v1.y = (1-v1.y)*m_dwScreenHeight*0.5f;

v2.x = (1+v2.x)*m_dwScreenWidth*0.5f;
v2.y = (1-v2.y)*m_dwScreenHeight*0.5f;

v3.x = (1+v3.x)*m_dwScreenWidth*0.5f;
v3.y = (1-v3.y)*m_dwScreenHeight*0.5f;

D3DXPLANE triPlane;
D3DXPlaneFromPoints(&triPlane, &v1, &v2, &v3);
A = triPlane.a;
B = triPlane.b;
C = triPlane.c;
D = triPlane.d;

dz = -(A/C);

std::vector<D3DXVECTOR3> triListIn;
triListIn.push_back(v1);
triListIn.push_back(v2);
triListIn.push_back(v3);
ClipTriangle(triListIn);
m_dwColor = RGB(0xff,0x00,0x00);
for(int i=1; i<triListIn.size()-1; i++)
ScanTriangleA(dc, triListIn[0], triListIn[i+0], triListIn[i+1]);

// draw another triangle
v1.x = 0;
v1.y = -2;
v1.z = 0.5f;

v2.x = -2;
v2.y = 2;
v2.z = 2;

v3.x = 4;
v3.y = -1;
v3.z = -10;

//Transform here
D3DXVec3Transform(&vA, &v1, &m_mWorldViewProj);
D3DXVec3Transform(&vB, &v2, &m_mWorldViewProj);
D3DXVec3Transform(&vC, &v3, &m_mWorldViewProj);
v1 = D3DXVECTOR3(vA.x, vA.y, vA.z)/vA.w;
v2 = D3DXVECTOR3(vB.x, vB.y, vB.z)/vB.w;
v3 = D3DXVECTOR3(vC.x, vC.y, vC.z)/vC.w;

//convert 3d cubic(range -1 to 1)point into 2d screen space point
v1.x = (1+v1.x)*m_dwScreenWidth*0.5f;
v1.y = (1-v1.y)*m_dwScreenHeight*0.5f;

v2.x = (1+v2.x)*m_dwScreenWidth*0.5f;
v2.y = (1-v2.y)*m_dwScreenHeight*0.5f;

v3.x = (1+v3.x)*m_dwScreenWidth*0.5f;
v3.y = (1-v3.y)*m_dwScreenHeight*0.5f;

D3DXPlaneFromPoints(&triPlane, &v1, &v2, &v3);
A = triPlane.a;
B = triPlane.b;
C = triPlane.c;
D = triPlane.d;

dz = -(A/C);

triListIn.clear();
triListIn.push_back(v1);
triListIn.push_back(v2);
triListIn.push_back(v3);
ClipTriangle(triListIn);
m_dwColor = RGB(0x00,0x00,0xff);
for(int i=1; i<triListIn.size()-1; i++)
ScanTriangleA(dc, triListIn[0], triListIn[i+0], triListIn[i+1]);

float fDiff = timeGetTime() - fTime;
CString szTxt;
szTxt.Format(_T("FPS = %0.5f"), fDiff);
dc.SetTextColor(RGB(0x00,0x00,0xff));
dc.TextOutW(20, 20, szTxt);
}


This is code for directx Rendering


//-----------------------------------------------------------------------------
// Name: InitD3D()
// Desc: Initializes Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
// Create the D3D object.
if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
return E_FAIL;

// Set up the structure used to create the D3DDevice
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof( d3dpp ) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.BackBufferCount = 1;
d3dpp.EnableAutoDepthStencil = TRUE;

// Create the D3DDevice
if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp, &g_pd3dDevice ) ) )
{
return E_FAIL;
}

// Turn off culling, so we see the front and back of the triangle
g_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW );

// Turn off D3D lighting, since we are providing our own vertex colors
g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE );

g_pd3dDevice->SetRenderState( D3DRS_ZENABLE, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_ZWRITEENABLE, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_ZFUNC, D3DCMP_LESSEQUAL );

return S_OK;
}




//-----------------------------------------------------------------------------
// Name: InitGeometry()
// Desc: Creates the scene geometry
//-----------------------------------------------------------------------------
HRESULT InitGeometry()
{
// Initialize three vertices for rendering a triangle
CUSTOMVERTEX g_Vertices[] =
{
{ 0, 0, 0.5f, 0xffff0000, },
{ -2, 2, -2, 0xffff0000, },
{ 4, 1, 5, 0xffff0000, },

{ 0, -2, 0.5f, 0xff0000ff, },
{ -2, 2, 2, 0xff0000ff, },
{ 4, -1, -10, 0xff0000ff, },
};

// Create the vertex buffer.
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 6 * sizeof( CUSTOMVERTEX ),
0, D3DFVF_CUSTOMVERTEX,
D3DPOOL_DEFAULT, &g_pVB, NULL ) ) )
{
return E_FAIL;
}

// Fill the vertex buffer.
VOID* pVertices;
if( FAILED( g_pVB->Lock( 0, sizeof( g_Vertices ), ( void** )&pVertices, 0 ) ) )
return E_FAIL;
memcpy( pVertices, g_Vertices, sizeof( g_Vertices ) );
g_pVB->Unlock();

return S_OK;
}
//-----------------------------------------------------------------------------
// Name: SetupMatrices()
// Desc: Sets up the world, view, and projection transform Matrices.
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
// For our world matrix, we will just rotate the object about the y-axis.
D3DXMATRIXA16 matWorld;
D3DXMatrixIdentity( &matWorld );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );

// Set up our view matrix. A view matrix can be defined given an eye point,
// a point to lookat, and a direction for which way is up. Here, we set the
// eye five units back along the z-axis and up three units, look at the
// origin, and define "up" to be in the y-direction.
D3DXVECTOR3 vEyePt( 0.0f, 3.0f, -5.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 0.0f, 1.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );

// For the projection matrix, we set up a perspective transform (which
// transforms geometry from 3D view space to 2D viewport space, with
// a perspective divide making objects smaller in the distance). To build
// a perpsective transform, we need the field of view (1/4 pi is common),
// the aspect ratio, and the near and far clipping planes (which define at
// what distances geometry should be no longer be rendered).
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.0f, 1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}



//-----------------------------------------------------------------------------
// Name: Render()
// Desc: Draws the scene
//-----------------------------------------------------------------------------
VOID Render()
{
// Clear the backbuffer to a black color
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER | D3DCLEAR_TARGET, D3DCOLOR_XRGB( 0, 0, 0 ), 1.0f, 0 );

// Begin the scene
if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
{
// Setup the world, view, and projection Matrices
SetupMatrices();

// Render the vertex buffer contents
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ) );
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );

// End the scene
g_pd3dDevice->EndScene();
}

// Present the backbuffer contents to the display
g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}


Yes Clipping has issues here and i checked it that ZBuffer has to be initialized with very low number then do the lessequal comparison but i also like to see if someone check its basic way of working whether is correct or not.
I took a quick peek in your code and I noticed that you could implement similar handling of projection and clipping as used in Direct3D and do the clipping in homogeneous space. That way your code would be closer to the Direct3D pipeline.

Cheers!
ok issue is for those triangles whose vertices are behind the camera. Can anyone know the way to correct it after looking my above code.

Also after initializing the zBuffer to bigNumber say 1e08 its giving correct lessequal comparison but i would like you guys to see the code of it too.

Thank you.
Thnx Kauna,

problem is solved by doing homogenous clipping.

This topic is closed to new replies.

Advertisement