mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 14:51:51 +00:00
- since the clip planes for plane mirrors did not work anymore I reimplemented them using shader based logic. It still needs to be seen if this affects performance on older hardware.
This commit is contained in:
parent
7cbffc7c14
commit
d868f60f6c
13 changed files with 650 additions and 16 deletions
|
@ -1046,6 +1046,7 @@ add_executable( zdoom WIN32
|
|||
gl/data/gl_data.cpp
|
||||
gl/data/gl_portaldata.cpp
|
||||
gl/data/gl_setup.cpp
|
||||
gl/data/gl_matrix.cpp
|
||||
gl/data/gl_vertexbuffer.cpp
|
||||
gl/dynlights/a_dynlight.cpp
|
||||
gl/utility/gl_clock.cpp
|
||||
|
|
496
src/gl/data/gl_matrix.cpp
Normal file
496
src/gl/data/gl_matrix.cpp
Normal file
|
@ -0,0 +1,496 @@
|
|||
/* --------------------------------------------------
|
||||
|
||||
Lighthouse3D
|
||||
|
||||
VSMatrix - Very Simple Matrix Library
|
||||
|
||||
http://www.lighthouse3d.com/very-simple-libs
|
||||
|
||||
This is a simplified version of VSMatrix that has been adjusted for GZDoom's needs.
|
||||
|
||||
----------------------------------------------------*/
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "doomtype.h"
|
||||
#include "gl/data/gl_matrix.h"
|
||||
|
||||
static inline double
|
||||
DegToRad(double degrees)
|
||||
{
|
||||
return (double)(degrees * (M_PI / 180.0f));
|
||||
};
|
||||
|
||||
// sets the square matrix mat to the identity matrix,
|
||||
// size refers to the number of rows (or columns)
|
||||
void
|
||||
VSMatrix::setIdentityMatrix( double *mat, int size) {
|
||||
|
||||
// fill matrix with 0s
|
||||
for (int i = 0; i < size * size; ++i)
|
||||
mat[i] = 0.0f;
|
||||
|
||||
// fill diagonal with 1s
|
||||
for (int i = 0; i < size; ++i)
|
||||
mat[i + i * size] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// glLoadIdentity implementation
|
||||
void
|
||||
VSMatrix::loadIdentity()
|
||||
{
|
||||
// fill matrix with 0s
|
||||
for (int i = 0; i < 16; ++i)
|
||||
mMatrix[i] = 0.0f;
|
||||
|
||||
// fill diagonal with 1s
|
||||
for (int i = 0; i < 4; ++i)
|
||||
mMatrix[i + i * 4] = 1.0f;
|
||||
}
|
||||
|
||||
|
||||
// glMultMatrix implementation
|
||||
void
|
||||
VSMatrix::multMatrix(const double *aMatrix)
|
||||
{
|
||||
|
||||
double res[16];
|
||||
|
||||
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] += mMatrix[k*4 + i] * aMatrix[j*4 + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(mMatrix, res, 16 * sizeof(double));
|
||||
}
|
||||
|
||||
// glMultMatrix implementation
|
||||
void
|
||||
VSMatrix::multMatrix(const float *aMatrix)
|
||||
{
|
||||
|
||||
double res[16];
|
||||
|
||||
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] += mMatrix[k*4 + i] * aMatrix[j*4 + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(mMatrix, res, 16 * sizeof(double));
|
||||
}
|
||||
|
||||
|
||||
|
||||
// glLoadMatrix implementation
|
||||
void
|
||||
VSMatrix::loadMatrix(const double *aMatrix)
|
||||
{
|
||||
memcpy(mMatrix, aMatrix, 16 * sizeof(double));
|
||||
}
|
||||
|
||||
// glLoadMatrix implementation
|
||||
void
|
||||
VSMatrix::loadMatrix(const float *aMatrix)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
mMatrix[i] = aMatrix[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// gl Translate implementation with matrix selection
|
||||
void
|
||||
VSMatrix::translate(double x, double y, double z)
|
||||
{
|
||||
double mat[16];
|
||||
|
||||
setIdentityMatrix(mat);
|
||||
mat[12] = x;
|
||||
mat[13] = y;
|
||||
mat[14] = z;
|
||||
|
||||
multMatrix(mat);
|
||||
}
|
||||
|
||||
|
||||
// gl Scale implementation with matrix selection
|
||||
void
|
||||
VSMatrix::scale(double x, double y, double z)
|
||||
{
|
||||
double mat[16];
|
||||
|
||||
setIdentityMatrix(mat,4);
|
||||
mat[0] = x;
|
||||
mat[5] = y;
|
||||
mat[10] = z;
|
||||
|
||||
multMatrix(mat);
|
||||
}
|
||||
|
||||
|
||||
// gl Rotate implementation with matrix selection
|
||||
void
|
||||
VSMatrix::rotate(double angle, double x, double y, double z)
|
||||
{
|
||||
double mat[16];
|
||||
double v[3];
|
||||
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
|
||||
double radAngle = DegToRad(angle);
|
||||
double co = cos(radAngle);
|
||||
double si = sin(radAngle);
|
||||
normalize(v);
|
||||
double x2 = v[0]*v[0];
|
||||
double y2 = v[1]*v[1];
|
||||
double z2 = v[2]*v[2];
|
||||
|
||||
// mat[0] = x2 + (y2 + z2) * co;
|
||||
mat[0] = co + x2 * (1 - co);// + (y2 + z2) * co;
|
||||
mat[4] = v[0] * v[1] * (1 - co) - v[2] * si;
|
||||
mat[8] = v[0] * v[2] * (1 - co) + v[1] * si;
|
||||
mat[12]= 0.0f;
|
||||
|
||||
mat[1] = v[0] * v[1] * (1 - co) + v[2] * si;
|
||||
// mat[5] = y2 + (x2 + z2) * co;
|
||||
mat[5] = co + y2 * (1 - co);
|
||||
mat[9] = v[1] * v[2] * (1 - co) - v[0] * si;
|
||||
mat[13]= 0.0f;
|
||||
|
||||
mat[2] = v[0] * v[2] * (1 - co) - v[1] * si;
|
||||
mat[6] = v[1] * v[2] * (1 - co) + v[0] * si;
|
||||
// mat[10]= z2 + (x2 + y2) * co;
|
||||
mat[10]= co + z2 * (1 - co);
|
||||
mat[14]= 0.0f;
|
||||
|
||||
mat[3] = 0.0f;
|
||||
mat[7] = 0.0f;
|
||||
mat[11]= 0.0f;
|
||||
mat[15]= 1.0f;
|
||||
|
||||
multMatrix(mat);
|
||||
}
|
||||
|
||||
|
||||
// gluLookAt implementation
|
||||
void
|
||||
VSMatrix::lookAt(double xPos, double yPos, double zPos,
|
||||
double xLook, double yLook, double zLook,
|
||||
double xUp, double yUp, double zUp)
|
||||
{
|
||||
double 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);
|
||||
|
||||
double 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(m1);
|
||||
multMatrix(m2);
|
||||
}
|
||||
|
||||
|
||||
// gluPerspective implementation
|
||||
void
|
||||
VSMatrix::perspective(double fov, double ratio, double nearp, double farp)
|
||||
{
|
||||
double projMatrix[16];
|
||||
|
||||
double 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(projMatrix);
|
||||
}
|
||||
|
||||
|
||||
// glOrtho implementation
|
||||
void
|
||||
VSMatrix::ortho(double left, double right,
|
||||
double bottom, double top,
|
||||
double nearp, double farp)
|
||||
{
|
||||
double 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(m);
|
||||
}
|
||||
|
||||
|
||||
// glFrustum implementation
|
||||
void
|
||||
VSMatrix::frustum(double left, double right,
|
||||
double bottom, double top,
|
||||
double nearp, double farp)
|
||||
{
|
||||
double m[16];
|
||||
|
||||
setIdentityMatrix(m,4);
|
||||
|
||||
m[0 * 4 + 0] = 2 * nearp / (right-left);
|
||||
m[1 * 4 + 1] = 2 * nearp / (top - bottom);
|
||||
m[2 * 4 + 0] = (right + left) / (right - left);
|
||||
m[2 * 4 + 1] = (top + bottom) / (top - bottom);
|
||||
m[2 * 4 + 2] = - (farp + nearp) / (farp - nearp);
|
||||
m[2 * 4 + 3] = -1.0f;
|
||||
m[3 * 4 + 2] = - 2 * farp * nearp / (farp-nearp);
|
||||
m[3 * 4 + 3] = 0.0f;
|
||||
|
||||
multMatrix(m);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// returns a pointer to the requested matrix
|
||||
double *
|
||||
VSMatrix::get(MatrixTypes aType)
|
||||
{
|
||||
return mMatrix[aType];
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/* -----------------------------------------------------
|
||||
SEND MATRICES TO OPENGL
|
||||
------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
// universal
|
||||
void
|
||||
VSMatrix::matrixToGL(int loc)
|
||||
{
|
||||
float copyto[16];
|
||||
copy(copyto);
|
||||
glUniformMatrix4fv(loc, 1, false, copyto);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// AUX functions
|
||||
// -----------------------------------------------------
|
||||
|
||||
|
||||
// Compute res = M * point
|
||||
void
|
||||
VSMatrix::multMatrixPoint(const double *point, double *res)
|
||||
{
|
||||
|
||||
for (int i = 0; i < 4; ++i)
|
||||
{
|
||||
|
||||
res[i] = 0.0f;
|
||||
|
||||
for (int j = 0; j < 4; j++) {
|
||||
|
||||
res[i] += point[j] * mMatrix[j*4 + i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// res = a cross b;
|
||||
void
|
||||
VSMatrix::crossProduct(const double *a, const double *b, double *res) {
|
||||
|
||||
res[0] = a[1] * b[2] - b[1] * a[2];
|
||||
res[1] = a[2] * b[0] - b[2] * a[0];
|
||||
res[2] = a[0] * b[1] - b[0] * a[1];
|
||||
}
|
||||
|
||||
|
||||
// returns a . b
|
||||
double
|
||||
VSMatrix::dotProduct(const double *a, const double *b) {
|
||||
|
||||
double res = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Normalize a vec3
|
||||
void
|
||||
VSMatrix::normalize(double *a) {
|
||||
|
||||
double mag = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
|
||||
|
||||
a[0] /= mag;
|
||||
a[1] /= mag;
|
||||
a[2] /= mag;
|
||||
}
|
||||
|
||||
|
||||
// res = b - a
|
||||
void
|
||||
VSMatrix::subtract(const double *a, const double *b, double *res) {
|
||||
|
||||
res[0] = b[0] - a[0];
|
||||
res[1] = b[1] - a[1];
|
||||
res[2] = b[2] - a[2];
|
||||
}
|
||||
|
||||
|
||||
// res = a + b
|
||||
void
|
||||
VSMatrix::add(const double *a, const double *b, double *res) {
|
||||
|
||||
res[0] = b[0] + a[0];
|
||||
res[1] = b[1] + a[1];
|
||||
res[2] = b[2] + a[2];
|
||||
}
|
||||
|
||||
|
||||
// returns |a|
|
||||
double
|
||||
VSMatrix::length(const double *a) {
|
||||
|
||||
return(sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
M3(int i, int j)
|
||||
{
|
||||
return (i*3+j);
|
||||
};
|
||||
|
||||
|
||||
|
||||
// computes the derived normal matrix for the view matrix
|
||||
void
|
||||
VSMatrix::computeNormalMatrix(const double *aMatrix)
|
||||
{
|
||||
|
||||
double mMat3x3[9];
|
||||
|
||||
mMat3x3[0] = aMatrix[0];
|
||||
mMat3x3[1] = aMatrix[1];
|
||||
mMat3x3[2] = aMatrix[2];
|
||||
|
||||
mMat3x3[3] = aMatrix[4];
|
||||
mMat3x3[4] = aMatrix[5];
|
||||
mMat3x3[5] = aMatrix[6];
|
||||
|
||||
mMat3x3[6] = aMatrix[8];
|
||||
mMat3x3[7] = aMatrix[9];
|
||||
mMat3x3[8] = aMatrix[10];
|
||||
|
||||
double det, invDet;
|
||||
|
||||
det = mMat3x3[0] * (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) +
|
||||
mMat3x3[1] * (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) +
|
||||
mMat3x3[2] * (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]);
|
||||
|
||||
invDet = 1.0f/det;
|
||||
|
||||
mMatrix[0] = (mMat3x3[4] * mMat3x3[8] - mMat3x3[5] * mMat3x3[7]) * invDet;
|
||||
mMatrix[1] = (mMat3x3[5] * mMat3x3[6] - mMat3x3[8] * mMat3x3[3]) * invDet;
|
||||
mMatrix[2] = (mMat3x3[3] * mMat3x3[7] - mMat3x3[4] * mMat3x3[6]) * invDet;
|
||||
mMatrix[3] = 0.0f;
|
||||
mMatrix[4] = (mMat3x3[2] * mMat3x3[7] - mMat3x3[1] * mMat3x3[8]) * invDet;
|
||||
mMatrix[5] = (mMat3x3[0] * mMat3x3[8] - mMat3x3[2] * mMat3x3[6]) * invDet;
|
||||
mMatrix[6] = (mMat3x3[1] * mMat3x3[6] - mMat3x3[7] * mMat3x3[0]) * invDet;
|
||||
mMatrix[7] = 0.0f;
|
||||
mMatrix[8] = (mMat3x3[1] * mMat3x3[5] - mMat3x3[4] * mMat3x3[2]) * invDet;
|
||||
mMatrix[9] = (mMat3x3[2] * mMat3x3[3] - mMat3x3[0] * mMat3x3[5]) * invDet;
|
||||
mMatrix[10] =(mMat3x3[0] * mMat3x3[4] - mMat3x3[3] * mMat3x3[1]) * invDet;
|
||||
mMatrix[11] = 0.0;
|
||||
mMatrix[12] = 0.0;
|
||||
mMatrix[13] = 0.0;
|
||||
mMatrix[14] = 0.0;
|
||||
mMatrix[15] = 1.0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// aux function resMat = resMat * aMatrix
|
||||
void
|
||||
VSMatrix::multMatrix(double *resMat, const double *aMatrix)
|
||||
{
|
||||
|
||||
double res[16];
|
||||
|
||||
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] += resMat[k*4 + i] * aMatrix[j*4 + k];
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(resMat, res, 16 * sizeof(double));
|
||||
}
|
93
src/gl/data/gl_matrix.h
Normal file
93
src/gl/data/gl_matrix.h
Normal file
|
@ -0,0 +1,93 @@
|
|||
|
||||
// Matrix class based on code from VSML:
|
||||
|
||||
/** ----------------------------------------------------------
|
||||
* \class VSMathLib
|
||||
*
|
||||
* Lighthouse3D
|
||||
*
|
||||
* VSMathLib - Very Simple Matrix Library
|
||||
*
|
||||
* Full documentation at
|
||||
* http://www.lighthouse3d.com/very-simple-libs
|
||||
*
|
||||
* This class aims at easing geometric transforms, camera
|
||||
* placement and projection definition for programmers
|
||||
* working with OpenGL core versions.
|
||||
*
|
||||
*
|
||||
---------------------------------------------------------------*/
|
||||
#ifndef __VSMatrix__
|
||||
#define __VSMatrix__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
class VSMatrix {
|
||||
|
||||
public:
|
||||
|
||||
VSMatrix()
|
||||
{
|
||||
}
|
||||
|
||||
VSMatrix(int)
|
||||
{
|
||||
loadIdentity();
|
||||
}
|
||||
|
||||
void translate(double x, double y, double z);
|
||||
void scale(double x, double y, double z);
|
||||
void rotate(double angle, double x, double y, double z);
|
||||
void loadIdentity();
|
||||
void multMatrix(const float *aMatrix);
|
||||
void multMatrix(const double *aMatrix);
|
||||
void multMatrix(const VSMatrix &aMatrix)
|
||||
{
|
||||
multMatrix(aMatrix.mMatrix);
|
||||
}
|
||||
void loadMatrix(const double *aMatrix);
|
||||
void loadMatrix(const float *aMatrix);
|
||||
void lookAt(double xPos, double yPos, double zPos, double xLook, double yLook, double zLook, double xUp, double yUp, double zUp);
|
||||
void perspective(double fov, double ratio, double nearp, double farp);
|
||||
void ortho(double left, double right, double bottom, double top, double nearp=-1.0f, double farp=1.0f);
|
||||
void frustum(double left, double right, double bottom, double top, double nearp, double farp);
|
||||
void copy(double * pDest)
|
||||
{
|
||||
memcpy(pDest, mMatrix, 16 * sizeof(double));
|
||||
}
|
||||
|
||||
void copy(float * pDest)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
pDest[i] = (float)mMatrix[i];
|
||||
}
|
||||
}
|
||||
|
||||
void matrixToGL(int location);
|
||||
void multMatrixPoint(const double *point, double *res);
|
||||
|
||||
void computeNormalMatrix(const float *aMatrix);
|
||||
void computeNormalMatrix(const double *aMatrix);
|
||||
void computeNormalMatrix(const VSMatrix &aMatrix)
|
||||
{
|
||||
computeNormalMatrix(aMatrix.mMatrix);
|
||||
}
|
||||
|
||||
protected:
|
||||
static void crossProduct(const double *a, const double *b, double *res);
|
||||
static double dotProduct(const double *a, const double * b);
|
||||
static void normalize(double *a);
|
||||
static void subtract(const double *a, const double *b, double *res);
|
||||
static void add(const double *a, const double *b, double *res);
|
||||
static double length(const double *a);
|
||||
static void multMatrix(double *resMatrix, const double *aMatrix);
|
||||
|
||||
static void setIdentityMatrix(double *mat, int size = 4);
|
||||
|
||||
/// The storage for matrices
|
||||
double mMatrix[16];
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -83,6 +83,7 @@ void FRenderState::Reset()
|
|||
mColormapState = CM_DEFAULT;
|
||||
mLightParms[3] = -1.f;
|
||||
mSpecialEffect = EFF_NONE;
|
||||
mClipHeight = 0.f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -114,12 +115,13 @@ bool FRenderState::ApplyShader()
|
|||
}
|
||||
else
|
||||
{
|
||||
// todo: check how performance is affected by using 'discard' in a shader and if necessary create a separate set of discard-less shaders.
|
||||
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4);
|
||||
activeShader->Bind();
|
||||
}
|
||||
|
||||
int fogset = 0;
|
||||
//glColor4fv(mColor.vec);
|
||||
|
||||
if (mFogEnabled)
|
||||
{
|
||||
if ((mFogColor & 0xffffff) == 0)
|
||||
|
@ -143,6 +145,7 @@ bool FRenderState::ApplyShader()
|
|||
activeShader->muObjectColor.Set(mObjectColor);
|
||||
activeShader->muDynLightColor.Set(mDynColor.vec);
|
||||
activeShader->muInterpolationFactor.Set(mInterpolationFactor);
|
||||
activeShader->muClipHeight.Set(mClipHeight);
|
||||
|
||||
if (mGlowEnabled)
|
||||
{
|
||||
|
|
|
@ -57,6 +57,7 @@ class FRenderState
|
|||
int mBlendEquation;
|
||||
bool m2D;
|
||||
float mInterpolationFactor;
|
||||
float mClipHeight;
|
||||
|
||||
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
|
||||
FStateVec4 mColor;
|
||||
|
@ -100,6 +101,16 @@ public:
|
|||
mCurrentVertexBuffer = NULL;
|
||||
}
|
||||
|
||||
void SetClipHeight(float clip)
|
||||
{
|
||||
mClipHeight = clip;
|
||||
}
|
||||
|
||||
float GetClipHeight()
|
||||
{
|
||||
return mClipHeight;
|
||||
}
|
||||
|
||||
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
|
||||
{
|
||||
mColor.Set(r, g, b, a);
|
||||
|
|
|
@ -79,6 +79,7 @@ EXTERN_CVAR(Bool, gl_noquery)
|
|||
EXTERN_CVAR(Int, r_mirror_recursions)
|
||||
|
||||
TArray<GLPortal *> GLPortal::portals;
|
||||
TArray<float> GLPortal::planestack;
|
||||
int GLPortal::recursion;
|
||||
int GLPortal::MirrorFlag;
|
||||
int GLPortal::PlaneMirrorFlag;
|
||||
|
@ -200,6 +201,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
glStencilFunc(GL_EQUAL,recursion,~0); // create stencil
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); // increment stencil of valid pixels
|
||||
glColorMask(0,0,0,0); // don't write to the graphics buffer
|
||||
gl_RenderState.SetEffect(EFF_STENCIL);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.ResetColor();
|
||||
glDepthFunc(GL_LESS);
|
||||
|
@ -235,7 +237,8 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
gl_RenderState.EnableTexture(true);
|
||||
glDepthFunc(GL_LESS);
|
||||
glColorMask(1,1,1,1);
|
||||
glDepthRange(0,1);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
glDepthRange(0, 1);
|
||||
|
||||
GLuint sampleCount;
|
||||
|
||||
|
@ -264,6 +267,7 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glColorMask(1,1,1,1);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDepthMask(false); // don't write to Z-buffer!
|
||||
}
|
||||
|
@ -283,9 +287,8 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
glDisable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
// The clip plane from the previous portal must be deactivated for this one.
|
||||
clipsave = glIsEnabled(GL_CLIP_PLANE0+renderdepth-1);
|
||||
if (clipsave) glDisable(GL_CLIP_PLANE0+renderdepth-1);
|
||||
planestack.Push(gl_RenderState.GetClipHeight());
|
||||
gl_RenderState.SetClipHeight(0.f);
|
||||
|
||||
// save viewpoint
|
||||
savedviewx=viewx;
|
||||
|
@ -345,7 +348,11 @@ void GLPortal::End(bool usestencil)
|
|||
|
||||
PortalAll.Clock();
|
||||
GLRenderer->mCurrentPortal = NextPortal;
|
||||
if (clipsave) glEnable (GL_CLIP_PLANE0+renderdepth-1);
|
||||
|
||||
float f;
|
||||
planestack.Pop(f);
|
||||
gl_RenderState.SetClipHeight(f);
|
||||
|
||||
if (usestencil)
|
||||
{
|
||||
if (needdepth) FDrawInfo::EndDrawInfo();
|
||||
|
@ -360,6 +367,7 @@ void GLPortal::End(bool usestencil)
|
|||
GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
||||
glColorMask(0,0,0,0); // no graphics
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
|
@ -386,7 +394,8 @@ void GLPortal::End(bool usestencil)
|
|||
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glColorMask(1,1,1,1);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
glColorMask(1, 1, 1, 1);
|
||||
recursion--;
|
||||
|
||||
// restore old stencil op.
|
||||
|
@ -421,8 +430,10 @@ void GLPortal::End(bool usestencil)
|
|||
glDepthFunc(GL_LEQUAL);
|
||||
glDepthRange(0,1);
|
||||
glColorMask(0,0,0,0); // no graphics
|
||||
gl_RenderState.SetEffect(EFF_STENCIL);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
DrawPortalStencil();
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
glColorMask(1,1,1,1);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
@ -778,18 +789,16 @@ void GLPlaneMirrorPortal::DrawContents()
|
|||
|
||||
validcount++;
|
||||
|
||||
float f = FIXED2FLOAT(planez);
|
||||
if (PlaneMirrorMode < 0) f -= 65536.f; // ceiling mirror: clip everytihng with a z lower than the portal's ceiling
|
||||
else f += 65536.f; // floor mirror: clip everything with a z higher than the portal's floor
|
||||
gl_RenderState.SetClipHeight(f);
|
||||
|
||||
PlaneMirrorFlag++;
|
||||
GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
ClearClipper();
|
||||
|
||||
glEnable(GL_CLIP_PLANE0+renderdepth);
|
||||
// This only works properly for non-sloped planes so don't bother with the math.
|
||||
//double d[4]={origin->a/65536., origin->c/65536., origin->b/65536., FIXED2FLOAT(origin->d)};
|
||||
double d[4]={0, static_cast<double>(PlaneMirrorMode), 0, FIXED2FLOAT(origin->d)};
|
||||
glClipPlane(GL_CLIP_PLANE0+renderdepth, d);
|
||||
|
||||
GLRenderer->DrawScene();
|
||||
glDisable(GL_CLIP_PLANE0+renderdepth);
|
||||
PlaneMirrorFlag--;
|
||||
PlaneMirrorMode=old_pm;
|
||||
}
|
||||
|
@ -988,12 +997,12 @@ void GLHorizonPortal::DrawContents()
|
|||
|
||||
gltexture->Bind();
|
||||
|
||||
bool pushed = gl_SetPlaneTextureRotation(sp, gltexture);
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
|
||||
bool pushed = gl_SetPlaneTextureRotation(sp, gltexture);
|
||||
|
||||
float vx=FIXED2FLOAT(viewx);
|
||||
float vy=FIXED2FLOAT(viewy);
|
||||
|
|
|
@ -82,6 +82,7 @@ class GLPortal
|
|||
static int recursion;
|
||||
static unsigned int QueryObject;
|
||||
protected:
|
||||
static TArray<float> planestack;
|
||||
static int MirrorFlag;
|
||||
static int PlaneMirrorFlag;
|
||||
static int renderdepth;
|
||||
|
@ -101,7 +102,6 @@ private:
|
|||
angle_t savedviewangle;
|
||||
AActor * savedviewactor;
|
||||
area_t savedviewarea;
|
||||
unsigned char clipsave;
|
||||
GLPortal *NextPortal;
|
||||
TArray<BYTE> savedmapsection;
|
||||
TArray<unsigned int> mPrimIndices;
|
||||
|
|
|
@ -200,6 +200,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
muGlowTopPlane.Init(hShader, "uGlowTopPlane");
|
||||
muFixedColormap.Init(hShader, "uFixedColormap");
|
||||
muInterpolationFactor.Init(hShader, "uInterpolationFactor");
|
||||
muClipHeight.Init(hShader, "uClipHeight");
|
||||
|
||||
timer_index = glGetUniformLocation(hShader, "timer");
|
||||
lights_index = glGetUniformLocation(hShader, "lights");
|
||||
|
|
|
@ -193,6 +193,7 @@ class FShader
|
|||
FUniform4f muGlowBottomPlane;
|
||||
FUniform4f muGlowTopPlane;
|
||||
FBufferedUniform1f muInterpolationFactor;
|
||||
FBufferedUniform1f muClipHeight;
|
||||
|
||||
int timer_index;
|
||||
int lights_index;
|
||||
|
|
|
@ -9,6 +9,12 @@ in vec2 glowdist;
|
|||
|
||||
void main()
|
||||
{
|
||||
#ifndef NO_DISCARD
|
||||
// clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient.
|
||||
if (pixelpos.y > uClipHeight + 65536.0) discard;
|
||||
if (pixelpos.y < uClipHeight - 65536.0) discard;
|
||||
#endif
|
||||
|
||||
float fogdist;
|
||||
float fogfactor;
|
||||
|
||||
|
|
|
@ -216,6 +216,12 @@ vec4 applyFog(vec4 frag, float fogfactor)
|
|||
|
||||
void main()
|
||||
{
|
||||
#ifndef NO_DISCARD
|
||||
// clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient.
|
||||
if (pixelpos.y > uClipHeight + 65536.0) discard;
|
||||
if (pixelpos.y < uClipHeight - 65536.0) discard;
|
||||
#endif
|
||||
|
||||
vec4 frag = ProcessTexel();
|
||||
|
||||
switch (uFixedColormap)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// This file contains common data definitions for both vertex and fragment shader
|
||||
|
||||
uniform vec4 uCameraPos;
|
||||
uniform float uClipHeight;
|
||||
|
||||
uniform int uTextureMode;
|
||||
|
||||
|
|
|
@ -2,6 +2,12 @@ in vec4 pixelpos;
|
|||
|
||||
void main()
|
||||
{
|
||||
#ifndef NO_DISCARD
|
||||
// clip plane emulation for plane reflections. These are always perfectly horizontal so a simple check of the pixelpos's y coordinate is sufficient.
|
||||
if (pixelpos.y > uClipHeight + 65536.0) discard;
|
||||
if (pixelpos.y < uClipHeight - 65536.0) discard;
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4(1.0);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue