📄 bsploader.cpp
字号:
Present_Parameters.BackBufferFormat = DisplayMode.Format;// Render to the area of the screen.
Present_Parameters.BackBufferCount = 1; // Number of back buffers.
Present_Parameters.EnableAutoDepthStencil = TRUE; // Check documentation.
Present_Parameters.AutoDepthStencilFormat = D3DFMT_D16; // Check documentation.
// Now we must create the rendering device.
if(FAILED(Direct3D_Object->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,
VertexProcessing, &Present_Parameters, &D3D_Device)))
{
MessageBox(NULL, "CreateDevice() failed! Make sure you have DirectX 9.",
"Error!", MB_OK);
return false;
}
// One last check to be sure.
if(D3D_Device == NULL)
{
MessageBox(NULL, "D3D_Device is equal to NULL!?!", "Error!", MB_OK);
return false;
}
D3D_Device->SetRenderState(D3DRS_LIGHTING, FALSE);
D3D_Device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
D3D_Device->SetRenderState(D3DRS_ZENABLE, TRUE);
// Here we set up the object this demo will render (for example a polygon).
if(!InitializeObject()) return false;
// Set the projection.
D3DXMATRIXA16 Projection;
D3DXMatrixPerspectiveFovLH(&Projection, 45.0f, 640/480, 0.1f, 1000.0f);
D3D_Device->SetTransform(D3DTS_PROJECTION, &Projection);
return true;
}
bool InitializeObject()
{
// Load the .bsp level.
if(!BspLevel.LoadLevel("maps//ugpTestMap.bsp")) return false;
BspLevel.SwapAxis();
Texture = new LPDIRECT3DTEXTURE9[BspLevel.m_totalTextures];
LightMaps = new LPDIRECT3DTEXTURE9[BspLevel.m_totalLightMaps];
// Load the textures we will need.
for(int i = 0; i < BspLevel.m_totalTextures; i++)
{
if(strcmp("noshader", BspLevel.m_textures[i].file) == 0) continue;
strcat(BspLevel.m_textures[i].file, ".tga");
// Here we load the texture into the texture object.
if(D3DXCreateTextureFromFile(D3D_Device, BspLevel.m_textures[i].file,
&Texture[i]) != D3D_OK) return false;
}
// Load the lightmaps we will need.
for(int i = 0; i < BspLevel.m_totalLightMaps; i++)
{
ApplyGamma(&BspLevel.m_lightMaps[i].lightMap[0][0][0],
128 * 128 * 3, 3, 10);
if(FAILED(D3DXCreateTexture(D3D_Device, 128, 128, 1, 0,
D3DFMT_R8G8B8, D3DPOOL_MANAGED, &LightMaps[i]))) return false;
D3DLOCKED_RECT lr;
LightMaps[i]->LockRect(0, &lr, NULL, 0);
DWORD *tempImg = (DWORD*)lr.pBits;
if(!tempImg) continue;
int index = 0;
for(int k = 0; k < 128; k++)
{
for(int j = 0; j < 128; j++)
{
tempImg[index++] = (BspLevel.m_lightMaps[i].lightMap[j][k][0] << 16) |
(BspLevel.m_lightMaps[i].lightMap[j][k][1] << 8) |
BspLevel.m_lightMaps[i].lightMap[j][k][2];
}
}
LightMaps[i]->UnlockRect(0);
}
// Set the camera's default position.
Camera.SetCamera(0, 150, -150, 0, 150, -149, 0, 1, 0);
// Create the vertex buffer that will hold the square.
if(FAILED(D3D_Device->CreateVertexBuffer(sizeof(stQ3Vertex) *
BspLevel.m_totalVertices, 0, 0, D3DPOOL_DEFAULT, &Vertex_Buffer, NULL)))
return false;
// Pointer to the buffer.
stQ3Vertex* Vertices;
// Lock the buffer we can write to it.
if(FAILED(Vertex_Buffer->Lock(0, sizeof(stQ3Vertex) *
BspLevel.m_totalVertices, (void**)&Vertices, 0))) return false;
// Here we copy the square's data into the vertex buffer.
memcpy(Vertices, BspLevel.m_vertices, sizeof(stQ3Vertex) * BspLevel.m_totalVertices);
Vertex_Buffer->Unlock();
// Set description.
D3DVERTEXELEMENT9 Declaration[] =
{
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
{0, 20, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
{0, 28, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 40, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0},
D3DDECL_END()
};
D3D_Device->CreateVertexDeclaration(Declaration, &VertexDeclaration);
return true;
}
void RenderScene()
{
// Clear the screen.
D3D_Device->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER,
D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
// Tell Direct 3D we are now going to start drawing.
D3D_Device->BeginScene();
// Set the view positions matrix releated info.
D3DXMATRIXA16 View;
D3DXMatrixIdentity(&View);
D3DXVECTOR3 Eye(Camera.mPos.x, Camera.mPos.y, Camera.mPos.z);
D3DXVECTOR3 LookAt(Camera.mView.x, Camera.mView.y, Camera.mView.z);
D3DXVECTOR3 Up(Camera.mUp.x, Camera.mUp.y, Camera.mUp.z);
// Set view.
D3DXMatrixLookAtLH(&View, &Eye, &LookAt, &Up);
D3D_Device->SetTransform(D3DTS_VIEW, &View);
for(int i = 0; i < BspLevel.m_totalFaces; i++)
{
if(BspLevel.m_faces[i].type != 1) continue;
stQ3Face *pFace = &BspLevel.m_faces[i];
// Set texture image.
D3D_Device->SetTexture(0, Texture[pFace->texID]);
D3D_Device->SetTexture(1, LightMaps[pFace->lightmapID]);
// Set up data stream.
D3D_Device->SetVertexDeclaration(VertexDeclaration);
D3D_Device->SetStreamSource(0, Vertex_Buffer, 0, sizeof(stQ3Vertex));
// Draw.
D3D_Device->DrawPrimitive(D3DPT_TRIANGLEFAN, pFace->startVertexIndex,
pFace->totalVertices / 2);
}
// Checking for input. We move the camera based on the button(s) that were pressed.
if(GetKeyState(VK_UP) & 0x80) Camera.MoveCamera(FORWARD);
if(GetKeyState(VK_DOWN) & 0x80) Camera.MoveCamera(BACKWARD);
if(GetKeyState(VK_LEFT) & 0x80) Camera.StrafeCam(STRAFE_LEFT);
if(GetKeyState(VK_RIGHT) & 0x80) Camera.StrafeCam(STRAFE_RIGHT);
// Rotate camera
POINT mousePos;
GetCursorPos(&mousePos);
Camera.RotateByMouse(mousePos.x, mousePos.y, (640 >> 1), (480 >> 1));
SetCursorPos((640 >> 1), (480 >> 1));
// We are done drawing for this scene.
D3D_Device->EndScene();
// Swap the old frame with the new one.
D3D_Device->Present(NULL, NULL, NULL, NULL);
}
void ShutdownDirect3D()
{
// Here we release the Direct3D objects.
BspLevel.Shutdown();
for(int i = 0; i < BspLevel.m_totalTextures; i++)
{
if(Texture[i] != NULL)
{
Texture[i]->Release();
Texture[i] = NULL;
}
}
for(int i = 0; i < BspLevel.m_totalLightMaps; i++)
{
if(LightMaps[i] != NULL)
{
LightMaps[i]->Release();
LightMaps[i] = NULL;
}
}
delete[] Texture;
delete[] LightMaps;
Texture = NULL;
LightMaps = NULL;
if(D3D_Device != NULL)
{
D3D_Device->Release();
D3D_Device = NULL;
}
if(Direct3D_Object != NULL)
{
Direct3D_Object->Release();
Direct3D_Object = NULL;
}
if(Vertex_Buffer != NULL)
{
Vertex_Buffer->Release();
Vertex_Buffer = NULL;
}
if(VertexDeclaration != NULL)
{
VertexDeclaration->Release();
VertexDeclaration = NULL;
}
}
// Recap:
// Loading and rendering a Quake 3 level is pretty easy. Loading is nothing
// more than reading in each section of data into its allocated array then
// drawing everything out each frame. In the next demo we'll add a PVS system.
// Copyright December 2004
// All Rights Reserved!
// Allen Sherrod
// ProgrammingAce@UltimateGameProgramming.com
// www.UltimateGameProgramming.com
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -