Sign in to follow this  

BSP Patch Problem

This topic is 4304 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, I am working on a simple 3D Engine(Directx and coding in C++).In a few moths ago i found a tutorial about Quake 3 BSP maps and i am using it for my map system now.It's working well but i have a problem.I can't open and render patches ( curved surfaces ).I tried several ways to make it but i couldn't success. Here is the source code of BSP map tutorial.I did make some changes on it for collision detection in my engine but this is the skeleton system. http://rapidshare.de/files/14429640/q3bsp.zip.html Please help me.What i need to do? Can anyone show it on the sorucecode? Tahnks.

Share this post


Link to post
Share on other sites
*sighs* I'll mention this again [smile]

You might be lucky, but most people won't download an arbitrary archive of source code from a web forum. Firstly theres a lot of risk with (potentially) malicious code; secondly it takes a long time to step through a new codebase - you have to download it, extract it, open it up in your editor, compile it (not always easy), run it, find the right piece of code, think about it, try stuff, post back here.

Help us to help you!

You're best off posting back here with the relevant fragments of code surrounded by [ source ]...[ /source ] tags. Which lines of code are relevant to curved surfaces? what function calls are you using? what results are you getting (error codes etc..)?

There are a couple of ways to generate curved surfaces - manually via tesselating geometry yourself on the CPU or in hardware using Direct3D's patches functionality. The problem with the latter is that it is entirely dependent on the hardware supporting the functionality - it won't be emulated. This is particularly important as hardware Higher Order Surfaces seemed to go out of fashion around the time that stencil shadows became the new cool thing. Not many chipsets support it.

hth
Jack

Share this post


Link to post
Share on other sites
The zip file includes just two files.A cpp and a h file.

Here is the cpp


#include "QBD_bsp.h"

#include <stdio.h>

//******************************************************************//
// Once Again A lot of the code here is going to stay the same, so I'm
// going to remove some of the comments from the last tutorial
// in order to help the changes stand out more.
//******************************************************************//

void FindTextureExtension(char *strFileName)
{
char strJPGPath[MAX_PATH] = {0};
char strTGAPath[MAX_PATH] = {0};
FILE *fp = NULL;

GetCurrentDirectory(MAX_PATH, strJPGPath);

// Add on a '\' and the file name to the end of the current path.
// We create 2 seperate strings to test each image extension.
strcat(strJPGPath, "\\");
strcat(strJPGPath, strFileName);
strcpy(strTGAPath, strJPGPath);

// Add the extensions on to the file name and path
strcat(strJPGPath, ".jpg");
strcat(strTGAPath, ".tga");

// Check if there is a jpeg file with the texture name
if((fp = fopen(strJPGPath, "rb")) != NULL)
{
// If so, then let's add ".jpg" onto the file name and return
strcat(strFileName, ".jpg");
return;
}

// Check if there is a targa file with the texture name
if((fp = fopen(strTGAPath, "rb")) != NULL)
{
// If so, then let's add a ".tga" onto the file name and return
strcat(strFileName, ".tga");
return;
}
}

ChangeGamma(byte *pImage, int size, float factor)
{
// Go through every pixel in the lightmap
for(int i = 0; i < size / 3; i++, pImage += 3)
{
float scale = 1.0f, temp = 0.0f;
float r = 0, g = 0, b = 0;

// extract the current RGB values
r = (float)pImage[0];
g = (float)pImage[1];
b = (float)pImage[2];

// Multiply the factor by the RGB values, while keeping it to a 255 ratio
r = r * factor / 255.0f;
g = g * factor / 255.0f;
b = b * factor / 255.0f;

// Check if the the values went past the highest value
if(r > 1.0f && (temp = (1.0f/r)) < scale) scale=temp;
if(g > 1.0f && (temp = (1.0f/g)) < scale) scale=temp;
if(b > 1.0f && (temp = (1.0f/b)) < scale) scale=temp;

// Get the scale for this pixel and multiply it by our pixel values
scale*=255.0f;
r*=scale; g*=scale; b*=scale;

// Assign the new gamma'nized RGB values to our image
pImage[0] = (byte)r;
pImage[1] = (byte)g;
pImage[2] = (byte)b;
}
}

QBD_BSP::QBD_BSP()
{
// Lot's of Nullifying Pointers and such.
// It's a good habit to get into
// (yet one I still don't always follow)
m_pVB = NULL;
m_pIB = NULL;
m_pTextureMaps = NULL;
m_pLightMaps = NULL;

numVerts = 0;
numFaces = 0;
numIndex = 0;
numTextures = 0;
numLights = 0;

//*********************NEW**********************//
numPlanes = 0;
numNodes = 0;
numLeaves = 0;
numLeafFaces = 0;

memset(&m_sVisData, 0, sizeof(BSP_VISDATA));
//*********************NEW**********************//

m_pTextures = NULL;
m_pLightmap = NULL;
m_pVerts = NULL;
m_pFaces = NULL;
m_pIndices = NULL;

m_pRenderState[rShowTextureMap] = true;
m_pRenderState[rShowLightMap] = true;
//*********************NEW**********************//
m_pRenderState[rUsePVS] = true;
//*********************NEW**********************//
}

bool QBD_BSP::Initialize(IDirect3DDevice9* pDevice)
{
// Link our pointer to a valid D3D Device
// Pretty simple, really.
if((m_pDevice = pDevice) == NULL)
return false;

return true;
}

//******************************************************************//
// NEW - Changes to file Loading
//
// A lot of the loading is very similar to previous data
// structures. Really a cut and paste job. The only big departure
// is the visData chunk, which I'll cover when we get to it.
//******************************************************************//

bool QBD_BSP::Load(const char *strFileName)
{
FILE *fp = NULL;

// Check if the .bsp file could be opened
if((fp = fopen(strFileName, "rb")) == NULL)
{
return false;
}

BSP_HEADER header;

fread(&header, 1, sizeof(BSP_HEADER), fp);

//allocate the space needed for our data structures
numVerts = header.entries[lVertcies].length / sizeof(BSP_VERTEX);
m_pVerts = new BSP_VERTEX[numVerts];

numFaces = header.entries[lFaces].length / sizeof(BSP_FACE);
m_pFaces = new BSP_FACE[numFaces];

numIndex = header.entries[lIndices].length / sizeof(BSP_INDEX);
m_pIndices = new BSP_INDEX[numIndex];

numTextures = header.entries[lTextures].length / sizeof(BSP_TEXTURE);
m_pTextures = new BSP_TEXTURE [numTextures];
m_pTextureMaps = new LPDIRECT3DTEXTURE9 [numTextures];

numLights = header.entries[lLightmaps].length / sizeof(BSP_LIGHTMAP);
m_pLightmap = new BSP_LIGHTMAP [numLights];
m_pLightMaps = new LPDIRECT3DTEXTURE9 [numLights];

//******************************************************************//
// NEW - BSP/PVS allocation
numPlanes = header.entries[lPlanes].length / sizeof(BSP_PLANE);
m_pPlanes = new BSP_PLANE[numPlanes];

numNodes = header.entries[lNodes].length / sizeof(BSP_NODE);
m_pNodes = new BSP_NODE[numNodes];

numLeaves = header.entries[lLeafs].length / sizeof(BSP_LEAF);
m_pLeaves = new BSP_LEAF[numLeaves];

numLeafFaces = header.entries[lLeaffaces].length / sizeof(BSP_LEAFFACES);
m_pLeafFaces = new BSP_LEAFFACES[numLeafFaces];
//******************************************************************//

// Read in the vertex information
fseek(fp, header.entries[lVertcies].offset, SEEK_SET);
fread(m_pVerts, numVerts, sizeof(BSP_VERTEX), fp);

// Read in the index information
fseek(fp, header.entries[lIndices].offset, SEEK_SET);
fread(m_pIndices, numIndex, sizeof(BSP_INDEX), fp);

// Read in all the face information
fseek(fp, header.entries[lFaces].offset, SEEK_SET);
fread(m_pFaces, numFaces, sizeof(BSP_FACE), fp);

// Read in all the texture information
fseek(fp, header.entries[lTextures].offset, SEEK_SET);
fread(m_pTextures, numTextures, sizeof(BSP_TEXTURE), fp);

// Seek to the position in the file that stores the lightmap information
fseek(fp, header.entries[lLightmaps].offset, SEEK_SET);

// Read in all the lightmap information
fread(m_pLightmap, numLights, sizeof(BSP_LIGHTMAP), fp);

//******************************************************************//
// NEW - BSP/PSV reading
fseek(fp, header.entries[lPlanes].offset, SEEK_SET);
fread(m_pPlanes, numPlanes, sizeof(BSP_PLANE), fp);

fseek(fp, header.entries[lNodes].offset, SEEK_SET);
fread(m_pNodes, numNodes, sizeof(BSP_NODE), fp);

fseek(fp, header.entries[lLeafs].offset, SEEK_SET);
fread(m_pLeaves, numLeaves, sizeof(BSP_LEAF), fp);

fseek(fp, header.entries[lLeaffaces].offset, SEEK_SET);
fread(m_pLeafFaces, numLeafFaces, sizeof(BSP_LEAFFACES), fp);
//******************************************************************//

//******************************************************************//
// NEW - Allocating visibility data
// the size of a visibility chunk can change from map to map so
// first we need to read in a the number of entries and the size
// of each, then multiply those together to get the total size.
if(header.entries[lVisdata].length)
{
//Read VisData
fseek(fp, header.entries[lVisdata].offset, SEEK_SET);
fread(&(m_sVisData.n_vecs), 1, sizeof(int), fp);
fread(&(m_sVisData.vecSize), 1, sizeof(int), fp);

int size = (m_sVisData.n_vecs * m_sVisData.vecSize);
m_sVisData.vecs = new byte[size];

fread(m_sVisData.vecs, 1, sizeof(byte) * size, fp);
}
else
{
m_sVisData.vecs = NULL;
}
//******************************************************************//

// Close the file
fclose(fp);

//Take all the data we just loaded and format it for DirectX use!
Build();

// Return a success
return true;
}

//******************************************************************//
// NEW - FindLeaf()
// This function will walk through the BSP tree to find the leaf
// that the camera is currently in. There are plenty of documents
// out there about how a BSP tree works, so I won't bore you with
// it here.
int QBD_BSP::FindLeaf(D3DXVECTOR3 camPos)
{
int index = 0;

while (index >= 0) {
const BSP_NODE& node = m_pNodes[index];
const BSP_PLANE& plane = m_pPlanes[node.plane];

// Distance from point to a plane
const double distance = D3DXVec3Dot( &plane.normal, &camPos ) - plane.dist;

if (distance >= 0) {
index = node.children[0];
} else {
index = node.children[1];
}
}

return ~index;
}
//******************************************************************//

//******************************************************************//
// NEW - ClusterVisible()
// I think the best way to describe this is to quote
// http://graphics.cs.brown.edu/games/quake/quake3.html:
//
// "The visData bit array contains precomputed visibility data
// between clusters. If the cluster with index a can potentially
// be seen by a viewer in the cluster with index b, then bit
// (a + b * visData.sz_vecs * 8) of visData.vecs has value 1.
// Otherwise, that bit has value 0."
//
// Catch all that?
bool QBD_BSP::ClusterVisible(int visCluster, int testCluster) {

if ((m_sVisData.vecs == NULL) || (visCluster < 0)) {
return true;
}

byte visSet = m_sVisData.vecs[(visCluster * m_sVisData.vecSize) + (testCluster >> 3)];

return (visSet & (1 << (testCluster & 7))) != 0;
}
//******************************************************************//

void QBD_BSP::Build()
{
for(int i = 0; i < numTextures; i++)
{
// Find the texture path/extension
FindTextureExtension(m_pTextures[i].name);

// Load the texture based off of what we found.
if(FAILED(D3DXCreateTextureFromFile( m_pDevice, m_pTextures[i].name,
&m_pTextureMaps[i] )))
{
// If the texture can't be loaded, simply make it NULL.
m_pTextureMaps[i] = NULL;
}
}

D3DLOCKED_RECT lockedRect;
IDirect3DSurface9 *pLightmapSurface;
unsigned char *pSurface;
DWORD dwCharsPerRow;

//Loop through each lightmap array
for (i = 0; i < numLights; i++)
{
// Run our ChangeGamma function to "lighten" the lightmap.
// For kicks, try commenting this line out and see what a
// difference it makes!
ChangeGamma((unsigned char *)m_pLightmap[i].imageBits, 128*128*3, 7);

// Create a blank texture
D3DXCreateTexture(m_pDevice, 128, 128, D3DX_DEFAULT, 0, D3DFMT_X8R8G8B8, D3DPOOL_MANAGED, &m_pLightMaps[i]);

// Grab the top level mipmap (original size) and lock the surface
m_pLightMaps[i]->GetSurfaceLevel(0, &pLightmapSurface);
pLightmapSurface->LockRect(&lockedRect, NULL, 0);

pSurface = static_cast<unsigned char*>(lockedRect.pBits);
dwCharsPerRow = lockedRect.Pitch;

// For each set of 3 values in the array write one RGB pixel on the texture.
for (DWORD r = 0; r < 128; r++)
{
DWORD dwIndex = r * dwCharsPerRow;
for (DWORD c = 0; c < 128; c++)
{
pSurface[dwIndex + c*4 + 0] = m_pLightmap[i].imageBits[r][c][2];
pSurface[dwIndex + c*4 + 1] = m_pLightmap[i].imageBits[r][c][1];
pSurface[dwIndex + c*4 + 2] = m_pLightmap[i].imageBits[r][c][0];
pSurface[dwIndex + c*4 + 3] = 255;
}
}

pLightmapSurface->UnlockRect();

// Now that we've created our texture, run it through a mipmap filter
D3DXFilterTexture(m_pLightMaps[i], 0, 0, D3DX_FILTER_LINEAR);
}

//Everything else in the function is exactly the same.

m_pDevice->CreateVertexBuffer( numVerts * sizeof(BSP_CUSTOM_VERTEX), 0,
BSP_CUSTOM_VERTEX_FVF, D3DPOOL_DEFAULT, &m_pVB, NULL );

BSP_CUSTOM_VERTEX *pVertices = NULL;

m_pVB->Lock(0, numVerts * sizeof(BSP_CUSTOM_VERTEX), (VOID**) &pVertices, 0);

for(i = 0; i < numVerts; i++)
{
pVertices[i].x = m_pVerts[i].position[0];
pVertices[i].y = m_pVerts[i].position[1];
pVertices[i].z = m_pVerts[i].position[2];

pVertices[i].nx = m_pVerts[i].normal[0];
pVertices[i].ny = m_pVerts[i].normal[1];
pVertices[i].nz = m_pVerts[i].normal[2];

pVertices[i].color = D3DCOLOR_RGBA(255,255,255,255);

pVertices[i].tu = m_pVerts[i].texcoord[0];
pVertices[i].tv = m_pVerts[i].texcoord[1];

pVertices[i].lu = m_pVerts[i].lightmap[0];
pVertices[i].lv = m_pVerts[i].lightmap[1];
}

m_pVB->Unlock();

m_pDevice->CreateIndexBuffer( numIndex * sizeof(BSP_INDEX), 0,
D3DFMT_INDEX32, D3DPOOL_DEFAULT, &m_pIB, NULL );

BSP_INDEX *pIndices = NULL;

m_pIB->Lock(0, numIndex * sizeof(BSP_INDEX), (VOID**) &pIndices, 0);

memcpy(pIndices, m_pIndices, numIndex * sizeof(BSP_INDEX));

m_pIB->Unlock();

//******************************************************************//
// NEW - One of the drawbacks of the BSP format that Q3 uses
// is that faces can be assigned to more than one leaf. If you
// simply blindly draw the faces of each visible leaf, you are
// potentially drawing each face multiple time. This structure
// tags each face as "Drawable" or not, so we can avoid this.
DrawnFaces.Resize(numFaces);
//******************************************************************//
}

//******************************************************************//
// NEW - Added the camera to the call
//******************************************************************//
void QBD_BSP::Render(QBD_Camera Camera)
{
m_pDevice->SetTextureStageState(0,D3DTSS_TEXCOORDINDEX,0);
m_pDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
m_pDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
m_pDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE);

m_pDevice->SetTextureStageState(1,D3DTSS_TEXCOORDINDEX,1);
m_pDevice->SetTextureStageState(1, D3DTSS_ALPHAOP, D3DTOP_DISABLE);
m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG1, D3DTA_TEXTURE);
m_pDevice->SetTextureStageState(1, D3DTSS_COLORARG2, D3DTA_CURRENT);
m_pDevice->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_MODULATE);

m_pDevice->SetFVF(BSP_CUSTOM_VERTEX_FVF);

m_pDevice->SetStreamSource(0, m_pVB, 0, sizeof(BSP_CUSTOM_VERTEX));

m_pDevice->SetIndices(m_pIB);

m_pDevice->SetTexture(0, NULL);
m_pDevice->SetTexture(1, NULL);

//******************************************************************//
// NEW - Set which faces should be drawn in our bitset class
if(m_pRenderState[rUsePVS])
{
DrawnFaces.ClearAll();

int Leaf = FindLeaf(Camera.GetPos());

int Cluster = m_pLeaves[Leaf].cluster;

//Find Visible Face Data
for(int l = 0; l < numLeaves; l++)
{
if(ClusterVisible(Cluster, m_pLeaves[l].cluster))
{
for(int f = 0; f < m_pLeaves[l].n_leaffaces; f++)
{
if(!DrawnFaces.On(m_pLeafFaces[m_pLeaves[l].leafface + f]))
{
DrawnFaces.Set(m_pLeafFaces[m_pLeaves[l].leafface + f]);
}
}
}
}
}
else
{
DrawnFaces.SetAll();
}
//******************************************************************//

//******************************************************************//
// NEW - Big Changes to the main render loop. This new method should
// be slightly more efficient, even though we could potentially be
// changing the texture for every face.
//******************************************************************//

int lastLightmap = -1;
int lastTexture = -1;

for(int i = 0; i < numFaces; i++)
{
int face = i;

if((m_pFaces[face].type == 1 || m_pFaces[face].type == 3) && DrawnFaces.On(i))
{
if(m_pRenderState[rShowTextureMap])
{
//If the texture is different from the one previously use, swap.
if(m_pFaces[face].texture != lastTexture)
{
lastTexture = m_pFaces[face].texture;

m_pDevice->SetTexture(0, m_pTextureMaps[m_pFaces[face].texture]);
}
}

if(m_pRenderState[rShowLightMap])
{
//If the lightmap is different from the one previously use, swap.
if(m_pFaces[face].lm_index != lastLightmap)
{
lastLightmap = m_pFaces[face].lm_index;
if(m_pFaces[face].lm_index < 0)
{
m_pDevice->SetTexture(1, NULL);
}
else
{
m_pDevice->SetTexture(1, m_pLightMaps[m_pFaces[face].lm_index]);
}
}
}

m_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST , m_pFaces[face].vertex, 0, m_pFaces[face].n_verts,
m_pFaces[face].meshvert, (m_pFaces[face].n_meshverts/3));
}
}
}

//******************************************************************//
// None of the rest of this is too complicated, so I'll
// leave you to figure it out.

void QBD_BSP::SetRenderState(BSP_RENDER_STATES state, bool value)
{
m_pRenderState[state] = value;
}

bool QBD_BSP::GetRenderState(BSP_RENDER_STATES state)
{
return m_pRenderState[state];
}

void QBD_BSP::Destroy()
{
m_pIB->Release();
m_pVB->Release();

delete [] m_pVerts;
delete [] m_pIndices;
delete [] m_pFaces;
delete [] m_pTextures;
}

QBD_BSP::~QBD_BSP()
{
// Call our destroy function
Destroy();
}




and here is the h file


#ifndef _QBD_BSP_
#define _QBD_BSP_

#include "Q3_BSP_DX.h"
#include "QBD_Camera.h"

#define Q3BSP_POLYGON 1
#define Q3BSP_PATCH 2
#define Q3BSP_MESH 3
#define Q3BSP_BILLBOARD 4

//******************************************************************//
// File Structure Definitions
// All the structures you see here are built from the
// "Unofficial Quake 3 Map Specs" at
// http://graphics.stanford.edu/~kekoa/q3/
// and it's companion site
// http://graphics.cs.brown.edu/games/quake/quake3.html
//
// If you're at all interested in the map format,
// these are a must read!
//
// Thanks to the fact that most of the map structures were
// already in place, not TOO much will need to change here
// but we are going to add some new functions to help us
// along the way!
//******************************************************************//

struct BSP_ENTRY
{
int offset;
int length;
};

struct BSP_HEADER
{
char idNumber[4];
int version;
BSP_ENTRY entries[17];
};

enum BSP_LUMP
{
lEntities,
lTextures,
lPlanes,
lNodes,
lLeafs,
lLeaffaces,
lLeafbrushes,
lModels,
lBrushes,
lBrushSides,
lVertcies,
lIndices,
lEffects,
lFaces,
lLightmaps,
lLightvols,
lVisdata
};

struct BSP_ENTITY
{
char *ents;
};

struct BSP_TEXTURE
{
char name[64];
int flags;
int contents;
};

struct BSP_PLANE
{
D3DXVECTOR3 normal;
float dist;
};

struct BSP_NODE
{
int plane;
int children[2];
int mins[3];
int maxs[3];
};

struct BSP_LEAF
{
int cluster;
int area;
int mins[3];
int maxs[3];
int leafface;
int n_leaffaces;
int leafbrush;
int n_leafbrushes;
};

typedef int BSP_LEAFFACES;

typedef int BSP_LEAFBRUSHES;

struct BSP_MODEL
{
float mins[3];
float maxs[3];
int face;
int n_faces;
int brush;
int n_brushes;
};

struct BSP_BRUSH
{
int brushside;
int n_brushsides;
int texture;
};

struct BSP_BRUSHSIDES
{
int plane;
int texture;
};

struct BSP_VERTEX
{
float position[3];
float texcoord[2];
float lightmap[2];
float normal[3];
BYTE color[4];
};

typedef WORD BSP_INDEX;

struct BSP_EFFECT
{
char name[64];
int brush;
int unknown;
};

struct BSP_FACE
{
int texture;
int effect;
int type;
int vertex;
int n_verts;
int meshvert;
int n_meshverts;
int lm_index;
int lm_start[2];
int lm_size[2];
float lm_origin[3];
float lm_vecs[2][3];
float normal[3];
int size[2];
};

struct BSP_LIGHTMAP
{
byte imageBits[128][128][3];
};

//*********************NEW**********************//
// Okay, so I missed one struct in the past
// tutorials. ^_^ So sue me!
struct BSP_VISDATA
{
int n_vecs;
int vecSize;
byte *vecs;
};
//*********************NEW**********************//

struct BSP_CUSTOM_VERTEX
{
float x, y, z;
float nx, ny, nz;
D3DCOLOR color;
float tu, tv;
float lu, lv;
};

#define BSP_CUSTOM_VERTEX_FVF (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_TEX1|D3DFVF_TEX2)

enum BSP_RENDER_STATES
{
rShowLightMap = 0,
rShowTextureMap,
rUsePVS,
};

//******************************************************************//
// CBitset Class
//
// This is a class by DigiBen that he created to aid in his PVS
// implementation. I figure, why reinvent the wheel? I've only
// made a slight alteration to the class (added a "SetAll" function)

class CBitset
{
public:

CBitset() : m_bits(0), m_size(0) {}

~CBitset()
{
if(m_bits)
{
delete m_bits;
m_bits = NULL;
}
}

void Resize(int count)
{
m_size = count/32 + 1;

if(m_bits)
{
delete m_bits;
m_bits = 0;
}

m_bits = new unsigned int[m_size];
ClearAll();
}

void Set(int i)
{
m_bits[i >> 5] |= (1 << (i & 31));
}

int On(int i)
{
return m_bits[i >> 5] & (1 << (i & 31 ));
}

void Clear(int i)
{
m_bits[i >> 5] &= ~(1 << (i & 31));
}

void ClearAll()
{
memset(m_bits, 0, sizeof(unsigned int) * m_size);
}

void SetAll()
{
memset(m_bits, 4294967295, sizeof(unsigned int) * m_size);
}

private:
unsigned int *m_bits;
int m_size;
};


class QBD_BSP
{

public:

// Our constructor
QBD_BSP();

// Our deconstructor
~QBD_BSP();

// Initialize our D3D Device inside the class.
bool Initialize(IDirect3DDevice9* pDevice);

// Loads a .bsp file
bool Load(const char *strFileName);

//*********************NEW**********************//
// Added the Camera to the call
void Render(QBD_Camera Camera);
//*********************NEW**********************//

// These two fuctions are really completely unnessicary!
// I've simply added them so that we can really easily
// Enable and Disable various parts of the map (like lightmaps)
// on the fly to get a better idea of what's going on beneath
// the hood.
void SetRenderState(BSP_RENDER_STATES state, bool value);
bool GetRenderState(BSP_RENDER_STATES state);

// This destroys the level data
void Destroy();

private:

// Used to turn the loaded data into a DirectX friendly format!
void Build();

//*********************NEW**********************//
// New functions to help us use the PVS!
// Descriptions in the .cpp file
int FindLeaf(D3DXVECTOR3 camPos);
bool ClusterVisible(int visCluster, int testCluster);
//*********************NEW**********************//

// A pointer to our rendering device. I have one of these in
// Almost all my classes, but that's just my preference. Your
// Milage may vary.
LPDIRECT3DDEVICE9 m_pDevice;

// In order of appearace:
// Our Vertex Buffer, Index Buffer, Texture Map, and Lightmap Array.
LPDIRECT3DVERTEXBUFFER9 m_pVB;
LPDIRECT3DINDEXBUFFER9 m_pIB;
LPDIRECT3DTEXTURE9 *m_pTextureMaps;
LPDIRECT3DTEXTURE9 *m_pLightMaps;

//*********************NEW**********************//
int numPlanes;
int numNodes;
int numLeaves;
int numLeafFaces;
//*********************NEW**********************//

int numVerts;
int numFaces;
int numIndex;
int numTextures;
int numLights;

//*********************NEW**********************//
// New data structures for PVS implementation
BSP_PLANE *m_pPlanes;
BSP_NODE *m_pNodes;
BSP_LEAF *m_pLeaves;
BSP_LEAFFACES *m_pLeafFaces;
BSP_VISDATA m_sVisData;

CBitset DrawnFaces;
//*********************NEW**********************//

BSP_LIGHTMAP *m_pLightmap;
BSP_TEXTURE *m_pTextures;
BSP_VERTEX *m_pVerts;
BSP_FACE *m_pFaces;
BSP_INDEX *m_pIndices;

// Again, this is just fluff I've added for easy effect switching.
bool m_pRenderState[3];
};
//******************************************************************//

#endif

Share this post


Link to post
Share on other sites
Those are Bezier patches. You use the 4 control points that the BSP file gives you and generate the patch. You might want to visit the Math and Physics forum to find out the beizer patch math code.

Share this post


Link to post
Share on other sites

This topic is 4304 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this