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 "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
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
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
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
00280
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
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
00371
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
00377
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 }}