Multiview Shader Matrices buffer now supplied correctly

- decomposed the MVP into three separate matrices so the view matrix only needs to be supplied to the shader once per frame
- huge speed boost to the render thread, only a handful of ms per frame now, any framedrops are purely from the GPU
This commit is contained in:
Simon 2020-10-08 21:16:18 +01:00
parent b004763108
commit fb4d4a81d2
24 changed files with 195 additions and 128 deletions

View file

@ -1365,15 +1365,15 @@ void VR_Init()
long renderThreadCPUTime = 0; long renderThreadCPUTime = 0;
void Doom3Quest_prepareEyeBuffer(int eye ) void Doom3Quest_prepareEyeBuffer( )
{ {
renderThreadCPUTime = GetTimeInMilliSeconds();
ovrRenderer *renderer = Doom3Quest_useScreenLayer() ? &gAppState.Scene.CylinderRenderer : &gAppState.Renderer; ovrRenderer *renderer = Doom3Quest_useScreenLayer() ? &gAppState.Scene.CylinderRenderer : &gAppState.Renderer;
ovrFramebuffer *frameBuffer = &(renderer->FrameBuffer); ovrFramebuffer *frameBuffer = &(renderer->FrameBuffer);
ovrFramebuffer_SetCurrent(frameBuffer); ovrFramebuffer_SetCurrent(frameBuffer);
renderThreadCPUTime = GetTimeInMilliSeconds();
GL(glEnable(GL_SCISSOR_TEST)); GL(glEnable(GL_SCISSOR_TEST));
GL(glDepthMask(GL_TRUE)); GL(glDepthMask(GL_TRUE));
GL(glEnable(GL_DEPTH_TEST)); GL(glEnable(GL_DEPTH_TEST));

View file

@ -139,10 +139,10 @@ idItem::UpdateRenderEntity
*/ */
bool idItem::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const { bool idItem::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const {
/* if ( lastRenderViewTime == renderView->time ) { if ( lastRenderViewTime == renderView->time ) {
return false; return false;
} }
*/
lastRenderViewTime = renderView->time; lastRenderViewTime = renderView->time;
// check for glow highlighting if near the center of the view // check for glow highlighting if near the center of the view

View file

@ -468,7 +468,7 @@ void idPlayerView::SingleView( idUserInterface *hud, const renderView_t *view )
player->DrawHUD(hud); player->DrawHUD(hud);
} }
renderSystem->CaptureRenderToImage( "_hudImage" ); //renderSystem->CaptureRenderToImage( "_hudImage" );
// place the sound origin for the player // place the sound origin for the player
gameSoundWorld->PlaceListener( view->vieworg, view->viewaxis, player->entityNumber + 1, gameLocal.time, hud ? hud->State().GetString( "location" ) : "Undefined" ); gameSoundWorld->PlaceListener( view->vieworg, view->viewaxis, player->entityNumber + 1, gameLocal.time, hud ? hud->State().GetString( "location" ) : "Undefined" );
@ -727,34 +727,21 @@ idPlayerView::RenderPlayerView
void idPlayerView::RenderPlayerView( idUserInterface *hud ) { void idPlayerView::RenderPlayerView( idUserInterface *hud ) {
const renderView_t *view = player->GetRenderView(); const renderView_t *view = player->GetRenderView();
{
renderView_t *eyeView = view ? new renderView_t(*view) : NULL;
/* if (eyeView &&
!game->InCinematic())
{
eyeView->vieworg += (vr_eye.GetInteger() == 0 ? 1.0f : -1.0f) * eyeView->viewaxis[1] *
(vr_ipd.GetFloat() / 2.0f) * vr_worldscale.GetFloat();
}*/
if (g_skipViewEffects.GetBool()) { if (g_skipViewEffects.GetBool()) {
SingleView(hud, eyeView); SingleView( hud, view );
} else { } else {
if (player->GetInfluenceMaterial() || player->GetInfluenceEntity()) { if (player->GetInfluenceMaterial() || player->GetInfluenceEntity()) {
InfluenceVision(hud, eyeView); InfluenceVision( hud, view );
} else if (gameLocal.time < dvFinishTime) { } else if (gameLocal.time < dvFinishTime) {
DoubleVision(hud, eyeView, dvFinishTime - gameLocal.time); DoubleVision( hud, view, dvFinishTime - gameLocal.time );
} else if (player->PowerUpActive(BERSERK)) { } else if (player->PowerUpActive(BERSERK)) {
BerserkVision(hud, eyeView); BerserkVision( hud, view );
} else { } else {
SingleView(hud, eyeView); SingleView( hud, view );
} }
ScreenFade(); ScreenFade();
} }
delete eyeView;
}
if ( net_clientLagOMeter.GetBool() && lagoMaterial && gameLocal.isClient ) { if ( net_clientLagOMeter.GetBool() && lagoMaterial && gameLocal.isClient ) {
renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f ); renderSystem->SetColor4( 1.0f, 1.0f, 1.0f, 1.0f );
renderSystem->DrawStretchPic( 10.0f, 380.0f, 64.0f, 64.0f, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial ); renderSystem->DrawStretchPic( 10.0f, 380.0f, 64.0f, 64.0f, 0.0f, 0.0f, 1.0f, 1.0f, lagoMaterial );

View file

@ -170,8 +170,7 @@ bool idSmokeParticles::EmitSmoke( const idDeclParticle *smoke, const int systemS
return false; return false;
} }
if ( !gameLocal.isNewFrame ) if ( !gameLocal.isNewFrame ) {
{
return false; return false;
} }
@ -298,11 +297,10 @@ bool idSmokeParticles::UpdateRenderEntity( renderEntity_s *renderEntity, const r
return false; return false;
} }
// Need to regenerate smoke particles for each eye - commented this out or you only get smoke in the left eye! // don't regenerate it if it is current
/* if ( renderView->time == currentParticleTime && !renderView->forceUpdate && !renderView->forceSmokeUpdate ) { if ( renderView->time == currentParticleTime && !renderView->forceUpdate ) {
return false; return false;
}*/ }
currentParticleTime = renderView->time; currentParticleTime = renderView->time;
particleGen_t g; particleGen_t g;

View file

@ -193,7 +193,7 @@ void idGuiModel::EmitSurface( guiModelSurface_t *surf, float modelMatrix[16], fl
viewEntity_t *guiSpace = (viewEntity_t *)R_ClearedFrameAlloc( sizeof( *guiSpace ) ); viewEntity_t *guiSpace = (viewEntity_t *)R_ClearedFrameAlloc( sizeof( *guiSpace ) );
memcpy( guiSpace->modelMatrix, modelMatrix, sizeof( guiSpace->modelMatrix ) ); memcpy( guiSpace->modelMatrix, modelMatrix, sizeof( guiSpace->modelMatrix ) );
memcpy( guiSpace->modelViewMatrix, modelViewMatrix, sizeof( guiSpace->modelViewMatrix ) ); memcpy(guiSpace->viewMatrix, modelViewMatrix, sizeof( guiSpace->viewMatrix ) );
guiSpace->weaponDepthHack = depthHack; guiSpace->weaponDepthHack = depthHack;
// add the surface, which might recursively create another gui // add the surface, which might recursively create another gui
@ -209,13 +209,13 @@ void idGuiModel::EmitToCurrentView( float modelMatrix[16], bool depthHack ) {
float modelViewMatrix[48]; float modelViewMatrix[48];
//Left Eye //Left Eye
myGlMultMatrix( modelMatrix, tr.viewDef->worldSpace.eyeModelViewMatrix[0], myGlMultMatrix( modelMatrix, tr.viewDef->worldSpace.eyeViewMatrix[0],
modelViewMatrix ); modelViewMatrix );
//Right Eye //Right Eye
myGlMultMatrix( modelMatrix, tr.viewDef->worldSpace.eyeModelViewMatrix[1], myGlMultMatrix( modelMatrix, tr.viewDef->worldSpace.eyeViewMatrix[1],
modelViewMatrix + 16); modelViewMatrix + 16);
//Center Eye //Center Eye
myGlMultMatrix( modelMatrix, tr.viewDef->worldSpace.eyeModelViewMatrix[2], myGlMultMatrix( modelMatrix, tr.viewDef->worldSpace.eyeViewMatrix[2],
modelViewMatrix + 32); modelViewMatrix + 32);
for ( int i = 0 ; i < surfaces.Num() ; i++ ) { for ( int i = 0 ; i < surfaces.Num() ; i++ ) {
@ -281,12 +281,22 @@ void idGuiModel::EmitFullScreen( void ) {
viewDef->projectionMatrix[15] = 1.0f; viewDef->projectionMatrix[15] = 1.0f;
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
viewDef->worldSpace.eyeModelViewMatrix[i][0] = 1.0f; viewDef->worldSpace.eyeViewMatrix[i][0] = 1.0f;
viewDef->worldSpace.eyeModelViewMatrix[i][5] = 1.0f; viewDef->worldSpace.eyeViewMatrix[i][5] = 1.0f;
viewDef->worldSpace.eyeModelViewMatrix[i][10] = 1.0f; viewDef->worldSpace.eyeViewMatrix[i][10] = 1.0f;
viewDef->worldSpace.eyeModelViewMatrix[i][15] = 1.0f; viewDef->worldSpace.eyeViewMatrix[i][15] = 1.0f;
} }
viewDef->worldSpace.viewMatrix[0] = 1.0f;
viewDef->worldSpace.viewMatrix[5] = 1.0f;
viewDef->worldSpace.viewMatrix[10] = 1.0f;
viewDef->worldSpace.viewMatrix[15] = 1.0f;
viewDef->worldSpace.modelMatrix[0] = 1.0f;
viewDef->worldSpace.modelMatrix[5] = 1.0f;
viewDef->worldSpace.modelMatrix[10] = 1.0f;
viewDef->worldSpace.modelMatrix[15] = 1.0f;
viewDef->maxDrawSurfs = surfaces.Num(); viewDef->maxDrawSurfs = surfaces.Num();
viewDef->drawSurfs = (drawSurf_t **)R_FrameAlloc( viewDef->maxDrawSurfs * sizeof( viewDef->drawSurfs[0] ) ); viewDef->drawSurfs = (drawSurf_t **)R_FrameAlloc( viewDef->maxDrawSurfs * sizeof( viewDef->drawSurfs[0] ) );
viewDef->numDrawSurfs = 0; viewDef->numDrawSurfs = 0;
@ -296,7 +306,7 @@ void idGuiModel::EmitFullScreen( void ) {
// add the surfaces to this view // add the surfaces to this view
for ( int i = 0 ; i < surfaces.Num() ; i++ ) { for ( int i = 0 ; i < surfaces.Num() ; i++ ) {
EmitSurface( &surfaces[i], viewDef->worldSpace.modelMatrix, viewDef->worldSpace.modelViewMatrix, false ); EmitSurface(&surfaces[i], viewDef->worldSpace.modelMatrix, viewDef->worldSpace.viewMatrix, false );
} }
tr.viewDef = oldViewDef; tr.viewDef = oldViewDef;

View file

@ -260,8 +260,8 @@ void R_LockSurfaceScene( viewDef_t *parms ) {
for (vModel = tr.lockSurfacesCmd.viewDef->viewEntitys; vModel; vModel = vModel->next) { for (vModel = tr.lockSurfacesCmd.viewDef->viewEntitys; vModel; vModel = vModel->next) {
for (int eye = 0; eye < 3; ++eye) { for (int eye = 0; eye < 3; ++eye) {
myGlMultMatrix(vModel->modelMatrix, myGlMultMatrix(vModel->modelMatrix,
tr.lockSurfacesCmd.viewDef->worldSpace.eyeModelViewMatrix[eye], tr.lockSurfacesCmd.viewDef->worldSpace.eyeViewMatrix[eye],
vModel->eyeModelViewMatrix[eye]); vModel->eyeViewMatrix[eye]);
} }
} }

View file

@ -128,10 +128,10 @@ bool idRenderWorldLocal::PortalIsFoggedOut( const portal_t *p ) {
a = -0.5f / alpha; a = -0.5f / alpha;
} }
forward[0] = a * tr.viewDef->worldSpace.eyeModelViewMatrix[2][2]; forward[0] = a * tr.viewDef->worldSpace.eyeViewMatrix[2][2];
forward[1] = a * tr.viewDef->worldSpace.eyeModelViewMatrix[2][6]; forward[1] = a * tr.viewDef->worldSpace.eyeViewMatrix[2][6];
forward[2] = a * tr.viewDef->worldSpace.eyeModelViewMatrix[2][10]; forward[2] = a * tr.viewDef->worldSpace.eyeViewMatrix[2][10];
forward[3] = a * tr.viewDef->worldSpace.eyeModelViewMatrix[2][14]; forward[3] = a * tr.viewDef->worldSpace.eyeViewMatrix[2][14];
w = p->w; w = p->w;
for ( i = 0 ; i < w->GetNumPoints() ; i++ ) { for ( i = 0 ; i < w->GetNumPoints() ; i++ ) {

View file

@ -259,6 +259,8 @@ static void RB_GLSL_GetUniformLocations(shaderProgram_t* shader) {
GL_UseProgram(shader); GL_UseProgram(shader);
shader->localLightOrigin = qglGetUniformLocation(shader->program, "u_lightOrigin"); shader->localLightOrigin = qglGetUniformLocation(shader->program, "u_lightOrigin");
//May need to move this to the shader matrices uniform block?
shader->localViewOrigin = qglGetUniformLocation(shader->program, "u_viewOrigin"); shader->localViewOrigin = qglGetUniformLocation(shader->program, "u_viewOrigin");
shader->lightProjection = qglGetUniformLocation(shader->program, "u_lightProjection"); shader->lightProjection = qglGetUniformLocation(shader->program, "u_lightProjection");
shader->bumpMatrixS = qglGetUniformLocation(shader->program, "u_bumpMatrixS"); shader->bumpMatrixS = qglGetUniformLocation(shader->program, "u_bumpMatrixS");
@ -276,8 +278,11 @@ static void RB_GLSL_GetUniformLocations(shaderProgram_t* shader) {
shader->alphaTest = qglGetUniformLocation(shader->program, "u_alphaTest"); shader->alphaTest = qglGetUniformLocation(shader->program, "u_alphaTest");
shader->specularExponent = qglGetUniformLocation(shader->program, "u_specularExponent"); shader->specularExponent = qglGetUniformLocation(shader->program, "u_specularExponent");
GLuint shaderMatricesUniformLocation = glGetUniformBlockIndex(shader->program, "ShaderMatrices"); shader->projectionMatrix = qglGetUniformLocation(shader->program, "u_projectionMatrix");
shader->modelMatrix = qglGetUniformLocation(shader->program, "u_modelMatrix");
//Shader Matrices for the View Matrix
GLuint shaderMatricesUniformLocation = glGetUniformBlockIndex(shader->program, "ShaderMatrices");
int numBufferBindings = 0; int numBufferBindings = 0;
shader->shaderMatricesBinding = numBufferBindings++; shader->shaderMatricesBinding = numBufferBindings++;
glUniformBlockBinding( glUniformBlockBinding(
@ -518,12 +523,12 @@ void R_ReloadGLSLPrograms_f(const idCmdArgs& args) {
/* /*
================= =================
RB_ComputeMVP RB_ComputeProjection
Compute the model view matrix, with eventually required projection matrix depth hacks Compute the required projection matrix depth hacks
================= =================
*/ */
void RB_ComputeMVP( const drawSurf_t * const surf, float mvp[32] ) { void RB_ComputeProjection(const drawSurf_t * const surf, float *projection) {
// Get the projection matrix // Get the projection matrix
float localProjectionMatrix[16]; float localProjectionMatrix[16];
memcpy(localProjectionMatrix, backEnd.viewDef->projectionMatrix, sizeof(localProjectionMatrix)); memcpy(localProjectionMatrix, backEnd.viewDef->projectionMatrix, sizeof(localProjectionMatrix));
@ -536,8 +541,7 @@ void RB_ComputeMVP( const drawSurf_t * const surf, float mvp[32] ) {
localProjectionMatrix[14] = backEnd.viewDef->projectionMatrix[14] - surf->space->modelDepthHack; localProjectionMatrix[14] = backEnd.viewDef->projectionMatrix[14] - surf->space->modelDepthHack;
} }
myGlMultMatrix(surf->space->eyeModelViewMatrix[0], localProjectionMatrix, mvp); memcpy(projection, localProjectionMatrix, sizeof(localProjectionMatrix));
myGlMultMatrix(surf->space->eyeModelViewMatrix[1], localProjectionMatrix, (mvp + 16) );
} }
/* /*
@ -817,9 +821,17 @@ static void RB_GLSL_CreateDrawInteractions(const drawSurf_t* surf, const viewLig
// perform setup here that will not change over multiple interaction passes // perform setup here that will not change over multiple interaction passes
if ( surf->space != backEnd.currentSpace ) { if ( surf->space != backEnd.currentSpace ) {
float mvp[32]; float projection[16];
RB_ComputeMVP(surf, mvp); RB_ComputeProjection(surf, projection);
GL_UniformBuffer(offsetof(shaderProgram_t, shaderMatricesBuffer), mvp); GL_UniformMatrix4fv(offsetof(shaderProgram_t, projectionMatrix), projection);
GL_UniformMatrix4fv(offsetof(shaderProgram_t, modelMatrix), surf->space->modelMatrix);
if (!backEnd.glState.currentProgram->shaderMatricesBufferSet)
{
// We can set the uniform now as it shader is already bound
GL_UniformBuffer(offsetof(shaderProgram_t, shaderMatricesBuffer), backEnd.viewDef->worldSpace.viewMatrix);
backEnd.glState.currentProgram->shaderMatricesBufferSet = true;
}
} }
// Hack Depth Range if necessary // Hack Depth Range if necessary
@ -977,10 +989,18 @@ void RB_GLSL_RenderDrawSurfChainWithFunction(const drawSurf_t* drawSurfs,
// Change the MVP matrix if needed // Change the MVP matrix if needed
if ( drawSurf->space != backEnd.currentSpace ) { if ( drawSurf->space != backEnd.currentSpace ) {
float mvp[32]; float projection[16];
RB_ComputeMVP(drawSurf, mvp); RB_ComputeProjection(drawSurf, projection);
GL_UniformMatrix4fv(offsetof(shaderProgram_t, projectionMatrix), projection);
GL_UniformMatrix4fv(offsetof(shaderProgram_t, modelMatrix), drawSurf->space->modelMatrix);
// We can set the uniform now, as the shader is already bound // We can set the uniform now, as the shader is already bound
GL_UniformBuffer(offsetof(shaderProgram_t, shaderMatricesBuffer), mvp); if (!backEnd.glState.currentProgram->shaderMatricesBufferSet)
{
// We can set the uniform now as it shader is already bound
GL_UniformBuffer(offsetof(shaderProgram_t, shaderMatricesBuffer), backEnd.viewDef->worldSpace.viewMatrix);
backEnd.glState.currentProgram->shaderMatricesBufferSet = true;
}
} }
// Hack Depth Range if necessary // Hack Depth Range if necessary
@ -1290,15 +1310,15 @@ void RB_GLSL_FogPass(const drawSurf_t* drawSurfs, const drawSurf_t* drawSurfs2,
// It is expected to be already active // It is expected to be already active
globalImages->fogImage->Bind(); globalImages->fogImage->Bind();
fogPlanes[0][0] = a * backEnd.viewDef->worldSpace.eyeModelViewMatrix[2][2]; fogPlanes[0][0] = a * backEnd.viewDef->worldSpace.eyeViewMatrix[2][2];
fogPlanes[0][1] = a * backEnd.viewDef->worldSpace.eyeModelViewMatrix[2][6]; fogPlanes[0][1] = a * backEnd.viewDef->worldSpace.eyeViewMatrix[2][6];
fogPlanes[0][2] = a * backEnd.viewDef->worldSpace.eyeModelViewMatrix[2][10]; fogPlanes[0][2] = a * backEnd.viewDef->worldSpace.eyeViewMatrix[2][10];
fogPlanes[0][3] = a * backEnd.viewDef->worldSpace.eyeModelViewMatrix[2][14]; fogPlanes[0][3] = a * backEnd.viewDef->worldSpace.eyeViewMatrix[2][14];
fogPlanes[1][0] = a * backEnd.viewDef->worldSpace.eyeModelViewMatrix[2][0]; fogPlanes[1][0] = a * backEnd.viewDef->worldSpace.eyeViewMatrix[2][0];
fogPlanes[1][1] = a * backEnd.viewDef->worldSpace.eyeModelViewMatrix[2][4]; fogPlanes[1][1] = a * backEnd.viewDef->worldSpace.eyeViewMatrix[2][4];
fogPlanes[1][2] = a * backEnd.viewDef->worldSpace.eyeModelViewMatrix[2][8]; fogPlanes[1][2] = a * backEnd.viewDef->worldSpace.eyeViewMatrix[2][8];
fogPlanes[1][3] = a * backEnd.viewDef->worldSpace.eyeModelViewMatrix[2][12]; fogPlanes[1][3] = a * backEnd.viewDef->worldSpace.eyeViewMatrix[2][12];
// texture 1 is the entering plane fade correction // texture 1 is the entering plane fade correction
GL_SelectTexture(1); GL_SelectTexture(1);
@ -1659,10 +1679,17 @@ void RB_GLSL_FillDepthBuffer(drawSurf_t** drawSurfs, int numDrawSurfs) {
// Change the MVP matrix if needed // Change the MVP matrix if needed
if ( drawSurf->space != backEnd.currentSpace ) { if ( drawSurf->space != backEnd.currentSpace ) {
float mvp[32]; float projection[16];
RB_ComputeMVP(drawSurf, mvp); RB_ComputeProjection(drawSurf, projection);
GL_UniformMatrix4fv(offsetof(shaderProgram_t, projectionMatrix), projection);
GL_UniformMatrix4fv(offsetof(shaderProgram_t, modelMatrix), drawSurf->space->modelMatrix);
if (!backEnd.glState.currentProgram->shaderMatricesBufferSet)
{
// We can set the uniform now as it shader is already bound // We can set the uniform now as it shader is already bound
GL_UniformBuffer(offsetof(shaderProgram_t, shaderMatricesBuffer), mvp); GL_UniformBuffer(offsetof(shaderProgram_t, shaderMatricesBuffer), backEnd.viewDef->worldSpace.viewMatrix);
backEnd.glState.currentProgram->shaderMatricesBufferSet = true;
}
} }
// Hack Depth Range if necessary // Hack Depth Range if necessary
@ -1722,7 +1749,7 @@ RB_GLSL_T_RenderShaderPasses
This is also called for the generated 2D rendering This is also called for the generated 2D rendering
================== ==================
*/ */
void RB_GLSL_T_RenderShaderPasses(const drawSurf_t* surf, const float mvp[16]) { void RB_GLSL_T_RenderShaderPasses(const drawSurf_t* surf, const float projection[16]) {
// global constants // global constants
static const GLfloat zero[1] = { 0 }; static const GLfloat zero[1] = { 0 };
@ -1970,13 +1997,13 @@ void RB_GLSL_T_RenderShaderPasses(const drawSurf_t* surf, const float mvp[16]) {
GL_VertexAttribPointer(offsetof(shaderProgram_t, attr_TexCoord), 3, GL_FLOAT, false, sizeof(idDrawVert), GL_VertexAttribPointer(offsetof(shaderProgram_t, attr_TexCoord), 3, GL_FLOAT, false, sizeof(idDrawVert),
ac->normal.ToFloatPtr()); ac->normal.ToFloatPtr());
// Setup the modelViewMatrix, we will need it to compute the reflection // Setup the viewMatrix, we will need it to compute the reflection
GL_UniformMatrix4fv(offsetof(shaderProgram_t, modelViewMatrix), surf->space->eyeModelViewMatrix[2]); GL_UniformMatrix4fv(offsetof(shaderProgram_t, modelViewMatrix), surf->space->eyeViewMatrix[2]);
// Setup the texture matrix like original D3 code does: using the transpose modelViewMatrix of the view // Setup the texture matrix like original D3 code does: using the transpose viewMatrix of the view
// NB: this is curious, not sure why this is done like this.... // NB: this is curious, not sure why this is done like this....
float mat[16]; float mat[16];
R_TransposeGLMatrix(backEnd.viewDef->worldSpace.eyeModelViewMatrix[2], mat); R_TransposeGLMatrix(backEnd.viewDef->worldSpace.eyeViewMatrix[2], mat);
GL_UniformMatrix4fv(offsetof(shaderProgram_t, textureMatrix), mat); GL_UniformMatrix4fv(offsetof(shaderProgram_t, textureMatrix), mat);
} else { // TG_EXPLICIT } else { // TG_EXPLICIT
// Otherwise, this is just regular surface shader with explicit texcoords // Otherwise, this is just regular surface shader with explicit texcoords
@ -2020,8 +2047,15 @@ void RB_GLSL_T_RenderShaderPasses(const drawSurf_t* surf, const float mvp[16]) {
// MVP // MVP
if ( !bMVPSet[pStage->texture.texgen] ) { if ( !bMVPSet[pStage->texture.texgen] ) {
// Setup the MVP uniform GL_UniformMatrix4fv(offsetof(shaderProgram_t, projectionMatrix), projection);
GL_UniformBuffer(offsetof(shaderProgram_t, shaderMatricesBuffer), mvp); GL_UniformMatrix4fv(offsetof(shaderProgram_t, modelMatrix), surf->space->modelMatrix);
if (!backEnd.glState.currentProgram->shaderMatricesBufferSet)
{
// We can set the uniform now as it shader is already bound
GL_UniformBuffer(offsetof(shaderProgram_t, shaderMatricesBuffer), backEnd.viewDef->worldSpace.viewMatrix);
backEnd.glState.currentProgram->shaderMatricesBufferSet = true;
}
bMVPSet[pStage->texture.texgen] = true; bMVPSet[pStage->texture.texgen] = true;
} }
} }
@ -2197,7 +2231,7 @@ int RB_GLSL_DrawShaderPasses(drawSurf_t** drawSurfs, int numDrawSurfs) {
// For each surface loop // For each surface loop
///////////////////////// /////////////////////////
float mvp[32]; float projection[16];
backEnd.currentSpace = NULL; backEnd.currentSpace = NULL;
int i; int i;
@ -2226,7 +2260,7 @@ int RB_GLSL_DrawShaderPasses(drawSurf_t** drawSurfs, int numDrawSurfs) {
// Change the MVP matrix if needed // Change the MVP matrix if needed
if ( drawSurfs[i]->space != backEnd.currentSpace ) { if ( drawSurfs[i]->space != backEnd.currentSpace ) {
RB_ComputeMVP(drawSurfs[i], mvp); RB_ComputeProjection(drawSurfs[i], projection);
// We can't set the uniform now, as we still don't know which shader to use // We can't set the uniform now, as we still don't know which shader to use
} }
@ -2240,7 +2274,7 @@ int RB_GLSL_DrawShaderPasses(drawSurf_t** drawSurfs, int numDrawSurfs) {
//////////////////// ////////////////////
// Do the real work // Do the real work
//////////////////// ////////////////////
RB_GLSL_T_RenderShaderPasses(drawSurfs[i], mvp); RB_GLSL_T_RenderShaderPasses(drawSurfs[i], projection);
if (bNeedRestoreDepthRange) { if (bNeedRestoreDepthRange) {
qglDepthRangef(0.0f, 1.0f); qglDepthRangef(0.0f, 1.0f);
@ -2508,6 +2542,20 @@ void RB_GLSL_PrepareShaders(void) {
// No shaders set by default // No shaders set by default
GL_UseProgram(NULL); GL_UseProgram(NULL);
//Indicate that none have the view matrix set yet
interactionShader.shaderMatricesBufferSet = false;
interactionShader.shaderMatricesBufferSet = false;
interactionPhongShader.shaderMatricesBufferSet = false;
fogShader.shaderMatricesBufferSet = false;
blendLightShader.shaderMatricesBufferSet = false;
zfillShader.shaderMatricesBufferSet = false;
zfillClipShader.shaderMatricesBufferSet = false;
diffuseMapShader.shaderMatricesBufferSet = false;
diffuseCubeShader.shaderMatricesBufferSet = false;
skyboxCubeShader.shaderMatricesBufferSet = false;
reflectionCubeShader.shaderMatricesBufferSet = false;
stencilShadowShader.shaderMatricesBufferSet = false;
// Always enable the vertex, color and texcoord attributes arrays // Always enable the vertex, color and texcoord attributes arrays
GL_EnableVertexAttribArray(ATTR_VERTEX); GL_EnableVertexAttribArray(ATTR_VERTEX);
GL_EnableVertexAttribArray(ATTR_COLOR); GL_EnableVertexAttribArray(ATTR_COLOR);

View file

@ -33,8 +33,10 @@ in highp vec4 attr_Vertex;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_fogMatrix; uniform mat4 u_fogMatrix;
// Out // Out
@ -44,7 +46,7 @@ out vec2 var_TexFogEnter;
void main() void main()
{ {
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
// What will be computed: // What will be computed:
// //

View file

@ -35,8 +35,10 @@ in vec3 attr_TexCoord;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_textureMatrix; uniform mat4 u_textureMatrix;
uniform lowp float u_colorAdd; uniform lowp float u_colorAdd;
uniform lowp float u_colorModulate; uniform lowp float u_colorModulate;
@ -56,6 +58,6 @@ void main()
var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd); var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd);
} }
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
} }
)"; )";

View file

@ -36,8 +36,10 @@ in vec4 attr_TexCoord;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_textureMatrix; uniform mat4 u_textureMatrix;
uniform lowp float u_colorAdd; uniform lowp float u_colorAdd;
uniform lowp float u_colorModulate; uniform lowp float u_colorModulate;
@ -57,6 +59,6 @@ void main()
var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd); var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd);
} }
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
} }
)"; )";

View file

@ -33,8 +33,10 @@ in highp vec4 attr_Vertex; // input Vertex Coordinates
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_fogMatrix; // fogPlanes 0, 1, 3 (CATION: not 2!), 2 uniform mat4 u_fogMatrix; // fogPlanes 0, 1, 3 (CATION: not 2!), 2
// Out // Out
@ -44,7 +46,7 @@ out vec2 var_TexFogEnter; // output FogEnter TexCoord
void main() void main()
{ {
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
// What will be computed: // What will be computed:
// //

View file

@ -38,8 +38,10 @@ in vec3 attr_Normal;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_lightProjection; uniform mat4 u_lightProjection;
uniform lowp float u_colorModulate; uniform lowp float u_colorModulate;
uniform lowp float u_colorAdd; uniform lowp float u_colorAdd;
@ -92,6 +94,6 @@ void main()
var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd); var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd);
} }
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
} }
)"; )";

View file

@ -38,8 +38,10 @@ in vec3 attr_Normal;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_lightProjection; uniform mat4 u_lightProjection;
uniform lowp float u_colorModulate; uniform lowp float u_colorModulate;
uniform lowp float u_colorAdd; uniform lowp float u_colorAdd;
@ -93,6 +95,6 @@ void main()
var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd); var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd);
} }
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
} }
)"; )";

View file

@ -42,8 +42,10 @@ in vec3 attr_TexCoord;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_modelViewMatrix; uniform mat4 u_modelViewMatrix;
uniform mat4 u_textureMatrix; uniform mat4 u_textureMatrix;
uniform lowp float u_colorAdd; uniform lowp float u_colorAdd;
@ -67,6 +69,6 @@ void main()
var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd); var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd);
} }
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
} }
)"; )";

View file

@ -34,8 +34,10 @@ in lowp vec4 attr_Color;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_textureMatrix; uniform mat4 u_textureMatrix;
uniform lowp float u_colorAdd; uniform lowp float u_colorAdd;
uniform lowp float u_colorModulate; uniform lowp float u_colorModulate;
@ -56,6 +58,6 @@ void main()
var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd); var_Color = (attr_Color * u_colorModulate) + vec4(u_colorAdd);
} }
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
} }
)"; )";

View file

@ -33,8 +33,10 @@ in highp vec4 attr_Vertex;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform vec4 u_lightOrigin; uniform vec4 u_lightOrigin;
// Out // Out
@ -42,6 +44,6 @@ uniform vec4 u_lightOrigin;
void main() void main()
{ {
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * (attr_Vertex.w * u_lightOrigin + attr_Vertex - u_lightOrigin); gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * (attr_Vertex.w * u_lightOrigin + attr_Vertex - u_lightOrigin)));
} }
)"; )";

View file

@ -34,8 +34,10 @@ in vec4 attr_TexCoord;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_textureMatrix; uniform mat4 u_textureMatrix;
uniform vec4 u_clipPlane; uniform vec4 u_clipPlane;
@ -50,6 +52,6 @@ void main()
var_TexClip = vec2( dot( u_clipPlane, attr_Vertex), 0.5 ); var_TexClip = vec2( dot( u_clipPlane, attr_Vertex), 0.5 );
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
} }
)"; )";

View file

@ -34,8 +34,10 @@ in vec4 attr_TexCoord;
// Uniforms // Uniforms
uniform ShaderMatrices uniform ShaderMatrices
{ {
uniform highp mat4 modelViewProjectionMatrix[NUM_VIEWS]; uniform highp mat4 viewMatrix[NUM_VIEWS];
} u_shaderMatrices; } u_shaderMatrices;
uniform highp mat4 u_modelMatrix;
uniform highp mat4 u_projectionMatrix;
uniform mat4 u_textureMatrix; uniform mat4 u_textureMatrix;
// Out // Out
@ -46,6 +48,6 @@ void main()
{ {
var_TexDiffuse = (u_textureMatrix * attr_TexCoord).xy; // Homogeneous coordinates of textureMatrix supposed to be 1 var_TexDiffuse = (u_textureMatrix * attr_TexCoord).xy; // Homogeneous coordinates of textureMatrix supposed to be 1
gl_Position = u_shaderMatrices.modelViewProjectionMatrix[gl_ViewID_OVR] * attr_Vertex; gl_Position = u_projectionMatrix * (u_shaderMatrices.viewMatrix[gl_ViewID_OVR] * (u_modelMatrix * attr_Vertex));
} }
)"; )";

View file

@ -273,8 +273,8 @@ viewEntity_t* R_SetEntityDefViewEntity(idRenderEntityLocal* def) {
// we may not have a viewDef if we are just creating shadows at entity creation time // we may not have a viewDef if we are just creating shadows at entity creation time
if ( tr.viewDef ) { if ( tr.viewDef ) {
for (int eye = 0; eye <= 2; ++eye) { for (int eye = 0; eye <= 2; ++eye) {
myGlMultMatrix(vModel->modelMatrix, tr.viewDef->worldSpace.eyeModelViewMatrix[eye], myGlMultMatrix(vModel->modelMatrix, tr.viewDef->worldSpace.eyeViewMatrix[eye],
vModel->eyeModelViewMatrix[eye]); vModel->eyeViewMatrix[eye]);
} }
vModel->next = tr.viewDef->viewEntitys; vModel->next = tr.viewDef->viewEntitys;
@ -630,7 +630,7 @@ idScreenRect R_ClippedLightScissorRectangle(viewLight_t* vLight) {
idPlane eye, clip; idPlane eye, clip;
idVec3 ndc; idVec3 ndc;
R_TransformModelToClip(w[j].ToVec3(), tr.viewDef->worldSpace.eyeModelViewMatrix[2], tr.viewDef->projectionMatrix, eye, R_TransformModelToClip(w[j].ToVec3(), tr.viewDef->worldSpace.eyeViewMatrix[2], tr.viewDef->projectionMatrix, eye,
clip); clip);
if ( clip[3] <= 0.01f ) { if ( clip[3] <= 0.01f ) {
@ -695,7 +695,7 @@ idScreenRect R_CalcLightScissorRectangle(viewLight_t* vLight) {
tri = vLight->lightDef->frustumTris; tri = vLight->lightDef->frustumTris;
for ( int i = 0; i < tri->numVerts; i++ ) { for ( int i = 0; i < tri->numVerts; i++ ) {
R_TransformModelToClip(tri->verts[i].xyz, tr.viewDef->worldSpace.eyeModelViewMatrix[2], R_TransformModelToClip(tri->verts[i].xyz, tr.viewDef->worldSpace.eyeViewMatrix[2],
tr.viewDef->projectionMatrix, eye, clip); tr.viewDef->projectionMatrix, eye, clip);
// if it is near clipped, clip the winding polygons to the view frustum // if it is near clipped, clip the winding polygons to the view frustum
@ -1052,7 +1052,7 @@ idRenderModel* R_EntityDefDynamicModel(idRenderEntityLocal* def) {
if ( def->dynamicModel && model->DepthHack() != 0.0f && tr.viewDef ) { if ( def->dynamicModel && model->DepthHack() != 0.0f && tr.viewDef ) {
idPlane eye, clip; idPlane eye, clip;
idVec3 ndc; idVec3 ndc;
R_TransformModelToClip(def->parms.origin, tr.viewDef->worldSpace.eyeModelViewMatrix[2], tr.viewDef->projectionMatrix, R_TransformModelToClip(def->parms.origin, tr.viewDef->worldSpace.eyeViewMatrix[2], tr.viewDef->projectionMatrix,
eye, eye,
clip); clip);
R_TransformClipToDevice(clip, tr.viewDef, ndc); R_TransformClipToDevice(clip, tr.viewDef, ndc);

View file

@ -372,9 +372,9 @@ typedef struct viewEntity_s {
union { union {
// local coords to left/right/center eye coords // local coords to left/right/center eye coords
float eyeModelViewMatrix[3][16]; float eyeViewMatrix[3][16];
// Can also be treated as a float[48] // Can also be treated as a float[48]
float modelViewMatrix[48]; float viewMatrix[48];
}; };
} viewEntity_t; } viewEntity_t;
@ -1259,8 +1259,10 @@ typedef struct shaderProgram_s {
GLint alphaTest; GLint alphaTest;
GLint specularExponent; GLint specularExponent;
// GLint modelViewProjectionMatrix; GLint modelMatrix;
//New for multiview GLint projectionMatrix;
//New for multiview - The view matrix uniform
bool shaderMatricesBufferSet;
GLuint shaderMatricesBuffer; GLuint shaderMatricesBuffer;
GLuint shaderMatricesBinding; GLuint shaderMatricesBinding;

View file

@ -737,10 +737,10 @@ void R_GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc )
for ( i = 0 ; i < 4 ; i ++ ) { for ( i = 0 ; i < 4 ; i ++ ) {
view[i] = view[i] =
global[0] * tr.primaryView->worldSpace.eyeModelViewMatrix[2][ i + 0 * 4 ] + global[0] * tr.primaryView->worldSpace.eyeViewMatrix[2][i + 0 * 4 ] +
global[1] * tr.primaryView->worldSpace.eyeModelViewMatrix[2][ i + 1 * 4 ] + global[1] * tr.primaryView->worldSpace.eyeViewMatrix[2][i + 1 * 4 ] +
global[2] * tr.primaryView->worldSpace.eyeModelViewMatrix[2][ i + 2 * 4 ] + global[2] * tr.primaryView->worldSpace.eyeViewMatrix[2][i + 2 * 4 ] +
tr.primaryView->worldSpace.eyeModelViewMatrix[2][ i + 3 * 4 ]; tr.primaryView->worldSpace.eyeViewMatrix[2][i + 3 * 4 ];
} }
for ( i = 0 ; i < 4 ; i ++ ) { for ( i = 0 ; i < 4 ; i ++ ) {
@ -755,10 +755,10 @@ void R_GlobalToNormalizedDeviceCoordinates( const idVec3 &global, idVec3 &ndc )
for ( i = 0 ; i < 4 ; i ++ ) { for ( i = 0 ; i < 4 ; i ++ ) {
view[i] = view[i] =
global[0] * tr.viewDef->worldSpace.eyeModelViewMatrix[2][ i + 0 * 4 ] + global[0] * tr.viewDef->worldSpace.eyeViewMatrix[2][i + 0 * 4 ] +
global[1] * tr.viewDef->worldSpace.eyeModelViewMatrix[2][ i + 1 * 4 ] + global[1] * tr.viewDef->worldSpace.eyeViewMatrix[2][i + 1 * 4 ] +
global[2] * tr.viewDef->worldSpace.eyeModelViewMatrix[2][ i + 2 * 4 ] + global[2] * tr.viewDef->worldSpace.eyeViewMatrix[2][i + 2 * 4 ] +
tr.viewDef->worldSpace.eyeModelViewMatrix[2][ i + 3 * 4 ]; tr.viewDef->worldSpace.eyeViewMatrix[2][i + 3 * 4 ];
} }
@ -913,7 +913,7 @@ void R_SetViewMatrix( viewDef_t *viewDef ) {
// convert from our coordinate system (looking down X) // convert from our coordinate system (looking down X)
// to OpenGL's coordinate system (looking down -Z) // to OpenGL's coordinate system (looking down -Z)
myGlMultMatrix(viewerMatrix, s_flipMatrix, world->eyeModelViewMatrix[eye]); myGlMultMatrix(viewerMatrix, s_flipMatrix, world->eyeViewMatrix[eye]);
} }
} }
} }

View file

@ -473,10 +473,10 @@ void world_to_hclip( const viewDef_t *viewDef, const idVec4 &global, idVec4 &cli
for ( i = 0 ; i < 4 ; i ++ ) { for ( i = 0 ; i < 4 ; i ++ ) {
view[i] = view[i] =
global[0] * viewDef->worldSpace.eyeModelViewMatrix[2][ i + 0 * 4 ] + global[0] * viewDef->worldSpace.eyeViewMatrix[2][i + 0 * 4 ] +
global[1] * viewDef->worldSpace.eyeModelViewMatrix[2][ i + 1 * 4 ] + global[1] * viewDef->worldSpace.eyeViewMatrix[2][i + 1 * 4 ] +
global[2] * viewDef->worldSpace.eyeModelViewMatrix[2][ i + 2 * 4 ] + global[2] * viewDef->worldSpace.eyeViewMatrix[2][i + 2 * 4 ] +
global[3] * viewDef->worldSpace.eyeModelViewMatrix[2][ i + 3 * 4 ]; global[3] * viewDef->worldSpace.eyeViewMatrix[2][i + 3 * 4 ];
} }

View file

@ -125,7 +125,7 @@ bool R_PreciseCullSurface( const drawSurf_t *drawSurf, idBounds &ndcBounds ) {
int j; int j;
unsigned int pointFlags; unsigned int pointFlags;
R_TransformModelToClip( tri->verts[i].xyz, drawSurf->space->eyeModelViewMatrix[2], R_TransformModelToClip( tri->verts[i].xyz, drawSurf->space->eyeViewMatrix[2],
tr.viewDef->projectionMatrix, eye, clip ); tr.viewDef->projectionMatrix, eye, clip );
pointFlags = 0; pointFlags = 0;