RenderTiny_Device.cpp
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 Filename    :   RenderTiny_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 "RenderTiny_Device.h"
00025 
00026 #include "Kernel/OVR_Log.h"
00027 
00028 namespace OVR { namespace RenderTiny {
00029 
00030 void Model::Render(const Matrix4f& ltw, RenderDevice* ren)
00031 {
00032     if (Visible)
00033     {
00034         Matrix4f m = ltw * GetMatrix();
00035         ren->Render(m, this);
00036     }
00037 }
00038 
00039 void Container::Render(const Matrix4f& ltw, RenderDevice* ren)
00040 {
00041     Matrix4f m = ltw * GetMatrix();
00042     for(unsigned i = 0; i < Nodes.GetSize(); i++)
00043     {
00044         Nodes[i]->Render(m, ren);
00045     }
00046 }
00047 
00048 void Scene::Render(RenderDevice* ren, const Matrix4f& view)
00049 {
00050     Lighting.Update(view, LightPos);
00051 
00052     ren->SetLighting(&Lighting);
00053 
00054     World.Render(view, ren);
00055 }
00056 
00057 
00058 
00059 UInt16 CubeIndices[] =
00060 {
00061     0, 1, 3,
00062     3, 1, 2,
00063 
00064     5, 4, 6,
00065     6, 4, 7,
00066 
00067     8, 9, 11,
00068     11, 9, 10,
00069 
00070     13, 12, 14,
00071     14, 12, 15,
00072 
00073     16, 17, 19,
00074     19, 17, 18,
00075 
00076     21, 20, 22,
00077     22, 20, 23
00078 };
00079 
00080 
00081 void Model::AddSolidColorBox(float x1, float y1, float z1,
00082                              float x2, float y2, float z2,
00083                              Color c)
00084 {
00085     float t;
00086 
00087     if(x1 > x2)
00088     {
00089         t = x1;
00090         x1 = x2;
00091         x2 = t;
00092     }
00093     if(y1 > y2)
00094     {
00095         t = y1;
00096         y1 = y2;
00097         y2 = t;
00098     }
00099     if(z1 > z2)
00100     {
00101         t = z1;
00102         z1 = z2;
00103         z2 = t;
00104     }
00105 
00106     // Cube vertices and their normals.
00107     Vector3f CubeVertices[][3] =
00108     {
00109         Vector3f(x1, y2, z1), Vector3f(z1, x1), Vector3f(0.0f, 1.0f, 0.0f),
00110         Vector3f(x2, y2, z1), Vector3f(z1, x2), Vector3f(0.0f, 1.0f, 0.0f),
00111         Vector3f(x2, y2, z2), Vector3f(z2, x2), Vector3f(0.0f, 1.0f, 0.0f),
00112         Vector3f(x1, y2, z2), Vector3f(z2, x1), Vector3f(0.0f, 1.0f, 0.0f),
00113 
00114         Vector3f(x1, y1, z1), Vector3f(z1, x1), Vector3f(0.0f, -1.0f, 0.0f),
00115         Vector3f(x2, y1, z1), Vector3f(z1, x2), Vector3f(0.0f, -1.0f, 0.0f),
00116         Vector3f(x2, y1, z2), Vector3f(z2, x2), Vector3f(0.0f, -1.0f, 0.0f),
00117         Vector3f(x1, y1, z2), Vector3f(z2, x1), Vector3f(0.0f, -1.0f, 0.0f),
00118 
00119         Vector3f(x1, y1, z2), Vector3f(z2, y1), Vector3f(-1.0f, 0.0f, 0.0f),
00120         Vector3f(x1, y1, z1), Vector3f(z1, y1), Vector3f(-1.0f, 0.0f, 0.0f),
00121         Vector3f(x1, y2, z1), Vector3f(z1, y2), Vector3f(-1.0f, 0.0f, 0.0f),
00122         Vector3f(x1, y2, z2), Vector3f(z2, y2), Vector3f(-1.0f, 0.0f, 0.0f),
00123 
00124         Vector3f(x2, y1, z2), Vector3f(z2, y1), Vector3f(1.0f, 0.0f, 0.0f),
00125         Vector3f(x2, y1, z1), Vector3f(z1, y1), Vector3f(1.0f, 0.0f, 0.0f),
00126         Vector3f(x2, y2, z1), Vector3f(z1, y2), Vector3f(1.0f, 0.0f, 0.0f),
00127         Vector3f(x2, y2, z2), Vector3f(z2, y2), Vector3f(1.0f, 0.0f, 0.0f),
00128 
00129         Vector3f(x1, y1, z1), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, -1.0f),
00130         Vector3f(x2, y1, z1), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, -1.0f),
00131         Vector3f(x2, y2, z1), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, -1.0f),
00132         Vector3f(x1, y2, z1), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, -1.0f),
00133 
00134         Vector3f(x1, y1, z2), Vector3f(x1, y1), Vector3f(0.0f, 0.0f, 1.0f),
00135         Vector3f(x2, y1, z2), Vector3f(x2, y1), Vector3f(0.0f, 0.0f, 1.0f),
00136         Vector3f(x2, y2, z2), Vector3f(x2, y2), Vector3f(0.0f, 0.0f, 1.0f),
00137         Vector3f(x1, y2, z2), Vector3f(x1, y2), Vector3f(0.0f, 0.0f, 1.0f)
00138     };
00139 
00140 
00141     UInt16 startIndex = GetNextVertexIndex();
00142 
00143     enum
00144     {
00145         CubeVertexCount = sizeof(CubeVertices) / sizeof(CubeVertices[0]),
00146         CubeIndexCount  = sizeof(CubeIndices) / sizeof(CubeIndices[0])
00147     };
00148 
00149     for(int v = 0; v < CubeVertexCount; v++)
00150     {
00151         AddVertex(Vertex(CubeVertices[v][0], c, CubeVertices[v][1].x, CubeVertices[v][1].y, CubeVertices[v][2]));
00152     }
00153 
00154     // Renumber indices
00155     for(int i = 0; i < CubeIndexCount / 3; i++)
00156     {
00157         AddTriangle(CubeIndices[i * 3] + startIndex,
00158                     CubeIndices[i * 3 + 1] + startIndex,
00159                     CubeIndices[i * 3 + 2] + startIndex);
00160     }
00161 }
00162 
00163 
00164 //-------------------------------------------------------------------------------------
00165 
00166 
00167 void ShaderFill::Set(PrimitiveType prim) const
00168 {
00169     Shaders->Set(prim);
00170     for(int i = 0; i < 8; i++)
00171     {
00172         if(Textures[i])
00173         {
00174             Textures[i]->Set(i);
00175         }
00176     }
00177 }
00178 
00179 
00180 
00181 //-------------------------------------------------------------------------------------
00182 // ***** Rendering
00183 
00184 
00185 RenderDevice::RenderDevice()
00186     : CurPostProcess(PostProcess_None),
00187       SceneColorTexW(0), SceneColorTexH(0),
00188       SceneRenderScale(1),      
00189       Distortion(1.0f, 0.18f, 0.115f),
00190       PostProcessShaderActive(PostProcessShader_DistortionAndChromAb)
00191 {
00192     PostProcessShaderRequested = PostProcessShaderActive;
00193 }
00194 
00195 ShaderFill* RenderDevice::CreateTextureFill(RenderTiny::Texture* t)
00196 {
00197     ShaderSet* shaders = CreateShaderSet();
00198     shaders->SetShader(LoadBuiltinShader(Shader_Vertex, VShader_MVP));
00199     shaders->SetShader(LoadBuiltinShader(Shader_Fragment, FShader_Texture));
00200     ShaderFill* f = new ShaderFill(*shaders);
00201     f->SetTexture(0, t);
00202     return f;
00203 }
00204 
00205 void RenderDevice::SetLighting(const LightingParams* lt)
00206 {
00207     if (!LightingBuffer)
00208         LightingBuffer = *CreateBuffer();
00209 
00210     LightingBuffer->Data(Buffer_Uniform, lt, sizeof(LightingParams));
00211     SetCommonUniformBuffer(1, LightingBuffer);
00212 }
00213 
00214 
00215 
00216 void RenderDevice::SetSceneRenderScale(float ss)
00217 {
00218     SceneRenderScale = ss;
00219     pSceneColorTex = NULL;
00220 }
00221 
00222 void RenderDevice::SetViewport(const Viewport& vp)
00223 {
00224     VP = vp;
00225 
00226     if (CurPostProcess == PostProcess_Distortion)
00227     {
00228         Viewport svp = vp;
00229         svp.w = (int)ceil(SceneRenderScale * vp.w);
00230         svp.h = (int)ceil(SceneRenderScale * vp.h);
00231         svp.x = (int)ceil(SceneRenderScale * vp.x);
00232         svp.y = (int)ceil(SceneRenderScale * vp.y);
00233         SetRealViewport(svp);
00234     }
00235     else
00236     {
00237         SetRealViewport(vp);
00238     }
00239 }
00240 
00241 
00242 bool RenderDevice::initPostProcessSupport(PostProcessType pptype)
00243 {
00244     if (pptype != PostProcess_Distortion)
00245         return true;
00246 
00247 
00248     if (PostProcessShaderRequested !=  PostProcessShaderActive)
00249     {
00250         pPostProcessShader.Clear();
00251         PostProcessShaderActive = PostProcessShaderRequested;
00252     }
00253 
00254     if (!pPostProcessShader)
00255     {
00256         Shader *vs   = LoadBuiltinShader(Shader_Vertex, VShader_PostProcess);
00257 
00258         Shader *ppfs = NULL;
00259         if (PostProcessShaderActive == PostProcessShader_Distortion)
00260         {
00261             ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcess);
00262         }
00263         else if (PostProcessShaderActive == PostProcessShader_DistortionAndChromAb)
00264         {
00265             ppfs = LoadBuiltinShader(Shader_Fragment, FShader_PostProcessWithChromAb);
00266         }
00267         else
00268             OVR_ASSERT(false);
00269     
00270         pPostProcessShader = *CreateShaderSet();
00271         pPostProcessShader->SetShader(vs);
00272         pPostProcessShader->SetShader(ppfs);
00273     }
00274 
00275 
00276     int texw = (int)ceil(SceneRenderScale * WindowWidth),
00277         texh = (int)ceil(SceneRenderScale * WindowHeight);
00278 
00279     // If pSceneColorTex is already created and is of correct size, we are done.
00280     // It's important to check width/height in case window size changed.
00281     if (pSceneColorTex && (texw == SceneColorTexW) && (texh == SceneColorTexH))
00282     {
00283         return true;
00284     }
00285 
00286     pSceneColorTex = *CreateTexture(Texture_RGBA | Texture_RenderTarget | Params.Multisample,
00287                                     texw, texh, NULL);
00288     if (!pSceneColorTex)
00289     {
00290         return false;
00291     }
00292     SceneColorTexW = texw;
00293     SceneColorTexH = texh;
00294     pSceneColorTex->SetSampleMode(Sample_ClampBorder | Sample_Linear);
00295 
00296 
00297     if (!pFullScreenVertexBuffer)
00298     {
00299         pFullScreenVertexBuffer = *CreateBuffer();
00300         const RenderTiny::Vertex QuadVertices[] =
00301         {
00302             Vertex(Vector3f(0, 1, 0), Color(1, 1, 1, 1), 0, 0),
00303             Vertex(Vector3f(1, 1, 0), Color(1, 1, 1, 1), 1, 0),
00304             Vertex(Vector3f(0, 0, 0), Color(1, 1, 1, 1), 0, 1),
00305             Vertex(Vector3f(1, 0, 0), Color(1, 1, 1, 1), 1, 1)
00306         };
00307         pFullScreenVertexBuffer->Data(Buffer_Vertex, QuadVertices, sizeof(QuadVertices));
00308     }
00309     return true;
00310 }
00311 
00312 void RenderDevice::SetProjection(const Matrix4f& proj)
00313 {
00314     Proj = proj;
00315     SetWorldUniforms(proj);
00316 }
00317 
00318 void RenderDevice::BeginScene(PostProcessType pptype)
00319 {
00320     BeginRendering();
00321 
00322     if ((pptype != PostProcess_None) && initPostProcessSupport(pptype))
00323     {
00324         CurPostProcess = pptype;
00325     }
00326     else
00327     {
00328         CurPostProcess = PostProcess_None;
00329     }
00330 
00331     if (CurPostProcess == PostProcess_Distortion)
00332     {
00333         SetRenderTarget(pSceneColorTex);
00334         SetViewport(VP);
00335     }
00336     else
00337     {
00338         SetRenderTarget(0);
00339     }
00340 
00341     SetWorldUniforms(Proj);    
00342 }
00343 
00344 void RenderDevice::FinishScene()
00345 {    
00346     if (CurPostProcess == PostProcess_None)
00347         return;
00348     
00349     SetRenderTarget(0);
00350     SetRealViewport(VP);
00351     FinishScene1();
00352 
00353     CurPostProcess = PostProcess_None;
00354 }
00355 
00356 
00357 
00358 void RenderDevice::FinishScene1()
00359 {
00360     // Clear with black
00361     Clear(0.0f, 0.0f, 0.0f, 1.0f);
00362 
00363     float w = float(VP.w) / float(WindowWidth),
00364           h = float(VP.h) / float(WindowHeight),
00365           x = float(VP.x) / float(WindowWidth),
00366           y = float(VP.y) / float(WindowHeight);
00367 
00368     float as = float(VP.w) / float(VP.h);
00369 
00370     // We are using 1/4 of DistortionCenter offset value here, since it is
00371     // relative to [-1,1] range that gets mapped to [0, 0.5].
00372     pPostProcessShader->SetUniform2f("LensCenter",
00373                                      x + (w + Distortion.XCenterOffset * 0.5f)*0.5f, y + h*0.5f);
00374     pPostProcessShader->SetUniform2f("ScreenCenter", x + w*0.5f, y + h*0.5f);
00375 
00376     // MA: This is more correct but we would need higher-res texture vertically; we should adopt this
00377     // once we have asymmetric input texture scale.
00378     float scaleFactor = 1.0f / Distortion.Scale;
00379 
00380     pPostProcessShader->SetUniform2f("Scale",   (w/2) * scaleFactor, (h/2) * scaleFactor * as);
00381     pPostProcessShader->SetUniform2f("ScaleIn", (2/w),               (2/h) / as);
00382 
00383     pPostProcessShader->SetUniform4f("HmdWarpParam",
00384                                      Distortion.K[0], Distortion.K[1], Distortion.K[2], Distortion.K[3]);
00385 
00386     if (PostProcessShaderRequested == PostProcessShader_DistortionAndChromAb)
00387     {
00388         pPostProcessShader->SetUniform4f("ChromAbParam",
00389                                         Distortion.ChromaticAberration[0], 
00390                                         Distortion.ChromaticAberration[1],
00391                                         Distortion.ChromaticAberration[2],
00392                                         Distortion.ChromaticAberration[3]);
00393     }
00394 
00395     Matrix4f texm(w, 0, 0, x,
00396                   0, h, 0, y,
00397                   0, 0, 0, 0,
00398                   0, 0, 0, 1);
00399     pPostProcessShader->SetUniform4x4f("Texm", texm);
00400 
00401     Matrix4f view(2, 0, 0, -1,
00402                   0, 2, 0, -1,
00403                   0, 0, 0, 0,
00404                   0, 0, 0, 1);
00405 
00406     ShaderFill fill(pPostProcessShader);
00407     fill.SetTexture(0, pSceneColorTex);
00408     Render(&fill, pFullScreenVertexBuffer, NULL, view, 0, 4, Prim_TriangleStrip);
00409 }
00410 
00411 
00412 int GetNumMipLevels(int w, int h)
00413 {
00414     int n = 1;
00415     while(w > 1 || h > 1)
00416     {
00417         w >>= 1;
00418         h >>= 1;
00419         n++;
00420     }
00421     return n;
00422 }
00423 
00424 void FilterRgba2x2(const UByte* src, int w, int h, UByte* dest)
00425 {
00426     for(int j = 0; j < (h & ~1); j += 2)
00427     {
00428         const UByte* psrc = src + (w * j * 4);
00429         UByte*       pdest = dest + ((w >> 1) * (j >> 1) * 4);
00430 
00431         for(int i = 0; i < w >> 1; i++, psrc += 8, pdest += 4)
00432         {
00433             pdest[0] = (((int)psrc[0]) + psrc[4] + psrc[w * 4 + 0] + psrc[w * 4 + 4]) >> 2;
00434             pdest[1] = (((int)psrc[1]) + psrc[5] + psrc[w * 4 + 1] + psrc[w * 4 + 5]) >> 2;
00435             pdest[2] = (((int)psrc[2]) + psrc[6] + psrc[w * 4 + 2] + psrc[w * 4 + 6]) >> 2;
00436             pdest[3] = (((int)psrc[3]) + psrc[7] + psrc[w * 4 + 3] + psrc[w * 4 + 7]) >> 2;
00437         }
00438     }
00439 }
00440 
00441 
00442 }}


oculus_sdk
Author(s):
autogenerated on Fri Aug 28 2015 11:53:11