// glLoadIdentity implementation void VSML::loadIdentity(MatrixTypes aType) { setIdentityMatrix(mMatrix[aType]); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(aType); #endif }
// glLoadMatrix implementation void VSML::loadMatrix(MatrixTypes aType, float *aMatrix) { memcpy(mMatrix[aType], aMatrix, 16 * sizeof(float)); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(aType); #endif }
// gluLookAt implementation void VSML::lookAt(float xPos, float yPos, float zPos, float xLook, float yLook, float zLook, float xUp, float yUp, float zUp) { float dir[3], right[3], up[3]; up[0] = xUp; up[1] = yUp; up[2] = zUp; dir[0] = (xLook - xPos); dir[1] = (yLook - yPos); dir[2] = (zLook - zPos); normalize(dir); crossProduct(dir,up,right); normalize(right); crossProduct(right,dir,up); normalize(up); float m1[16],m2[16]; m1[0] = right[0]; m1[4] = right[1]; m1[8] = right[2]; m1[12] = 0.0f; m1[1] = up[0]; m1[5] = up[1]; m1[9] = up[2]; m1[13] = 0.0f; m1[2] = -dir[0]; m1[6] = -dir[1]; m1[10] = -dir[2]; m1[14] = 0.0f; m1[3] = 0.0f; m1[7] = 0.0f; m1[11] = 0.0f; m1[15] = 1.0f; setIdentityMatrix(m2,4); m2[12] = -xPos; m2[13] = -yPos; m2[14] = -zPos; multMatrix(MODELVIEW, m1); multMatrix(MODELVIEW, m2); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(MODELVIEW); #endif }
// glPopMatrix implementation void VSML::popMatrix(MatrixTypes aType) { float *m = mMatrixStack[aType][mMatrixStack[aType].size()-1]; memcpy(mMatrix[aType], m, sizeof(float) * 16); mMatrixStack[aType].pop_back(); free(m); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(aType); #endif }
// glScale implementation with matrix selection void VSML::scale(MatrixTypes aType, float x, float y, float z) { float mat[16]; setIdentityMatrix(mat,4); mat[0] = x; mat[5] = y; mat[10] = z; multMatrix(aType,mat); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(aType); #endif }
// glTranslate implementation with matrix selection void VSML::translate(MatrixTypes aType, float x, float y, float z) { float mat[16]; setIdentityMatrix(mat); mat[12] = x; mat[13] = y; mat[14] = z; multMatrix(aType,mat); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(aType); #endif }
// glOrtho implementation void VSML::ortho(float left, float right, float bottom, float top, float nearp, float farp) { float m[16]; setIdentityMatrix(m,4); m[0 * 4 + 0] = 2 / (right - left); m[1 * 4 + 1] = 2 / (top - bottom); m[2 * 4 + 2] = -2 / (farp - nearp); m[3 * 4 + 0] = -(right + left) / (right - left); m[3 * 4 + 1] = -(top + bottom) / (top - bottom); m[3 * 4 + 2] = -(farp + nearp) / (farp - nearp); multMatrix(PROJECTION, m); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(PROJECTION); #endif }
// gluPerspective implementation void VSML::perspective(float fov, float ratio, float nearp, float farp) { float projMatrix[16]; float f = 1.0f / tan (fov * (M_PI / 360.0f)); setIdentityMatrix(projMatrix,4); projMatrix[0] = f / ratio; projMatrix[1 * 4 + 1] = f; projMatrix[2 * 4 + 2] = (farp + nearp) / (nearp - farp); projMatrix[3 * 4 + 2] = (2.0f * farp * nearp) / (nearp - farp); projMatrix[2 * 4 + 3] = -1.0f; projMatrix[3 * 4 + 3] = 0.0f; multMatrix(PROJECTION, projMatrix); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(PROJECTION); #endif }
// glMultMatrix implementation void VSML::multMatrix(MatrixTypes aType, float *aMatrix) { float *a, *b, res[16]; a = mMatrix[aType]; b = aMatrix; for (int i = 0; i < 4; ++i) { for (int j = 0; j < 4; ++j) { res[j*4 + i] = 0.0f; for (int k = 0; k < 4; ++k) { res[j*4 + i] += a[k*4 + i] * b[j*4 + k]; } } } memcpy(mMatrix[aType], res, 16 * sizeof(float)); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(aType); #endif }
// glRotate implementation with matrix selection void VSML::rotate(MatrixTypes aType, float angle, float x, float y, float z) { float mat[16]; float radAngle = DegToRad(angle); float co = cos(radAngle); float si = sin(radAngle); float x2 = x*x; float y2 = y*y; float z2 = z*z; mat[0] = x2 + (y2 + z2) * co; mat[4] = x * y * (1 - co) - z * si; mat[8] = x * z * (1 - co) + y * si; mat[12]= 0.0f; mat[1] = x * y * (1 - co) + z * si; mat[5] = y2 + (x2 + z2) * co; mat[9] = y * z * (1 - co) - x * si; mat[13]= 0.0f; mat[2] = x * z * (1 - co) - y * si; mat[6] = y * z * (1 - co) + x * si; mat[10]= z2 + (x2 + y2) * co; mat[14]= 0.0f; mat[3] = 0.0f; mat[7] = 0.0f; mat[11]= 0.0f; mat[15]= 1.0f; multMatrix(aType,mat); #ifdef VSML_ALWAYS_SEND_TO_OPENGL matrixToGL(aType); #endif }
bool FRenderState::ApplyShader() { static uint64_t firstFrame = 0; // if firstFrame is not yet initialized, initialize it to current time // if we're going to overflow a float (after ~4.6 hours, or 24 bits), re-init to regain precision if ((firstFrame == 0) || (screen->FrameTime - firstFrame >= 1<<24) || level.ShaderStartTime >= firstFrame) firstFrame = screen->FrameTime; static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f }; if (mSpecialEffect > EFF_NONE) { activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect, mPassType); } else { activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f, mPassType); activeShader->Bind(); } int fogset = 0; if (mFogEnabled) { if ((mFogColor & 0xffffff) == 0) { fogset = gl_fogmode; } else { fogset = -gl_fogmode; } } glVertexAttrib4fv(VATTR_COLOR, mColor.vec); glVertexAttrib4fv(VATTR_NORMAL, mNormal.vec); //activeShader->muObjectColor2.Set(mObjectColor2); activeShader->muObjectColor2.Set(mObjectColor2); activeShader->muDesaturation.Set(mDesaturation / 255.f); activeShader->muFogEnabled.Set(fogset); activeShader->muPalLightLevels.Set(static_cast<int>(gl_bandedswlight) | (static_cast<int>(gl_fogmode) << 8)); activeShader->muGlobVis.Set(GLRenderer->mGlobVis / 32.0f); activeShader->muTextureMode.Set(mTextureMode); activeShader->muCameraPos.Set(mCameraPos.vec); activeShader->muLightParms.Set(mLightParms); activeShader->muFogColor.Set(mFogColor); activeShader->muObjectColor.Set(mObjectColor); activeShader->muDynLightColor.Set(mDynColor.vec); activeShader->muInterpolationFactor.Set(mInterpolationFactor); activeShader->muClipHeight.Set(mClipHeight); activeShader->muClipHeightDirection.Set(mClipHeightDirection); activeShader->muTimer.Set((double)(screen->FrameTime - firstFrame) * (double)mShaderTimer / 1000.); activeShader->muAlphaThreshold.Set(mAlphaThreshold); activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now activeShader->muClipSplit.Set(mClipSplit); if (mGlowEnabled) { activeShader->muGlowTopColor.Set(mGlowTop.vec); activeShader->muGlowBottomColor.Set(mGlowBottom.vec); activeShader->currentglowstate = 1; } else if (activeShader->currentglowstate) { // if glowing is on, disable it. activeShader->muGlowTopColor.Set(nulvec); activeShader->muGlowBottomColor.Set(nulvec); activeShader->currentglowstate = 0; } if (mGlowEnabled || mObjectColor2.a != 0) { activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec); activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec); } if (mSplitEnabled) { activeShader->muSplitTopPlane.Set(mSplitTopPlane.vec); activeShader->muSplitBottomPlane.Set(mSplitBottomPlane.vec); activeShader->currentsplitstate = 1; } else if (activeShader->currentsplitstate) { activeShader->muSplitTopPlane.Set(nulvec); activeShader->muSplitBottomPlane.Set(nulvec); activeShader->currentsplitstate = 0; } if (mClipLineEnabled) { activeShader->muClipLine.Set(mClipLine.vec); activeShader->currentcliplinestate = 1; } else if (activeShader->currentcliplinestate) { activeShader->muClipLine.Set(-10000000.0, 0, 0, 0); activeShader->currentcliplinestate = 0; } if (mColormapState != activeShader->currentfixedcolormap) { float r, g, b; activeShader->currentfixedcolormap = mColormapState; if (mColormapState == CM_DEFAULT) { activeShader->muFixedColormap.Set(0); } else if (mColormapState > CM_DEFAULT && mColormapState < CM_MAXCOLORMAP) { if (FGLRenderBuffers::IsEnabled()) { // When using postprocessing to apply the colormap, we must render the image fullbright here. activeShader->muFixedColormap.Set(2); activeShader->muColormapStart.Set(1, 1, 1, 1.f); } else { FSpecialColormap *scm = &SpecialColormaps[mColormapState - CM_FIRSTSPECIALCOLORMAP]; float m[] = { scm->ColorizeEnd[0] - scm->ColorizeStart[0], scm->ColorizeEnd[1] - scm->ColorizeStart[1], scm->ColorizeEnd[2] - scm->ColorizeStart[2], 0.f }; activeShader->muFixedColormap.Set(1); activeShader->muColormapStart.Set(scm->ColorizeStart[0], scm->ColorizeStart[1], scm->ColorizeStart[2], 0.f); activeShader->muColormapRange.Set(m); } } else if (mColormapState == CM_FOGLAYER) { activeShader->muFixedColormap.Set(3); } else if (mColormapState == CM_LITE) { if (gl_enhanced_nightvision) { r = 0.375f, g = 1.0f, b = 0.375f; } else { r = g = b = 1.f; } activeShader->muFixedColormap.Set(2); activeShader->muColormapStart.Set(r, g, b, 1.f); } else if (mColormapState >= CM_TORCH) { int flicker = mColormapState - CM_TORCH; r = (0.8f + (7 - flicker) / 70.0f); if (r > 1.0f) r = 1.0f; b = g = r; if (gl_enhanced_nightvision) b = g * 0.75f; activeShader->muFixedColormap.Set(2); activeShader->muColormapStart.Set(r, g, b, 1.f); } } if (mTextureMatrixEnabled) { matrixToGL(mTextureMatrix, activeShader->texturematrix_index); activeShader->currentTextureMatrixState = true; } else if (activeShader->currentTextureMatrixState) { activeShader->currentTextureMatrixState = false; matrixToGL(identityMatrix, activeShader->texturematrix_index); } if (mModelMatrixEnabled) { matrixToGL(mModelMatrix, activeShader->modelmatrix_index); VSMatrix norm; norm.computeNormalMatrix(mModelMatrix); matrixToGL(norm, activeShader->normalmodelmatrix_index); activeShader->currentModelMatrixState = true; } else if (activeShader->currentModelMatrixState) { activeShader->currentModelMatrixState = false; matrixToGL(identityMatrix, activeShader->modelmatrix_index); matrixToGL(identityMatrix, activeShader->normalmodelmatrix_index); } return true; }