/* * Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include "3d.h" #include "HardwareInternal.h" #include "renderer.h" // Whether or not to use T&L transforms or the pass-thru ones static int sUseTransformPassthru = -1; extern float Z_bias; void g3_GetModelViewMatrix(const vector *viewPos, const matrix *viewMatrix, float *mvMat) { matrix localOrient = (*viewMatrix); vector localPos = -(*viewPos); mvMat[0] = localOrient.rvec.x; mvMat[1] = localOrient.uvec.x; mvMat[2] = localOrient.fvec.x; mvMat[3] = 0.0f; mvMat[4] = localOrient.rvec.y; mvMat[5] = localOrient.uvec.y; mvMat[6] = localOrient.fvec.y; mvMat[7] = 0.0f; mvMat[8] = localOrient.rvec.z; mvMat[9] = localOrient.uvec.z; mvMat[10] = localOrient.fvec.z; mvMat[11] = 0.0f; mvMat[12] = localPos * localOrient.rvec; mvMat[13] = localPos * localOrient.uvec; mvMat[14] = localPos * localOrient.fvec + Z_bias; mvMat[15] = 1.0f; } void g3_TransformMult(float res[4][4], float a[4][4], float b[4][4]) { float temp[4][4]; int x, y; for (y = 0; y < 4; ++y) { for (x = 0; x < 4; ++x) { temp[y][x] = (a[y][0] * b[0][x]) + (a[y][1] * b[1][x]) + (a[y][2] * b[2][x]) + (a[y][3] * b[3][x]); } } memcpy(res, temp, 16 * sizeof(float)); } void g3_TransformTrans(float res[4][4], float t[4][4]) { float temp[4][4]; int y; for (y = 0; y < 4; ++y) { int x; for (x = 0; x < 4; ++x) { temp[x][y] = t[y][x]; } } memcpy(res, temp, 16 * sizeof(float)); } void g3_UpdateFullTransform() { // ModelView -> projection g3_TransformMult(gTransformFull, gTransformModelView, gTransformProjection); // projection -> ViewPort g3_TransformMult(gTransformFull, gTransformFull, gTransformViewPort); } void g3_ForceTransformRefresh(void) { sUseTransformPassthru = -1; } void g3_RefreshTransforms(bool usePassthru) { if (sUseTransformPassthru == 1 && usePassthru) { // we don't have to do anything because we are already setup for pass-thru return; } if (usePassthru) { // setup OpenGL to use pass-thru rend_TransformSetToPassthru(); } else { // extract the viewport data from the renderer int viewportWidth, viewportHeight, viewportX, viewportY; rend_GetProjectionScreenParameters(viewportX, viewportY, viewportWidth, viewportHeight); // setup OpenGL to use full transform stack // TODO: in the future we only need to set those that have changed rend_TransformSetViewport(viewportX, viewportY, viewportWidth, viewportHeight); rend_TransformSetProjection(gTransformProjection); rend_TransformSetModelView(gTransformModelView); } // store the pass-thru sUseTransformPassthru = (usePassthru) ? 1 : 0; }