void TinyGLRenderer::setupCameraPerspective(float pitch, float heading, float fov) { // TODO: Find a correct and exact formula for the FOV TGLfloat glFOV = 0.63 * fov; // Approximative and experimental formula if (fov > 79.0 && fov < 81.0) glFOV = 50.5; // Somewhat good value for fov == 80 else if (fov > 59.0 && fov < 61.0) glFOV = 36.0; // Somewhat good value for fov == 60 // NOTE: tinyGL viewport implementation needs to be checked as it doesn't behave the same as openGL tglViewport(0, kTopBorderHeight, kOriginalWidth, kFrameHeight); tglMatrixMode(TGL_PROJECTION); tglLoadIdentity(); Math::Matrix4 m = Math::makePerspectiveMatrix(glFOV, (TGLfloat)kOriginalWidth / (TGLfloat)kFrameHeight, 1.0, 10000.0); tglMultMatrixf(m.getData()); // Rotate the model to simulate the rotation of the camera tglMatrixMode(TGL_MODELVIEW); tglLoadIdentity(); tglRotatef(pitch, -1.0f, 0.0f, 0.0f); tglRotatef(heading - 180.0f, 0.0f, 1.0f, 0.0f); tglGetFloatv(TGL_MODELVIEW_MATRIX, _cubeModelViewMatrix); tglGetFloatv(TGL_PROJECTION_MATRIX, _cubeProjectionMatrix); tglGetIntegerv(TGL_VIEWPORT, (TGLint *)_cubeViewport); }
static void tglShadowProjection(Graphics::Vector3d light, Graphics::Vector3d plane, Graphics::Vector3d normal, bool dontNegate) { // Based on GPL shadow projection example by // (c) 2002-2003 Phaetos <*****@*****.**> float d, c; float mat[16]; float nx, ny, nz, lx, ly, lz, px, py, pz; nx = normal.x(); ny = normal.y(); nz = normal.z(); // for some unknown for me reason normal need negation if (!dontNegate) { nx = -nx; ny = -ny; nz = -nz; } lx = light.x(); ly = light.y(); lz = light.z(); px = plane.x(); py = plane.y(); pz = plane.z(); d = nx * lx + ny * ly + nz * lz; c = px * nx + py * ny + pz * nz - d; mat[0] = lx * nx + c; mat[4] = ny * lx; mat[8] = nz * lx; mat[12] = -lx * c - lx * d; mat[1] = nx * ly; mat[5] = ly * ny + c; mat[9] = nz * ly; mat[13] = -ly * c - ly * d; mat[2] = nx * lz; mat[6] = ny * lz; mat[10] = lz * nz + c; mat[14] = -lz * c - lz * d; mat[3] = nx; mat[7] = ny; mat[11] = nz; mat[15] = -d; tglMultMatrixf(mat); }
// below funcs lookAt, transformPoint and tgluProject are from Mesa glu sources static void lookAt(TGLfloat eyex, TGLfloat eyey, TGLfloat eyez, TGLfloat centerx, TGLfloat centery, TGLfloat centerz, TGLfloat upx, TGLfloat upy, TGLfloat upz) { TGLfloat m[16]; TGLfloat x[3], y[3], z[3]; TGLfloat mag; z[0] = eyex - centerx; z[1] = eyey - centery; z[2] = eyez - centerz; mag = sqrt(z[0] * z[0] + z[1] * z[1] + z[2] * z[2]); if (mag) { z[0] /= mag; z[1] /= mag; z[2] /= mag; } y[0] = upx; y[1] = upy; y[2] = upz; x[0] = y[1] * z[2] - y[2] * z[1]; x[1] = -y[0] * z[2] + y[2] * z[0]; x[2] = y[0] * z[1] - y[1] * z[0]; y[0] = z[1] * x[2] - z[2] * x[1]; y[1] = -z[0] * x[2] + z[2] * x[0]; y[2] = z[0] * x[1] - z[1] * x[0]; mag = sqrt(x[0] * x[0] + x[1] * x[1] + x[2] * x[2]); if (mag) { x[0] /= mag; x[1] /= mag; x[2] /= mag; } mag = sqrt(y[0] * y[0] + y[1] * y[1] + y[2] * y[2]); if (mag) { y[0] /= mag; y[1] /= mag; y[2] /= mag; } #define M(row,col) m[col * 4 + row] M(0, 0) = x[0]; M(0, 1) = x[1]; M(0, 2) = x[2]; M(0, 3) = 0.0f; M(1, 0) = y[0]; M(1, 1) = y[1]; M(1, 2) = y[2]; M(1, 3) = 0.0f; M(2, 0) = z[0]; M(2, 1) = z[1]; M(2, 2) = z[2]; M(2, 3) = 0.0f; M(3, 0) = 0.0f; M(3, 1) = 0.0f; M(3, 2) = 0.0f; M(3, 3) = 1.0f; #undef M tglMultMatrixf(m); tglTranslatef(-eyex, -eyey, -eyez); }