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_GL_Device.h"
00025 #include "Kernel/OVR_Log.h"
00026
00027 namespace OVR { namespace RenderTiny { namespace GL {
00028
00029
00030
00031 static const char* StdVertexShaderSrc =
00032 "uniform mat4 Proj;\n"
00033 "uniform mat4 View;\n"
00034 "attribute vec4 Position;\n"
00035 "attribute vec4 Color;\n"
00036 "attribute vec2 TexCoord;\n"
00037 "attribute vec3 Normal;\n"
00038 "varying vec4 oColor;\n"
00039 "varying vec2 oTexCoord;\n"
00040 "varying vec3 oNormal;\n"
00041 "varying vec3 oVPos;\n"
00042 "void main()\n"
00043 "{\n"
00044 " gl_Position = Proj * (View * Position);\n"
00045 " oNormal = vec3(View * vec4(Normal,0));\n"
00046 " oVPos = vec3(View * Position);\n"
00047 " oTexCoord = TexCoord;\n"
00048 " oColor = Color;\n"
00049 "}\n";
00050
00051 static const char* DirectVertexShaderSrc =
00052 "uniform mat4 View;\n"
00053 "attribute vec4 Position;\n"
00054 "attribute vec4 Color;\n"
00055 "attribute vec2 TexCoord;\n"
00056 "attribute vec3 Normal;\n"
00057 "varying vec4 oColor;\n"
00058 "varying vec2 oTexCoord;\n"
00059 "varying vec3 oNormal;\n"
00060 "void main()\n"
00061 "{\n"
00062 " gl_Position = View * Position;\n"
00063 " oTexCoord = TexCoord;\n"
00064 " oColor = Color;\n"
00065 " oNormal = vec3(View * vec4(Normal,0));\n"
00066 "}\n";
00067
00068 static const char* SolidFragShaderSrc =
00069 "uniform vec4 Color;\n"
00070 "void main()\n"
00071 "{\n"
00072 " gl_FragColor = Color;\n"
00073 "}\n";
00074
00075 static const char* GouraudFragShaderSrc =
00076 "varying vec4 oColor;\n"
00077 "void main()\n"
00078 "{\n"
00079 " gl_FragColor = oColor;\n"
00080 "}\n";
00081
00082 static const char* TextureFragShaderSrc =
00083 "uniform sampler2D Texture0;\n"
00084 "varying vec4 oColor;\n"
00085 "varying vec2 oTexCoord;\n"
00086 "void main()\n"
00087 "{\n"
00088 " gl_FragColor = oColor * texture2D(Texture0, oTexCoord);\n"
00089 " if (gl_FragColor.a < 0.4)\n"
00090 " discard;\n"
00091 "}\n";
00092
00093 #define LIGHTING_COMMON \
00094 "uniform vec3 Ambient;\n" \
00095 "uniform vec4 LightPos[8];\n" \
00096 "uniform vec4 LightColor[8];\n" \
00097 "uniform float LightCount;\n" \
00098 "varying vec4 oColor;\n" \
00099 "varying vec2 oTexCoord;\n" \
00100 "varying vec3 oNormal;\n" \
00101 "varying vec3 oVPos;\n" \
00102 "vec4 DoLight()\n" \
00103 "{\n" \
00104 " vec3 norm = normalize(oNormal);\n" \
00105 " vec3 light = Ambient;\n" \
00106 " for (int i = 0; i < int(LightCount); i++)\n" \
00107 " {\n" \
00108 " vec3 ltp = (LightPos[i].xyz - oVPos);\n" \
00109 " float ldist = length(ltp);\n" \
00110 " ltp = normalize(ltp);\n" \
00111 " light += clamp(LightColor[i].rgb * oColor.rgb * (dot(norm, ltp) / ldist), 0.0,1.0);\n" \
00112 " }\n" \
00113 " return vec4(light, oColor.a);\n" \
00114 "}\n"
00115
00116 static const char* LitSolidFragShaderSrc =
00117 LIGHTING_COMMON
00118 "void main()\n"
00119 "{\n"
00120 " gl_FragColor = DoLight() * oColor;\n"
00121 "}\n";
00122
00123 static const char* LitTextureFragShaderSrc =
00124 "uniform sampler2D Texture0;\n"
00125 LIGHTING_COMMON
00126 "void main()\n"
00127 "{\n"
00128 " gl_FragColor = DoLight() * texture2D(Texture0, oTexCoord);\n"
00129 "}\n";
00130
00131 static const char* PostProcessVertexShaderSrc =
00132 "uniform mat4 View;\n"
00133 "uniform mat4 Texm;\n"
00134 "attribute vec4 Position;\n"
00135 "attribute vec2 TexCoord;\n"
00136 "varying vec2 oTexCoord;\n"
00137 "void main()\n"
00138 "{\n"
00139 " gl_Position = View * Position;\n"
00140 " oTexCoord = vec2(Texm * vec4(TexCoord,0,1));\n"
00141 " oTexCoord.y = 1.0-oTexCoord.y;\n"
00142 "}\n";
00143
00144 static const char* PostProcessFragShaderSrc =
00145 "uniform vec2 LensCenter;\n"
00146 "uniform vec2 ScreenCenter;\n"
00147 "uniform vec2 Scale;\n"
00148 "uniform vec2 ScaleIn;\n"
00149 "uniform vec4 HmdWarpParam;\n"
00150 "uniform sampler2D Texture0;\n"
00151 "varying vec2 oTexCoord;\n"
00152 "\n"
00153 "vec2 HmdWarp(vec2 in01)\n"
00154 "{\n"
00155 " vec2 theta = (in01 - LensCenter) * ScaleIn;\n"
00156 " float rSq = theta.x * theta.x + theta.y * theta.y;\n"
00157 " vec2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
00158 " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
00159 " return LensCenter + Scale * theta1;\n"
00160 "}\n"
00161 "void main()\n"
00162 "{\n"
00163 " vec2 tc = HmdWarp(oTexCoord);\n"
00164 " if (!all(equal(clamp(tc, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)), tc)))\n"
00165 " gl_FragColor = vec4(0);\n"
00166 " else\n"
00167 " gl_FragColor = texture2D(Texture0, tc);\n"
00168 "}\n";
00169
00170
00171 static const char* PostProcessFullFragShaderSrc =
00172 "uniform vec2 LensCenter;\n"
00173 "uniform vec2 ScreenCenter;\n"
00174 "uniform vec2 Scale;\n"
00175 "uniform vec2 ScaleIn;\n"
00176 "uniform vec4 HmdWarpParam;\n"
00177 "uniform vec4 ChromAbParam;\n"
00178 "uniform sampler2D Texture0;\n"
00179 "varying vec2 oTexCoord;\n"
00180 "\n"
00181
00182
00183
00184 "void main()\n"
00185 "{\n"
00186 " vec2 theta = (oTexCoord - LensCenter) * ScaleIn;\n"
00187 " float rSq= theta.x * theta.x + theta.y * theta.y;\n"
00188 " vec2 theta1 = theta * (HmdWarpParam.x + HmdWarpParam.y * rSq + "
00189 " HmdWarpParam.z * rSq * rSq + HmdWarpParam.w * rSq * rSq * rSq);\n"
00190 " \n"
00191 " // Detect whether blue texture coordinates are out of range since these will scaled out the furthest.\n"
00192 " vec2 thetaBlue = theta1 * (ChromAbParam.z + ChromAbParam.w * rSq);\n"
00193 " vec2 tcBlue = LensCenter + Scale * thetaBlue;\n"
00194 " if (!all(equal(clamp(tcBlue, ScreenCenter-vec2(0.25,0.5), ScreenCenter+vec2(0.25,0.5)), tcBlue)))\n"
00195 " {\n"
00196 " gl_FragColor = vec4(0);\n"
00197 " return;\n"
00198 " }\n"
00199 " \n"
00200 " // Now do blue texture lookup.\n"
00201 " float blue = texture2D(Texture0, tcBlue).b;\n"
00202 " \n"
00203 " // Do green lookup (no scaling).\n"
00204 " vec2 tcGreen = LensCenter + Scale * theta1;\n"
00205 " vec4 center = texture2D(Texture0, tcGreen);\n"
00206 " \n"
00207 " // Do red scale and lookup.\n"
00208 " vec2 thetaRed = theta1 * (ChromAbParam.x + ChromAbParam.y * rSq);\n"
00209 " vec2 tcRed = LensCenter + Scale * thetaRed;\n"
00210 " float red = texture2D(Texture0, tcRed).r;\n"
00211 " \n"
00212 " gl_FragColor = vec4(red, center.g, blue, 1);\n"
00213 "}\n";
00214
00215 static const char* VShaderSrcs[VShader_Count] =
00216 {
00217 DirectVertexShaderSrc,
00218 StdVertexShaderSrc,
00219 PostProcessVertexShaderSrc
00220 };
00221 static const char* FShaderSrcs[FShader_Count] =
00222 {
00223 SolidFragShaderSrc,
00224 GouraudFragShaderSrc,
00225 TextureFragShaderSrc,
00226 PostProcessFragShaderSrc,
00227 PostProcessFullFragShaderSrc,
00228 LitSolidFragShaderSrc,
00229 LitTextureFragShaderSrc
00230 };
00231
00232
00233
00234 RenderDevice::RenderDevice(const RendererParams& p)
00235 {
00236 for (int i = 0; i < VShader_Count; i++)
00237 VertexShaders[i] = *new Shader(this, Shader_Vertex, VShaderSrcs[i]);
00238
00239 for (int i = 0; i < FShader_Count; i++)
00240 FragShaders[i] = *new Shader(this, Shader_Fragment, FShaderSrcs[i]);
00241
00242 Ptr<ShaderSet> gouraudShaders = *new ShaderSet();
00243 gouraudShaders->SetShader(VertexShaders[VShader_MVP]);
00244 gouraudShaders->SetShader(FragShaders[FShader_Gouraud]);
00245 DefaultFill = *new ShaderFill(gouraudShaders);
00246
00247 glGenFramebuffersEXT(1, &CurrentFbo);
00248 }
00249
00250 Shader *RenderDevice::LoadBuiltinShader(ShaderStage stage, int shader)
00251 {
00252 switch (stage)
00253 {
00254 case Shader_Vertex: return VertexShaders[shader];
00255 case Shader_Fragment: return FragShaders[shader];
00256 default:
00257 return NULL;
00258 }
00259 }
00260
00261
00262 void RenderDevice::BeginRendering()
00263 {
00264 glEnable(GL_DEPTH_TEST);
00265 glEnable(GL_CULL_FACE);
00266 glFrontFace(GL_CW);
00267
00268 glLineWidth(3.0f);
00269 glEnable(GL_LINE_SMOOTH);
00270 glEnable(GL_BLEND);
00271 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
00272
00273 glMatrixMode(GL_MODELVIEW);
00274 glLoadIdentity();
00275 }
00276
00277 void RenderDevice::SetDepthMode(bool enable, bool write, CompareFunc func)
00278 {
00279 if (enable)
00280 {
00281 glEnable(GL_DEPTH_TEST);
00282 glDepthMask(write);
00283 switch (func)
00284 {
00285 case Compare_Always: glDepthFunc(GL_ALWAYS); break;
00286 case Compare_Less: glDepthFunc(GL_LESS); break;
00287 case Compare_Greater: glDepthFunc(GL_GREATER); break;
00288 default: assert(0);
00289 }
00290 }
00291 else
00292 glDisable(GL_DEPTH_TEST);
00293 }
00294
00295 void RenderDevice::SetRealViewport(const Viewport& vp)
00296 {
00297 int wh;
00298 if (CurRenderTarget)
00299 wh = CurRenderTarget->Height;
00300 else
00301 wh = WindowHeight;
00302 glViewport(vp.x, wh-vp.y-vp.h, vp.w, vp.h);
00303
00304 glEnable(GL_SCISSOR_TEST);
00305 glScissor(vp.x, wh-vp.y-vp.h, vp.w, vp.h);
00306 }
00307
00308 void RenderDevice::Clear(float r, float g, float b, float a, float depth)
00309 {
00310 glClearColor(r,g,b,a);
00311 glClearDepth(depth);
00312 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
00313 }
00314
00315 RBuffer* RenderDevice::GetDepthBuffer(int w, int h, int ms)
00316 {
00317 for (unsigned i = 0; i < DepthBuffers.GetSize(); i++)
00318 if (w == DepthBuffers[i]->Width && h == DepthBuffers[i]->Height)
00319 return DepthBuffers[i];
00320
00321
00322 Ptr<RBuffer> newDepth = *new RBuffer(GL_DEPTH24_STENCIL8, w, h);
00323 DepthBuffers.PushBack(newDepth);
00324 return newDepth.GetPtr();
00325 }
00326
00327 void RenderDevice::SetRenderTarget(RenderTiny::Texture* color, RenderTiny::Texture*, RenderTiny::Texture* stencil)
00328 {
00329 OVR_UNUSED(stencil);
00330
00331 CurRenderTarget = (Texture*)color;
00332 if (color == NULL)
00333 {
00334 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
00335 return;
00336 }
00337
00338 RBuffer* depth = GetDepthBuffer(color->GetWidth(), color->GetHeight(), 0);
00339
00340 glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, CurrentFbo);
00341 glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, ((Texture*)color)->TexId, 0);
00342 if (depth)
00343
00344 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, ((RBuffer*)depth)->BufId);
00345 else
00346 glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
00347
00348 GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
00349 if (status != GL_FRAMEBUFFER_COMPLETE_EXT)
00350 OVR_DEBUG_LOG(("framebuffer not complete: %x", status));
00351 }
00352
00353
00354 void RenderDevice::SetWorldUniforms(const Matrix4f& proj)
00355 {
00356 Proj = proj.Transposed();
00357 }
00358
00359 void RenderDevice::SetTexture(RenderTiny::ShaderStage, int slot, const Texture* t)
00360 {
00361 glActiveTexture(GL_TEXTURE0 + slot);
00362 glBindTexture(GL_TEXTURE_2D, ((Texture*)t)->TexId);
00363 glActiveTexture(GL_TEXTURE0);
00364 }
00365
00366 Buffer* RenderDevice::CreateBuffer()
00367 {
00368 return new Buffer(this);
00369 }
00370
00371 void RenderDevice::Render(const Matrix4f& matrix, Model* model)
00372 {
00373
00374 if (!model->VertexBuffer)
00375 {
00376 Ptr<RenderTiny::Buffer> vb = *CreateBuffer();
00377 vb->Data(Buffer_Vertex, &model->Vertices[0], model->Vertices.GetSize() * sizeof(Vertex));
00378 model->VertexBuffer = vb;
00379 }
00380 if (!model->IndexBuffer)
00381 {
00382 Ptr<RenderTiny::Buffer> ib = *CreateBuffer();
00383 ib->Data(Buffer_Index, &model->Indices[0], model->Indices.GetSize() * 2);
00384 model->IndexBuffer = ib;
00385 }
00386
00387 Render(model->Fill ? (const ShaderFill*)model->Fill : (const ShaderFill*)DefaultFill,
00388 model->VertexBuffer, model->IndexBuffer,
00389 matrix, 0, (int)model->Indices.GetSize(), model->GetPrimType());
00390 }
00391
00392 void RenderDevice::Render(const ShaderFill* fill, RenderTiny::Buffer* vertices, RenderTiny::Buffer* indices,
00393 const Matrix4f& matrix, int offset, int count, PrimitiveType rprim)
00394 {
00395 ShaderSet* shaders = (ShaderSet*) ((ShaderFill*)fill)->GetShaders();
00396
00397 GLenum prim;
00398 switch (rprim)
00399 {
00400 case Prim_Triangles:
00401 prim = GL_TRIANGLES;
00402 break;
00403 case Prim_Lines:
00404 prim = GL_LINES;
00405 break;
00406 case Prim_TriangleStrip:
00407 prim = GL_TRIANGLE_STRIP;
00408 break;
00409 default:
00410 assert(0);
00411 return;
00412 }
00413
00414 fill->Set();
00415 if (shaders->ProjLoc >= 0)
00416 glUniformMatrix4fv(shaders->ProjLoc, 1, 0, &Proj.M[0][0]);
00417 if (shaders->ViewLoc >= 0)
00418 glUniformMatrix4fv(shaders->ViewLoc, 1, 0, &matrix.Transposed().M[0][0]);
00419
00420 if (shaders->UsesLighting && Lighting->Version != shaders->LightingVer)
00421 {
00422 shaders->LightingVer = Lighting->Version;
00423 Lighting->Set(shaders);
00424 }
00425
00426 glBindBuffer(GL_ARRAY_BUFFER, ((Buffer*)vertices)->GLBuffer);
00427 for (int i = 0; i < 4; i++)
00428 glEnableVertexAttribArray(i);
00429
00430 glVertexAttribPointer(0, 3, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, Pos));
00431 glVertexAttribPointer(1, 4, GL_UNSIGNED_BYTE, true, sizeof(Vertex), (char*)offset + offsetof(Vertex, C));
00432 glVertexAttribPointer(2, 2, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, U));
00433 glVertexAttribPointer(3, 3, GL_FLOAT, false, sizeof(Vertex), (char*)offset + offsetof(Vertex, Norm));
00434
00435 if (indices)
00436 {
00437 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ((Buffer*)indices)->GLBuffer);
00438 glDrawElements(prim, count, GL_UNSIGNED_SHORT, NULL);
00439 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00440 }
00441 else
00442 {
00443 glDrawArrays(prim, 0, count);
00444 }
00445
00446 for (int i = 0; i < 4; i++)
00447 glDisableVertexAttribArray(i);
00448 }
00449
00450 void RenderDevice::SetLighting(const LightingParams* lt)
00451 {
00452 Lighting = lt;
00453 }
00454
00455 Buffer::~Buffer()
00456 {
00457 if (GLBuffer)
00458 glDeleteBuffers(1, &GLBuffer);
00459 }
00460
00461 bool Buffer::Data(int use, const void* buffer, size_t size)
00462 {
00463 switch (use & Buffer_TypeMask)
00464 {
00465 case Buffer_Index: Use = GL_ELEMENT_ARRAY_BUFFER; break;
00466 default: Use = GL_ARRAY_BUFFER; break;
00467 }
00468
00469 if (!GLBuffer)
00470 glGenBuffers(1, &GLBuffer);
00471
00472 int mode = GL_DYNAMIC_DRAW;
00473 if (use & Buffer_ReadOnly)
00474 mode = GL_STATIC_DRAW;
00475
00476 glBindBuffer(Use, GLBuffer);
00477 glBufferData(Use, size, buffer, mode);
00478 glBindBuffer(Use, 0);
00479 return 1;
00480 }
00481
00482 void* Buffer::Map(size_t start, size_t size, int flags)
00483 {
00484 int mode = GL_WRITE_ONLY;
00485
00486
00487
00488 glBindBuffer(Use, GLBuffer);
00489 void* v = glMapBuffer(Use, mode);
00490 glBindBuffer(Use, 0);
00491 return v;
00492 }
00493
00494 bool Buffer::Unmap(void*)
00495 {
00496 glBindBuffer(Use, GLBuffer);
00497 int r = glUnmapBuffer(Use);
00498 glBindBuffer(Use, 0);
00499 return r;
00500 }
00501
00502 bool Shader::Compile(const char* src)
00503 {
00504 if (!GLShader)
00505 GLShader = glCreateShader(GLStage());
00506
00507 glShaderSource(GLShader, 1, &src, 0);
00508 glCompileShader(GLShader);
00509 GLint r;
00510 glGetShaderiv(GLShader, GL_COMPILE_STATUS, &r);
00511 if (!r)
00512 {
00513 GLchar msg[1024];
00514 glGetShaderInfoLog(GLShader, sizeof(msg), 0, msg);
00515 if (msg[0])
00516 OVR_DEBUG_LOG(("Compiling shader\n%s\nfailed: %s\n", src, msg));
00517 if (!r)
00518 return 0;
00519 }
00520 return 1;
00521 }
00522
00523 ShaderSet::ShaderSet()
00524 {
00525 Prog = glCreateProgram();
00526 }
00527 ShaderSet::~ShaderSet()
00528 {
00529 glDeleteProgram(Prog);
00530 }
00531
00532 bool ShaderSet::Link()
00533 {
00534 glBindAttribLocation(Prog, 0, "Position");
00535 glBindAttribLocation(Prog, 1, "Color");
00536 glBindAttribLocation(Prog, 2, "TexCoord");
00537 glBindAttribLocation(Prog, 3, "Normal");
00538
00539 glLinkProgram(Prog);
00540 GLint r;
00541 glGetProgramiv(Prog, GL_LINK_STATUS, &r);
00542 if (!r)
00543 {
00544 GLchar msg[1024];
00545 glGetProgramInfoLog(Prog, sizeof(msg), 0, msg);
00546 OVR_DEBUG_LOG(("Linking shaders failed: %s\n", msg));
00547 if (!r)
00548 return 0;
00549 }
00550 glUseProgram(Prog);
00551
00552 UniformInfo.Clear();
00553 LightingVer = 0;
00554 UsesLighting = 0;
00555 GLuint i = 0;
00556 for(;; i++)
00557 {
00558 GLsizei namelen;
00559 GLint size = 0;
00560 GLenum type;
00561 GLchar name[32];
00562 glGetActiveUniform(Prog, i, sizeof(name), &namelen, &size, &type, name);
00563 if (size)
00564 {
00565 int l = glGetUniformLocation(Prog, name);
00566 char *np = name;
00567 while (*np)
00568 {
00569 if (*np == '[')
00570 *np = 0;
00571 np++;
00572 }
00573 Uniform u;
00574 u.Name = name;
00575 u.Location = l;
00576 u.Size = size;
00577 switch (type)
00578 {
00579 case GL_FLOAT: u.Type = 1; break;
00580 case GL_FLOAT_VEC2: u.Type = 2; break;
00581 case GL_FLOAT_VEC3: u.Type = 3; break;
00582 case GL_FLOAT_VEC4: u.Type = 4; break;
00583 case GL_FLOAT_MAT4: u.Type = 16; break;
00584 default:
00585 continue;
00586 }
00587 UniformInfo.PushBack(u);
00588 if (!strcmp(name, "LightCount"))
00589 UsesLighting = 1;
00590 }
00591 else
00592 break;
00593 }
00594
00595 ProjLoc = glGetUniformLocation(Prog, "Proj");
00596 ViewLoc = glGetUniformLocation(Prog, "View");
00597 for (int i = 0; i < 8; i++)
00598 {
00599 char texv[32];
00600 sprintf(texv, "Texture%d", i);
00601 TexLoc[i] = glGetUniformLocation(Prog, texv);
00602 if (TexLoc[i] < 0)
00603 break;
00604
00605 glUniform1i(TexLoc[i], i);
00606 }
00607 if (UsesLighting)
00608 OVR_ASSERT(ProjLoc >= 0 && ViewLoc >= 0);
00609 return 1;
00610 }
00611
00612 void ShaderSet::Set(PrimitiveType) const
00613 {
00614 glUseProgram(Prog);
00615 }
00616
00617 bool ShaderSet::SetUniform(const char* name, int n, const float* v)
00618 {
00619 for (int i = 0; i < UniformInfo.GetSize(); i++)
00620 if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
00621 {
00622 OVR_ASSERT(UniformInfo[i].Location >= 0);
00623 glUseProgram(Prog);
00624 switch (UniformInfo[i].Type)
00625 {
00626 case 1: glUniform1fv(UniformInfo[i].Location, n, v); break;
00627 case 2: glUniform2fv(UniformInfo[i].Location, n/2, v); break;
00628 case 3: glUniform3fv(UniformInfo[i].Location, n/3, v); break;
00629 case 4: glUniform4fv(UniformInfo[i].Location, n/4, v); break;
00630 default: OVR_ASSERT(0);
00631 }
00632 return 1;
00633 }
00634
00635 OVR_DEBUG_LOG(("Warning: uniform %s not present in selected shader", name));
00636 return 0;
00637 }
00638
00639 bool ShaderSet::SetUniform4x4f(const char* name, const Matrix4f& m)
00640 {
00641 for (int i = 0; i < UniformInfo.GetSize(); i++)
00642 if (!strcmp(UniformInfo[i].Name.ToCStr(), name))
00643 {
00644 glUseProgram(Prog);
00645 glUniformMatrix4fv(UniformInfo[i].Location, 1, 1, &m.M[0][0]);
00646 return 1;
00647 }
00648
00649 OVR_DEBUG_LOG(("Warning: uniform %s not present in selected shader", name));
00650 return 0;
00651 }
00652
00653 Texture::Texture(RenderDevice* r, int w, int h) : Ren(r), Width(w), Height(h)
00654 {
00655 glGenTextures(1, &TexId);
00656 }
00657
00658 Texture::~Texture()
00659 {
00660 if (TexId)
00661 glDeleteTextures(1, &TexId);
00662 }
00663
00664 void Texture::Set(int slot, RenderTiny::ShaderStage stage) const
00665 {
00666 Ren->SetTexture(stage, slot, this);
00667 }
00668
00669 void Texture::SetSampleMode(int sm)
00670 {
00671 glBindTexture(GL_TEXTURE_2D, TexId);
00672 switch (sm & Sample_FilterMask)
00673 {
00674 case Sample_Linear:
00675 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00676 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00677 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
00678 break;
00679
00680 case Sample_Anisotropic:
00681 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00682 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00683 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
00684 break;
00685
00686 case Sample_Nearest:
00687 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00688 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00689 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 0);
00690 break;
00691 }
00692
00693 switch (sm & Sample_AddressMask)
00694 {
00695 case Sample_Repeat:
00696 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00697 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00698 break;
00699
00700 case Sample_Clamp:
00701 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00702 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00703 break;
00704
00705 case Sample_ClampBorder:
00706 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
00707 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
00708 break;
00709 }
00710 glBindTexture(GL_TEXTURE_2D, 0);
00711 }
00712
00713 Texture* RenderDevice::CreateTexture(int format, int width, int height, const void* data, int mipcount)
00714 {
00715 GLenum glformat, gltype = GL_UNSIGNED_BYTE;
00716 switch(format & Texture_TypeMask)
00717 {
00718 case Texture_RGBA: glformat = GL_RGBA; break;
00719 case Texture_Depth: glformat = GL_DEPTH; gltype = GL_DEPTH_COMPONENT; break;
00720 default:
00721 return NULL;
00722 }
00723 Texture* NewTex = new Texture(this, width, height);
00724 glBindTexture(GL_TEXTURE_2D, NewTex->TexId);
00725 glGetError();
00726
00727 glTexImage2D(GL_TEXTURE_2D, 0, glformat, width, height, 0, glformat, gltype, data);
00728 OVR_ASSERT(!glGetError());
00729
00730 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
00731 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
00732 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
00733 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00734
00735 if (format == (Texture_RGBA|Texture_GenMipmaps))
00736 {
00737 int srcw = width, srch = height;
00738 int level = 0;
00739 UByte* mipmaps = NULL;
00740 do
00741 {
00742 level++;
00743 int mipw = srcw >> 1; if (mipw < 1) mipw = 1;
00744 int miph = srch >> 1; if (miph < 1) miph = 1;
00745 if (mipmaps == NULL)
00746 mipmaps = (UByte*)OVR_ALLOC(mipw * miph * 4);
00747 FilterRgba2x2(level == 1 ? (const UByte*)data : mipmaps, srcw, srch, mipmaps);
00748 glTexImage2D(GL_TEXTURE_2D, level, glformat, mipw, miph, 0, glformat, gltype, mipmaps);
00749 OVR_ASSERT(!glGetError());
00750 srcw = mipw;
00751 srch = miph;
00752 } while (srcw > 1 || srch > 1);
00753 if (mipmaps)
00754 OVR_FREE(mipmaps);
00755 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level);
00756 OVR_ASSERT(!glGetError());
00757 }
00758 else
00759 {
00760 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipcount-1);
00761 OVR_ASSERT(!glGetError());
00762 }
00763
00764 OVR_ASSERT(!glGetError());
00765 glBindTexture(GL_TEXTURE_2D, 0);
00766 return NewTex;
00767 }
00768
00769 RBuffer::RBuffer(GLenum format, GLint w, GLint h)
00770 {
00771 Width = w;
00772 Height = h;
00773 glGenRenderbuffersEXT(1, &BufId);
00774 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, BufId);
00775 glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, w, h);
00776 glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
00777 }
00778
00779 RBuffer::~RBuffer()
00780 {
00781 glDeleteRenderbuffersEXT(1, &BufId);
00782 }
00783
00784 }}}