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 "../Render/Render_Device.h"
00025 #include "../Render/Render_Font.h"
00026
00027 #include "Kernel/OVR_Log.h"
00028
00029 namespace OVR { namespace Render {
00030
00031 void Model::Render(const Matrix4f& ltw, RenderDevice* ren)
00032 {
00033 if(Visible)
00034 {
00035 Matrix4f m = ltw * GetMatrix();
00036 ren->Render(m, this);
00037 }
00038 }
00039
00040 void Container::Render(const Matrix4f& ltw, RenderDevice* ren)
00041 {
00042 Matrix4f m = ltw * GetMatrix();
00043 for(unsigned i = 0; i < Nodes.GetSize(); i++)
00044 {
00045 Nodes[i]->Render(m, ren);
00046 }
00047 }
00048
00049 Matrix4f SceneView::GetViewMatrix() const
00050 {
00051 Matrix4f view = Matrix4f(GetOrientation().Conj()) * Matrix4f::Translation(GetPosition());
00052 return view;
00053 }
00054
00055 void LightingParams::Update(const Matrix4f& view, const Vector4f* SceneLightPos)
00056 {
00057 Version++;
00058 for (int i = 0; i < LightCount; i++)
00059 {
00060 LightPos[i] = view.Transform(SceneLightPos[i]);
00061 }
00062 }
00063
00064 void Scene::Render(RenderDevice* ren, const Matrix4f& view)
00065 {
00066 Lighting.Update(view, LightPos);
00067
00068 ren->SetLighting(&Lighting);
00069
00070 World.Render(view, ren);
00071 }
00072
00073
00074
00075 UInt16 CubeIndices[] =
00076 {
00077 0, 1, 3,
00078 3, 1, 2,
00079
00080 5, 4, 6,
00081 6, 4, 7,
00082
00083 8, 9, 11,
00084 11, 9, 10,
00085
00086 13, 12, 14,
00087 14, 12, 15,
00088
00089 16, 17, 19,
00090 19, 17, 18,
00091
00092 21, 20, 22,
00093 22, 20, 23
00094 };
00095
00096
00097
00098 Model* Model::CreateAxisFaceColorBox(float x1, float x2, Color xcolor,
00099 float y1, float y2, Color ycolor,
00100 float z1, float z2, Color zcolor)
00101 {
00102 float t;
00103
00104 if(x1 > x2)
00105 {
00106 t = x1;
00107 x1 = x2;
00108 x2 = t;
00109 }
00110 if(y1 > y2)
00111 {
00112 t = y1;
00113 y1 = y2;
00114 y2 = t;
00115 }
00116 if(z1 > z2)
00117 {
00118 t = z1;
00119 z1 = z2;
00120 z2 = t;
00121 }
00122
00123 Model* box = new Model();
00124
00125 UInt16 startIndex = 0;
00126
00127 startIndex =
00128 box->AddVertex(Vector3f(x1, y2, z1), ycolor);
00129 box->AddVertex(Vector3f(x2, y2, z1), ycolor);
00130 box->AddVertex(Vector3f(x2, y2, z2), ycolor);
00131 box->AddVertex(Vector3f(x1, y2, z2), ycolor);
00132
00133 box->AddVertex(Vector3f(x1, y1, z1), ycolor);
00134 box->AddVertex(Vector3f(x2, y1, z1), ycolor);
00135 box->AddVertex(Vector3f(x2, y1, z2), ycolor);
00136 box->AddVertex(Vector3f(x1, y1, z2), ycolor);
00137
00138 box->AddVertex(Vector3f(x1, y1, z2), xcolor);
00139 box->AddVertex(Vector3f(x1, y1, z1), xcolor);
00140 box->AddVertex(Vector3f(x1, y2, z1), xcolor);
00141 box->AddVertex(Vector3f(x1, y2, z2), xcolor);
00142
00143 box->AddVertex(Vector3f(x2, y1, z2), xcolor);
00144 box->AddVertex(Vector3f(x2, y1, z1), xcolor);
00145 box->AddVertex(Vector3f(x2, y2, z1), xcolor);
00146 box->AddVertex(Vector3f(x2, y2, z2), xcolor);
00147
00148 box->AddVertex(Vector3f(x1, y1, z1), zcolor);
00149 box->AddVertex(Vector3f(x2, y1, z1), zcolor);
00150 box->AddVertex(Vector3f(x2, y2, z1), zcolor);
00151 box->AddVertex(Vector3f(x1, y2, z1), zcolor);
00152
00153 box->AddVertex(Vector3f(x1, y1, z2), zcolor);
00154 box->AddVertex(Vector3f(x2, y1, z2), zcolor);
00155 box->AddVertex(Vector3f(x2, y2, z2), zcolor);
00156 box->AddVertex(Vector3f(x1, y2, z2), zcolor);
00157
00158
00159 enum
00160 {
00161
00162 CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
00163 };
00164
00165
00166 for(int i = 0; i < CubeIndexCount / 3; i++)
00167 {
00168 box->AddTriangle(CubeIndices[i * 3] + startIndex,
00169 CubeIndices[i * 3 + 1] + startIndex,
00170 CubeIndices[i * 3 + 2] + startIndex);
00171 }
00172
00173 return box;
00174 }
00175
00176 void Model::AddSolidColorBox(float x1, float y1, float z1,
00177 float x2, float y2, float z2,
00178 Color c)
00179 {
00180 float t;
00181
00182 if(x1 > x2)
00183 {
00184 t = x1;
00185 x1 = x2;
00186 x2 = t;
00187 }
00188 if(y1 > y2)
00189 {
00190 t = y1;
00191 y1 = y2;
00192 y2 = t;
00193 }
00194 if(z1 > z2)
00195 {
00196 t = z1;
00197 z1 = z2;
00198 z2 = t;
00199 }
00200
00201
00202 Vector3f CubeVertices[][3] =
00203 {
00204 Vector3f(x1, y2, z1), Vector3f(z1, x1), Vector3f(0.0f, 1.0f, 0.0f),
00205 Vector3f(x2, y2, z1), Vector3f(z1, x2), Vector3f(0.0f, 1.0f, 0.0f),
00206 Vector3f(x2, y2, z2), Vector3f(z2, x2), Vector3f(0.0f, 1.0f, 0.0f),
00207 Vector3f(x1, y2, z2), Vector3f(z2, x1), Vector3f(0.0f, 1.0f, 0.0f),
00208
00209 Vector3f(x1, y1, z1), Vector3f(z1, x1), Vector3f(0.0f, -1.0f, 0.0f),
00210 Vector3f(x2, y1, z1), Vector3f(z1, x2), Vector3f(0.0f, -1.0f, 0.0f),
00211 Vector3f(x2, y1, z2), Vector3f(z2, x2), Vector3f(0.0f, -1.0f, 0.0f),
00212 Vector3f(x1, y1, z2), Vector3f(z2, x1), Vector3f(0.0f, -1.0f, 0.0f),
00213
00214 Vector3f(x1, y1, z2), Vector3f(z2, y1), Vector3f(-1.0f, 0.0f, 0.0f),
00215 Vector3f(x1, y1, z1), Vector3f(z1, y1), Vector3f(-1.0f, 0.0f, 0.0f),
00216 Vector3f(x1, y2, z1), Vector3f(z1, y2), Vector3f(-1.0f, 0.0f, 0.0f),
00217 Vector3f(x1, y2, z2), Vector3f(z2, y2), Vector3f(-1.0f, 0.0f, 0.0f),
00218
00219 Vector3f(x2, y1, z2), Vector3f(z2, y1), Vector3f(1.0f, 0.0f, 0.0f),
00220 Vector3f(x2, y1, z1), Vector3f(z1, y1), Vector3f(1.0f, 0.0f, 0.0f),
00221 Vector3f(x2, y2, z1), Vector3f(z1, y2), Vector3f(1.0f, 0.0f, 0.0f),
00222 Vector3f(x2, y2, z2), Vector3f(z2, y2), Vector3f(1.0f, 0.0f, 0.0f),
00223
00224 Vector3f(x1, y1, z1), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, -1.0f),
00225 Vector3f(x2, y1, z1), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, -1.0f),
00226 Vector3f(x2, y2, z1), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, -1.0f),
00227 Vector3f(x1, y2, z1), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, -1.0f),
00228
00229 Vector3f(x1, y1, z2), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, 1.0f),
00230 Vector3f(x2, y1, z2), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, 1.0f),
00231 Vector3f(x2, y2, z2), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, 1.0f),
00232 Vector3f(x1, y2, z2), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, 1.0f)
00233 };
00234
00235
00236 UInt16 startIndex = GetNextVertexIndex();
00237
00238 enum
00239 {
00240 CubeVertexCount = sizeof(CubeVertices) / sizeof(CubeVertices[0]),
00241 CubeIndexCount = sizeof(CubeIndices) / sizeof(CubeIndices[0])
00242 };
00243
00244 for(int v = 0; v < CubeVertexCount; v++)
00245 {
00246 AddVertex(Vertex(CubeVertices[v][0], c, CubeVertices[v][1].x, CubeVertices[v][1].y, CubeVertices[v][2]));
00247 }
00248
00249
00250 for(int i = 0; i < CubeIndexCount / 3; i++)
00251 {
00252 AddTriangle(CubeIndices[i * 3] + startIndex,
00253 CubeIndices[i * 3 + 1] + startIndex,
00254 CubeIndices[i * 3 + 2] + startIndex);
00255 }
00256 }
00257
00258
00259
00260 Model* Model::CreateBox(Color c, Vector3f origin, Vector3f size)
00261 {
00262 Model *box = new Model();
00263 Vector3f s = size * 0.5f;
00264
00265 box->AddVertex(-s.x, s.y, -s.z, c, 0, 1, 0, 0, -1);
00266 box->AddVertex(s.x, s.y, -s.z, c, 1, 1, 0, 0, -1);
00267 box->AddVertex(s.x, -s.y, -s.z, c, 1, 0, 0, 0, -1);
00268 box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, 0, 0, -1);
00269 box->AddTriangle(2, 1, 0);
00270 box->AddTriangle(0, 3, 2);
00271
00272 box->AddVertex(s.x, s.y, s.z, c, 1, 1, 0, 0, 1);
00273 box->AddVertex(-s.x, s.y, s.z, c, 0, 1, 0, 0, 1);
00274 box->AddVertex(-s.x, -s.y, s.z, c, 0, 0, 0, 0, 1);
00275 box->AddVertex(s.x, -s.y, s.z, c, 1, 0, 0, 0, 1);
00276 box->AddTriangle(6, 5, 4);
00277 box->AddTriangle(4, 7, 6);
00278
00279 box->AddVertex(-s.x, s.y, -s.z, c, 1, 0, -1, 0, 0);
00280 box->AddVertex(-s.x, s.y, s.z, c, 1, 1, -1, 0, 0);
00281 box->AddVertex(-s.x, -s.y, s.z, c, 0, 1, -1, 0, 0);
00282 box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, -1, 0, 0);
00283 box->AddTriangle(10, 11, 8);
00284 box->AddTriangle(8, 9, 10);
00285
00286 box->AddVertex(s.x, s.y, -s.z, c, 1, 0, 1, 0, 0);
00287 box->AddVertex(s.x, -s.y, -s.z, c, 0, 0, 1, 0, 0);
00288 box->AddVertex(s.x, -s.y, s.z, c, 0, 1, 1, 0, 0);
00289 box->AddVertex(s.x, s.y, s.z, c, 1, 1, 1, 0, 0);
00290 box->AddTriangle(14, 15, 12);
00291 box->AddTriangle(12, 13, 14);
00292
00293 box->AddVertex(-s.x, -s.y, s.z, c, 0, 1, 0, -1, 0);
00294 box->AddVertex(s.x, -s.y, s.z, c, 1, 1, 0, -1, 0);
00295 box->AddVertex(s.x, -s.y, -s.z, c, 1, 0, 0, -1, 0);
00296 box->AddVertex(-s.x, -s.y, -s.z, c, 0, 0, 0, -1, 0);
00297 box->AddTriangle(18, 19, 16);
00298 box->AddTriangle(16, 17, 18);
00299
00300 box->AddVertex(-s.x, s.y, -s.z, c, 0, 0, 0, 1, 0);
00301 box->AddVertex(s.x, s.y, -s.z, c, 1, 0, 0, 1, 0);
00302 box->AddVertex(s.x, s.y, s.z, c, 1, 1, 0, 1, 0);
00303 box->AddVertex(-s.x, s.y, s.z, c, 0, 1, 0, 1, 0);
00304 box->AddTriangle(20, 21, 22);
00305 box->AddTriangle(22, 23, 20);
00306
00307 box->SetPosition(origin);
00308 return box;
00309 }
00310
00311
00312 Model* Model::CreateCylinder(Color color, Vector3f origin, float height, float radius, int sides)
00313 {
00314 Model *cyl = new Model();
00315 float halfht = height * 0.5f;
00316 for(UInt16 i = 0; i < sides; i++)
00317 {
00318 float x = cosf(Math<float>::TwoPi * i / float(sides));
00319 float y = sinf(Math<float>::TwoPi * i / float(sides));
00320
00321 cyl->AddVertex(radius * x, radius * y, halfht, color, x + 1, y, 0, 0, 1);
00322 cyl->AddVertex(radius * x, radius * y, -1.0f*halfht, color, x, y, 0, 0, -1);
00323
00324 UInt16 j = 0;
00325 if(i < sides - 1)
00326 {
00327 j = i + 1;
00328 cyl->AddTriangle(0, i * 4 + 4, i * 4);
00329 cyl->AddTriangle(1, i * 4 + 1, i * 4 + 5);
00330 }
00331
00332 float nx = cosf(Math<float>::Pi * (0.5f + 2.0f * i / float(sides)));
00333 float ny = sinf(Math<float>::Pi * (0.5f + 2.0f * i / float(sides)));
00334 cyl->AddVertex(radius * x, radius * y, halfht, color, x + 1, y, nx, ny, 0);
00335 cyl->AddVertex(radius * x, radius * y, -1.0f*halfht, color, x, y, nx, ny, 0);
00336
00337 cyl->AddTriangle(i * 4 + 2, j * 4 + 2, i * 4 + 3);
00338 cyl->AddTriangle(i * 4 + 3, j * 4 + 2, j * 4 + 3);
00339 }
00340 cyl->SetPosition(origin);
00341 return cyl;
00342 };
00343
00344
00345 Model* Model::CreateCone(Color color, Vector3f origin, float height, float radius, int sides)
00346 {
00347 Model *cone = new Model();
00348 float halfht = height * 0.5f;
00349 cone->AddVertex(0.0f, 0.0f, -1.0f*halfht, color, 0, 0, 0, 0, -1);
00350
00351 for(UInt16 i = 0; i < sides; i++)
00352 {
00353 float x = cosf(Math<float>::TwoPi * i / float(sides));
00354 float y = sinf(Math<float>::TwoPi * i / float(sides));
00355
00356 cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, 0, 0, -1);
00357
00358 UInt16 j = 1;
00359 if(i < sides - 1)
00360 {
00361 j = i + 1;
00362 }
00363
00364 float next_x = cosf(Math<float>::TwoPi * j / float(sides));
00365 float next_y = sinf(Math<float>::TwoPi * j / float(sides));
00366
00367 Vector3f normal = Vector3f(x, y, -halfht).Cross(Vector3f(next_x, next_y, -halfht));
00368
00369 cone->AddVertex(0.0f, 0.0f, halfht, color, 1, 0, normal.x, normal.y, normal.z);
00370 cone->AddVertex(radius * x, radius * y, -1.0f*halfht, color, 0, 0, normal.x, normal.y, normal.z);
00371
00372 cone->AddTriangle(0, 3*i + 1, 3*j + 1);
00373 cone->AddTriangle(3*i + 2, 3*j + 3, 3*i + 3);
00374 }
00375 cone->SetPosition(origin);
00376 return cone;
00377 };
00378
00379
00380 Model* Model::CreateSphere(Color color, Vector3f origin, float radius, int sides)
00381 {
00382 Model *sphere = new Model();
00383 UInt16 usides = (UInt16) sides;
00384 UInt16 halfsides = usides/2;
00385
00386 for(UInt16 k = 0; k < halfsides; k++) {
00387
00388 float z = cosf(Math<float>::Pi * k / float(halfsides));
00389 float z_r = sinf(Math<float>::Pi * k / float(halfsides));
00390
00391 if (k == 0)
00392 {
00393 sphere->AddVertex(0.0f, 0.0f, radius, color, 0, 0, 0, 0, 1);
00394 sphere->AddVertex(0.0f, 0.0f, -radius, color, 1, 1, 0, 0, -1);
00395 }
00396 else
00397 {
00398 for(UInt16 i = 0; i < sides; i++)
00399 {
00400 float x = cosf(Math<float>::TwoPi * i / float(sides)) * z_r;
00401 float y = sinf(Math<float>::TwoPi * i / float(sides)) * z_r;
00402
00403 UInt16 j = 0;
00404 if(i < sides - 1)
00405 {
00406 j = i + 1;
00407 }
00408
00409 sphere->AddVertex(radius * x, radius * y, radius * z, color, 0, 1, x, y, z);
00410
00411 UInt16 indi = 2 + (k -1)*usides + i;
00412 UInt16 indj = 2 + (k -1)*usides + j;
00413 if (k == 1)
00414 sphere->AddTriangle(0, j + 2, i + 2);
00415 else if (k == halfsides - 1)
00416 {
00417 sphere->AddTriangle(1, indi, indj);
00418 sphere->AddTriangle(indi, indi - usides, indj);
00419 sphere->AddTriangle(indi - usides, indj - usides, indj);
00420 }
00421 else
00422 {
00423 sphere->AddTriangle(indi, indi - usides, indj);
00424 sphere->AddTriangle(indi - usides, indj - usides, indj);
00425 }
00426 }
00427 }
00428 }
00429 sphere->SetPosition(origin);
00430 return sphere;
00431 };
00432
00433 Model* Model::CreateGrid(Vector3f origin, Vector3f stepx, Vector3f stepy,
00434 int halfx, int halfy, int nmajor, Color minor, Color major)
00435 {
00436 Model* grid = new Model(Prim_Lines);
00437 float halfxf = (float)halfx;
00438 float halfyf = (float)halfy;
00439
00440 for(int jn = 0; jn <= halfy; jn++)
00441 {
00442 float j = (float)jn;
00443
00444 grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 0, 0.5f),
00445 grid->AddVertex((stepx * halfxf) + (stepy * j), (jn % nmajor) ? minor : major, 1, 0.5f));
00446
00447 if(j)
00448 grid->AddLine(grid->AddVertex((stepx * -halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 0, 0.5f),
00449 grid->AddVertex((stepx * halfxf) + (stepy * -j), (jn % nmajor) ? minor : major, 1, 0.5f));
00450 }
00451
00452 for(int in = 0; in <= halfx; in++)
00453 {
00454 float i = (float)in;
00455
00456 grid->AddLine(grid->AddVertex((stepx * i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
00457 grid->AddVertex((stepx * i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
00458
00459 if(i)
00460 grid->AddLine(grid->AddVertex((stepx * -i) + (stepy * -halfyf), (in % nmajor) ? minor : major, 0, 0.5f),
00461 grid->AddVertex((stepx * -i) + (stepy * halfyf), (in % nmajor) ? minor : major, 1, 0.5f));
00462 }
00463
00464 grid->SetPosition(origin);
00465 return grid;
00466 }
00467
00468
00469
00470
00471
00472 void ShaderFill::Set(PrimitiveType prim) const
00473 {
00474 Shaders->Set(prim);
00475 for(int i = 0; i < 8; i++)
00476 if(Textures[i])
00477 {
00478 Textures[i]->Set(i);
00479 }
00480 }
00481
00482
00483
00484
00485
00486
00487
00488 RenderDevice::RenderDevice()
00489 : CurPostProcess(PostProcess_None),
00490 SceneColorTexW(0), SceneColorTexH(0),
00491 SceneRenderScale(1),
00492
00493 Distortion(1.0f, 0.18f, 0.115f),
00494 DistortionClearColor(0, 0, 0),
00495 PostProcessShaderActive(PostProcessShader_DistortionAndChromAb),
00496 TotalTextureMemoryUsage(0)
00497 {
00498 PostProcessShaderRequested = PostProcessShaderActive;
00499 }
00500
00501 Fill* RenderDevice::CreateTextureFill(Render::Texture* t, bool useAlpha)
00502 {
00503 ShaderSet* shaders = CreateShaderSet();
00504 shaders->SetShader(LoadBuiltinShader(Shader_Vertex, VShader_MVP));
00505 shaders->SetShader(LoadBuiltinShader(Shader_Fragment, useAlpha ? FShader_AlphaTexture : FShader_Texture));
00506 Fill* f = new ShaderFill(*shaders);
00507 f->SetTexture(0, t);
00508 return f;
00509 }
00510
00511 void LightingParams::Set(ShaderSet* s) const
00512 {
00513 s->SetUniform4fv("Ambient", 1, &Ambient);
00514 s->SetUniform1f("LightCount", LightCount);
00515 s->SetUniform4fv("LightPos", (int)LightCount, LightPos);
00516 s->SetUniform4fv("LightColor", (int)LightCount, LightColor);
00517 }
00518
00519 void RenderDevice::SetLighting(const LightingParams* lt)
00520 {
00521 if (!LightingBuffer)
00522 LightingBuffer = *CreateBuffer();
00523
00524 LightingBuffer->Data(Buffer_Uniform, lt, sizeof(LightingParams));
00525 SetCommonUniformBuffer(1, LightingBuffer);
00526 }
00527
00528 float RenderDevice::MeasureText(const Font* font, const char* str, float size, float* strsize)
00529 {
00530 UPInt length = strlen(str);
00531 float w = 0;
00532 float xp = 0;
00533 float yp = 0;
00534
00535 for (UPInt i = 0; i < length; i++)
00536 {
00537 if(str[i] == '\n')
00538 {
00539 yp += font->lineheight;
00540 if(xp > w)
00541 {
00542 w = xp;
00543 }
00544 xp = 0;
00545 continue;
00546 }
00547
00548
00549 if(str[i] == '\t')
00550 {
00551 char *p = 0;
00552 float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
00553 i += p - (str + i + 1);
00554 xp = tabPixels;
00555 }
00556 else
00557 {
00558 const Font::Char* ch = &font->chars[str[i]];
00559 xp += ch->advance;
00560 }
00561 }
00562
00563 if(xp > w)
00564 {
00565 w = xp;
00566 }
00567
00568 if(strsize)
00569 {
00570 strsize[0] = (size / font->lineheight) * w;
00571 strsize[1] = (size / font->lineheight) * (yp + font->lineheight);
00572 }
00573 return (size / font->lineheight) * w;
00574 }
00575
00576 void RenderDevice::RenderText(const Font* font, const char* str,
00577 float x, float y, float size, Color c)
00578 {
00579 if(!pTextVertexBuffer)
00580 {
00581 pTextVertexBuffer = *CreateBuffer();
00582 if(!pTextVertexBuffer)
00583 {
00584 return;
00585 }
00586 }
00587
00588 if(!font->fill)
00589 {
00590 font->fill = CreateTextureFill(Ptr<Texture>(
00591 *CreateTexture(Texture_R, font->twidth, font->theight, font->tex)), true);
00592 }
00593
00594 UPInt length = strlen(str);
00595
00596 pTextVertexBuffer->Data(Buffer_Vertex, NULL, length * 6 * sizeof(Vertex));
00597 Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, length * 6 * sizeof(Vertex), Map_Discard);
00598 if(!vertices)
00599 {
00600 return;
00601 }
00602
00603 Matrix4f m = Matrix4f(size / font->lineheight, 0, 0, 0,
00604 0, size / font->lineheight, 0, 0,
00605 0, 0, 0, 0,
00606 x, y, 0, 1).Transposed();
00607
00608 float xp = 0, yp = (float)font->ascent;
00609 int ivertex = 0;
00610
00611 for (UPInt i = 0; i < length; i++)
00612 {
00613 if(str[i] == '\n')
00614 {
00615 yp += font->lineheight;
00616 xp = 0;
00617 continue;
00618 }
00619
00620 if(str[i] == '\t')
00621 {
00622 char *p = 0;
00623 float tabPixels = (float)OVR_strtoq(str + i + 1, &p, 10);
00624 i += p - (str + i + 1);
00625 xp = tabPixels;
00626 continue;
00627 }
00628
00629 const Font::Char* ch = &font->chars[str[i]];
00630 Vertex* chv = &vertices[ivertex];
00631 for(int j = 0; j < 6; j++)
00632 {
00633 chv[j].C = c;
00634 }
00635 float x = xp + ch->x;
00636 float y = yp - ch->y;
00637 float cx = font->twidth * (ch->u2 - ch->u1);
00638 float cy = font->theight * (ch->v2 - ch->v1);
00639 chv[0] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
00640 chv[1] = Vertex(Vector3f(x + cx, y, 0), c, ch->u2, ch->v1);
00641 chv[2] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
00642 chv[3] = Vertex(Vector3f(x, y, 0), c, ch->u1, ch->v1);
00643 chv[4] = Vertex(Vector3f(x + cx, cy + y, 0), c, ch->u2, ch->v2);
00644 chv[5] = Vertex(Vector3f(x, y + cy, 0), c, ch->u1, ch->v2);
00645 ivertex += 6;
00646
00647 xp += ch->advance;
00648 }
00649
00650 pTextVertexBuffer->Unmap(vertices);
00651
00652 Render(font->fill, pTextVertexBuffer, NULL, m, 0, ivertex, Prim_Triangles);
00653 }
00654
00655 void RenderDevice::FillRect(float left, float top, float right, float bottom, Color c)
00656 {
00657 if(!pTextVertexBuffer)
00658 {
00659 pTextVertexBuffer = *CreateBuffer();
00660 if(!pTextVertexBuffer)
00661 {
00662 return;
00663 }
00664 }
00665
00666
00667 Fill* fill = CreateSimpleFill();
00668
00669 pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
00670 Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
00671 if(!vertices)
00672 {
00673 return;
00674 }
00675
00676 vertices[0] = Vertex(Vector3f(left, top, 0.0f), c);
00677 vertices[1] = Vertex(Vector3f(right, top, 0), c);
00678 vertices[2] = Vertex(Vector3f(left, bottom, 0), c);
00679 vertices[3] = Vertex(Vector3f(left, bottom, 0), c);
00680 vertices[4] = Vertex(Vector3f(right, top, 0), c);
00681 vertices[5] = Vertex(Vector3f(right, bottom, 0), c);
00682
00683 pTextVertexBuffer->Unmap(vertices);
00684
00685 Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
00686 }
00687
00688 void RenderDevice::FillGradientRect(float left, float top, float right, float bottom, Color col_top, Color col_btm)
00689 {
00690 if(!pTextVertexBuffer)
00691 {
00692 pTextVertexBuffer = *CreateBuffer();
00693 if(!pTextVertexBuffer)
00694 {
00695 return;
00696 }
00697 }
00698
00699
00700 Fill* fill = CreateSimpleFill();
00701
00702 pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
00703 Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
00704 if(!vertices)
00705 {
00706 return;
00707 }
00708
00709 vertices[0] = Vertex(Vector3f(left, top, 0.0f), col_top);
00710 vertices[1] = Vertex(Vector3f(right, top, 0), col_top);
00711 vertices[2] = Vertex(Vector3f(left, bottom, 0), col_btm);
00712 vertices[3] = Vertex(Vector3f(left, bottom, 0), col_btm);
00713 vertices[4] = Vertex(Vector3f(right, top, 0), col_top);
00714 vertices[5] = Vertex(Vector3f(right, bottom, 0), col_btm);
00715
00716 pTextVertexBuffer->Unmap(vertices);
00717
00718 Render(fill, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
00719 }
00720
00721 void RenderDevice::RenderImage(float left,
00722 float top,
00723 float right,
00724 float bottom,
00725 ShaderFill* image,
00726 unsigned char alpha)
00727 {
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757 Color c = Color(255, 255, 255, alpha);
00758 Ptr<Model> m = *new Model(Prim_Triangles);
00759 m->AddVertex(left, bottom, 0.0f, c, 0.0f, 0.0f);
00760 m->AddVertex(right, bottom, 0.0f, c, 1.0f, 0.0f);
00761 m->AddVertex(right, top, 0.0f, c, 1.0f, 1.0f);
00762 m->AddVertex(left, top, 0.0f, c, 0.0f, 1.0f);
00763 m->AddTriangle(2,1,0);
00764 m->AddTriangle(0,3,2);
00765 m->Fill = image;
00766
00767 Render(Matrix4f(), m);
00768 }
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782 void RenderDevice::SetSceneRenderScale(float ss)
00783 {
00784 SceneRenderScale = ss;
00785 pSceneColorTex = NULL;
00786 }
00787
00788 void RenderDevice::SetViewport(const Viewport& vp)
00789 {
00790 VP = vp;
00791
00792 if(CurPostProcess == PostProcess_Distortion)
00793 {
00794 Viewport svp = vp;
00795 svp.w = (int)ceil(SceneRenderScale * vp.w);
00796 svp.h = (int)ceil(SceneRenderScale * vp.h);
00797 svp.x = (int)ceil(SceneRenderScale * vp.x);
00798 svp.y = (int)ceil(SceneRenderScale * vp.y);
00799 SetRealViewport(svp);
00800 }
00801 else
00802 {
00803 SetRealViewport(vp);
00804 }
00805 }
00806
00807
00808 bool RenderDevice::initPostProcessSupport(PostProcessType pptype)
00809 {
00810 if(pptype != PostProcess_Distortion)
00811 {
00812 return true;
00813 }
00814
00815
00816 if (PostProcessShaderRequested != PostProcessShaderActive)
00817 {
00818 pPostProcessShader.Clear();
00819 PostProcessShaderActive = PostProcessShaderRequested;
00820 }
00821
00822 if (!pPostProcessShader)
00823 {
00824 Shader *vs = LoadBuiltinShader(Shader_Vertex, VShader_PostProcess);
00825
00826 Shader *ppfs = NULL;
00827
00828 if (PostProcessShaderActive == PostProcessShader_Distortion)
00829 {
00830 ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcess);
00831 }
00832 else if (PostProcessShaderActive == PostProcessShader_DistortionAndChromAb)
00833 {
00834 ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessWithChromAb);
00835 }
00836 else
00837 OVR_ASSERT(false);
00838
00839 pPostProcessShader = *CreateShaderSet();
00840 pPostProcessShader->SetShader(vs);
00841 pPostProcessShader->SetShader(ppfs);
00842 }
00843
00844
00845 int texw = (int)ceil(SceneRenderScale * WindowWidth),
00846 texh = (int)ceil(SceneRenderScale * WindowHeight);
00847
00848
00849
00850 if (pSceneColorTex && (texw == SceneColorTexW) && (texh == SceneColorTexH))
00851 {
00852 return true;
00853 }
00854
00855 pSceneColorTex = *CreateTexture(Texture_RGBA | Texture_RenderTarget | Params.Multisample,
00856 texw, texh, NULL);
00857 if(!pSceneColorTex)
00858 {
00859 return false;
00860 }
00861 SceneColorTexW = texw;
00862 SceneColorTexH = texh;
00863 pSceneColorTex->SetSampleMode(Sample_ClampBorder | Sample_Linear);
00864
00865
00866 if(!pFullScreenVertexBuffer)
00867 {
00868 pFullScreenVertexBuffer = *CreateBuffer();
00869 const Render::Vertex QuadVertices[] =
00870 {
00871 Vertex(Vector3f(0, 1, 0), Color(1, 1, 1, 1), 0, 0),
00872 Vertex(Vector3f(1, 1, 0), Color(1, 1, 1, 1), 1, 0),
00873 Vertex(Vector3f(0, 0, 0), Color(1, 1, 1, 1), 0, 1),
00874 Vertex(Vector3f(1, 0, 0), Color(1, 1, 1, 1), 1, 1)
00875 };
00876 pFullScreenVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices));
00877 }
00878 return true;
00879 }
00880
00881 void RenderDevice::SetProjection(const Matrix4f& proj)
00882 {
00883 Proj = proj;
00884 SetWorldUniforms(proj);
00885 }
00886
00887 void RenderDevice::BeginScene(PostProcessType pptype)
00888 {
00889 BeginRendering();
00890
00891 if((pptype != PostProcess_None) && initPostProcessSupport(pptype))
00892 {
00893 CurPostProcess = pptype;
00894 }
00895 else
00896 {
00897 CurPostProcess = PostProcess_None;
00898 }
00899
00900 if(CurPostProcess == PostProcess_Distortion)
00901 {
00902 SetRenderTarget(pSceneColorTex);
00903 SetViewport(VP);
00904 }
00905 else
00906 {
00907 SetRenderTarget(0);
00908 }
00909
00910 SetWorldUniforms(Proj);
00911 SetExtraShaders(NULL);
00912 }
00913
00914 void RenderDevice::FinishScene()
00915 {
00916 SetExtraShaders(0);
00917 if(CurPostProcess == PostProcess_None)
00918 {
00919 return;
00920 }
00921
00922 SetRenderTarget(0);
00923 SetRealViewport(VP);
00924 FinishScene1();
00925
00926 CurPostProcess = PostProcess_None;
00927 }
00928
00929
00930
00931 void RenderDevice::FinishScene1()
00932 {
00933 float r, g, b, a;
00934 DistortionClearColor.GetRGBA(&r, &g, &b, &a);
00935 Clear(r, g, b, a);
00936
00937 float w = float(VP.w) / float(WindowWidth),
00938 h = float(VP.h) / float(WindowHeight),
00939 x = float(VP.x) / float(WindowWidth),
00940 y = float(VP.y) / float(WindowHeight);
00941
00942 float as = float(VP.w) / float(VP.h);
00943
00944
00945
00946 pPostProcessShader->SetUniform2f("LensCenter",
00947 x + (w + Distortion.XCenterOffset * 0.5f)*0.5f, y + h*0.5f);
00948 pPostProcessShader->SetUniform2f("ScreenCenter", x + w*0.5f, y + h*0.5f);
00949
00950
00951
00952 float scaleFactor = 1.0f / Distortion.Scale;
00953
00954 pPostProcessShader->SetUniform2f("Scale", (w/2) * scaleFactor, (h/2) * scaleFactor * as);
00955 pPostProcessShader->SetUniform2f("ScaleIn", (2/w), (2/h) / as);
00956
00957 pPostProcessShader->SetUniform4f("HmdWarpParam",
00958 Distortion.K[0], Distortion.K[1], Distortion.K[2], Distortion.K[3]);
00959
00960 if (PostProcessShaderRequested == PostProcessShader_DistortionAndChromAb)
00961 {
00962 pPostProcessShader->SetUniform4f("ChromAbParam",
00963 Distortion.ChromaticAberration[0],
00964 Distortion.ChromaticAberration[1],
00965 Distortion.ChromaticAberration[2],
00966 Distortion.ChromaticAberration[3]);
00967 }
00968
00969 Matrix4f texm(w, 0, 0, x,
00970 0, h, 0, y,
00971 0, 0, 0, 0,
00972 0, 0, 0, 1);
00973 pPostProcessShader->SetUniform4x4f("Texm", texm);
00974
00975 Matrix4f view(2, 0, 0, -1,
00976 0, 2, 0, -1,
00977 0, 0, 0, 0,
00978 0, 0, 0, 1);
00979
00980 ShaderFill fill(pPostProcessShader);
00981 fill.SetTexture(0, pSceneColorTex);
00982 RenderWithAlpha(&fill, pFullScreenVertexBuffer, NULL, view, 0, 4, Prim_TriangleStrip);
00983 }
00984
00985 bool CollisionModel::TestPoint(const Vector3f& p) const
00986 {
00987 for(unsigned i = 0; i < Planes.GetSize(); i++)
00988 if(Planes[i].TestSide(p) > 0)
00989 {
00990 return 0;
00991 }
00992
00993 return 1;
00994 }
00995
00996 bool CollisionModel::TestRay(const Vector3f& origin, const Vector3f& norm, float& len, Planef* ph) const
00997 {
00998 if(TestPoint(origin))
00999 {
01000 len = 0;
01001 *ph = Planes[0];
01002 return true;
01003 }
01004 Vector3f fullMove = origin + norm * len;
01005
01006 int crossing = -1;
01007 float cdot1 = 0, cdot2 = 0;
01008
01009 for(unsigned i = 0; i < Planes.GetSize(); ++i)
01010 {
01011 float dot2 = Planes[i].TestSide(fullMove);
01012 if(dot2 > 0)
01013 {
01014 return false;
01015 }
01016 float dot1 = Planes[i].TestSide(origin);
01017 if(dot1 > 0)
01018 {
01019 if(dot2 <= 0)
01020 {
01021
01022 if(crossing == -1)
01023 {
01024 crossing = i;
01025 cdot2 = dot2;
01026 cdot1 = dot1;
01027 }
01028 else
01029 {
01030 if(dot2 > cdot2)
01031 {
01032 crossing = i;
01033 cdot2 = dot2;
01034 cdot1 = dot1;
01035 }
01036 }
01037 }
01038 }
01039 }
01040
01041 if(crossing < 0)
01042 {
01043 return false;
01044 }
01045
01046 assert(TestPoint(origin + norm * len));
01047
01048 len = len * cdot1 / (cdot1 - cdot2) - 0.05f;
01049 if(len < 0)
01050 {
01051 len = 0;
01052 }
01053 float tp = Planes[crossing].TestSide(origin + norm * len);
01054 OVR_ASSERT(fabsf(tp) < 0.05f + Mathf::Tolerance);
01055 OVR_UNUSED(tp);
01056
01057 if(ph)
01058 {
01059 *ph = Planes[crossing];
01060 }
01061 return true;
01062 }
01063
01064 int GetNumMipLevels(int w, int h)
01065 {
01066 int n = 1;
01067 while(w > 1 || h > 1)
01068 {
01069 w >>= 1;
01070 h >>= 1;
01071 n++;
01072 }
01073 return n;
01074 }
01075
01076 void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest)
01077 {
01078 for(int j = 0; j < (h & ~1); j += 2)
01079 {
01080 const UByte* psrc = src + (w * j * 4);
01081 UByte* pdest = dest + ((w >> 1) * (j >> 1) * 4);
01082
01083 for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4)
01084 {
01085 pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2;
01086 pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2;
01087 pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2;
01088 pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2;
01089 }
01090 }
01091 }
01092
01093 int GetTextureSize(int format, int w, int h)
01094 {
01095 switch (format & Texture_TypeMask)
01096 {
01097 case Texture_R: return w*h;
01098 case Texture_RGBA: return w*h*4;
01099 case Texture_DXT1: {
01100 int bw = (w+3)/4, bh = (h+3)/4;
01101 return bw * bh * 8;
01102 }
01103 case Texture_DXT3:
01104 case Texture_DXT5: {
01105 int bw = (w+3)/4, bh = (h+3)/4;
01106 return bw * bh * 16;
01107 }
01108
01109 default:
01110 OVR_ASSERT(0);
01111 }
01112 return 0;
01113 }
01114
01115 }}