00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "Kernel/OVR_Log.h"
00025 #include "Kernel/OVR_Std.h"
00026
00027 #include "RenderTiny_D3D1X_Device.h"
00028
00029 #include <d3dcompiler.h>
00030
00031 namespace OVR { namespace RenderTiny { namespace D3D10 {
00032
00033
00034
00035
00036 static D3D1x_(INPUT_ELEMENT_DESC) ModelVertexDesc[] =
00037 {
00038 {"Position", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Pos), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00039 {"Color", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, offsetof(Vertex, C), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00040 {"TexCoord", 0, DXGI_FORMAT_R32G32_FLOAT, 0, offsetof(Vertex, U), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00041 {"Normal", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, offsetof(Vertex, Norm), D3D1x_(INPUT_PER_VERTEX_DATA), 0},
00042 };
00043
00044
00045
00046
00047 static const char* StdVertexShaderSrc =
00048 "float4x4 Proj;\n"
00049 "float4x4 View;\n"
00050 "struct Varyings\n"
00051 "{\n"
00052 " float4 Position : SV_Position;\n"
00053 " float4 Color : COLOR0;\n"
00054 " float2 TexCoord : TEXCOORD0;\n"
00055 " float3 Normal : NORMAL;\n"
00056 " float3 VPos : TEXCOORD4;\n"
00057 "};\n"
00058 "void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0,"
00059 " in float3 Normal : NORMAL,\n"
00060 " out Varyings ov)\n"
00061 "{\n"
00062 " ov.Position = mul(Proj, mul(View, Position));\n"
00063 " ov.Normal = mul(View, Normal);\n"
00064 " ov.VPos = mul(View, Position);\n"
00065 " ov.TexCoord = TexCoord;\n"
00066 " ov.Color = Color;\n"
00067 "}\n";
00068
00069
00070 static const char* DirectVertexShaderSrc =
00071 "float4x4 View : register(c4);\n"
00072 "void main(in float4 Position : POSITION, in float4 Color : COLOR0,\n"
00073 " in float2 TexCoord : TEXCOORD0, in float3 Normal : NORMAL,\n"
00074 " out float4 oPosition : SV_Position, out float4 oColor : COLOR,\n"
00075 " out float2 oTexCoord : TEXCOORD0,"
00076 " out float3 oNormal : NORMAL)\n"
00077 "{\n"
00078 " oPosition = mul(View, Position);\n"
00079 " oTexCoord = TexCoord;\n"
00080 " oColor = Color;\n"
00081 " oNormal = mul(View, Normal);\n"
00082 "}\n";
00083
00084 static const char* SolidPixelShaderSrc =
00085 "float4 Color;\n"
00086 "struct Varyings\n"
00087 "{\n"
00088 " float4 Position : SV_Position;\n"
00089 " float4 Color : COLOR0;\n"
00090 " float2 TexCoord : TEXCOORD0;\n"
00091 "};\n"
00092 "float4 main(in Varyings ov) : SV_Target\n"
00093 "{\n"
00094 " return Color;\n"
00095 "}\n";
00096
00097 static const char* GouraudPixelShaderSrc =
00098 "struct Varyings\n"
00099 "{\n"
00100 " float4 Position : SV_Position;\n"
00101 " float4 Color : COLOR0;\n"
00102 " float2 TexCoord : TEXCOORD0;\n"
00103 "};\n"
00104 "float4 main(in Varyings ov) : SV_Target\n"
00105 "{\n"
00106 " return ov.Color;\n"
00107 "}\n";
00108
00109 static const char* TexturePixelShaderSrc =
00110 "Texture2D Texture : register(t0);\n"
00111 "SamplerState Linear : register(s0);\n"
00112 "struct Varyings\n"
00113 "{\n"
00114 " float4 Position : SV_Position;\n"
00115 " float4 Color : COLOR0;\n"
00116 " float2 TexCoord : TEXCOORD0;\n"
00117 "};\n"
00118 "float4 main(in Varyings ov) : SV_Target\n"
00119 "{\n"
00120 " float4 color2 = ov.Color * Texture.Sample(Linear, ov.TexCoord);\n"
00121 " if (color2.a <= 0.4)\n"
00122 " discard;\n"
00123 " return color2;\n"
00124 "}\n";
00125
00126
00127 #define LIGHTING_COMMON \
00128 "cbuffer Lighting : register(b1)\n" \
00129 "{\n" \
00130 " float3 Ambient;\n" \
00131 " float3 LightPos[8];\n" \
00132 " float4 LightColor[8];\n" \
00133 " float LightCount;\n" \
00134 "};\n" \
00135 "struct Varyings\n" \
00136 "{\n" \
00137 " float4 Position : SV_Position;\n" \
00138 " float4 Color : COLOR0;\n" \
00139 " float2 TexCoord : TEXCOORD0;\n" \
00140 " float3 Normal : NORMAL;\n" \
00141 " float3 VPos : TEXCOORD4;\n" \
00142 "};\n" \
00143 "float4 DoLight(Varyings v)\n" \
00144 "{\n" \
00145 " float3 norm = normalize(v.Normal);\n" \
00146 " float3 light = Ambient;\n" \
00147 " for (uint i = 0; i < LightCount; i++)\n"\
00148 " {\n" \
00149 " float3 ltp = (LightPos[i] - v.VPos);\n" \
00150 " float ldist = dot(ltp,ltp);\n" \
00151 " ltp = normalize(ltp);\n" \
00152 " light += saturate(LightColor[i] * v.Color.rgb * dot(norm, ltp) / sqrt(ldist));\n"\
00153 " }\n" \
00154 " return float4(light, v.Color.a);\n" \
00155 "}\n"
00156
00157 static const char* LitSolidPixelShaderSrc =
00158 LIGHTING_COMMON
00159 "float4 main(in Varyings ov) : SV_Target\n"
00160 "{\n"
00161 " return DoLight(ov) * ov.Color;\n"
00162 "}\n";
00163
00164 static const char* LitTexturePixelShaderSrc =
00165 "Texture2D Texture : register(t0);\n"
00166 "SamplerState Linear : register(s0);\n"
00167 LIGHTING_COMMON
00168 "float4 main(in Varyings ov) : SV_Target\n"
00169 "{\n"
00170 " return DoLight(ov) * Texture.Sample(Linear, ov.TexCoord);\n"
00171 "}\n";
00172
00173
00174
00175
00176
00177 static const char* PostProcessVertexShaderSrc =
00178 "float4x4 View : register(c4);\n"
00179 "float4x4 Texm : register(c8);\n"
00180 "void main(in float4 Position : POSITION, in float4 Color : COLOR0, in float2 TexCoord : TEXCOORD0,\n"
00181 " out float4 oPosition : SV_Position, out float4 oColor : COLOR, out float2 oTexCoord : TEXCOORD0)\n"
00182 "{\n"
00183 " oPosition = mul(View, Position);\n"
00184 " oTexCoord = mul(Texm, float4(TexCoord,0,1));\n"
00185 " oColor = Color;\n"
00186 "}\n";
00187
00188
00189 static const char* PostProcessPixelShaderSrc =
00190 "Texture2D Texture : register(t0);\n"
00191 "SamplerState Linear : register(s0);\n"
00192 "float2 LensCenter;\n"
00193 "float2 ScreenCenter;\n"
00194 "float2 Scale;\n"
00195 "float2 ScaleIn;\n"
00196 "float4 HmdWarpParam;\n"
00197 "\n"
00198
00199
00200
00201
00202 "float2 HmdWarp(float2 in01)\n"
00203 "{\n"
00204 " float2 theta = (in01 - LensCenter) * ScaleIn;\n"
00205 " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
00206 " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
00207 " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
00208 " return LensCenter + Scale * theta1;\n"
00209 "}\n"
00210
00211 "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
00212 " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
00213 "{\n"
00214 " float2 tc = HmdWarp(oTexCoord);\n"
00215 " if (any(clamp(tc, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tc))\n"
00216 " return 0;\n"
00217 " return Texture.Sample(Linear, tc);\n"
00218 "}\n";
00219
00220
00221 static const char* PostProcessPixelShaderWithChromAbSrc =
00222 "Texture2D Texture : register(t0);\n"
00223 "SamplerState Linear : register(s0);\n"
00224 "float2 LensCenter;\n"
00225 "float2 ScreenCenter;\n"
00226 "float2 Scale;\n"
00227 "float2 ScaleIn;\n"
00228 "float4 HmdWarpParam;\n"
00229 "float4 ChromAbParam;\n"
00230 "\n"
00231
00232
00233
00234
00235 "float4 main(in float4 oPosition : SV_Position, in float4 oColor : COLOR,\n"
00236 " in float2 oTexCoord : TEXCOORD0) : SV_Target\n"
00237 "{\n"
00238 " float2 theta = (oTexCoord - LensCenter) * ScaleIn;\n"
00239 " float rSq= theta.x * theta.x + theta.y * theta.y;\n"
00240 " float2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
00241 " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
00242 " \n"
00243 " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
00244 " float2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
00245 " float2 tcBlue = LensCenter + Scale * thetaBlue;\n"
00246 " if (any(clamp(tcBlue, ScreenCenter-float2(0.25,0.5), ScreenCenter+float2(0.25, 0.5)) - tcBlue))\n"
00247 " return 0;\n"
00248 " \n"
00249 " // Now do blue texture lookup.\n"
00250 " float blue = Texture.Sample(Linear, tcBlue).b;\n"
00251 " \n"
00252 " // Do green lookup (no scaling).\n"
00253 " float2 tcGreen = LensCenter + Scale * theta1;\n"
00254 " float green = Texture.Sample(Linear, tcGreen).g;\n"
00255 " \n"
00256 " // Do red scale and lookup.\n"
00257 " float2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
00258 " float2 tcRed = LensCenter + Scale * thetaRed;\n"
00259 " float red = Texture.Sample(Linear, tcRed).r;\n"
00260 " \n"
00261 " return float4(red, green, blue, 1);\n"
00262 "}\n";
00263
00264
00265 static const char* VShaderSrcs[VShader_Count] =
00266 {
00267 DirectVertexShaderSrc,
00268 StdVertexShaderSrc,
00269 PostProcessVertexShaderSrc
00270 };
00271 static const char* FShaderSrcs[FShader_Count] =
00272 {
00273 SolidPixelShaderSrc,
00274 GouraudPixelShaderSrc,
00275 TexturePixelShaderSrc,
00276 PostProcessPixelShaderSrc,
00277 PostProcessPixelShaderWithChromAbSrc,
00278 LitSolidPixelShaderSrc,
00279 LitTexturePixelShaderSrc
00280 };
00281
00282
00283
00284
00285
00286 Buffer::~Buffer()
00287 {
00288 }
00289
00290 bool Buffer::Data(int use, const void *buffer, size_t size)
00291 {
00292 if (D3DBuffer && Size >= size)
00293 {
00294 if (Dynamic)
00295 {
00296 if (!buffer)
00297 return true;
00298
00299 void* v = Map(0, size, Map_Discard);
00300 if (v)
00301 {
00302 memcpy(v, buffer, size);
00303 Unmap(v);
00304 return true;
00305 }
00306 }
00307 else
00308 {
00309 Ren->Context->UpdateSubresource(D3DBuffer, 0, NULL, buffer, 0, 0);
00310 return true;
00311 }
00312 }
00313 if (D3DBuffer)
00314 {
00315 D3DBuffer = NULL;
00316 Size = 0;
00317 Use = 0;
00318 Dynamic = 0;
00319 }
00320
00321 D3D1x_(BUFFER_DESC) desc;
00322 memset(&desc, 0, sizeof(desc));
00323 if (use & Buffer_ReadOnly)
00324 {
00325 desc.Usage = D3D1x_(USAGE_IMMUTABLE);
00326 desc.CPUAccessFlags = 0;
00327 }
00328 else
00329 {
00330 desc.Usage = D3D1x_(USAGE_DYNAMIC);
00331 desc.CPUAccessFlags = D3D1x_(CPU_ACCESS_WRITE);
00332 Dynamic = 1;
00333 }
00334
00335 switch(use & Buffer_TypeMask)
00336 {
00337 case Buffer_Vertex: desc.BindFlags = D3D1x_(BIND_VERTEX_BUFFER); break;
00338 case Buffer_Index: desc.BindFlags = D3D1x_(BIND_INDEX_BUFFER); break;
00339 case Buffer_Uniform:
00340 desc.BindFlags = D3D1x_(BIND_CONSTANT_BUFFER);
00341 size += ((size + 15) & ~15) - size;
00342 break;
00343 }
00344
00345 desc.ByteWidth = (unsigned)size;
00346
00347 D3D1x_(SUBRESOURCE_DATA) sr;
00348 sr.pSysMem = buffer;
00349 sr.SysMemPitch = 0;
00350 sr.SysMemSlicePitch = 0;
00351
00352 HRESULT hr = Ren->Device->CreateBuffer(&desc, buffer ? &sr : NULL, &D3DBuffer.GetRawRef());
00353 if (SUCCEEDED(hr))
00354 {
00355 Use = use;
00356 Size = desc.ByteWidth;
00357 return 1;
00358 }
00359 return 0;
00360 }
00361
00362 void* Buffer::Map(size_t start, size_t size, int flags)
00363 {
00364 OVR_UNUSED(size);
00365
00366 D3D1x_(MAP) mapFlags = D3D1x_(MAP_WRITE);
00367 if (flags & Map_Discard)
00368 mapFlags = D3D1x_(MAP_WRITE_DISCARD);
00369 if (flags & Map_Unsynchronized)
00370 mapFlags = D3D1x_(MAP_WRITE_NO_OVERWRITE);
00371
00372 void* map = 0;
00373 if (SUCCEEDED(D3DBuffer->Map(mapFlags, 0, &map)))
00374 return ((char*)map) + start;
00375 return NULL;
00376 }
00377
00378 bool Buffer::Unmap(void *m)
00379 {
00380 OVR_UNUSED(m);
00381
00382 D3DBuffer->Unmap();
00383 return true;
00384 }
00385
00386
00387
00388
00389
00390 template<> bool Shader<RenderTiny::Shader_Vertex, ID3D10VertexShader>::Load(void* shader, size_t size)
00391 {
00392 return SUCCEEDED(Ren->Device->CreateVertexShader(shader, size, &D3DShader));
00393 }
00394 template<> bool Shader<RenderTiny::Shader_Pixel, ID3D10PixelShader>::Load(void* shader, size_t size)
00395 {
00396 return SUCCEEDED(Ren->Device->CreatePixelShader(shader, size, &D3DShader));
00397 }
00398
00399 template<> void Shader<RenderTiny::Shader_Vertex, ID3D10VertexShader>::Set(PrimitiveType) const
00400 {
00401 Ren->Context->VSSetShader(D3DShader);
00402 }
00403 template<> void Shader<RenderTiny::Shader_Pixel, ID3D10PixelShader>::Set(PrimitiveType) const
00404 {
00405 Ren->Context->PSSetShader(D3DShader);
00406 }
00407
00408 template<> void Shader<RenderTiny::Shader_Vertex, ID3D1xVertexShader>::SetUniformBuffer(RenderTiny::Buffer* buffer, int i)
00409 {
00410 Ren->Context->VSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
00411 }
00412 template<> void Shader<RenderTiny::Shader_Pixel, ID3D1xPixelShader>::SetUniformBuffer(RenderTiny::Buffer* buffer, int i)
00413 {
00414 Ren->Context->PSSetConstantBuffers(i, 1, &((Buffer*)buffer)->D3DBuffer.GetRawRef());
00415 }
00416
00417
00418
00419
00420
00421 ShaderBase::ShaderBase(RenderDevice* r, ShaderStage stage)
00422 : RenderTiny::Shader(stage), Ren(r), UniformData(0)
00423 {
00424 }
00425 ShaderBase::~ShaderBase()
00426 {
00427 if (UniformData)
00428 OVR_FREE(UniformData);
00429 }
00430
00431 bool ShaderBase::SetUniform(const char* name, int n, const float* v)
00432 {
00433 for(unsigned i = 0; i < UniformInfo.GetSize(); i++)
00434 {
00435 if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
00436 {
00437 memcpy(UniformData + UniformInfo[i].Offset, v, n * sizeof(float));
00438 return 1;
00439 }
00440 }
00441 return 0;
00442 }
00443
00444 void ShaderBase::InitUniforms(ID3D10Blob* s)
00445 {
00446 ID3D10ShaderReflection* ref = NULL;
00447 D3D10ReflectShader(s->GetBufferPointer(), s->GetBufferSize(), &ref);
00448 ID3D10ShaderReflectionConstantBuffer* buf = ref->GetConstantBufferByIndex(0);
00449 D3D10_SHADER_BUFFER_DESC bufd;
00450 if (FAILED(buf->GetDesc(&bufd)))
00451 {
00452 UniformsSize = 0;
00453 if (UniformData)
00454 {
00455 OVR_FREE(UniformData);
00456 UniformData = 0;
00457 }
00458 return;
00459 }
00460
00461 for(unsigned i = 0; i < bufd.Variables; i++)
00462 {
00463 ID3D10ShaderReflectionVariable* var = buf->GetVariableByIndex(i);
00464 if (var)
00465 {
00466 D3D10_SHADER_VARIABLE_DESC vd;
00467 if (SUCCEEDED(var->GetDesc(&vd)))
00468 {
00469 Uniform u;
00470 u.Name = vd.Name;
00471 u.Offset = vd.StartOffset;
00472 u.Size = vd.Size;
00473 UniformInfo.PushBack(u);
00474 }
00475 }
00476 }
00477
00478 UniformsSize = bufd.Size;
00479 UniformData = (unsigned char*)OVR_ALLOC(bufd.Size);
00480 }
00481
00482 void ShaderBase::UpdateBuffer(Buffer* buf)
00483 {
00484 if (UniformsSize)
00485 {
00486 buf->Data(Buffer_Uniform, UniformData, UniformsSize);
00487 }
00488 }
00489
00490
00491
00492
00493
00494 Texture::Texture(RenderDevice* ren, int fmt, int w, int h)
00495 : Ren(ren), Tex(NULL), TexSv(NULL), TexRtv(NULL), TexDsv(NULL), Width(w), Height(h)
00496 {
00497 OVR_UNUSED(fmt);
00498 Sampler = Ren->GetSamplerState(0);
00499 }
00500
00501 Texture::~Texture()
00502 {
00503 }
00504
00505 void Texture::Set(int slot, RenderTiny::ShaderStage stage) const
00506 {
00507 Ren->SetTexture(stage, slot, this);
00508 }
00509
00510 void Texture::SetSampleMode(int sm)
00511 {
00512 Sampler = Ren->GetSamplerState(sm);
00513 }
00514
00515
00516
00517
00518
00519
00520 RenderDevice::RenderDevice(const RendererParams& p, HWND window)
00521 {
00522 RECT rc;
00523 GetClientRect(window, &rc);
00524 UINT width = rc.right - rc.left;
00525 UINT height = rc.bottom - rc.top;
00526 WindowWidth = width;
00527 WindowHeight = height;
00528 Window = window;
00529 Params = p;
00530
00531 HRESULT hr = CreateDXGIFactory(__uuidof(IDXGIFactory), (void**)(&DXGIFactory.GetRawRef()));
00532 if (FAILED(hr))
00533 return;
00534
00535
00536 if (Params.MonitorName.GetLength() > 0)
00537 {
00538 for(UINT AdapterIndex = 0; ; AdapterIndex++)
00539 {
00540 HRESULT hr = DXGIFactory->EnumAdapters(AdapterIndex, &Adapter.GetRawRef());
00541 if (hr == DXGI_ERROR_NOT_FOUND)
00542 break;
00543
00544 DXGI_ADAPTER_DESC Desc;
00545 Adapter->GetDesc(&Desc);
00546
00547 UpdateMonitorOutputs();
00548
00549 if (FullscreenOutput)
00550 break;
00551 }
00552
00553 if (!FullscreenOutput)
00554 Adapter = NULL;
00555 }
00556
00557 if (!Adapter)
00558 {
00559 DXGIFactory->EnumAdapters(0, &Adapter.GetRawRef());
00560 }
00561
00562 int flags = 0;
00563
00564 hr = D3D10CreateDevice(Adapter, D3D10_DRIVER_TYPE_HARDWARE, NULL, flags, D3D1x_(SDK_VERSION),
00565 &Device.GetRawRef());
00566 Context = Device;
00567 Context->AddRef();
00568
00569 if (FAILED(hr))
00570 return;
00571
00572 if (!RecreateSwapChain())
00573 return;
00574
00575 if (Params.Fullscreen)
00576 SwapChain->SetFullscreenState(1, FullscreenOutput);
00577
00578 CurRenderTarget = NULL;
00579 for(int i = 0; i < Shader_Count; i++)
00580 {
00581 UniformBuffers[i] = *CreateBuffer();
00582 MaxTextureSet[i] = 0;
00583 }
00584
00585 ID3D10Blob* vsData = CompileShader("vs_4_0", DirectVertexShaderSrc);
00586 VertexShaders[VShader_MV] = *new VertexShader(this, vsData);
00587 for(int i = 1; i < VShader_Count; i++)
00588 {
00589 VertexShaders[i] = *new VertexShader(this, CompileShader("vs_4_0", VShaderSrcs[i]));
00590 }
00591
00592 for(int i = 0; i < FShader_Count; i++)
00593 {
00594 PixelShaders[i] = *new PixelShader(this, CompileShader("ps_4_0", FShaderSrcs[i]));
00595 }
00596
00597 SPInt bufferSize = vsData->GetBufferSize();
00598 const void* buffer = vsData->GetBufferPointer();
00599 ID3D1xInputLayout** objRef = &ModelVertexIL.GetRawRef();
00600
00601 HRESULT validate = Device->CreateInputLayout(ModelVertexDesc, sizeof(ModelVertexDesc)/sizeof(D3D1x_(INPUT_ELEMENT_DESC)),
00602 buffer, bufferSize, objRef);
00603 OVR_UNUSED(validate);
00604
00605 Ptr<ShaderSet> gouraudShaders = *new ShaderSet();
00606 gouraudShaders->SetShader(VertexShaders[VShader_MVP]);
00607 gouraudShaders->SetShader(PixelShaders[FShader_Gouraud]);
00608 DefaultFill = *new ShaderFill(gouraudShaders);
00609
00610 D3D1x_(BLEND_DESC) bm;
00611 memset(&bm, 0, sizeof(bm));
00612 bm.BlendEnable[0] = true;
00613 bm.BlendOp = bm.BlendOpAlpha = D3D1x_(BLEND_OP_ADD);
00614 bm.SrcBlend = bm.SrcBlendAlpha = D3D1x_(BLEND_SRC_ALPHA);
00615 bm.DestBlend = bm.DestBlendAlpha = D3D1x_(BLEND_INV_SRC_ALPHA);
00616 bm.RenderTargetWriteMask[0] = D3D1x_(COLOR_WRITE_ENABLE_ALL);
00617 Device->CreateBlendState(&bm, &BlendState.GetRawRef());
00618
00619 D3D1x_(RASTERIZER_DESC) rs;
00620 memset(&rs, 0, sizeof(rs));
00621 rs.AntialiasedLineEnable = true;
00622 rs.CullMode = D3D1x_(CULL_BACK);
00623 rs.DepthClipEnable = true;
00624 rs.FillMode = D3D1x_(FILL_SOLID);
00625 Device->CreateRasterizerState(&rs, &Rasterizer.GetRawRef());
00626
00627 QuadVertexBuffer = *CreateBuffer();
00628 const RenderTiny::Vertex QuadVertices[] =
00629 { Vertex(Vector3f(0, 1, 0)), Vertex(Vector3f(1, 1, 0)),
00630 Vertex(Vector3f(0, 0, 0)), Vertex(Vector3f(1, 0, 0)) };
00631 QuadVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices));
00632
00633 SetDepthMode(0, 0);
00634 }
00635
00636 RenderDevice::~RenderDevice()
00637 {
00638 if (SwapChain && Params.Fullscreen)
00639 {
00640 SwapChain->SetFullscreenState(false, NULL);
00641 }
00642 }
00643
00644
00645
00646 RenderTiny::RenderDevice* RenderDevice::CreateDevice(const RendererParams& rp, void* oswnd)
00647 {
00648 return new RenderDevice(rp, (HWND)oswnd);
00649 }
00650
00651
00652
00653
00654
00655
00656
00657 BOOL CALLBACK MonitorEnumFunc(HMONITOR hMonitor, HDC, LPRECT, LPARAM dwData)
00658 {
00659 RenderDevice* renderer = (RenderDevice*)dwData;
00660
00661 MONITORINFOEX monitor;
00662 monitor.cbSize = sizeof(monitor);
00663
00664 if (::GetMonitorInfo(hMonitor, &monitor) && monitor.szDevice[0])
00665 {
00666 DISPLAY_DEVICE dispDev;
00667 memset(&dispDev, 0, sizeof(dispDev));
00668 dispDev.cb = sizeof(dispDev);
00669
00670 if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0))
00671 {
00672 if (strstr(String(dispDev.DeviceName).ToCStr(), renderer->GetParams().MonitorName.ToCStr()))
00673 {
00674 renderer->FSDesktopX = monitor.rcMonitor.left;
00675 renderer->FSDesktopY = monitor.rcMonitor.top;
00676 return FALSE;
00677 }
00678 }
00679 }
00680
00681 return TRUE;
00682 }
00683
00684
00685 void RenderDevice::UpdateMonitorOutputs()
00686 {
00687 HRESULT hr;
00688
00689 bool deviceNameFound = false;
00690
00691 for(UINT OutputIndex = 0; ; OutputIndex++)
00692 {
00693 Ptr<IDXGIOutput> Output;
00694 hr = Adapter->EnumOutputs(OutputIndex, &Output.GetRawRef());
00695 if (hr == DXGI_ERROR_NOT_FOUND)
00696 {
00697 break;
00698 }
00699
00700 DXGI_OUTPUT_DESC OutDesc;
00701 Output->GetDesc(&OutDesc);
00702
00703 MONITORINFOEX monitor;
00704 monitor.cbSize = sizeof(monitor);
00705 if (::GetMonitorInfo(OutDesc.Monitor, &monitor) && monitor.szDevice[0])
00706 {
00707 DISPLAY_DEVICE dispDev;
00708 memset(&dispDev, 0, sizeof(dispDev));
00709 dispDev.cb = sizeof(dispDev);
00710
00711 if (::EnumDisplayDevices(monitor.szDevice, 0, &dispDev, 0))
00712 {
00713 if (strstr(String(dispDev.DeviceName).ToCStr(), Params.MonitorName.ToCStr()))
00714 {
00715 deviceNameFound = true;
00716 FullscreenOutput = Output;
00717 FSDesktopX = monitor.rcMonitor.left;
00718 FSDesktopY = monitor.rcMonitor.top;
00719 break;
00720 }
00721 }
00722 }
00723 }
00724
00725 if (!deviceNameFound && !Params.MonitorName.IsEmpty())
00726 {
00727 EnumDisplayMonitors(0, 0, MonitorEnumFunc, (LPARAM)this);
00728 }
00729 }
00730
00731 bool RenderDevice::RecreateSwapChain()
00732 {
00733 DXGI_SWAP_CHAIN_DESC scDesc;
00734 memset(&scDesc, 0, sizeof(scDesc));
00735 scDesc.BufferCount = 1;
00736 scDesc.BufferDesc.Width = WindowWidth;
00737 scDesc.BufferDesc.Height = WindowHeight;
00738 scDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
00739 scDesc.BufferDesc.RefreshRate.Numerator = 60;
00740 scDesc.BufferDesc.RefreshRate.Denominator = 1;
00741 scDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
00742 scDesc.OutputWindow = Window;
00743 scDesc.SampleDesc.Count = Params.Multisample;
00744 scDesc.SampleDesc.Quality = 0;
00745 scDesc.Windowed = (Params.Fullscreen != Display_Fullscreen);
00746 scDesc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
00747
00748 if (SwapChain)
00749 {
00750 SwapChain->SetFullscreenState(FALSE, NULL);
00751 SwapChain->Release();
00752 SwapChain = NULL;
00753 }
00754
00755 Ptr<IDXGISwapChain> newSC;
00756 if (FAILED(DXGIFactory->CreateSwapChain(Device, &scDesc, &newSC.GetRawRef())))
00757 return false;
00758 SwapChain = newSC;
00759
00760 BackBuffer = NULL;
00761 BackBufferRT = NULL;
00762 HRESULT hr = SwapChain->GetBuffer(0, __uuidof(ID3D1xTexture2D), (void**)&BackBuffer.GetRawRef());
00763 if (FAILED(hr))
00764 return false;
00765
00766 hr = Device->CreateRenderTargetView(BackBuffer, NULL, &BackBufferRT.GetRawRef());
00767 if (FAILED(hr))
00768 return false;
00769
00770 Texture* depthBuffer = GetDepthBuffer(WindowWidth, WindowHeight, Params.Multisample);
00771 CurDepthBuffer = depthBuffer;
00772 if (CurRenderTarget == NULL)
00773 {
00774 Context->OMSetRenderTargets(1, &BackBufferRT.GetRawRef(), depthBuffer->TexDsv);
00775 }
00776 return true;
00777 }
00778
00779 bool RenderDevice::SetParams(const RendererParams& newParams)
00780 {
00781 String oldMonitor = Params.MonitorName;
00782
00783 Params = newParams;
00784 if (newParams.MonitorName != oldMonitor)
00785 {
00786 UpdateMonitorOutputs();
00787 }
00788
00789
00790 pSceneColorTex = NULL;
00791 return RecreateSwapChain();
00792 }
00793
00794
00795 bool RenderDevice::SetFullscreen(DisplayMode fullscreen)
00796 {
00797 if (fullscreen == Params.Fullscreen)
00798 return true;
00799
00800 HRESULT hr = SwapChain->SetFullscreenState(fullscreen, fullscreen ? FullscreenOutput : NULL);
00801 if (FAILED(hr))
00802 {
00803 return false;
00804 }
00805
00806 Params.Fullscreen = fullscreen;
00807 return true;
00808 }
00809
00810 void RenderDevice::SetRealViewport(const Viewport& vp)
00811 {
00812 D3DViewport.Width = vp.w;
00813 D3DViewport.Height = vp.h;
00814 D3DViewport.MinDepth = 0;
00815 D3DViewport.MaxDepth = 1;
00816 D3DViewport.TopLeftX = vp.x;
00817 D3DViewport.TopLeftY = vp.y;
00818 Context->RSSetViewports(1, &D3DViewport);
00819 }
00820
00821 static int GetDepthStateIndex(bool enable, bool write, RenderDevice::CompareFunc func)
00822 {
00823 if (!enable)
00824 return 0;
00825 return 1 + int(func) * 2 + write;
00826 }
00827
00828 void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func)
00829 {
00830 int index = GetDepthStateIndex(enable, write, func);
00831 if (DepthStates[index])
00832 {
00833 CurDepthState = DepthStates[index];
00834 Context->OMSetDepthStencilState(DepthStates[index], 0);
00835 return;
00836 }
00837
00838 D3D1x_(DEPTH_STENCIL_DESC) dss;
00839 memset(&dss, 0, sizeof(dss));
00840 dss.DepthEnable = enable;
00841 switch(func)
00842 {
00843 case Compare_Always: dss.DepthFunc = D3D1x_(COMPARISON_ALWAYS); break;
00844 case Compare_Less: dss.DepthFunc = D3D1x_(COMPARISON_LESS); break;
00845 case Compare_Greater: dss.DepthFunc = D3D1x_(COMPARISON_GREATER); break;
00846 default:
00847 assert(0);
00848 }
00849 dss.DepthWriteMask = write ? D3D1x_(DEPTH_WRITE_MASK_ALL) : D3D1x_(DEPTH_WRITE_MASK_ZERO);
00850 Device->CreateDepthStencilState(&dss, &DepthStates[index].GetRawRef());
00851 Context->OMSetDepthStencilState(DepthStates[index], 0);
00852 CurDepthState = DepthStates[index];
00853 }
00854
00855 Texture* RenderDevice::GetDepthBuffer(int w, int h, int ms)
00856 {
00857 for(unsigned i = 0; i < DepthBuffers.GetSize(); i++)
00858 {
00859 if (w == DepthBuffers[i]->Width && h == DepthBuffers[i]->Height &&
00860 ms == DepthBuffers[i]->Samples)
00861 return DepthBuffers[i];
00862 }
00863
00864 Ptr<Texture> newDepth = *CreateTexture(Texture_Depth | Texture_RenderTarget | ms, w, h, NULL);
00865 if (newDepth == NULL)
00866 {
00867 OVR_DEBUG_LOG(("Failed to get depth buffer."));
00868 return NULL;
00869 }
00870
00871 DepthBuffers.PushBack(newDepth);
00872 return newDepth.GetPtr();
00873 }
00874
00875 void RenderDevice::Clear(float r, float g, float b, float a, float depth)
00876 {
00877 const float color[] = {r, g, b, a};
00878
00879
00880
00881
00882 ID3D1xDepthStencilState* oldDepthState = CurDepthState;
00883 StandardUniformData clearUniforms;
00884
00885 SetDepthMode(true, true, Compare_Always);
00886
00887 Context->IASetInputLayout(ModelVertexIL);
00888 Context->GSSetShader(NULL);
00889
00890 ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
00891 if (MaxTextureSet[Shader_Fragment])
00892 {
00893 Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv);
00894 }
00895
00896 ID3D1xBuffer* vertexBuffer = QuadVertexBuffer->GetBuffer();
00897 UINT vertexStride = sizeof(Vertex);
00898 UINT vertexOffset = 0;
00899 Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
00900
00901 clearUniforms.View = Matrix4f(2, 0, 0, 0,
00902 0, 2, 0, 0,
00903 0, 0, 0, 0,
00904 -1, -1, depth, 1);
00905 UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, &clearUniforms, sizeof(clearUniforms));
00906
00907 ID3D1xBuffer* vertexConstants = UniformBuffers[Shader_Vertex]->GetBuffer();
00908 Context->VSSetConstantBuffers(0, 1, &vertexConstants);
00909 Context->IASetPrimitiveTopology(D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP));
00910 VertexShaders[VShader_MV]->Set(Prim_TriangleStrip);
00911 PixelShaders[FShader_Solid]->Set(Prim_TriangleStrip);
00912
00913 UniformBuffers[Shader_Pixel]->Data(Buffer_Uniform, color, sizeof(color));
00914 PixelShaders[FShader_Solid]->SetUniformBuffer(UniformBuffers[Shader_Pixel]);
00915
00916
00917 Context->OMSetBlendState(NULL, NULL, 0xffffffff);
00918 Context->Draw(4, 0);
00919
00920
00921 CurDepthState = oldDepthState;
00922 Context->OMSetDepthStencilState(CurDepthState, 0);
00923 }
00924
00925
00926
00927 Buffer* RenderDevice::CreateBuffer()
00928 {
00929 return new Buffer(this);
00930 }
00931
00932
00933 ID3D10Blob* RenderDevice::CompileShader(const char* profile, const char* src, const char* mainName)
00934 {
00935 ID3D10Blob* shader;
00936 ID3D10Blob* errors;
00937 HRESULT hr = D3DCompile(src, strlen(src), NULL, NULL, NULL, mainName, profile,
00938 0, 0, &shader, &errors);
00939 if (FAILED(hr))
00940 {
00941 OVR_DEBUG_LOG(("Compiling D3D shader for %s failed\n%s\n\n%s",
00942 profile, src, errors->GetBufferPointer()));
00943 OutputDebugStringA((char*)errors->GetBufferPointer());
00944 return NULL;
00945 }
00946 if (errors)
00947 {
00948 errors->Release();
00949 }
00950 return shader;
00951 }
00952
00953 void RenderDevice::SetCommonUniformBuffer(int i, RenderTiny::Buffer* buffer)
00954 {
00955 CommonUniforms[i] = (Buffer*)buffer;
00956
00957 Context->PSSetConstantBuffers(1, 1, &CommonUniforms[1]->D3DBuffer.GetRawRef());
00958 Context->VSSetConstantBuffers(1, 1, &CommonUniforms[1]->D3DBuffer.GetRawRef());
00959 }
00960
00961 RenderTiny::Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader)
00962 {
00963 switch(stage)
00964 {
00965 case Shader_Vertex:
00966 return VertexShaders[shader];
00967 case Shader_Pixel:
00968 return PixelShaders[shader];
00969 default:
00970 return NULL;
00971 }
00972 }
00973
00974
00975 ID3D1xSamplerState* RenderDevice::GetSamplerState(int sm)
00976 {
00977 if (SamplerStates[sm])
00978 return SamplerStates[sm];
00979
00980 D3D1x_(SAMPLER_DESC) ss;
00981 memset(&ss, 0, sizeof(ss));
00982 if (sm & Sample_Clamp)
00983 ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_CLAMP);
00984 else if (sm & Sample_ClampBorder)
00985 ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_BORDER);
00986 else
00987 ss.AddressU = ss.AddressV = ss.AddressW = D3D1x_(TEXTURE_ADDRESS_WRAP);
00988
00989 if (sm & Sample_Nearest)
00990 {
00991 ss.Filter = D3D1x_(FILTER_MIN_MAG_MIP_POINT);
00992 }
00993 else if (sm & Sample_Anisotropic)
00994 {
00995 ss.Filter = D3D1x_(FILTER_ANISOTROPIC);
00996 ss.MaxAnisotropy = 8;
00997 }
00998 else
00999 {
01000 ss.Filter = D3D1x_(FILTER_MIN_MAG_MIP_LINEAR);
01001 }
01002 ss.MaxLOD = 15;
01003 Device->CreateSamplerState(&ss, &SamplerStates[sm].GetRawRef());
01004 return SamplerStates[sm];
01005 }
01006
01007
01008 void RenderDevice::SetTexture(RenderTiny::ShaderStage stage, int slot, const Texture* t)
01009 {
01010 if (MaxTextureSet[stage] <= slot)
01011 MaxTextureSet[stage] = slot + 1;
01012
01013 ID3D1xShaderResourceView* sv = t ? t->TexSv : NULL;
01014 switch(stage)
01015 {
01016 case Shader_Fragment:
01017 Context->PSSetShaderResources(slot, 1, &sv);
01018 if (t)
01019 {
01020 Context->PSSetSamplers(slot, 1, &t->Sampler.GetRawRef());
01021 }
01022 break;
01023
01024 case Shader_Vertex:
01025 Context->VSSetShaderResources(slot, 1, &sv);
01026 break;
01027 }
01028 }
01029
01030 Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount)
01031 {
01032 OVR_UNUSED(mipcount);
01033
01034 DXGI_FORMAT d3dformat;
01035 int bpp;
01036 switch(format & Texture_TypeMask)
01037 {
01038 case Texture_RGBA:
01039 bpp = 4;
01040 d3dformat = DXGI_FORMAT_R8G8B8A8_UNORM;
01041 break;
01042 case Texture_Depth:
01043 bpp = 0;
01044 d3dformat = DXGI_FORMAT_D32_FLOAT;
01045 break;
01046 default:
01047 return NULL;
01048 }
01049
01050 int samples = (format & Texture_SamplesMask);
01051 if (samples < 1)
01052 {
01053 samples = 1;
01054 }
01055
01056 Texture* NewTex = new Texture(this, format, width, height);
01057 NewTex->Samples = samples;
01058
01059 D3D1x_(TEXTURE2D_DESC) dsDesc;
01060 dsDesc.Width = width;
01061 dsDesc.Height = height;
01062 dsDesc.MipLevels = (format == (Texture_RGBA | Texture_GenMipmaps) && data) ? GetNumMipLevels(width, height) : 1;
01063 dsDesc.ArraySize = 1;
01064 dsDesc.Format = d3dformat;
01065 dsDesc.SampleDesc.Count = samples;
01066 dsDesc.SampleDesc.Quality = 0;
01067 dsDesc.Usage = D3D1x_(USAGE_DEFAULT);
01068 dsDesc.BindFlags = D3D1x_(BIND_SHADER_RESOURCE);
01069 dsDesc.CPUAccessFlags = 0;
01070 dsDesc.MiscFlags = 0;
01071
01072 if (format & Texture_RenderTarget)
01073 {
01074 if ((format & Texture_TypeMask) == Texture_Depth)
01075 {
01076 dsDesc.BindFlags = D3D1x_(BIND_DEPTH_STENCIL);
01077 }
01078 else
01079 {
01080 dsDesc.BindFlags |= D3D1x_(BIND_RENDER_TARGET);
01081 }
01082 }
01083
01084 HRESULT hr = Device->CreateTexture2D(&dsDesc, NULL, &NewTex->Tex.GetRawRef());
01085 if (FAILED(hr))
01086 {
01087 OVR_DEBUG_LOG_TEXT(("Failed to create 2D D3D texture."));
01088 NewTex->Release();
01089 return NULL;
01090 }
01091 if (dsDesc.BindFlags & D3D1x_(BIND_SHADER_RESOURCE))
01092 {
01093 Device->CreateShaderResourceView(NewTex->Tex, NULL, &NewTex->TexSv.GetRawRef());
01094 }
01095
01096 if (data)
01097 {
01098 Context->UpdateSubresource(NewTex->Tex, 0, NULL, data, width * bpp, width * height * bpp);
01099 if (format == (Texture_RGBA | Texture_GenMipmaps))
01100 {
01101 int srcw = width, srch = height;
01102 int level = 0;
01103 UByte* mipmaps = NULL;
01104 do
01105 {
01106 level++;
01107 int mipw = srcw >> 1;
01108 if (mipw < 1)
01109 {
01110 mipw = 1;
01111 }
01112 int miph = srch >> 1;
01113 if (miph < 1)
01114 {
01115 miph = 1;
01116 }
01117 if (mipmaps == NULL)
01118 {
01119 mipmaps = (UByte*)OVR_ALLOC(mipw * miph * 4);
01120 }
01121 FilterRgba2x2(level == 1 ? (const UByte*)data : mipmaps, srcw, srch, mipmaps);
01122 Context->UpdateSubresource(NewTex->Tex, level, NULL, mipmaps, mipw * bpp, miph * bpp);
01123 srcw = mipw;
01124 srch = miph;
01125 }
01126 while(srcw > 1 || srch > 1);
01127
01128 if (mipmaps != NULL)
01129 {
01130 OVR_FREE(mipmaps);
01131 }
01132 }
01133 }
01134
01135 if (format & Texture_RenderTarget)
01136 {
01137 if ((format & Texture_TypeMask) == Texture_Depth)
01138 {
01139 Device->CreateDepthStencilView(NewTex->Tex, NULL, &NewTex->TexDsv.GetRawRef());
01140 }
01141 else
01142 {
01143 Device->CreateRenderTargetView(NewTex->Tex, NULL, &NewTex->TexRtv.GetRawRef());
01144 }
01145 }
01146
01147 return NewTex;
01148 }
01149
01150
01151
01152
01153 void RenderDevice::BeginRendering()
01154 {
01155 Context->RSSetState(Rasterizer);
01156 }
01157
01158 void RenderDevice::SetRenderTarget(RenderTiny::Texture* colorTex,
01159 RenderTiny::Texture* depth, RenderTiny::Texture* stencil)
01160 {
01161 OVR_UNUSED(stencil);
01162
01163 CurRenderTarget = (Texture*)colorTex;
01164 if (colorTex == NULL)
01165 {
01166 Texture* newDepthBuffer = GetDepthBuffer(WindowWidth, WindowHeight, Params.Multisample);
01167 if (newDepthBuffer == NULL)
01168 {
01169 OVR_DEBUG_LOG(("New depth buffer creation failed."));
01170 }
01171 if (newDepthBuffer != NULL)
01172 {
01173 CurDepthBuffer = GetDepthBuffer(WindowWidth, WindowHeight, Params.Multisample);
01174 Context->OMSetRenderTargets(1, &BackBufferRT.GetRawRef(), CurDepthBuffer->TexDsv);
01175 }
01176 return;
01177 }
01178 if (depth == NULL)
01179 {
01180 depth = GetDepthBuffer(colorTex->GetWidth(), colorTex->GetHeight(), CurRenderTarget->Samples);
01181 }
01182
01183 ID3D1xShaderResourceView* sv[8] = {0, 0, 0, 0, 0, 0, 0, 0};
01184 if (MaxTextureSet[Shader_Fragment])
01185 {
01186 Context->PSSetShaderResources(0, MaxTextureSet[Shader_Fragment], sv);
01187 }
01188 memset(MaxTextureSet, 0, sizeof(MaxTextureSet));
01189
01190 CurDepthBuffer = (Texture*)depth;
01191 Context->OMSetRenderTargets(1, &((Texture*)colorTex)->TexRtv.GetRawRef(), ((Texture*)depth)->TexDsv);
01192 }
01193
01194
01195 void RenderDevice::SetWorldUniforms(const Matrix4f& proj)
01196 {
01197 StdUniforms.Proj = proj.Transposed();
01198
01199 }
01200
01201
01202 void RenderDevice::Render(const Matrix4f& matrix, Model* model)
01203 {
01204
01205 if (!model->VertexBuffer)
01206 {
01207 Ptr<Buffer> vb = *CreateBuffer();
01208 vb->Data(Buffer_Vertex, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex));
01209 model->VertexBuffer = vb;
01210 }
01211 if (!model->IndexBuffer)
01212 {
01213 Ptr<Buffer> ib = *CreateBuffer();
01214 ib->Data(Buffer_Index, &model->Indices[0], model->Indices.GetSize() * 2);
01215 model->IndexBuffer = ib;
01216 }
01217
01218 Render(model->Fill ? model->Fill : DefaultFill,
01219 model->VertexBuffer, model->IndexBuffer,
01220 matrix, 0, (unsigned)model->Indices.GetSize(), model->GetPrimType());
01221 }
01222
01223 void RenderDevice::Render(const ShaderFill* fill, RenderTiny::Buffer* vertices, RenderTiny::Buffer* indices,
01224 const Matrix4f& matrix, int offset, int count, PrimitiveType rprim)
01225 {
01226 Context->IASetInputLayout(ModelVertexIL);
01227 if (indices)
01228 {
01229 Context->IASetIndexBuffer(((Buffer*)indices)->GetBuffer(), DXGI_FORMAT_R16_UINT, 0);
01230 }
01231
01232 ID3D1xBuffer* vertexBuffer = ((Buffer*)vertices)->GetBuffer();
01233 UINT vertexStride = sizeof(Vertex);
01234 UINT vertexOffset = offset;
01235 Context->IASetVertexBuffers(0, 1, &vertexBuffer, &vertexStride, &vertexOffset);
01236
01237 ShaderSet* shaders = ((ShaderFill*)fill)->GetShaders();
01238
01239 ShaderBase* vshader = ((ShaderBase*)shaders->GetShader(Shader_Vertex));
01240 unsigned char* vertexData = vshader->UniformData;
01241 if (vertexData)
01242 {
01243 StandardUniformData* stdUniforms = (StandardUniformData*) vertexData;
01244 stdUniforms->View = matrix.Transposed();
01245 stdUniforms->Proj = StdUniforms.Proj;
01246 UniformBuffers[Shader_Vertex]->Data(Buffer_Uniform, vertexData, vshader->UniformsSize);
01247 vshader->SetUniformBuffer(UniformBuffers[Shader_Vertex]);
01248 }
01249
01250 for(int i = Shader_Vertex + 1; i < Shader_Count; i++)
01251 if (shaders->GetShader(i))
01252 {
01253 ((ShaderBase*)shaders->GetShader(i))->UpdateBuffer(UniformBuffers[i]);
01254 ((ShaderBase*)shaders->GetShader(i))->SetUniformBuffer(UniformBuffers[i]);
01255 }
01256
01257 D3D1x_(PRIMITIVE_TOPOLOGY) prim;
01258 switch(rprim)
01259 {
01260 case Prim_Triangles:
01261 prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLELIST);
01262 break;
01263 case Prim_Lines:
01264 prim = D3D1x_(PRIMITIVE_TOPOLOGY_LINELIST);
01265 break;
01266 case Prim_TriangleStrip:
01267 prim = D3D1x_(PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
01268 break;
01269 default:
01270 assert(0);
01271 return;
01272 }
01273 Context->IASetPrimitiveTopology(prim);
01274
01275 fill->Set(rprim);
01276
01277 if (indices)
01278 {
01279 Context->DrawIndexed(count, 0, 0);
01280 }
01281 else
01282 {
01283 Context->Draw(count, 0);
01284 }
01285 }
01286
01287
01288 void RenderDevice::Present()
01289 {
01290 SwapChain->Present(0, 0);
01291 }
01292
01293 void RenderDevice::ForceFlushGPU()
01294 {
01295 D3D1x_QUERY_DESC queryDesc = { D3D1x_(QUERY_EVENT), 0 };
01296 Ptr<ID3D1xQuery> query;
01297 BOOL done = FALSE;
01298
01299 if (Device->CreateQuery(&queryDesc, &query.GetRawRef()) == S_OK)
01300 {
01301
01302 query->End();
01303
01304
01305 do { }
01306 while(!done && !FAILED(query->GetData(&done, sizeof(BOOL), 0)));
01307 }
01308 }
01309
01310 }}}
01311