Render_Device.cpp
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 Filename    :   Render_Device.cpp
00004 Content     :   Platform renderer for simple scene graph - implementation
00005 Created     :   September 6, 2012
00006 Authors     :   Andrew Reisse
00007 
00008 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
00009 
00010 Licensed under the Apache License, Version 2.0 (the "License");
00011 you may not use this file except in compliance with the License.
00012 You may obtain a copy of the License at
00013 
00014 http://www.apache.org/licenses/LICENSE-2.0
00015 
00016 Unless required by applicable law or agreed to in writing, software
00017 distributed under the License is distributed on an "AS IS" BASIS,
00018 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00019 See the License for the specific language governing permissions and
00020 limitations under the License.
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 // Colors are specified for planes perpendicular to the axis
00097 // For example, "xColor" is the color of the y-z plane
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     // Cube
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         //  CubeVertexCount = sizeof(CubeVertices)/sizeof(CubeVertices[0]),
00162         CubeIndexCount  = sizeof(CubeIndices) / sizeof(CubeIndices[0])
00163     };
00164 
00165     // Renumber indices
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     // Cube vertices and their normals.
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     // Renumber indices
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 // Triangulation of a cylinder centered at the origin
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 //Triangulation of a cone centered at the origin
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 //Triangulation of a sphere centered at the origin
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)); // the radius of the cross circle with coordinate z
00390 
00391         if (k == 0)  
00392         {       // add north and south poles
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) // NorthPole
00414                     sphere->AddTriangle(0, j + 2, i + 2);
00415                 else if (k == halfsides - 1)  //SouthPole
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         } // end else
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 // ***** Rendering
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         // Tab followed by a numbers sets position to specified offset.
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         // Tab followed by a numbers sets position to specified offset.
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     // Get!!
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     // Get!!
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     if(!pTextVertexBuffer)
00730     {
00731         pTextVertexBuffer = *CreateBuffer();
00732         if(!pTextVertexBuffer)
00733         {
00734             return;
00735         }
00736     }
00737 
00738     pTextVertexBuffer->Data(Buffer_Vertex, NULL, 6 * sizeof(Vertex));
00739     Vertex* vertices = (Vertex*)pTextVertexBuffer->Map(0, 6 * sizeof(Vertex), Map_Discard);
00740     if(!vertices)
00741     {
00742         return;
00743     }
00744 
00745     vertices[0] = Vertex(Vector3f(left,  top, 0.0f), Color(255, 255, 255, 255));
00746     vertices[1] = Vertex(Vector3f(right, top, 0), Color(255, 255, 255, 255));
00747     vertices[2] = Vertex(Vector3f(left,  bottom, 0), Color(255, 255, 255, 255));
00748     vertices[3] = Vertex(Vector3f(left,  bottom, 0), Color(255, 255, 255, 255));
00749     vertices[4] = Vertex(Vector3f(right, top, 0), Color(255, 255, 255, 255));
00750     vertices[5] = Vertex(Vector3f(right, bottom, 0), Color(255, 255, 255, 255));
00751 
00752     pTextVertexBuffer->Unmap(vertices);
00753 
00754     Render(image, pTextVertexBuffer, NULL, Matrix4f(), 0, 6, Prim_Triangles);
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 void RenderDevice::GetStereoViewports(const Viewport& in, Viewport* out) const
00772 {
00773     out[0] = out[1] = in;
00774     if (StereoBufferMode == Stereo_SplitH)
00775     {
00776         out[0].w = out[1].w = in.w / 2;
00777         out[1].x += WindowWidth / 2;
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     // If pSceneColorTex is already created and is of correct size, we are done.
00849     // It's important to check width/height in case window size changed.
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     // We are using 1/4 of DistortionCenter offset value here, since it is
00945     // relative to [-1,1] range that gets mapped to [0, 0.5].
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     // MA: This is more correct but we would need higher-res texture vertically; we should adopt this
00951     // once we have asymmetric input texture scale.
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                 //assert(crossing==-1);
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 }}


oculus_sdk
Author(s):
autogenerated on Mon Oct 6 2014 03:01:19