Rise
The Vieneo Province
Graphics.cpp
Go to the documentation of this file.
1 #include "Graphics.h"
2 #include "GameClass.h"
3 #include "gui.h"
4 
5 #include <WinSock2.h>
6 #include <WS2tcpip.h>
7 #include <Windows.h>
8 
9 #include "DXUT.h"
10 //#include "SDKmisc.h" // For DXUTFindDXSDKMediaFileCch
11 #include "DXUTgui.h"
12 
13 #include "resource.h"
14 #include "polyobj.h"
15 
17 {
18  gui = g;
19  logger = g->game->logger;
20 
22  g_pEffect = nullptr;
24  for (short t = 0; t < humantextureC; t++)
25  m_pddsAvatar[t] = nullptr;
26 
28 }
29 
31 {
33 }
34 
36 {
37  logger->Log("Adding font resources...");
38 
39  // EuroseWide Heavy
40  if (AddFontResourceEx(L"Fonts\\euroswh.ttf", FR_PRIVATE, nullptr) == 0)
41  {
42  MessageBoxW(nullptr, L"Error loading euroswh.ttf in Fonts\\...", L"Error loading font!", MB_ICONERROR | MB_OK);
43  logger->Log("Error loading \"euroswh.ttf\" in Fonts\\...", Logger::Level::Error);
44  }
45 
46  // DejaVu Sans Mono
47  if (AddFontResourceEx(L"Fonts\\DejaVuSansMono.ttf", FR_PRIVATE, nullptr) == 0)
48  {
49  MessageBoxW(nullptr, L"Error loading DejaVuSansMono.ttf in Fonts\\...", L"Error loading font!", MB_ICONERROR | MB_OK);
50  logger->Log("Error loading \"DejaVuSansMono.ttf\" in Fonts\\...", Logger::Level::Error);
51  }
52 
53  // Lucida Handwriting
54  if (AddFontResourceEx(L"Fonts\\lhandw.ttf", FR_PRIVATE, nullptr) == 0)
55  {
56  MessageBoxW(nullptr, L"Error loading lhandw.ttf in Fonts\\...", L"Error loading font!", MB_ICONERROR | MB_OK);
57  logger->Log("Error loading \"lhandw.ttf\" in Fonts\\...", Logger::Level::Error);
58  }
59 }
60 
62 {
63  logger->Log("Removing font resources...");
64 
65  RemoveFontResourceEx(L"Fonts\\LicensePlate.ttf", FR_PRIVATE, nullptr);
66  RemoveFontResourceEx(L"Fonts\\rcaf6-GIMP.ttf", FR_PRIVATE, nullptr);
67 
68  RemoveFontResourceEx(L"Fonts\\euroswh.ttf", FR_PRIVATE, nullptr);
69  RemoveFontResourceEx(L"Fonts\\DejaVuSansMono.ttf", FR_PRIVATE, nullptr);
70  RemoveFontResourceEx(L"Fonts\\lhandw.ttf", FR_PRIVATE, nullptr);
71 
72  RemoveFontResourceEx(L"Fonts\\cour.ttf", FR_PRIVATE, nullptr);
73  RemoveFontResourceEx(L"Fonts\\pala.ttf", FR_PRIVATE, nullptr);
74 }
75 
76 //--------------------------------------------------------------------------------------
77 // This function loads the mesh and ensures the mesh has normals; it also optimizes the
78 // mesh for the graphics card's vertex cache, which improves performance by organizing
79 // the internal triangle list for less cache misses.
80 //--------------------------------------------------------------------------------------
81 /*
82 HRESULT Graphics::LoadMesh(IDirect3DDevice9* pd3dDevice, WCHAR* strFileName, ID3DXMesh** ppMesh)
83 {
84  ID3DXMesh* pMesh = nullptr;
85  WCHAR str[MAX_PATH];
86  HRESULT hr;
87 
88  // ChangeCockpit the mesh with D3DX and get back a ID3DXMesh*. For this
89  // sample we'll ignore the X file's embedded materials since we know
90  // exactly the model we're loading. See the mesh samples such as
91  // "OptimizedMesh" for a more generic mesh loading example.
92  V_RETURN(DXUTFindDXSDKMediaFileCch(str, MAX_PATH, strFileName));
93 
94  V_RETURN(D3DXLoadMeshFromX(str, D3DXMESH_MANAGED, pd3dDevice, NULL, NULL, NULL, NULL, &pMesh));
95 
96  // Make sure there are normals which are required for lighting
97  if (!(pMesh->GetFVF() & D3DFVF_NORMAL))
98  {
99  ID3DXMesh* pTempMesh;
100  V(pMesh->CloneMeshFVF(pMesh->GetOptions(),
101  pMesh->GetFVF() | D3DFVF_NORMAL,
102  pd3dDevice, &pTempMesh));
103  V(D3DXComputeNormals(pTempMesh, NULL));
104 
105  SAFE_RELEASE(pMesh);
106  pMesh = pTempMesh;
107  }
108 
109  // Optimize the mesh for this graphics card's vertex cache
110  // so when rendering the mesh's triangle list the vertices will
111  // cache hit more often so it won't have to re-execute the vertex shader
112  // on those vertices so it will improve perf.
113  DWORD *rgdwAdjacency = new DWORD[pMesh->GetNumFaces() * 3];
114  if (rgdwAdjacency == nullptr)
115  return E_OUTOFMEMORY;
116  V(pMesh->GenerateAdjacency(1e-6f, rgdwAdjacency));
117  V(pMesh->OptimizeInplace(D3DXMESHOPT_VERTEXCACHE, rgdwAdjacency, NULL, NULL, NULL));
118 
119  SAFE_DELETE_ARRAY(rgdwAdjacency);
120 
121  *ppMesh = pMesh;
122 
123  return S_OK;
124 }
125 */
126 
127 HRESULT Graphics::OnResetDevice(void) const
128 {
129  HRESULT hr;
130  if (g_pEffect)
131  {
132  V_RETURN(g_pEffect->OnResetDevice());
133  gui->game->UpdateTrackedResource("g_pEffect", 2);
134  }
135  return S_OK;
136 }
137 
139 {
140  SAFE_RELEASE(g_pEffect);
141  gui->game->UpdateTrackedResource("g_pEffect", 3);
142 
143  char msg[99];
144 
145  // These are released once we get to STATUS_LOADING
147  {
148  for (short t = 0; t < 3; t++)
149  {
150  SAFE_RELEASE(m_pddsLightningAndBackground[t]);
151  sprintf_s(msg, 99, "m_pddsLightningAndBackground[%i]", t);
152  gui->game->UpdateTrackedResource(msg, 3);
153  }
154 
155  SAFE_RELEASE(m_pddsCloudBaseMapAndNetwork);
156  gui->game->UpdateTrackedResource("m_pddsCloudBaseMapAndNetwork", 3);
157  }
158 
159  for (short t = 1; t < humantextureC; t++)
160  {
161  if (m_pddsAvatar[t])
162  {
163  SAFE_RELEASE(m_pddsAvatar[t]);
164  sprintf_s(msg, 99, "m_pddsAvatar[%i]", t);
165  gui->game->UpdateTrackedResource(msg, 3);
166  }
167  }
168 }
169 
170 void Graphics::DrawImmigration(IDirect3DDevice9* pd3dDevice, float fElapsedTime)
171 {
172  logger->AddToCallStack("Graphics::DrawImmigration");
173 
174  D3DXMATRIX matScale;
175  D3DXMatrixScaling(&matScale, gui->game->displayscale, gui->game->displayscale, 1.0f); // both use Y due to locked 7x5 aspect
176  gui->g_pTextSprite->SetTransform(&matScale);
177 
178  gui->g_pTextSprite->Begin(D3DXSPRITE_ALPHABLEND);
179 
180  gui->g_pTextSprite->Draw(gui->m_pddsGUIInterlace, nullptr, nullptr, nullptr, 0xFFFFFFFF);
181 
183 
184  if (!gui->immigrationPassed)
185  gui->DrawErrorBoxes();
186 
187  gui->g_pTextSprite->End();
188 
189  logger->AddToCallStack("Graphics::DrawImmigration HUD");
190 
191  gui->g_HUD.OnRender(fElapsedTime);
192 
193  if (!gui->tempobject.VB)
194  return;
195 
196  logger->AddToCallStack("Graphics::DrawImmigration HUMAN");
197 
198 #pragma region Human
199  pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, false);
200  pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_CW);
201  pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
202 
203  // Turn off D3D lighting, since we are providing our own vertex colors
204  pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
205 
206  // ReSharper disable once CppEntityAssignedButNoRead
207  HRESULT hr;
208  D3DVIEWPORT9 mvp, oldmvp;
209  // 49,271 and 128x128
210  // all of these use displayscaley because the aspect is locked
211  mvp.X = static_cast<DWORD>(49.0f * gui->game->displayscale);
212  mvp.Y = static_cast<DWORD>(271.0f * gui->game->displayscale);
213  mvp.Width = static_cast<DWORD>(128.0f * gui->game->displayscale);
214  mvp.Height = static_cast<DWORD>(128.0f * gui->game->displayscale);
215  mvp.MinZ = 0.0001f; mvp.MaxZ = 0.01f;
216  V(pd3dDevice->GetViewport(&oldmvp));
217  V(pd3dDevice->SetViewport(&mvp));
218 
219  V(pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xFFC0B19C, 1.0f, 0));
220 
221  D3DXMATRIX matWorld, matrixBase;
222  D3DXMatrixScaling(&matrixBase, gui->weight, gui->weight, gui->height);
223 
224  // Set up the rotation matrix to generate 1 full rotation (2*PI radians)
225  // every 1000 ms. To avoid the loss of precision inherent in very high
226  // floating point numbers, the system time is modulated by the rotation
227  // period before conversion to a radian angle.
228 
229  // Set up our view matrix. A view matrix can be defined given an eye point,
230  // a point to lookat, and a direction for which way is up. Here, we set the
231  // eye five units back along the z-axis and up three units, look at the
232  // origin, and define "up" to be in the y-direction.
233  D3DXVECTOR3 vEyePt(0.0f, 0.0f, 0.0005f);
234  D3DXVECTOR3 vLookatPt(0.0f, 0.0f, 0.0f);
235  D3DXVECTOR3 vUpVec(0.0f, 1.0f, 0.0f);
236  D3DXMATRIX matView;
237  D3DXMatrixLookAtRH(&matView, &vEyePt, &vLookatPt, &vUpVec);
238 
239 
240  // For the projection matrix, we set up a perspective transform (which
241  // transforms geometry from 3D view space to 2D viewport space, with
242  // a perspective divide making objects smaller in the distance). To build
243  // a perpsective transform, we need the field of view (1/4 pi is common),
244  // the aspect ratio, and the near and far clipping planes (which define at
245  // what distances geometry should be no longer be rendered).
246  D3DXMATRIXA16 matProj;
247  D3DXMatrixPerspectiveFovRH(&matProj, D3DX_PI / 4, 1.0f, 0.0001f, 0.01f);
248 
249 
250  pd3dDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE);
251  pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); // TEXTURE is default
252  pd3dDevice->SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_TFACTOR); // TEXTURE is default
253  pd3dDevice->SetRenderState(D3DRS_TEXTUREFACTOR, gui->skintone);
254 
255  // Render the vertex buffer contents
256  pd3dDevice->SetStreamSource(0, gui->tempobject.VB, 0, sizeof(D3DVERTEX));
257  pd3dDevice->SetFVF(D3DFVF_VERTEX);
258  bool firstone = true;
259  static float fTimer = 0.0f;
260  if (!gui->pBuffer)
261  fTimer += fElapsedTime*1.0472f;
262 
263  for (short t = 0; t < gui->polyobj.GetComponents(); t++)
264  {
265  const s_mesh_component tempcomponent = gui->polyobj.GetComponent(t);
266  if (tempcomponent.type == 100 || // torso
267  tempcomponent.type == 101 || // head
268  tempcomponent.type == 103 || // UL
269  tempcomponent.type == 104) // UR
270  {
271  float fAngle = sinf(fTimer)*D3DX_PI*0.125f;
272  D3DXMatrixRotationX(&matWorld, -D3DX_HALFPI);
273  matWorld = matrixBase * matWorld;
274  D3DXMATRIX matTemp;
275  if (tempcomponent.type == 100 && !firstone && gui->g_HUD.GetRadioButton(IDC_MALE)->GetChecked())
276  D3DXMatrixTranslation(&matTemp, tempcomponent.nominalxyz.x, tempcomponent.nominalxyz.y + 0.00009f, tempcomponent.nominalxyz.z - 0.00165f);
277  else
278  {
279  D3DXMatrixTranslation(&matTemp, tempcomponent.nominalxyz.x, tempcomponent.nominalxyz.y, tempcomponent.nominalxyz.z - 0.00165f);
280  if (tempcomponent.type == 100 && gui->g_HUD.GetRadioButton(IDC_MALE)->GetChecked())
281  firstone = false;
282  }
283  matWorld = matTemp * matWorld;
284  D3DXMatrixRotationY(&matTemp, fAngle);
285  matWorld = matWorld * matTemp;
286 
287  if (tempcomponent.attachto == 0 || // unassigned
288  (tempcomponent.type == 100 && tempcomponent.attachto == 250) || // bare torso
289  tempcomponent.attachto == gui->g_HUD.GetSlider(IDC_NOSE)->GetValue() ||
290  tempcomponent.attachto == gui->g_HUD.GetSlider(IDC_EARS)->GetValue() ||
291  tempcomponent.attachto == gui->g_HUD.GetSlider(IDC_JAWLINE)->GetValue() ||
292  tempcomponent.attachto == gui->g_HUD.GetSlider(IDC_HAIRSTYLE)->GetValue() ||
293  tempcomponent.attachto == gui->g_HUD.GetSlider(IDC_HEAD)->GetValue() ||
294  tempcomponent.attachto == gui->g_HUD.GetSlider(IDC_FEATURE)->GetValue())
295  {
296  D3DXMATRIX mWorldViewProj = matWorld * matView * matProj;
297  V(g_pEffect->SetMatrix("matWorldViewProj", &mWorldViewProj));
298  V(g_pEffect->SetTexture("ColorMap", m_pddsAvatar[tempcomponent.texture]));
299  D3DXVECTOR4 tempvec4;
300  // age 18-88 is 0-1,
301  float powage = powf(gui->age, 2.0f);
302  tempvec4.x = gui->haircolor.r*(1.0f - powage) + 1.0f*powage; // hair/lips
303  tempvec4.y = gui->haircolor.g*(1.0f - powage) + 1.0f*powage;
304  tempvec4.z = gui->haircolor.b*(1.0f - powage) + 1.0f*powage;
305  tempvec4.w = gui->stubbleFreckle;
306  V(g_pEffect->SetVector("Radiosity", &tempvec4));
307  tempvec4.x = gui->skintone.r; // skin
308  tempvec4.y = gui->skintone.g;
309  tempvec4.z = gui->skintone.b;
310  tempvec4.w = gui->age;
311  V(g_pEffect->SetVector("shiplight", &tempvec4));
312  tempvec4.x = gui->eyecolor.r; // eyes
313  tempvec4.y = gui->eyecolor.g;
314  tempvec4.z = gui->eyecolor.b;
315  tempvec4.w = 0.0f; // unused but used in Makeship to signal whether to use alpha as transparency or colorization
316  V(g_pEffect->SetVector("ambient", &tempvec4));
317  g_pEffect->Begin(nullptr, 0);
318  g_pEffect->BeginPass(7);
319  pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, tempcomponent.startvertex, tempcomponent.primitives);
320  g_pEffect->EndPass();
321  g_pEffect->End();
322  }
323  else if (tempcomponent.attachto == gui->g_HUD.GetSlider(IDC_FRAMETYPE)->GetValue() &&
324  gui->g_HUD.GetSlider(IDC_FRAMETYPE)->GetVisible())
325  {
326  // eye glasses
327  pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, true);
328  pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
329  pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
330 
331  pd3dDevice->SetTransform(D3DTS_WORLD, &matWorld);
332  pd3dDevice->SetTransform(D3DTS_VIEW, &matView);
333  pd3dDevice->SetTransform(D3DTS_PROJECTION, &matProj);
334 
335  pd3dDevice->SetTexture(0, m_pddsAvatar[tempcomponent.texture]);
336 
337  pd3dDevice->DrawPrimitive(D3DPT_TRIANGLELIST, tempcomponent.startvertex, tempcomponent.primitives);
338  }
339  }
340  }
341 
342  V(pd3dDevice->SetViewport(&oldmvp)); // restore
343 
344  pd3dDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS);
345  pd3dDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
346  pd3dDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
347  pd3dDevice->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
348 
349 #pragma endregion
350 
351  logger->AddToCallStack("Graphics::DrawImmigration DONE");
352 }
353 
355 {
356  HRESULT hr;
357  D3DCAPS9 caps;
358  V_RETURN(DXUTGetD3D9Device()->GetDeviceCaps(&caps));
359 
360  // Test for vs and ps versions
361  if (caps.VertexShaderVersion >= D3DVS_VERSION(3, 0) &&
362  caps.PixelShaderVersion >= D3DPS_VERSION(3, 0))
363  {
364  DWORD dwShaderFlags = D3DXSHADER_OPTIMIZATION_LEVEL3;
365 
366 #ifdef DEBUG_VS
367  dwShaderFlags |= D3DXSHADER_FORCE_VS_SOFTWARE_NOOPT;
368 #endif
369 #ifdef DEBUG_PS
370  dwShaderFlags |= D3DXSHADER_FORCE_PS_SOFTWARE_NOOPT;
371 #endif
372 
373  hr = D3DXCreateEffectFromResource(DXUTGetD3D9Device(), nullptr, MAKEINTRESOURCE(IDR_RCDATA1), nullptr, nullptr, dwShaderFlags, nullptr, &g_pEffect, nullptr);
374  if (!SUCCEEDED(hr))
375  {
376  gui->game->logger->Log("Graphics::LoadShaderFile D3DXCreateEffectFromResource", Logger::Level::Error, hr);
377  return hr;
378  }
379  gui->game->AddTrackedResource("g_pEffect", D3DPOOL_FORCE_DWORD);
380 
381  logger->Log("D3DXCreateEffectFromFile() succeeded...");
382  V_RETURN(g_pEffect->SetTechnique("TShader"));
383  }
384  else
385  {
386  // if we are getting here it may be because a DLL is missing ... we package _43 of dx9 and dx10 as well as d3dcompiler
387  MessageBox(nullptr, L"Requires a graphics adapter with DirectX 9.0c (vs3.0 and ps3.0 support) or higher!", L"HLSL Error", MB_ICONERROR | MB_OK);
388  return E_FAIL;
389  }
390 
391  return S_OK;
392 }
LPDIRECT3DTEXTURE9 m_pddsGUIInterlace
Definition: gui.h:733
#define humantextureC
Definition: Graphics.h:11
ID3DXEffect * g_pEffect
Definition: Graphics.h:30
void DrawImmigration(IDirect3DDevice9 *pd3dDevice, float fElapsedTime)
Definition: Graphics.cpp:170
float stubbleFreckle
Definition: gui.h:755
GameState displaystage
Definition: GameClass.h:121
unsigned char type
Definition: globals.h:406
Definition: gui.h:415
LPDIRECT3DTEXTURE9 m_pddsLightningAndBackground[3]
Definition: Graphics.h:32
GameClass * game
Definition: gui.h:857
HRESULT OnResetDevice(void) const
Definition: Graphics.cpp:127
HRESULT LoadShaderFile(void)
Definition: Graphics.cpp:354
void DrawErrorBoxes()
Definition: gui.cpp:4071
Graphics(HMI *g)
Definition: Graphics.cpp:16
float age
Definition: gui.h:755
float height
Definition: gui.h:755
LPDIRECT3DVERTEXBUFFER9 VB
Definition: globals.h:366
D3DXCOLOR eyecolor
Definition: gui.h:754
Definition: gui.h:452
Logger * logger
Definition: GameClass.h:113
void DrawRXTXLights(LPDIRECT3DTEXTURE9 *tex) const
Definition: gui.cpp:4053
Definition: gui.h:462
CDXUTDialog g_HUD
Definition: gui.h:710
s_mesh_component GetComponent(short i) const
Definition: polyobj.cpp:189
void AddFontsToSystem(void) const
Definition: Graphics.cpp:35
#define IDR_RCDATA1
Definition: resource.h:34
D3DXCOLOR haircolor
Definition: gui.h:754
LPDIRECT3DTEXTURE9 m_pddsCloudBaseMapAndNetwork
Definition: Graphics.h:31
D3DXVECTOR3 nominalxyz
Definition: globals.h:416
short attachto
Definition: globals.h:407
HMI * gui
Definition: Graphics.h:36
void OnDestroyDevice(void)
Definition: Graphics.cpp:138
PolyObj polyobj
Definition: gui.h:775
void RemoveFontsFromSystem(void) const
Definition: Graphics.cpp:61
s_polygon_object tempobject
Definition: gui.h:774
void Log(const char *msg, Level level=Info, int errorCode=0)
Definition: Logger.cpp:11
D3DXCOLOR skintone
Definition: gui.h:754
bool immigrationPassed
Definition: gui.h:776
Definition: gui.h:696
ID3DXSprite * g_pTextSprite
Definition: gui.h:726
LPD3DXBUFFER pBuffer
Definition: gui.h:761
UINT startvertex
Definition: globals.h:408
void AddTrackedResource(const char *name, _D3DPOOL pool=D3DPOOL_MANAGED)
Definition: GameClass.cpp:2702
float displayscale
Definition: GameClass.h:128
#define D3DFVF_VERTEX
Definition: globals.h:101
Logger * logger
Definition: Graphics.h:37
void UpdateTrackedResource(const char *name, int status)
Definition: GameClass.cpp:2725
void AddToCallStack(const char *msg)
Definition: Logger.cpp:86
~Graphics()
Definition: Graphics.cpp:30
unsigned short GetComponents() const
Definition: polyobj.cpp:184
LPDIRECT3DTEXTURE9 m_pddsAvatar[humantextureC]
Definition: Graphics.h:33
float weight
Definition: gui.h:755
Definition: gui.h:450