Merge branch 'v2.x'
This commit is contained in:
commit
77c4533e4b
111 changed files with 22656 additions and 6254 deletions
|
|
@ -239,33 +239,6 @@ set( ZDOOM_LIBS ${ZDOOM_LIBS} ${OPENGL_LIBRARIES} )
|
|||
include_directories( ${OPENGL_INCLUDE_DIR} )
|
||||
|
||||
|
||||
# check for GLEW
|
||||
find_path( GLEW_INCLUDE_DIR GL/glew.h
|
||||
PATHS "/usr/include"
|
||||
"/usr/local/include" )
|
||||
|
||||
if( GLEW_INCLUDE_DIR )
|
||||
message( STATUS "GLEW include files found at ${GLEW_INCLUDE_DIR}" )
|
||||
else( GLEW_INCLUDE_DIR )
|
||||
message( SEND_ERROR "Could not find GLEW include files" )
|
||||
endif( GLEW_INCLUDE_DIR )
|
||||
|
||||
# GLEW include directory
|
||||
include_directories( "${GLEW_INCLUDE_DIR}" )
|
||||
|
||||
if( NOT WIN32 OR APPLE )
|
||||
find_library( GLEW_LIBRARY libGLEW.so )
|
||||
else( NOT WIN32 OR APPLE )
|
||||
find_library( GLEW_LIBRARY glew32 )
|
||||
endif( NOT WIN32 OR APPLE )
|
||||
|
||||
if( NOT GLEW_LIBRARY )
|
||||
message( SEND_ERROR "Could not find GLEW library files" )
|
||||
endif( NOT GLEW_LIBRARY )
|
||||
|
||||
set( ZDOOM_LIBS ${ZDOOM_LIBS} ${GLEW_LIBRARY} )
|
||||
|
||||
|
||||
# Decide on the name of the FMOD library we want to use.
|
||||
|
||||
if( NOT FMOD_LIB_NAME AND MSVC )
|
||||
|
|
@ -581,6 +554,10 @@ endif( NOT DYN_FLUIDSYNTH )
|
|||
|
||||
# Start defining source files for ZDoom
|
||||
set( PLAT_WIN32_SOURCES
|
||||
gl/hqnx_asm/hq2x_asm.cpp
|
||||
gl/hqnx_asm/hq3x_asm.cpp
|
||||
gl/hqnx_asm/hq4x_asm.cpp
|
||||
gl/hqnx_asm/hqnx_asm_Image.cpp
|
||||
win32/eaxedit.cpp
|
||||
win32/fb_d3d9.cpp
|
||||
win32/fb_d3d9_wipe.cpp
|
||||
|
|
@ -727,6 +704,7 @@ file( GLOB HEADER_FILES
|
|||
gl/data/*.h
|
||||
gl/dynlights/*.h
|
||||
gl/hqnx/*.h
|
||||
gl/hqnx_asm/*.h
|
||||
gl/models/*.h
|
||||
gl/renderer/*.h
|
||||
gl/scene/*.h
|
||||
|
|
@ -1046,6 +1024,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
|
||||
|
|
@ -1063,6 +1042,7 @@ add_executable( zdoom WIN32
|
|||
gl/textures/gl_material.cpp
|
||||
gl/textures/gl_hirestex.cpp
|
||||
gl/textures/gl_bitmap.cpp
|
||||
gl/textures/gl_samplers.cpp
|
||||
gl/textures/gl_translate.cpp
|
||||
gl/textures/gl_hqresize.cpp
|
||||
gl/textures/gl_skyboxtexture.cpp
|
||||
|
|
@ -1093,6 +1073,7 @@ add_executable( zdoom WIN32
|
|||
gl/system/gl_framebuffer.cpp
|
||||
gl/system/gl_menu.cpp
|
||||
gl/system/gl_wipe.cpp
|
||||
gl/system/gl_load.c
|
||||
gl/models/gl_models_md3.cpp
|
||||
gl/models/gl_models_md2.cpp
|
||||
gl/models/gl_models.cpp
|
||||
|
|
@ -1297,6 +1278,7 @@ source_group("OpenGL Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/
|
|||
source_group("OpenGL Renderer\\Data" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/data/.+")
|
||||
source_group("OpenGL Renderer\\Dynamic Lights" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/dynlights/.+")
|
||||
source_group("OpenGL Renderer\\HQ Resize" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx/.+")
|
||||
source_group("OpenGL Renderer\\HQ Resize Assembly version" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/hqnx_asm/.+")
|
||||
source_group("OpenGL Renderer\\Models" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/models/.+")
|
||||
source_group("OpenGL Renderer\\Renderer" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/renderer/.+")
|
||||
source_group("OpenGL Renderer\\Scene" REGULAR_EXPRESSION "^${CMAKE_CURRENT_SOURCE_DIR}/gl/scene/.+")
|
||||
|
|
|
|||
|
|
@ -356,7 +356,6 @@ void InitGLRMapinfoData()
|
|||
glset.map_notexturefill = opt->notexturefill;
|
||||
glset.skyrotatevector = opt->skyrotatevector;
|
||||
glset.skyrotatevector2 = opt->skyrotatevector2;
|
||||
if (gl.shadermodel == 2 && glset.map_lightmode ==2) glset.map_lightmode = 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -469,9 +468,8 @@ void gl_RecalcVertexHeights(vertex_t * v)
|
|||
|
||||
void gl_InitData()
|
||||
{
|
||||
LineSpecials[157]=LS_SetGlobalFogParameter;
|
||||
LineSpecials[159]=LS_Sector_SetPlaneReflection;
|
||||
gl_InitModels();
|
||||
LineSpecials[157] = LS_SetGlobalFogParameter;
|
||||
LineSpecials[159] = LS_Sector_SetPlaneReflection;
|
||||
AdjustSpriteOffsets();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ EXTERN_CVAR(Int, gl_weaponlight);
|
|||
|
||||
inline int getExtraLight()
|
||||
{
|
||||
return extralight * gl_weaponlight; // ((glset.lightmode == 8)? 16:8);
|
||||
return extralight * gl_weaponlight;
|
||||
}
|
||||
|
||||
void gl_RecalcVertexHeights(vertex_t * v);
|
||||
|
|
@ -57,5 +57,8 @@ extern TArray<BYTE> currentmapsection;
|
|||
|
||||
void gl_InitPortals();
|
||||
void gl_BuildPortalCoverage(FPortalCoverage *coverage, subsector_t *subsector, FPortal *portal);
|
||||
void gl_InitData();
|
||||
|
||||
extern long gl_frameMS;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
495
src/gl/data/gl_matrix.cpp
Normal file
495
src/gl/data/gl_matrix.cpp
Normal file
|
|
@ -0,0 +1,495 @@
|
|||
/* --------------------------------------------------
|
||||
|
||||
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 FLOATTYPE
|
||||
DegToRad(FLOATTYPE degrees)
|
||||
{
|
||||
return (FLOATTYPE)(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( FLOATTYPE *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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// gl LoadIdentity 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;
|
||||
}
|
||||
|
||||
|
||||
// gl MultMatrix implementation
|
||||
void
|
||||
VSMatrix::multMatrix(const FLOATTYPE *aMatrix)
|
||||
{
|
||||
|
||||
FLOATTYPE 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(FLOATTYPE));
|
||||
}
|
||||
|
||||
#ifdef USE_DOUBLE
|
||||
// gl MultMatrix implementation
|
||||
void
|
||||
VSMatrix::multMatrix(const float *aMatrix)
|
||||
{
|
||||
|
||||
FLOATTYPE 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(FLOATTYPE));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// gl LoadMatrix implementation
|
||||
void
|
||||
VSMatrix::loadMatrix(const FLOATTYPE *aMatrix)
|
||||
{
|
||||
memcpy(mMatrix, aMatrix, 16 * sizeof(FLOATTYPE));
|
||||
}
|
||||
|
||||
#ifdef USE_DOUBLE
|
||||
// gl LoadMatrix implementation
|
||||
void
|
||||
VSMatrix::loadMatrix(const float *aMatrix)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
mMatrix[i] = aMatrix[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// gl Translate implementation with matrix selection
|
||||
void
|
||||
VSMatrix::translate(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z)
|
||||
{
|
||||
FLOATTYPE mat[16];
|
||||
|
||||
setIdentityMatrix(mat);
|
||||
mat[12] = x;
|
||||
mat[13] = y;
|
||||
mat[14] = z;
|
||||
|
||||
multMatrix(mat);
|
||||
}
|
||||
|
||||
|
||||
// gl Scale implementation with matrix selection
|
||||
void
|
||||
VSMatrix::scale(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z)
|
||||
{
|
||||
FLOATTYPE 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(FLOATTYPE angle, FLOATTYPE x, FLOATTYPE y, FLOATTYPE z)
|
||||
{
|
||||
FLOATTYPE mat[16];
|
||||
FLOATTYPE v[3];
|
||||
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
|
||||
FLOATTYPE radAngle = DegToRad(angle);
|
||||
FLOATTYPE co = cos(radAngle);
|
||||
FLOATTYPE si = sin(radAngle);
|
||||
normalize(v);
|
||||
FLOATTYPE x2 = v[0]*v[0];
|
||||
FLOATTYPE y2 = v[1]*v[1];
|
||||
FLOATTYPE 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(FLOATTYPE xPos, FLOATTYPE yPos, FLOATTYPE zPos,
|
||||
FLOATTYPE xLook, FLOATTYPE yLook, FLOATTYPE zLook,
|
||||
FLOATTYPE xUp, FLOATTYPE yUp, FLOATTYPE zUp)
|
||||
{
|
||||
FLOATTYPE 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);
|
||||
|
||||
FLOATTYPE 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(FLOATTYPE fov, FLOATTYPE ratio, FLOATTYPE nearp, FLOATTYPE farp)
|
||||
{
|
||||
FLOATTYPE f = 1.0f / tan (fov * (M_PI / 360.0f));
|
||||
|
||||
loadIdentity();
|
||||
mMatrix[0] = f / ratio;
|
||||
mMatrix[1 * 4 + 1] = f;
|
||||
mMatrix[2 * 4 + 2] = (farp + nearp) / (nearp - farp);
|
||||
mMatrix[3 * 4 + 2] = (2.0f * farp * nearp) / (nearp - farp);
|
||||
mMatrix[2 * 4 + 3] = -1.0f;
|
||||
mMatrix[3 * 4 + 3] = 0.0f;
|
||||
}
|
||||
|
||||
|
||||
// gl Ortho implementation
|
||||
void
|
||||
VSMatrix::ortho(FLOATTYPE left, FLOATTYPE right,
|
||||
FLOATTYPE bottom, FLOATTYPE top,
|
||||
FLOATTYPE nearp, FLOATTYPE farp)
|
||||
{
|
||||
loadIdentity();
|
||||
|
||||
mMatrix[0 * 4 + 0] = 2 / (right - left);
|
||||
mMatrix[1 * 4 + 1] = 2 / (top - bottom);
|
||||
mMatrix[2 * 4 + 2] = -2 / (farp - nearp);
|
||||
mMatrix[3 * 4 + 0] = -(right + left) / (right - left);
|
||||
mMatrix[3 * 4 + 1] = -(top + bottom) / (top - bottom);
|
||||
mMatrix[3 * 4 + 2] = -(farp + nearp) / (farp - nearp);
|
||||
}
|
||||
|
||||
|
||||
// gl Frustum implementation
|
||||
void
|
||||
VSMatrix::frustum(FLOATTYPE left, FLOATTYPE right,
|
||||
FLOATTYPE bottom, FLOATTYPE top,
|
||||
FLOATTYPE nearp, FLOATTYPE farp)
|
||||
{
|
||||
FLOATTYPE 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
|
||||
FLOATTYPE *
|
||||
VSMatrix::get(MatrixTypes aType)
|
||||
{
|
||||
return mMatrix[aType];
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/* -----------------------------------------------------
|
||||
SEND MATRICES TO OPENGL
|
||||
------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
|
||||
// universal
|
||||
void
|
||||
VSMatrix::matrixToGL(int loc)
|
||||
{
|
||||
#ifdef USE_DOUBLE
|
||||
float copyto[16];
|
||||
copy(copyto);
|
||||
glUniformMatrix4fv(loc, 1, false, copyto);
|
||||
#else
|
||||
glUniformMatrix4fv(loc, 1, false, mMatrix);
|
||||
#endif
|
||||
}
|
||||
|
||||
// -----------------------------------------------------
|
||||
// AUX functions
|
||||
// -----------------------------------------------------
|
||||
|
||||
|
||||
// Compute res = M * point
|
||||
void
|
||||
VSMatrix::multMatrixPoint(const FLOATTYPE *point, FLOATTYPE *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 FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *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
|
||||
FLOATTYPE
|
||||
VSMatrix::dotProduct(const FLOATTYPE *a, const FLOATTYPE *b) {
|
||||
|
||||
FLOATTYPE res = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
// Normalize a vec3
|
||||
void
|
||||
VSMatrix::normalize(FLOATTYPE *a) {
|
||||
|
||||
FLOATTYPE 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 FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *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 FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res) {
|
||||
|
||||
res[0] = b[0] + a[0];
|
||||
res[1] = b[1] + a[1];
|
||||
res[2] = b[2] + a[2];
|
||||
}
|
||||
|
||||
|
||||
// returns |a|
|
||||
FLOATTYPE
|
||||
VSMatrix::length(const FLOATTYPE *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 FLOATTYPE *aMatrix)
|
||||
{
|
||||
|
||||
FLOATTYPE 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];
|
||||
|
||||
FLOATTYPE 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(FLOATTYPE *resMat, const FLOATTYPE *aMatrix)
|
||||
{
|
||||
|
||||
FLOATTYPE 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(FLOATTYPE));
|
||||
}
|
||||
112
src/gl/data/gl_matrix.h
Normal file
112
src/gl/data/gl_matrix.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
|
||||
// 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>
|
||||
|
||||
#ifdef USE_DOUBLE
|
||||
typedef double FLOATTYPE;
|
||||
#else
|
||||
typedef float FLOATTYPE;
|
||||
#endif
|
||||
|
||||
class VSMatrix {
|
||||
|
||||
public:
|
||||
|
||||
VSMatrix()
|
||||
{
|
||||
}
|
||||
|
||||
VSMatrix(int)
|
||||
{
|
||||
loadIdentity();
|
||||
}
|
||||
|
||||
void translate(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
|
||||
void scale(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
|
||||
void rotate(FLOATTYPE angle, FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
|
||||
void loadIdentity();
|
||||
#ifdef USE_DOUBLE
|
||||
void multMatrix(const float *aMatrix);
|
||||
#endif
|
||||
void multMatrix(const FLOATTYPE *aMatrix);
|
||||
void multMatrix(const VSMatrix &aMatrix)
|
||||
{
|
||||
multMatrix(aMatrix.mMatrix);
|
||||
}
|
||||
void loadMatrix(const FLOATTYPE *aMatrix);
|
||||
#ifdef USE_DOUBLE
|
||||
void loadMatrix(const float *aMatrix);
|
||||
#endif
|
||||
void lookAt(FLOATTYPE xPos, FLOATTYPE yPos, FLOATTYPE zPos, FLOATTYPE xLook, FLOATTYPE yLook, FLOATTYPE zLook, FLOATTYPE xUp, FLOATTYPE yUp, FLOATTYPE zUp);
|
||||
void perspective(FLOATTYPE fov, FLOATTYPE ratio, FLOATTYPE nearp, FLOATTYPE farp);
|
||||
void ortho(FLOATTYPE left, FLOATTYPE right, FLOATTYPE bottom, FLOATTYPE top, FLOATTYPE nearp=-1.0f, FLOATTYPE farp=1.0f);
|
||||
void frustum(FLOATTYPE left, FLOATTYPE right, FLOATTYPE bottom, FLOATTYPE top, FLOATTYPE nearp, FLOATTYPE farp);
|
||||
void copy(FLOATTYPE * pDest)
|
||||
{
|
||||
memcpy(pDest, mMatrix, 16 * sizeof(FLOATTYPE));
|
||||
}
|
||||
|
||||
#ifdef USE_DOUBLE
|
||||
void copy(float * pDest)
|
||||
{
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
pDest[i] = (float)mMatrix[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const FLOATTYPE *get() const
|
||||
{
|
||||
return mMatrix;
|
||||
}
|
||||
|
||||
void matrixToGL(int location);
|
||||
void multMatrixPoint(const FLOATTYPE *point, FLOATTYPE *res);
|
||||
|
||||
#ifdef USE_DOUBLE
|
||||
void computeNormalMatrix(const float *aMatrix);
|
||||
#endif
|
||||
void computeNormalMatrix(const FLOATTYPE *aMatrix);
|
||||
void computeNormalMatrix(const VSMatrix &aMatrix)
|
||||
{
|
||||
computeNormalMatrix(aMatrix.mMatrix);
|
||||
}
|
||||
|
||||
protected:
|
||||
static void crossProduct(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res);
|
||||
static FLOATTYPE dotProduct(const FLOATTYPE *a, const FLOATTYPE * b);
|
||||
static void normalize(FLOATTYPE *a);
|
||||
static void subtract(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res);
|
||||
static void add(const FLOATTYPE *a, const FLOATTYPE *b, FLOATTYPE *res);
|
||||
static FLOATTYPE length(const FLOATTYPE *a);
|
||||
static void multMatrix(FLOATTYPE *resMatrix, const FLOATTYPE *aMatrix);
|
||||
|
||||
static void setIdentityMatrix(FLOATTYPE *mat, int size = 4);
|
||||
|
||||
/// The storage for matrices
|
||||
FLOATTYPE mMatrix[16];
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -62,7 +62,6 @@
|
|||
#include "gl/gl_functions.h"
|
||||
|
||||
void InitGLRMapinfoData();
|
||||
void gl_InitData();
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
@ -614,15 +613,6 @@ void gl_PreprocessLevel()
|
|||
{
|
||||
int i;
|
||||
|
||||
static int datadone=-1;
|
||||
|
||||
|
||||
if (datadone != restart)
|
||||
{
|
||||
datadone = restart;
|
||||
gl_InitData();
|
||||
}
|
||||
|
||||
PrepareSegs();
|
||||
PrepareSectorData();
|
||||
InitVertexData();
|
||||
|
|
|
|||
|
|
@ -45,27 +45,11 @@
|
|||
#include "c_cvars.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
||||
|
||||
CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
if (self < -1 || self > 2)
|
||||
{
|
||||
self = 0;
|
||||
}
|
||||
else if (self == -1)
|
||||
{
|
||||
if (!(gl.flags & RFL_NVIDIA)) self = 0;
|
||||
else self = 2;
|
||||
}
|
||||
else if (GLRenderer != NULL && GLRenderer->mVBO != NULL && GLRenderer->mVBO->vbo_arg != self)
|
||||
{
|
||||
Printf("Vertex buffer use will be changed for the next level.\n");
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Create / destroy the VBO
|
||||
|
|
@ -74,9 +58,10 @@ CUSTOM_CVAR(Int, gl_usevbo, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCA
|
|||
|
||||
FVertexBuffer::FVertexBuffer()
|
||||
{
|
||||
vbo_id = 0;
|
||||
if (gl_usevbo == -1) gl_usevbo.Callback();
|
||||
vao_id = vbo_id = 0;
|
||||
glGenBuffers(1, &vbo_id);
|
||||
glGenVertexArrays(1, &vao_id);
|
||||
|
||||
}
|
||||
|
||||
FVertexBuffer::~FVertexBuffer()
|
||||
|
|
@ -85,6 +70,15 @@ FVertexBuffer::~FVertexBuffer()
|
|||
{
|
||||
glDeleteBuffers(1, &vbo_id);
|
||||
}
|
||||
if (vao_id != 0)
|
||||
{
|
||||
glDeleteVertexArrays(1, &vao_id);
|
||||
}
|
||||
}
|
||||
|
||||
void FVertexBuffer::BindVBO()
|
||||
{
|
||||
glBindVertexArray(vao_id);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -96,13 +90,60 @@ FVertexBuffer::~FVertexBuffer()
|
|||
FFlatVertexBuffer::FFlatVertexBuffer()
|
||||
: FVertexBuffer()
|
||||
{
|
||||
vbo_arg = gl_usevbo;
|
||||
map = NULL;
|
||||
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||
{
|
||||
unsigned int bytesize = BUFFER_SIZE * sizeof(FFlatVertex);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferStorage(GL_ARRAY_BUFFER, bytesize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, bytesize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
|
||||
glBindVertexArray(vao_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glVertexAttribPointer(VATTR_VERTEX, 3,GL_FLOAT, false, sizeof(FFlatVertex), &VTO->x);
|
||||
glVertexAttribPointer(VATTR_TEXCOORD, 2,GL_FLOAT, false, sizeof(FFlatVertex), &VTO->u);
|
||||
glEnableVertexAttribArray(VATTR_VERTEX);
|
||||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
vbo_shadowdata.Reserve(BUFFER_SIZE);
|
||||
map = &vbo_shadowdata[0];
|
||||
}
|
||||
mNumReserved = mIndex = mCurIndex = 0;
|
||||
}
|
||||
|
||||
FFlatVertexBuffer::~FFlatVertexBuffer()
|
||||
{
|
||||
UnmapVBO();
|
||||
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// immediate mode fallback for drivers without GL_ARB_buffer_storage
|
||||
//
|
||||
// No single core method is performant enough to handle this adequately
|
||||
// so we have to resort to immediate mode instead...
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexBuffer::ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count)
|
||||
{
|
||||
// this will only get called if we can't acquire a persistently mapped buffer.
|
||||
#ifndef CORE_PROFILE
|
||||
glBegin(primtype);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
glVertexAttrib2fv(VATTR_TEXCOORD, &map[offset + i].u);
|
||||
glVertexAttrib3fv(VATTR_VERTEX, &map[offset + i].x);
|
||||
}
|
||||
glEnd();
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -118,7 +159,6 @@ void FFlatVertex::SetFlatVertex(vertex_t *vt, const secplane_t & plane)
|
|||
z = plane.ZatPoint(vt->fx, vt->fy);
|
||||
u = vt->fx/64.f;
|
||||
v = -vt->fy/64.f;
|
||||
w = /*dc = df =*/ 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -260,58 +300,18 @@ void FFlatVertexBuffer::CreateFlatVBO()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexBuffer::MapVBO()
|
||||
{
|
||||
if (map == NULL)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
map = (FFlatVertex*)glMapBufferRange(GL_ARRAY_BUFFER, 0, vbo_shadowdata.Size() * sizeof(FFlatVertex),
|
||||
GL_MAP_WRITE_BIT|GL_MAP_FLUSH_EXPLICIT_BIT|GL_MAP_UNSYNCHRONIZED_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexBuffer::UnmapVBO()
|
||||
{
|
||||
if (map != NULL)
|
||||
{
|
||||
glUnmapBuffer(GL_ARRAY_BUFFER);
|
||||
map = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane)
|
||||
{
|
||||
int startvt = sec->vboindex[plane];
|
||||
int countvt = sec->vbocount[plane];
|
||||
secplane_t &splane = sec->GetSecPlane(plane);
|
||||
FFlatVertex *vt = &vbo_shadowdata[startvt];
|
||||
for(int i=0; i<countvt; i++, vt++)
|
||||
FFlatVertex *mapvt = &map[startvt];
|
||||
for(int i=0; i<countvt; i++, vt++, mapvt++)
|
||||
{
|
||||
vt->z = splane.ZatPoint(vt->x, vt->y);
|
||||
if (plane == sector_t::floor && sec->transdoor) vt->z -= 1;
|
||||
}
|
||||
if (gl.flags & RFL_MAP_BUFFER_RANGE)
|
||||
{
|
||||
MapVBO();
|
||||
if (map == NULL) return; // Error
|
||||
memcpy(&map[startvt], &vbo_shadowdata[startvt], countvt * sizeof(FFlatVertex));
|
||||
glFlushMappedBufferRange(GL_ARRAY_BUFFER, startvt * sizeof(FFlatVertex), countvt * sizeof(FFlatVertex));
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferSubData(GL_ARRAY_BUFFER, startvt * sizeof(FFlatVertex), countvt * sizeof(FFlatVertex), &vbo_shadowdata[startvt]);
|
||||
mapvt->z = vt->z;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -323,12 +323,12 @@ void FFlatVertexBuffer::UpdatePlaneVertices(sector_t *sec, int plane)
|
|||
|
||||
void FFlatVertexBuffer::CreateVBO()
|
||||
{
|
||||
vbo_shadowdata.Clear();
|
||||
if (vbo_arg > 0)
|
||||
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||
{
|
||||
vbo_shadowdata.Resize(mNumReserved);
|
||||
CreateFlatVBO();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, vbo_shadowdata.Size() * sizeof(FFlatVertex), &vbo_shadowdata[0], GL_DYNAMIC_DRAW);
|
||||
mCurIndex = mIndex = vbo_shadowdata.Size();
|
||||
memcpy(map, &vbo_shadowdata[0], vbo_shadowdata.Size() * sizeof(FFlatVertex));
|
||||
}
|
||||
else if (sectors)
|
||||
{
|
||||
|
|
@ -340,27 +340,7 @@ void FFlatVertexBuffer::CreateVBO()
|
|||
sectors[i].vboheight[1] = sectors[i].vboheight[0] = FIXED_MIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexBuffer::BindVBO()
|
||||
{
|
||||
if (vbo_arg > 0)
|
||||
{
|
||||
UnmapVBO();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
glVertexPointer(3,GL_FLOAT, sizeof(FFlatVertex), &VTO->x);
|
||||
glTexCoordPointer(2,GL_FLOAT, sizeof(FFlatVertex), &VTO->u);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glDisableClientState(GL_INDEX_ARRAY);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -373,39 +353,31 @@ void FFlatVertexBuffer::CheckPlanes(sector_t *sector)
|
|||
{
|
||||
if (sector->GetPlaneTexZ(sector_t::ceiling) != sector->vboheight[sector_t::ceiling])
|
||||
{
|
||||
if (sector->ceilingdata == NULL) // only update if there's no thinker attached
|
||||
{
|
||||
UpdatePlaneVertices(sector, sector_t::ceiling);
|
||||
sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling);
|
||||
}
|
||||
UpdatePlaneVertices(sector, sector_t::ceiling);
|
||||
sector->vboheight[sector_t::ceiling] = sector->GetPlaneTexZ(sector_t::ceiling);
|
||||
}
|
||||
if (sector->GetPlaneTexZ(sector_t::floor) != sector->vboheight[sector_t::floor])
|
||||
{
|
||||
if (sector->floordata == NULL) // only update if there's no thinker attached
|
||||
{
|
||||
UpdatePlaneVertices(sector, sector_t::floor);
|
||||
sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor);
|
||||
}
|
||||
UpdatePlaneVertices(sector, sector_t::floor);
|
||||
sector->vboheight[sector_t::floor] = sector->GetPlaneTexZ(sector_t::floor);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// checks the validity of all planes attached to this sector
|
||||
// and updates them if possible. Anything moving will not be
|
||||
// updated unless it stops. This is to ensure that we never
|
||||
// have to synchronize with the rendering process.
|
||||
// and updates them if possible.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FFlatVertexBuffer::CheckUpdate(sector_t *sector)
|
||||
{
|
||||
if (vbo_arg == 2)
|
||||
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||
{
|
||||
CheckPlanes(sector);
|
||||
sector_t *hs = sector->GetHeightSec();
|
||||
if (hs != NULL) CheckPlanes(hs);
|
||||
for(unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++)
|
||||
for (unsigned i = 0; i < sector->e->XFloor.ffloors.Size(); i++)
|
||||
CheckPlanes(sector->e->XFloor.ffloors[i]->model);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
#define __VERTEXBUFFER_H
|
||||
|
||||
#include "tarray.h"
|
||||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
|
||||
struct vertex_t;
|
||||
struct secplane_t;
|
||||
|
|
@ -13,20 +15,28 @@ class FVertexBuffer
|
|||
{
|
||||
protected:
|
||||
unsigned int vbo_id;
|
||||
unsigned int vao_id;
|
||||
|
||||
public:
|
||||
FVertexBuffer();
|
||||
virtual ~FVertexBuffer();
|
||||
virtual void BindVBO() = 0;
|
||||
void BindVBO();
|
||||
};
|
||||
|
||||
struct FFlatVertex // exactly 32 bytes large
|
||||
struct FFlatVertex
|
||||
{
|
||||
float x,z,y,w; // w only for padding to make one vertex 32 bytes - maybe it will find some use later
|
||||
float x,z,y; // world position
|
||||
float u,v; // texture coordinates
|
||||
//float dc, df; // distance to floor and ceiling on walls - used for glowing
|
||||
|
||||
void SetFlatVertex(vertex_t *vt, const secplane_t &plane);
|
||||
void Set(float xx, float zz, float yy, float uu, float vv)
|
||||
{
|
||||
x = xx;
|
||||
z = zz;
|
||||
y = yy;
|
||||
u = uu;
|
||||
v = vv;
|
||||
}
|
||||
};
|
||||
|
||||
#define VTO ((FFlatVertex*)NULL)
|
||||
|
|
@ -35,28 +45,169 @@ struct FFlatVertex // exactly 32 bytes large
|
|||
class FFlatVertexBuffer : public FVertexBuffer
|
||||
{
|
||||
FFlatVertex *map;
|
||||
unsigned int mIndex;
|
||||
unsigned int mCurIndex;
|
||||
unsigned int mNumReserved;
|
||||
|
||||
void MapVBO();
|
||||
void CheckPlanes(sector_t *sector);
|
||||
|
||||
public:
|
||||
int vbo_arg;
|
||||
TArray<FFlatVertex> vbo_shadowdata; // this is kept around for non-VBO rendering
|
||||
const unsigned int BUFFER_SIZE = 2000000;
|
||||
const unsigned int BUFFER_SIZE_TO_USE = 1999500;
|
||||
|
||||
void ImmRenderBuffer(unsigned int primtype, unsigned int offset, unsigned int count);
|
||||
|
||||
public:
|
||||
TArray<FFlatVertex> vbo_shadowdata; // this is kept around for updating the actual (non-readable) buffer and as stand-in for pre GL 4.x
|
||||
|
||||
FFlatVertexBuffer();
|
||||
~FFlatVertexBuffer();
|
||||
|
||||
void CreateVBO();
|
||||
void CheckUpdate(sector_t *sector);
|
||||
|
||||
FFlatVertex *GetBuffer()
|
||||
{
|
||||
return &map[mCurIndex];
|
||||
}
|
||||
unsigned int GetCount(FFlatVertex *newptr, unsigned int *poffset)
|
||||
{
|
||||
|
||||
unsigned int newofs = (unsigned int)(newptr - map);
|
||||
unsigned int diff = newofs - mCurIndex;
|
||||
*poffset = mCurIndex;
|
||||
mCurIndex = newofs;
|
||||
if (mCurIndex >= BUFFER_SIZE_TO_USE) mCurIndex = mIndex;
|
||||
return diff;
|
||||
}
|
||||
#ifdef __GL_PCH_H // we need the system includes for this but we cannot include them ourselves without creating #define clashes. The affected files wouldn't try to draw anyway.
|
||||
void RenderArray(unsigned int primtype, unsigned int offset, unsigned int count)
|
||||
{
|
||||
drawcalls.Clock();
|
||||
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||
{
|
||||
glDrawArrays(primtype, offset, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImmRenderBuffer(primtype, offset, count);
|
||||
}
|
||||
drawcalls.Unclock();
|
||||
}
|
||||
|
||||
void RenderCurrent(FFlatVertex *newptr, unsigned int primtype, unsigned int *poffset = NULL, unsigned int *pcount = NULL)
|
||||
{
|
||||
unsigned int offset;
|
||||
unsigned int count = GetCount(newptr, &offset);
|
||||
RenderArray(primtype, offset, count);
|
||||
if (poffset) *poffset = offset;
|
||||
if (pcount) *pcount = count;
|
||||
}
|
||||
|
||||
#endif
|
||||
void Reset()
|
||||
{
|
||||
mCurIndex = mIndex;
|
||||
}
|
||||
|
||||
private:
|
||||
int CreateSubsectorVertices(subsector_t *sub, const secplane_t &plane, int floor);
|
||||
int CreateSectorVertices(sector_t *sec, const secplane_t &plane, int floor);
|
||||
int CreateVertices(int h, sector_t *sec, const secplane_t &plane, int floor);
|
||||
void CreateFlatVBO();
|
||||
void CreateVBO();
|
||||
void UpdatePlaneVertices(sector_t *sec, int plane);
|
||||
void BindVBO();
|
||||
void CheckUpdate(sector_t *sector);
|
||||
void UnmapVBO();
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct FSkyVertex
|
||||
{
|
||||
float x, y, z, u, v;
|
||||
PalEntry color;
|
||||
|
||||
void Set(float xx, float zz, float yy, float uu=0, float vv=0, PalEntry col=0xffffffff)
|
||||
{
|
||||
x = xx;
|
||||
z = zz;
|
||||
y = yy;
|
||||
u = uu;
|
||||
v = vv;
|
||||
color = col;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class FSkyVertexBuffer : public FVertexBuffer
|
||||
{
|
||||
public:
|
||||
static const int SKYHEMI_UPPER = 1;
|
||||
static const int SKYHEMI_LOWER = 2;
|
||||
|
||||
enum
|
||||
{
|
||||
SKYMODE_MAINLAYER = 0,
|
||||
SKYMODE_SECONDLAYER = 1,
|
||||
SKYMODE_FOGLAYER = 2
|
||||
};
|
||||
|
||||
private:
|
||||
TArray<FSkyVertex> mVertices;
|
||||
TArray<unsigned int> mPrimStart;
|
||||
|
||||
int mRows, mColumns;
|
||||
|
||||
void SkyVertex(int r, int c, bool yflip);
|
||||
void CreateSkyHemisphere(int hemi);
|
||||
void CreateDome();
|
||||
void RenderRow(int prim, int row);
|
||||
|
||||
public:
|
||||
|
||||
FSkyVertexBuffer();
|
||||
virtual ~FSkyVertexBuffer();
|
||||
void RenderDome(FMaterial *tex, int mode);
|
||||
|
||||
};
|
||||
|
||||
#define VSO ((FSkyVertex*)NULL)
|
||||
|
||||
struct FModelVertex
|
||||
{
|
||||
float x, y, z; // world position
|
||||
float u, v; // texture coordinates
|
||||
|
||||
void Set(float xx, float yy, float zz, float uu, float vv)
|
||||
{
|
||||
x = xx;
|
||||
y = yy;
|
||||
z = zz;
|
||||
u = uu;
|
||||
v = vv;
|
||||
}
|
||||
|
||||
void SetNormal(float nx, float ny, float nz)
|
||||
{
|
||||
// GZDoom currently doesn't use normals. This function is so that the high level code can pretend it does.
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FModelVertexBuffer : public FVertexBuffer
|
||||
{
|
||||
int mIndexFrame[2];
|
||||
unsigned int ibo_id;
|
||||
|
||||
public:
|
||||
// these are public because it's the models having to fill them in.
|
||||
TArray<FModelVertex> vbo_shadowdata; // this is kept around for interpolating on GL 2.0
|
||||
TArray<unsigned int> ibo_shadowdata; // this is kept around for interpolating on GL 2.0
|
||||
|
||||
FModelVertexBuffer();
|
||||
~FModelVertexBuffer();
|
||||
|
||||
unsigned int SetupFrame(unsigned int frame1, unsigned int frame2, float factor);
|
||||
};
|
||||
|
||||
#define VMO ((FModelVertex*)NULL)
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -521,11 +521,14 @@ void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius)
|
|||
{
|
||||
if (!subSec) return;
|
||||
|
||||
bool additive = (flags4&MF4_ADDITIVE) || gl_lights_additive;
|
||||
|
||||
subSec->validcount = ::validcount;
|
||||
|
||||
touching_subsectors = AddLightNode(&subSec->lighthead[additive], subSec, this, touching_subsectors);
|
||||
touching_subsectors = AddLightNode(&subSec->lighthead, subSec, this, touching_subsectors);
|
||||
if (subSec->sector->validcount != ::validcount)
|
||||
{
|
||||
touching_sector = AddLightNode(&subSec->render_sector->lighthead, subSec->sector, this, touching_sector);
|
||||
subSec->sector->validcount = ::validcount;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < subSec->numlines; i++)
|
||||
{
|
||||
|
|
@ -537,8 +540,7 @@ void ADynamicLight::CollectWithinRadius(subsector_t *subSec, float radius)
|
|||
if (DMulScale32 (y-seg->v1->y, seg->v2->x-seg->v1->x, seg->v1->x-x, seg->v2->y-seg->v1->y) <=0)
|
||||
{
|
||||
seg->linedef->validcount=validcount;
|
||||
touching_sides = AddLightNode(&seg->sidedef->lighthead[additive],
|
||||
seg->sidedef, this, touching_sides);
|
||||
touching_sides = AddLightNode(&seg->sidedef->lighthead, seg->sidedef, this, touching_sides);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -581,15 +583,21 @@ void ADynamicLight::LinkLight()
|
|||
node->lightsource = NULL;
|
||||
node = node->nextTarget;
|
||||
}
|
||||
node = touching_sector;
|
||||
while (node)
|
||||
{
|
||||
node->lightsource = NULL;
|
||||
node = node->nextTarget;
|
||||
}
|
||||
|
||||
if (radius>0)
|
||||
{
|
||||
// passing in radius*radius allows us to do a distance check without any calls to sqrtf
|
||||
::validcount++;
|
||||
subsector_t * subSec = R_PointInSubsector(x, y);
|
||||
if (subSec)
|
||||
{
|
||||
float fradius = FIXED2FLOAT(radius);
|
||||
::validcount++;
|
||||
CollectWithinRadius(subSec, fradius*fradius);
|
||||
}
|
||||
}
|
||||
|
|
@ -618,6 +626,17 @@ void ADynamicLight::LinkLight()
|
|||
else
|
||||
node = node->nextTarget;
|
||||
}
|
||||
|
||||
node = touching_sector;
|
||||
while (node)
|
||||
{
|
||||
if (node->lightsource == NULL)
|
||||
{
|
||||
node = DeleteLightNode(node);
|
||||
}
|
||||
else
|
||||
node = node->nextTarget;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -670,8 +689,8 @@ size_t AActor::PropagateMark()
|
|||
|
||||
CCMD(listlights)
|
||||
{
|
||||
int walls, sectors;
|
||||
int allwalls=0, allsectors=0;
|
||||
int walls, sectors, subsecs;
|
||||
int allwalls=0, allsectors=0, allsubsecs = 0;
|
||||
int i=0;
|
||||
ADynamicLight * dl;
|
||||
TThinkerIterator<ADynamicLight> it;
|
||||
|
|
@ -680,6 +699,7 @@ CCMD(listlights)
|
|||
{
|
||||
walls=0;
|
||||
sectors=0;
|
||||
subsecs = 0;
|
||||
Printf("%s at (%f, %f, %f), color = 0x%02x%02x%02x, radius = %f ",
|
||||
dl->target? dl->target->GetClass()->TypeName.GetChars() : dl->GetClass()->TypeName.GetChars(),
|
||||
FIXED2FLOAT(dl->x), FIXED2FLOAT(dl->y), FIXED2FLOAT(dl->z), dl->args[LIGHT_RED],
|
||||
|
|
@ -706,17 +726,25 @@ CCMD(listlights)
|
|||
|
||||
node=dl->touching_subsectors;
|
||||
|
||||
while (node)
|
||||
{
|
||||
allsubsecs++;
|
||||
subsecs++;
|
||||
node = node->nextTarget;
|
||||
}
|
||||
|
||||
node = dl->touching_sector;
|
||||
|
||||
while (node)
|
||||
{
|
||||
allsectors++;
|
||||
sectors++;
|
||||
node = node->nextTarget;
|
||||
}
|
||||
|
||||
Printf("- %d walls, %d subsectors\n", walls, sectors);
|
||||
Printf("- %d walls, %d subsectors, %d sectors\n", walls, subsecs, sectors);
|
||||
|
||||
}
|
||||
Printf("%i dynamic lights, %d walls, %d subsectors\n\n\n", i, allwalls, allsectors);
|
||||
Printf("%i dynamic lights, %d walls, %d subsectors, %d sectors\n\n\n", i, allwalls, allsubsecs, allsectors);
|
||||
}
|
||||
|
||||
CCMD(listsublights)
|
||||
|
|
@ -725,22 +753,15 @@ CCMD(listsublights)
|
|||
{
|
||||
subsector_t *sub = &subsectors[i];
|
||||
int lights = 0;
|
||||
int addlights = 0;
|
||||
|
||||
FLightNode * node = sub->lighthead[0];
|
||||
FLightNode * node = sub->lighthead;
|
||||
while (node != NULL)
|
||||
{
|
||||
lights++;
|
||||
node = node->nextLight;
|
||||
}
|
||||
|
||||
node = sub->lighthead[1];
|
||||
while (node != NULL)
|
||||
{
|
||||
addlights++;
|
||||
node = node->nextLight;
|
||||
}
|
||||
Printf(PRINT_LOG, "Subsector %d - %d lights, %d additive lights\n", i, lights, addlights);
|
||||
Printf(PRINT_LOG, "Subsector %d - %d lights\n", i, lights);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ public:
|
|||
FState *targetState;
|
||||
FLightNode * touching_sides;
|
||||
FLightNode * touching_subsectors;
|
||||
FLightNode * touching_sector;
|
||||
|
||||
private:
|
||||
float DistToSeg(seg_t *seg);
|
||||
|
|
@ -182,9 +183,8 @@ struct FDynLightData
|
|||
|
||||
|
||||
|
||||
bool gl_GetLight(Plane & p, ADynamicLight * light, int desaturation, bool checkside, bool forceadditive, FDynLightData &data);
|
||||
bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right, float & scale, int desaturation, bool checkside=true, bool forceadditive=true);
|
||||
bool gl_SetupLightTexture();
|
||||
bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &data);
|
||||
void gl_UploadLights(FDynLightData &data);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -68,11 +68,6 @@ CUSTOM_CVAR (Bool, gl_lights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOIN
|
|||
else gl_DeleteAllAttachedLights();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR (Bool, gl_dynlight_shader, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
if (self && (gl.maxuniforms < 1024 || gl.shadermodel < 4)) self = false;
|
||||
}
|
||||
|
||||
CVAR (Bool, gl_attachedlights, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Bool, gl_lights_checkside, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
CVAR (Float, gl_lights_intensity, 1.0f, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||
|
|
@ -90,8 +85,7 @@ CUSTOM_CVAR (Bool, gl_lights_additive, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG
|
|||
// Sets up the parameters to render one dynamic light onto one plane
|
||||
//
|
||||
//==========================================================================
|
||||
bool gl_GetLight(Plane & p, ADynamicLight * light,
|
||||
int desaturation, bool checkside, bool forceadditive, FDynLightData &ldata)
|
||||
bool gl_GetLight(Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &ldata)
|
||||
{
|
||||
Vector fn, pos;
|
||||
int i = 0;
|
||||
|
|
@ -137,14 +131,6 @@ bool gl_GetLight(Plane & p, ADynamicLight * light,
|
|||
i = 1;
|
||||
}
|
||||
|
||||
if (desaturation>0)
|
||||
{
|
||||
float gray=(r*77 + g*143 + b*37)/257;
|
||||
|
||||
r= (r*(32-desaturation)+ gray*desaturation)/32;
|
||||
g= (g*(32-desaturation)+ gray*desaturation)/32;
|
||||
b= (b*(32-desaturation)+ gray*desaturation)/32;
|
||||
}
|
||||
float *data = &ldata.arrays[i][ldata.arrays[i].Reserve(8)];
|
||||
data[0] = x;
|
||||
data[1] = z;
|
||||
|
|
@ -158,109 +144,3 @@ bool gl_GetLight(Plane & p, ADynamicLight * light,
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the parameters to render one dynamic light onto one plane
|
||||
//
|
||||
//==========================================================================
|
||||
bool gl_SetupLight(Plane & p, ADynamicLight * light, Vector & nearPt, Vector & up, Vector & right,
|
||||
float & scale, int desaturation, bool checkside, bool forceadditive)
|
||||
{
|
||||
Vector fn, pos;
|
||||
|
||||
float x = FIXED2FLOAT(light->x);
|
||||
float y = FIXED2FLOAT(light->y);
|
||||
float z = FIXED2FLOAT(light->z);
|
||||
|
||||
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||
float radius = (light->GetRadius() * gl_lights_size);
|
||||
|
||||
if (radius <= 0.f) return false;
|
||||
if (dist > radius) return false;
|
||||
if (checkside && gl_lights_checkside && p.PointOnSide(x, z, y))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (light->owned && light->target != NULL && !light->target->IsVisibleToPlayer())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
scale = 1.0f / ((2.f * radius) - dist);
|
||||
|
||||
// project light position onto plane (find closest point on plane)
|
||||
|
||||
|
||||
pos.Set(x,z,y);
|
||||
fn=p.Normal();
|
||||
fn.GetRightUp(right, up);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
nearPt = pos + fn * dist;
|
||||
#else
|
||||
Vector tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
#endif
|
||||
|
||||
float cs = 1.0f - (dist / radius);
|
||||
if (gl_lights_additive || light->flags4&MF4_ADDITIVE || forceadditive) cs*=0.2f; // otherwise the light gets too strong.
|
||||
float r = light->GetRed() / 255.0f * cs * gl_lights_intensity;
|
||||
float g = light->GetGreen() / 255.0f * cs * gl_lights_intensity;
|
||||
float b = light->GetBlue() / 255.0f * cs * gl_lights_intensity;
|
||||
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
Vector v;
|
||||
|
||||
gl_RenderState.BlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
v.Set(r, g, b);
|
||||
r = v.Length() - r;
|
||||
g = v.Length() - g;
|
||||
b = v.Length() - b;
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
if (desaturation>0)
|
||||
{
|
||||
float gray=(r*77 + g*143 + b*37)/257;
|
||||
|
||||
r= (r*(32-desaturation)+ gray*desaturation)/32;
|
||||
g= (g*(32-desaturation)+ gray*desaturation)/32;
|
||||
b= (b*(32-desaturation)+ gray*desaturation)/32;
|
||||
}
|
||||
glColor3f(r,g,b);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_SetupLightTexture()
|
||||
{
|
||||
|
||||
if (GLRenderer->gllight == NULL) return false;
|
||||
FMaterial * pat = FMaterial::ValidateTexture(GLRenderer->gllight);
|
||||
pat->BindPatch(CM_DEFAULT, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
inline fixed_t P_AproxDistance3(fixed_t dx, fixed_t dy, fixed_t dz)
|
||||
{
|
||||
return P_AproxDistance(P_AproxDistance(dx,dy),dz);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
/*
|
||||
** gl_dynlight1.cpp
|
||||
** dynamic light buffer for shader rendering
|
||||
** gl_lightbuffer.cpp
|
||||
** Buffer data maintenance for dynamic lights
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2009 Christoph Oelckers
|
||||
** Copyright 2014 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -38,206 +38,184 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#if 0 // unused for now. Code doesn't work
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "p_local.h"
|
||||
#include "vectors.h"
|
||||
#include "g_level.h"
|
||||
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/dynlights/gl_dynlight.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/dynlights/gl_dynlight.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/utility//gl_clock.h"
|
||||
|
||||
static const int INITIAL_BUFFER_SIZE = 160000; // This means 80000 lights per frame and 160000*16 bytes == 2.56 MB.
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
float *mMap;
|
||||
|
||||
FLightBuffer::FLightBuffer()
|
||||
{
|
||||
glGenBuffers(1, &mIDbuf_RGB);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_RGB);
|
||||
|
||||
glGenBuffers(1, &mIDbuf_Position);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_Position);
|
||||
mBufferSize = INITIAL_BUFFER_SIZE;
|
||||
mByteSize = mBufferSize * sizeof(float);
|
||||
if (gl.flags & RFL_SHADER_STORAGE_BUFFER)
|
||||
{
|
||||
mBufferType = GL_SHADER_STORAGE_BUFFER;
|
||||
mBlockAlign = -1;
|
||||
mBlockSize = mBufferSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
mBufferType = GL_UNIFORM_BUFFER;
|
||||
mBlockSize = gl.maxuniformblock / 16;
|
||||
if (mBlockSize > 2048) mBlockSize = 2048; // we don't really need a larger buffer
|
||||
mBlockAlign = mBlockSize / 2;
|
||||
}
|
||||
|
||||
glGenTextures(1, &mIDtex_RGB);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, mIDtex_RGB);
|
||||
gl.TexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA8, mIDbuf_RGB);
|
||||
glGenBuffers(1, &mBufferId);
|
||||
glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, mBufferId);
|
||||
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||
{
|
||||
glBufferStorage(mBufferType, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(mBufferType, mByteSize, NULL, GL_DYNAMIC_DRAW);
|
||||
mBufferPointer = NULL;
|
||||
}
|
||||
|
||||
glGenTextures(1, &mIDtex_Position);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, mIDtex_Position);
|
||||
gl.TexBufferARB(GL_TEXTURE_BUFFER, GL_RGBA32F, mIDbuf_Position);
|
||||
Clear();
|
||||
mLastMappedIndex = UINT_MAX;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FLightBuffer::~FLightBuffer()
|
||||
{
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
glDeleteBuffers(1, &mIDbuf_RGB);
|
||||
glDeleteBuffers(1, &mIDbuf_Position);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
glDeleteTextures(1, &mIDtex_RGB);
|
||||
glDeleteTextures(1, &mIDtex_Position);
|
||||
|
||||
glBindBuffer(mBufferType, 0);
|
||||
glDeleteBuffers(1, &mBufferId);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLightBuffer::BindTextures(int texunit1, int texunit2)
|
||||
void FLightBuffer::Clear()
|
||||
{
|
||||
glActiveTexture(texunit1);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, mIDtex_RGB);
|
||||
glActiveTexture(texunit2);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, mIDtex_Position);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
mIndex = 0;
|
||||
mIndices.Clear();
|
||||
mUploadIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This collects all currently actove
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLightBuffer::CollectLightSources()
|
||||
int FLightBuffer::UploadLights(FDynLightData &data)
|
||||
{
|
||||
if (gl_dynlight_shader && gl_lights && GLRenderer->mLightCount && gl_fixedcolormap == CM_DEFAULT)
|
||||
int size0 = data.arrays[0].Size()/4;
|
||||
int size1 = data.arrays[1].Size()/4;
|
||||
int size2 = data.arrays[2].Size()/4;
|
||||
int totalsize = size0 + size1 + size2 + 1;
|
||||
|
||||
if (mBlockAlign >= 0 && totalsize + (mIndex % mBlockAlign) > mBlockSize)
|
||||
{
|
||||
TArray<FLightRGB> pLights(100);
|
||||
TArray<FLightPosition> pPos(100);
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
mIndex = ((mIndex + mBlockAlign) / mBlockAlign) * mBlockAlign;
|
||||
|
||||
ADynamicLight *light;
|
||||
|
||||
while ((light = it.Next()) != NULL)
|
||||
// can't be rendered all at once.
|
||||
if (totalsize > mBlockSize)
|
||||
{
|
||||
if (!(light->flags2 & MF2_DORMANT))
|
||||
int diff = totalsize - mBlockSize;
|
||||
|
||||
size2 -= diff;
|
||||
if (size2 < 0)
|
||||
{
|
||||
FLightRGB rgb;
|
||||
FLightPosition pos;
|
||||
|
||||
rgb.R = light->GetRed();
|
||||
rgb.G = light->GetGreen();
|
||||
rgb.B = light->GetBlue();
|
||||
rgb.Type = (light->flags4 & MF4_SUBTRACTIVE)? 128 : (light->flags4 & MF4_ADDITIVE || foggy)? 255:0;
|
||||
pos.X = FIXED2FLOAT(light->x);
|
||||
pos.Y = FIXED2FLOAT(light->y);
|
||||
pos.Z = FIXED2FLOAT(light->z);
|
||||
pos.Distance = (light->GetRadius() * gl_lights_size);
|
||||
light->bufferindex = pPos.Size();
|
||||
pLights.Push(rgb);
|
||||
pPos.Push(pos);
|
||||
size1 += size2;
|
||||
size2 = 0;
|
||||
}
|
||||
else light->bufferindex = -1;
|
||||
if (size1 < 0)
|
||||
{
|
||||
size0 += size1;
|
||||
size1 = 0;
|
||||
}
|
||||
totalsize = size0 + size1 + size2 + 1;
|
||||
}
|
||||
GLRenderer->mLightCount = pPos.Size();
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_RGB);
|
||||
glBufferData(GL_TEXTURE_BUFFER, pLights.Size() * sizeof (FLightRGB), &pLights[0], GL_STREAM_DRAW);
|
||||
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, mIDbuf_Position);
|
||||
glBufferData(GL_TEXTURE_BUFFER, pPos.Size() * sizeof (FLightPosition), &pPos[0], GL_STREAM_DRAW);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (totalsize <= 1) return -1;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FLightIndexBuffer::FLightIndexBuffer()
|
||||
{
|
||||
glGenBuffers(1, &mIDBuffer);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, mIDBuffer);
|
||||
|
||||
glGenTextures(1, &mIDTexture);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, mIDTexture);
|
||||
gl.TexBufferARB(GL_TEXTURE_BUFFER, GL_R16UI, mIDBuffer);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FLightIndexBuffer::~FLightIndexBuffer()
|
||||
{
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
glDeleteBuffers(1, &mIDBuffer);
|
||||
|
||||
glBindTexture(GL_TEXTURE_BUFFER, 0);
|
||||
glDeleteTextures(1, &mIDTexture);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLightIndexBuffer::AddLight(ADynamicLight *light)
|
||||
{
|
||||
if (light->bufferindex >= 0)
|
||||
if (mIndex + totalsize > mBufferSize)
|
||||
{
|
||||
mBuffer.Push(light->bufferindex);
|
||||
// reallocate the buffer with twice the size
|
||||
unsigned int newbuffer;
|
||||
|
||||
// first unmap the old buffer
|
||||
glBindBuffer(mBufferType, mBufferId);
|
||||
glUnmapBuffer(mBufferType);
|
||||
|
||||
// create and bind the new buffer, bind the old one to a copy target (too bad that DSA is not yet supported well enough to omit this crap.)
|
||||
glGenBuffers(1, &newbuffer);
|
||||
glBindBufferBase(mBufferType, LIGHTBUF_BINDINGPOINT, newbuffer);
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, mBufferId);
|
||||
|
||||
// create the new buffer's storage (twice as large as the old one)
|
||||
mBufferSize *= 2;
|
||||
mByteSize *= 2;
|
||||
if (gl.flags & RFL_BUFFER_STORAGE)
|
||||
{
|
||||
glBufferStorage(mBufferType, mByteSize, NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
glBufferData(mBufferType, mByteSize, NULL, GL_DYNAMIC_DRAW);
|
||||
mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT|GL_MAP_INVALIDATE_BUFFER_BIT);
|
||||
}
|
||||
|
||||
// copy contents and delete the old buffer.
|
||||
glCopyBufferSubData(GL_COPY_READ_BUFFER, mBufferType, 0, 0, mByteSize/2);
|
||||
glBindBuffer(GL_COPY_READ_BUFFER, 0);
|
||||
glDeleteBuffers(1, &mBufferId);
|
||||
mBufferId = newbuffer;
|
||||
}
|
||||
|
||||
float *copyptr;
|
||||
|
||||
assert(mBufferPointer != NULL);
|
||||
if (mBufferPointer == NULL) return -1;
|
||||
copyptr = mBufferPointer + mIndex * 4;
|
||||
|
||||
float parmcnt[] = { 0, size0, size0 + size1, size0 + size1 + size2 };
|
||||
|
||||
memcpy(©ptr[0], parmcnt, 4 * sizeof(float));
|
||||
memcpy(©ptr[4], &data.arrays[0][0], 4 * size0*sizeof(float));
|
||||
memcpy(©ptr[4 + 4*size0], &data.arrays[1][0], 4 * size1*sizeof(float));
|
||||
memcpy(©ptr[4 + 4*(size0 + size1)], &data.arrays[2][0], 4 * size2*sizeof(float));
|
||||
|
||||
unsigned int bufferindex = mIndex;
|
||||
mIndex += totalsize;
|
||||
draw_dlight += (totalsize-1) / 2;
|
||||
return bufferindex;
|
||||
}
|
||||
|
||||
void FLightBuffer::Begin()
|
||||
{
|
||||
if (!(gl.flags & RFL_BUFFER_STORAGE))
|
||||
{
|
||||
glBindBuffer(mBufferType, mBufferId);
|
||||
mBufferPointer = (float*)glMapBufferRange(mBufferType, 0, mByteSize, GL_MAP_WRITE_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLightIndexBuffer::SendBuffer()
|
||||
void FLightBuffer::Finish()
|
||||
{
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, mIDBuffer);
|
||||
glBufferData(GL_TEXTURE_BUFFER, mBuffer.Size() * sizeof (short), &mBuffer[0], GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_TEXTURE_BUFFER, 0);
|
||||
if (!(gl.flags & RFL_BUFFER_STORAGE))
|
||||
{
|
||||
glBindBuffer(mBufferType, mBufferId);
|
||||
glUnmapBuffer(mBufferType);
|
||||
mBufferPointer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FLightIndexBuffer::BindTexture(int texunit1)
|
||||
int FLightBuffer::BindUBO(unsigned int index)
|
||||
{
|
||||
glActiveTexture(texunit1);
|
||||
glBindTexture(GL_TEXTURE_BUFFER, mIDTexture);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
unsigned int offset = (index / mBlockAlign) * mBlockAlign;
|
||||
|
||||
if (offset != mLastMappedIndex)
|
||||
{
|
||||
// this will only get called if a uniform buffer is used. For a shader storage buffer we only need to bind the buffer once at the start to all shader programs
|
||||
mLastMappedIndex = offset;
|
||||
glBindBufferRange(GL_UNIFORM_BUFFER, LIGHTBUF_BINDINGPOINT, mBufferId, offset*16, mBlockSize*16); // we go from counting vec4's to counting bytes here.
|
||||
}
|
||||
return (index - offset);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -1,66 +1,39 @@
|
|||
#ifndef __GL_LIGHTBUFFER_H
|
||||
#define __GL_LIGHTBUFFER_H
|
||||
|
||||
#if 0
|
||||
class ADynamicLight;
|
||||
|
||||
const int MAX_DYNLIGHTS = 40000; // should hopefully be enough
|
||||
|
||||
struct FLightRGB
|
||||
{
|
||||
unsigned char R,G,B,Type; // Type is 0 for normal, 1 for additive and 2 for subtractive
|
||||
};
|
||||
|
||||
struct FLightPosition
|
||||
{
|
||||
float X,Z,Y,Distance;
|
||||
};
|
||||
#include "tarray.h"
|
||||
struct FDynLightData;
|
||||
|
||||
class FLightBuffer
|
||||
{
|
||||
unsigned int mIDbuf_RGB;
|
||||
unsigned int mIDbuf_Position;
|
||||
TArray<int> mIndices;
|
||||
unsigned int mBufferId;
|
||||
float * mBufferPointer;
|
||||
|
||||
unsigned int mIDtex_RGB;
|
||||
unsigned int mIDtex_Position;
|
||||
unsigned int mBufferType;
|
||||
unsigned int mIndex;
|
||||
unsigned int mUploadIndex;
|
||||
unsigned int mLastMappedIndex;
|
||||
unsigned int mBlockAlign;
|
||||
unsigned int mBlockSize;
|
||||
unsigned int mBufferSize;
|
||||
unsigned int mByteSize;
|
||||
|
||||
public:
|
||||
|
||||
FLightBuffer();
|
||||
~FLightBuffer();
|
||||
//void MapBuffer();
|
||||
//void UnmapBuffer();
|
||||
void BindTextures(int uniloc1, int uniloc2);
|
||||
//void AddLight(ADynamicLight *light, bool foggy);
|
||||
void CollectLightSources();
|
||||
};
|
||||
|
||||
class FLightIndexBuffer
|
||||
{
|
||||
unsigned int mIDBuffer;
|
||||
unsigned int mIDTexture;
|
||||
|
||||
TArray<unsigned short> mBuffer;
|
||||
|
||||
public:
|
||||
|
||||
FLightIndexBuffer();
|
||||
~FLightIndexBuffer();
|
||||
void AddLight(ADynamicLight *light);
|
||||
void SendBuffer();
|
||||
void BindTexture(int loc1);
|
||||
|
||||
void ClearBuffer()
|
||||
{
|
||||
mBuffer.Clear();
|
||||
}
|
||||
|
||||
int GetLightIndex()
|
||||
{
|
||||
return mBuffer.Size();
|
||||
}
|
||||
|
||||
void Clear();
|
||||
int UploadLights(FDynLightData &data);
|
||||
void Begin();
|
||||
void Finish();
|
||||
int BindUBO(unsigned int index);
|
||||
unsigned int GetBlockSize() const { return mBlockSize; }
|
||||
unsigned int GetBufferType() const { return mBufferType; }
|
||||
unsigned int GetIndexPtr() const { return mIndices.Size(); }
|
||||
void StoreIndex(int index) { mIndices.Push(index); }
|
||||
int GetIndex(int i) const { return mIndices[i]; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2991
src/gl/hqnx_asm/hq2x_asm.cpp
Normal file
2991
src/gl/hqnx_asm/hq2x_asm.cpp
Normal file
File diff suppressed because it is too large
Load diff
3874
src/gl/hqnx_asm/hq3x_asm.cpp
Normal file
3874
src/gl/hqnx_asm/hq3x_asm.cpp
Normal file
File diff suppressed because it is too large
Load diff
5474
src/gl/hqnx_asm/hq4x_asm.cpp
Normal file
5474
src/gl/hqnx_asm/hq4x_asm.cpp
Normal file
File diff suppressed because it is too large
Load diff
39
src/gl/hqnx_asm/hqnx_asm.h
Normal file
39
src/gl/hqnx_asm/hqnx_asm.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
//hqnx filter library
|
||||
//----------------------------------------------------------
|
||||
//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com )
|
||||
//Copyright (C) 2009 Benjamin Berkels
|
||||
//
|
||||
//This program is free software; you can redistribute it and/or
|
||||
//modify it under the terms of the GNU Lesser General Public
|
||||
//License as published by the Free Software Foundation; either
|
||||
//version 2.1 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
|
||||
//Lesser General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU Lesser General Public
|
||||
//License along with this program; if not, write to the Free Software
|
||||
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
#ifndef __HQNX_H__
|
||||
#define __HQNX_H__
|
||||
|
||||
#pragma warning(disable:4799)
|
||||
|
||||
#include "hqnx_asm_Image.h"
|
||||
|
||||
namespace HQnX_asm
|
||||
{
|
||||
void DLL hq2x_32( int * pIn, unsigned char * pOut, int Xres, int Yres, int BpL );
|
||||
void DLL hq3x_32( int * pIn, unsigned char * pOut, int Xres, int Yres, int BpL );
|
||||
void DLL hq4x_32( int * pIn, unsigned char * pOut, int Xres, int Yres, int BpL );
|
||||
int DLL hq4x_32 ( CImage &ImageIn, CImage &ImageOut );
|
||||
|
||||
void DLL InitLUTs();
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //__HQNX_H__
|
||||
1179
src/gl/hqnx_asm/hqnx_asm_Image.cpp
Normal file
1179
src/gl/hqnx_asm/hqnx_asm_Image.cpp
Normal file
File diff suppressed because it is too large
Load diff
150
src/gl/hqnx_asm/hqnx_asm_Image.h
Normal file
150
src/gl/hqnx_asm/hqnx_asm_Image.h
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
//CImage class - loading and saving BMP and TGA files
|
||||
//----------------------------------------------------------
|
||||
//Copyright (C) 2003 MaxSt ( maxst@hiend3d.com )
|
||||
//
|
||||
//This program is free software; you can redistribute it and/or
|
||||
//modify it under the terms of the GNU Lesser General Public
|
||||
//License as published by the Free Software Foundation; either
|
||||
//version 2.1 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
|
||||
//Lesser General Public License for more details.
|
||||
//
|
||||
//You should have received a copy of the GNU Lesser General Public
|
||||
//License along with this program; if not, write to the Free Software
|
||||
//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
//#ifdef WIN32
|
||||
//#define DLL __declspec(dllexport)
|
||||
//#else
|
||||
#define DLL
|
||||
//#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#pragma once
|
||||
#pragma warning(disable: 4103)
|
||||
#pragma pack(1)
|
||||
|
||||
namespace HQnX_asm
|
||||
{
|
||||
|
||||
typedef struct { unsigned char b, g, r; } _BGR;
|
||||
typedef struct { unsigned char b, g, r, a; } _BGRA;
|
||||
|
||||
class CImage
|
||||
{
|
||||
public:
|
||||
DLL CImage();
|
||||
DLL ~CImage();
|
||||
|
||||
enum CImageErrors
|
||||
{
|
||||
eConvUnknownFormat = 10,
|
||||
eConvSourceMemory = 11,
|
||||
eConvDestMemory = 12,
|
||||
|
||||
eSaveBmpFileOpen = 20,
|
||||
eSaveBmpFileWrite = 21,
|
||||
eSaveBmpSourceMemory = 22,
|
||||
eSaveBmpColorDepth = 23,
|
||||
|
||||
eLoadBmpFileOpen = 30,
|
||||
eLoadBmpFileRead = 31,
|
||||
eLoadBmpBadFormat = 32,
|
||||
eLoadBmpInit = 33,
|
||||
eLoadBmpColorDepth = 34,
|
||||
|
||||
eSaveTgaFileOpen = 40,
|
||||
eSaveTgaFileWrite = 41,
|
||||
eSaveTgaSourceMemory = 42,
|
||||
eSaveTgaColorDepth = 43,
|
||||
|
||||
eLoadTgaFileOpen = 50,
|
||||
eLoadTgaFileRead = 51,
|
||||
eLoadTgaBadFormat = 52,
|
||||
eLoadTgaInit = 53,
|
||||
eLoadTgaColorDepth = 54,
|
||||
|
||||
eLoadFilename = 60,
|
||||
eSaveFilename = 61,
|
||||
};
|
||||
|
||||
struct _BMPFILEHEADER
|
||||
{
|
||||
unsigned short bfType;
|
||||
long int bfSize, bfRes1, bfOffBits;
|
||||
};
|
||||
|
||||
struct _BMPIMAGEHEADEROLD
|
||||
{
|
||||
long int biSize;
|
||||
unsigned short biWidth, biHeight;
|
||||
unsigned short biPlanes, biBitCount;
|
||||
};
|
||||
|
||||
struct _BMPIMAGEHEADER
|
||||
{
|
||||
long int biSize, biWidth, biHeight;
|
||||
unsigned short biPlanes, biBitCount;
|
||||
long int biCompression, biSizeImage;
|
||||
long int biXPelsPerMeter, biYPelsPerMeter;
|
||||
long int biClrUsed, biClrImportant;
|
||||
};
|
||||
|
||||
struct _TGAHEADER
|
||||
{
|
||||
unsigned char tiIdentSize;
|
||||
unsigned char tiPaletteIncluded;
|
||||
unsigned char tiImageType;
|
||||
unsigned short tiPaletteStart;
|
||||
unsigned short tiPaletteSize;
|
||||
unsigned char tiPaletteBpp;
|
||||
unsigned short tiX0;
|
||||
unsigned short tiY0;
|
||||
unsigned short tiXres;
|
||||
unsigned short tiYres;
|
||||
unsigned char tiBitPerPixel;
|
||||
unsigned char tiAttrBits;
|
||||
};
|
||||
|
||||
public:
|
||||
int DLL Init( int Xres, int Yres, unsigned short BitPerPixel );
|
||||
int DLL SetImage(unsigned char *img, int width, int height, int bpp);
|
||||
int DLL Destroy();
|
||||
int DLL ConvertTo32( void );
|
||||
int DLL ConvertTo24( void );
|
||||
int DLL ConvertTo16( void );
|
||||
int DLL Convert8To17( int transindex );
|
||||
int DLL Convert32To17( void );
|
||||
int SaveBmp(char *szFilename);
|
||||
int LoadBmp(char *szFilename);
|
||||
int SaveTga(char *szFilename, bool bCompressed );
|
||||
int LoadTga(char *szFilename);
|
||||
int DLL Load(char *szFilename);
|
||||
int DLL Save(char *szFilename);
|
||||
|
||||
private:
|
||||
void Output( char * pcData, int nSize );
|
||||
void Output( char c );
|
||||
void Output( void );
|
||||
unsigned char Input( void );
|
||||
|
||||
public:
|
||||
int m_Xres, m_Yres;
|
||||
unsigned short m_BitPerPixel;
|
||||
unsigned short m_BytePerPixel;
|
||||
unsigned char * m_pBitmap;
|
||||
_BGR m_Pal[256];
|
||||
|
||||
private:
|
||||
int m_NumPixel;
|
||||
FILE * f;
|
||||
int m_nCount;
|
||||
char m_cBuf[32768];
|
||||
};
|
||||
|
||||
#pragma pack(8)
|
||||
|
||||
}
|
||||
|
|
@ -59,6 +59,7 @@
|
|||
#include "gl/utility/gl_geometric.h"
|
||||
#include "gl/utility/gl_convert.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
|
||||
static inline float GetTimeFloat()
|
||||
{
|
||||
|
|
@ -68,7 +69,6 @@ static inline float GetTimeFloat()
|
|||
CVAR(Bool, gl_interpolate_model_frames, true, CVAR_ARCHIVE)
|
||||
CVAR(Bool, gl_light_models, true, CVAR_ARCHIVE)
|
||||
EXTERN_CVAR(Int, gl_fogmode)
|
||||
EXTERN_CVAR(Bool, gl_dynlight_shader)
|
||||
|
||||
extern TDeletingArray<FVoxel *> Voxels;
|
||||
extern TDeletingArray<FVoxelDef *> VoxelDefs;
|
||||
|
|
@ -92,6 +92,65 @@ public:
|
|||
|
||||
DeletingModelArray Models;
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FModelVertexBuffer::FModelVertexBuffer()
|
||||
{
|
||||
ibo_id = 0;
|
||||
glGenBuffers(1, &ibo_id);
|
||||
//for (unsigned i = 1; i < Models.Size(); i++)
|
||||
for (int i = Models.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
Models[i]->BuildVertexBuffer(this);
|
||||
}
|
||||
|
||||
glBindVertexArray(vao_id);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER,vbo_shadowdata.Size() * sizeof(FModelVertex), &vbo_shadowdata[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER,ibo_shadowdata.Size() * sizeof(unsigned int), &ibo_shadowdata[0], GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(VATTR_VERTEX);
|
||||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glEnableVertexAttribArray(VATTR_VERTEX2);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
FModelVertexBuffer::~FModelVertexBuffer()
|
||||
{
|
||||
if (ibo_id != 0)
|
||||
{
|
||||
glDeleteBuffers(1, &ibo_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Sets up the buffer starts for frame interpolation
|
||||
// This must be called after gl_RenderState.Apply!
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
unsigned int FModelVertexBuffer::SetupFrame(unsigned int frame1, unsigned int frame2, float factor)
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].x);
|
||||
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame1].u);
|
||||
glVertexAttribPointer(VATTR_VERTEX2, 3, GL_FLOAT, false, sizeof(FModelVertex), &VMO[frame2].x);
|
||||
return frame1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static TArray<FSpriteModelFrame> SpriteModelFrames;
|
||||
static int * SpriteModelHash;
|
||||
//TArray<FStateModelFrame> StateModelFrames;
|
||||
|
|
@ -619,7 +678,6 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf,
|
|||
const FState *curState,
|
||||
const int curTics,
|
||||
const PClass *ti,
|
||||
int cm,
|
||||
Matrix3x4 *normaltransform,
|
||||
int translation)
|
||||
{
|
||||
|
|
@ -676,15 +734,19 @@ void gl_RenderFrameModels( const FSpriteModelFrame *smf,
|
|||
|
||||
if (mdl!=NULL)
|
||||
{
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mModelVBO);
|
||||
|
||||
if ( smfNext && smf->modelframes[i] != smfNext->modelframes[i] )
|
||||
mdl->RenderFrameInterpolated(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, cm, translation);
|
||||
mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smfNext->modelframes[i], inter, translation);
|
||||
else
|
||||
mdl->RenderFrame(smf->skins[i], smf->modelframes[i], cm, translation);
|
||||
mdl->RenderFrame(smf->skins[i], smf->modelframes[i], smf->modelframes[i], 0.f, translation);
|
||||
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gl_RenderModel(GLSprite * spr, int cm)
|
||||
void gl_RenderModel(GLSprite * spr)
|
||||
{
|
||||
FSpriteModelFrame * smf = spr->modelframe;
|
||||
|
||||
|
|
@ -745,81 +807,41 @@ void gl_RenderModel(GLSprite * spr, int cm)
|
|||
// This is rather crappy way to transfer fixet_t type into angle in degrees, but its works!
|
||||
if(smf->flags & MDL_INHERITACTORPITCH) pitch += float(static_cast<double>(spr->actor->pitch >> 16) / (1 << 13) * 45 + static_cast<double>(spr->actor->pitch & 0x0000FFFF) / (1 << 29) * 45);
|
||||
if(smf->flags & MDL_INHERITACTORROLL) roll += float(static_cast<double>(spr->actor->roll >> 16) / (1 << 13) * 45 + static_cast<double>(spr->actor->roll & 0x0000FFFF) / (1 << 29) * 45);
|
||||
|
||||
if (gl.shadermodel < 4)
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE7); // Hijack the otherwise unused seventh texture matrix for the model to world transformation.
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
gl_RenderState.mModelMatrix.loadIdentity();
|
||||
|
||||
// Model space => World space
|
||||
glTranslatef(spr->x, spr->z, spr->y );
|
||||
gl_RenderState.mModelMatrix.translate(spr->x, spr->z, spr->y );
|
||||
|
||||
// Applying model transformations:
|
||||
// 1) Applying actor angle, pitch and roll to the model
|
||||
glRotatef(-angle, 0, 1, 0);
|
||||
glRotatef(pitch, 0, 0, 1);
|
||||
glRotatef(-roll, 1, 0, 0);
|
||||
gl_RenderState.mModelMatrix.rotate(-angle, 0, 1, 0);
|
||||
gl_RenderState.mModelMatrix.rotate(pitch, 0, 0, 1);
|
||||
gl_RenderState.mModelMatrix.rotate(-roll, 1, 0, 0);
|
||||
|
||||
// 2) Applying Doomsday like rotation of the weapon pickup models
|
||||
// The rotation angle is based on the elapsed time.
|
||||
|
||||
if( smf->flags & MDL_ROTATING )
|
||||
{
|
||||
glTranslatef(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ);
|
||||
glRotatef(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate);
|
||||
glTranslatef(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ);
|
||||
gl_RenderState.mModelMatrix.translate(smf->rotationCenterX, smf->rotationCenterY, smf->rotationCenterZ);
|
||||
gl_RenderState.mModelMatrix.rotate(rotateOffset, smf->xrotate, smf->yrotate, smf->zrotate);
|
||||
gl_RenderState.mModelMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterY, -smf->rotationCenterZ);
|
||||
}
|
||||
|
||||
// 3) Scaling model.
|
||||
glScalef(scaleFactorX, scaleFactorZ, scaleFactorY);
|
||||
gl_RenderState.mModelMatrix.scale(scaleFactorX, scaleFactorZ, scaleFactorY);
|
||||
|
||||
// 4) Aplying model offsets (model offsets do not depend on model scalings).
|
||||
glTranslatef(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale);
|
||||
gl_RenderState.mModelMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale);
|
||||
|
||||
// 5) Applying model rotations.
|
||||
glRotatef(-ANGLE_TO_FLOAT(smf->angleoffset), 0, 1, 0);
|
||||
glRotatef(smf->pitchoffset, 0, 0, 1);
|
||||
glRotatef(-smf->rolloffset, 1, 0, 0);
|
||||
|
||||
if (gl.shadermodel >= 4) glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
#if 0
|
||||
if (gl_light_models)
|
||||
{
|
||||
// The normal transform matrix only contains the inverse rotations and scalings but not the translations
|
||||
NormalTransform.MakeIdentity();
|
||||
|
||||
NormalTransform.Scale(1.f/scaleFactorX, 1.f/scaleFactorZ, 1.f/scaleFactorY);
|
||||
if( smf->flags & MDL_ROTATING ) NormalTransform.Rotate(smf->xrotate, smf->yrotate, smf->zrotate, -rotateOffset);
|
||||
if (pitch != 0) NormalTransform.Rotate(0,0,1,-pitch);
|
||||
if (angle != 0) NormalTransform.Rotate(0,1,0, angle);
|
||||
|
||||
gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, &ModelToWorld, &NormalTransform, translation );
|
||||
}
|
||||
#endif
|
||||
|
||||
gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), cm, NULL, translation );
|
||||
|
||||
if (gl.shadermodel < 4)
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
}
|
||||
else
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE7);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
gl_RenderState.mModelMatrix.rotate(-ANGLE_TO_FLOAT(smf->angleoffset), 0, 1, 0);
|
||||
gl_RenderState.mModelMatrix.rotate(smf->pitchoffset, 0, 0, 1);
|
||||
gl_RenderState.mModelMatrix.rotate(-smf->rolloffset, 1, 0, 0);
|
||||
gl_RenderState.EnableModelMatrix(true);
|
||||
gl_RenderFrameModels( smf, spr->actor->state, spr->actor->tics, RUNTIME_TYPE(spr->actor), NULL, translation );
|
||||
gl_RenderState.EnableModelMatrix(false);
|
||||
|
||||
glDepthFunc(GL_LESS);
|
||||
if (!( spr->actor->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
|
||||
|
|
@ -833,7 +855,7 @@ void gl_RenderModel(GLSprite * spr, int cm)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm)
|
||||
void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy)
|
||||
{
|
||||
AActor * playermo=players[consoleplayer].camera;
|
||||
FSpriteModelFrame *smf = gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->state->sprite, psp->state->GetFrame(), false);
|
||||
|
|
@ -842,11 +864,6 @@ void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm)
|
|||
if ( smf == NULL )
|
||||
return;
|
||||
|
||||
// [BB] The model has to be drawn independtly from the position of the player,
|
||||
// so we have to reset the GL_MODELVIEW matrix.
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
// [BB] In case the model should be rendered translucent, do back face culling.
|
||||
|
|
@ -858,28 +875,31 @@ void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm)
|
|||
glFrontFace(GL_CCW);
|
||||
}
|
||||
|
||||
// [BB] The model has to be drawn independently from the position of the player,
|
||||
// so we have to reset the view matrix.
|
||||
gl_RenderState.mViewMatrix.loadIdentity();
|
||||
|
||||
// Scaling model (y scale for a sprite means height, i.e. z in the world!).
|
||||
glScalef(smf->xscale, smf->zscale, smf->yscale);
|
||||
gl_RenderState.mViewMatrix.scale(smf->xscale, smf->zscale, smf->yscale);
|
||||
|
||||
// Aplying model offsets (model offsets do not depend on model scalings).
|
||||
glTranslatef(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale);
|
||||
gl_RenderState.mViewMatrix.translate(smf->xoffset / smf->xscale, smf->zoffset / smf->zscale, smf->yoffset / smf->yscale);
|
||||
|
||||
// [BB] Weapon bob, very similar to the normal Doom weapon bob.
|
||||
glRotatef(FIXED2FLOAT(ofsx)/4, 0, 1, 0);
|
||||
glRotatef(-FIXED2FLOAT(ofsy-WEAPONTOP)/4, 1, 0, 0);
|
||||
gl_RenderState.mViewMatrix.rotate(FIXED2FLOAT(ofsx)/4, 0, 1, 0);
|
||||
gl_RenderState.mViewMatrix.rotate(-FIXED2FLOAT(ofsy-WEAPONTOP)/4, 1, 0, 0);
|
||||
|
||||
// [BB] For some reason the jDoom models need to be rotated.
|
||||
glRotatef(90., 0, 1, 0);
|
||||
gl_RenderState.mViewMatrix.rotate(90.f, 0, 1, 0);
|
||||
|
||||
// Applying angleoffset, pitchoffset, rolloffset.
|
||||
glRotatef(-ANGLE_TO_FLOAT(smf->angleoffset), 0, 1, 0);
|
||||
glRotatef(smf->pitchoffset, 0, 0, 1);
|
||||
glRotatef(-smf->rolloffset, 1, 0, 0);
|
||||
gl_RenderState.mViewMatrix.rotate(-ANGLE_TO_FLOAT(smf->angleoffset), 0, 1, 0);
|
||||
gl_RenderState.mViewMatrix.rotate(smf->pitchoffset, 0, 0, 1);
|
||||
gl_RenderState.mViewMatrix.rotate(-smf->rolloffset, 1, 0, 0);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
|
||||
gl_RenderFrameModels( smf, psp->state, psp->tics, playermo->player->ReadyWeapon->GetClass(), cm, NULL, 0 );
|
||||
gl_RenderFrameModels( smf, psp->state, psp->tics, playermo->player->ReadyWeapon->GetClass(), NULL, 0 );
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
glDepthFunc(GL_LESS);
|
||||
if (!( playermo->RenderStyle == LegacyRenderStyles[STYLE_Normal] ))
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
|
@ -901,16 +921,3 @@ bool gl_IsHUDModelForPlayerAvailable (player_t * player)
|
|||
return ( smf != NULL );
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// gl_CleanModelData
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void gl_CleanModelData()
|
||||
{
|
||||
for (unsigned i=0;i<Models.Size(); i++)
|
||||
{
|
||||
Models[i]->CleanGLData();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@
|
|||
#define __GL_MODELS_H_
|
||||
|
||||
#include "gl/utility/gl_geometric.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "p_pspr.h"
|
||||
#include "r_data/voxels.h"
|
||||
|
||||
|
||||
#define MAX_LODS 4
|
||||
|
||||
enum { VX, VZ, VY };
|
||||
|
|
@ -27,11 +29,8 @@ public:
|
|||
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length) = 0;
|
||||
virtual int FindFrame(const char * name) = 0;
|
||||
virtual void RenderFrame(FTexture * skin, int frame, int cm, int translation=0) = 0;
|
||||
// [BB] Added RenderFrameInterpolated
|
||||
virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation=0) = 0;
|
||||
virtual void MakeGLData() {}
|
||||
virtual void CleanGLData() {}
|
||||
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0) = 0;
|
||||
virtual void BuildVertexBuffer(FModelVertexBuffer *buf) = 0;
|
||||
|
||||
|
||||
|
||||
|
|
@ -56,7 +55,7 @@ protected:
|
|||
int flags;
|
||||
};
|
||||
|
||||
struct FModelVertex
|
||||
struct DMDModelVertex
|
||||
{
|
||||
float xyz[3];
|
||||
};
|
||||
|
|
@ -92,8 +91,9 @@ protected:
|
|||
struct ModelFrame
|
||||
{
|
||||
char name[16];
|
||||
FModelVertex *vertices;
|
||||
FModelVertex *normals;
|
||||
DMDModelVertex *vertices;
|
||||
DMDModelVertex *normals;
|
||||
unsigned int vindex;
|
||||
};
|
||||
|
||||
struct DMDLoDInfo
|
||||
|
|
@ -107,7 +107,6 @@ protected:
|
|||
struct DMDLoD
|
||||
{
|
||||
FTriangle * triangles;
|
||||
int * glCommands;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -120,26 +119,27 @@ protected:
|
|||
ModelFrame * frames;
|
||||
DMDLoDInfo lodInfo[MAX_LODS];
|
||||
DMDLoD lods[MAX_LODS];
|
||||
char *vertexUsage; // Bitfield for each vertex.
|
||||
bool allowTexComp; // Allow texture compression with this.
|
||||
|
||||
static void RenderGLCommands(void *glCommands, unsigned int numVertices,FModelVertex * vertices);
|
||||
|
||||
public:
|
||||
FDMDModel()
|
||||
{
|
||||
loaded = false;
|
||||
frames = NULL;
|
||||
skins = NULL;
|
||||
lods[0].glCommands = NULL;
|
||||
for (int i = 0; i < MAX_LODS; i++)
|
||||
{
|
||||
lods[i].triangles = NULL;
|
||||
}
|
||||
info.numLODs = 0;
|
||||
texCoords = NULL;
|
||||
}
|
||||
virtual ~FDMDModel();
|
||||
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
||||
virtual int FindFrame(const char * name);
|
||||
virtual void RenderFrame(FTexture * skin, int frame, int cm, int translation=0);
|
||||
virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation=0);
|
||||
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
|
||||
virtual void BuildVertexBuffer(FModelVertexBuffer *buf);
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -189,11 +189,15 @@ class FMD3Model : public FModel
|
|||
MD3TexCoord * texcoords;
|
||||
MD3Vertex * vertices;
|
||||
|
||||
unsigned int vindex; // contains numframes arrays of vertices
|
||||
unsigned int iindex;
|
||||
|
||||
MD3Surface()
|
||||
{
|
||||
tris=NULL;
|
||||
vertices=NULL;
|
||||
texcoords=NULL;
|
||||
vindex = iindex = UINT_MAX;
|
||||
}
|
||||
|
||||
~MD3Surface()
|
||||
|
|
@ -220,30 +224,20 @@ class FMD3Model : public FModel
|
|||
MD3Frame * frames;
|
||||
MD3Surface * surfaces;
|
||||
|
||||
void RenderTriangles(MD3Surface * surf, MD3Vertex * vert);
|
||||
|
||||
public:
|
||||
FMD3Model() { }
|
||||
virtual ~FMD3Model();
|
||||
|
||||
virtual bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
||||
virtual int FindFrame(const char * name);
|
||||
virtual void RenderFrame(FTexture * skin, int frame, int cm, int translation=0);
|
||||
virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation=0);
|
||||
};
|
||||
|
||||
class FVoxelVertexBuffer;
|
||||
|
||||
struct FVoxelVertex
|
||||
{
|
||||
float x,y,z;
|
||||
float u,v;
|
||||
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
|
||||
virtual void BuildVertexBuffer(FModelVertexBuffer *buf);
|
||||
};
|
||||
|
||||
struct FVoxelVertexHash
|
||||
{
|
||||
// Returns the hash value for a key.
|
||||
hash_t Hash(const FVoxelVertex &key)
|
||||
hash_t Hash(const FModelVertex &key)
|
||||
{
|
||||
int ix = xs_RoundToInt(key.x);
|
||||
int iy = xs_RoundToInt(key.y);
|
||||
|
|
@ -252,7 +246,7 @@ struct FVoxelVertexHash
|
|||
}
|
||||
|
||||
// Compares two keys, returning zero if they are the same.
|
||||
int Compare(const FVoxelVertex &left, const FVoxelVertex &right)
|
||||
int Compare(const FModelVertex &left, const FModelVertex &right)
|
||||
{
|
||||
return left.x != right.x || left.y != right.y || left.z != right.z || left.u != right.u || left.v != right.v;
|
||||
}
|
||||
|
|
@ -266,7 +260,7 @@ struct FIndexInit
|
|||
}
|
||||
};
|
||||
|
||||
typedef TMap<FVoxelVertex, unsigned int, FVoxelVertexHash, FIndexInit> FVoxelMap;
|
||||
typedef TMap<FModelVertex, unsigned int, FVoxelVertexHash, FIndexInit> FVoxelMap;
|
||||
|
||||
|
||||
class FVoxelModel : public FModel
|
||||
|
|
@ -274,26 +268,25 @@ class FVoxelModel : public FModel
|
|||
protected:
|
||||
FVoxel *mVoxel;
|
||||
bool mOwningVoxel; // if created through MODELDEF deleting this object must also delete the voxel object
|
||||
TArray<FVoxelVertex> mVertices;
|
||||
TArray<FModelVertex> mVertices;
|
||||
TArray<unsigned int> mIndices;
|
||||
FVoxelVertexBuffer *mVBO;
|
||||
FTexture *mPalette;
|
||||
unsigned int vindex;
|
||||
unsigned int iindex;
|
||||
|
||||
void MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &check);
|
||||
void AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3, int y3, int z3, int x4, int y4, int z4, BYTE color, FVoxelMap &check);
|
||||
void AddVertex(FVoxelVertex &vert, FVoxelMap &check);
|
||||
unsigned int AddVertex(FModelVertex &vert, FVoxelMap &check);
|
||||
|
||||
public:
|
||||
FVoxelModel(FVoxel *voxel, bool owned);
|
||||
~FVoxelModel();
|
||||
bool Load(const char * fn, int lumpnum, const char * buffer, int length);
|
||||
void Initialize();
|
||||
void MakeGLData();
|
||||
void CleanGLData();
|
||||
virtual int FindFrame(const char * name);
|
||||
virtual void RenderFrame(FTexture * skin, int frame, int cm, int translation=0);
|
||||
virtual void RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation=0);
|
||||
virtual void RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation=0);
|
||||
FTexture *GetPaletteTexture() const { return mPalette; }
|
||||
void BuildVertexBuffer(FModelVertexBuffer *buf);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -341,13 +334,11 @@ struct FSpriteModelFrame
|
|||
|
||||
class GLSprite;
|
||||
|
||||
void gl_InitModels();
|
||||
FSpriteModelFrame * gl_FindModelFrame(const PClass * ti, int sprite, int frame, bool dropped);
|
||||
|
||||
void gl_RenderModel(GLSprite * spr, int cm);
|
||||
void gl_RenderModel(GLSprite * spr);
|
||||
// [BB] HUD weapon model rendering functions.
|
||||
void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy, int cm);
|
||||
void gl_RenderHUDModel(pspdef_t *psp, fixed_t ofsx, fixed_t ofsy);
|
||||
bool gl_IsHUDModelForPlayerAvailable (player_t * player);
|
||||
void gl_CleanModelData();
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -43,11 +43,13 @@
|
|||
#include "sc_man.h"
|
||||
#include "m_crc32.h"
|
||||
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/models/gl_models.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
||||
static float avertexnormals[NUMVERTEXNORMALS][3] = {
|
||||
#include "tab_anorms.h"
|
||||
|
|
@ -160,6 +162,8 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length)
|
|||
skins[i] = LoadSkin(path, buffer + info.offsetSkins + i*64);
|
||||
}
|
||||
|
||||
texCoords = new FTexCoord[info.numTexCoords];
|
||||
memcpy(texCoords, (byte*)buffer + info.offsetTexCoords, info.numTexCoords * sizeof(FTexCoord));
|
||||
|
||||
temp = (char*)buffer + info.offsetFrames;
|
||||
frames = new ModelFrame[info.numFrames];
|
||||
|
|
@ -170,8 +174,9 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length)
|
|||
dmd_packedVertex_t *pVtx;
|
||||
|
||||
memcpy(frame->name, pfr->name, sizeof(pfr->name));
|
||||
frame->vertices = new FModelVertex[info.numVertices];
|
||||
frame->normals = new FModelVertex[info.numVertices];
|
||||
frame->vertices = new DMDModelVertex[info.numVertices];
|
||||
frame->normals = new DMDModelVertex[info.numVertices];
|
||||
frame->vindex = UINT_MAX;
|
||||
|
||||
// Translate each vertex.
|
||||
for(k = 0, pVtx = pfr->vertices; k < info.numVertices; k++, pVtx++)
|
||||
|
|
@ -191,25 +196,11 @@ bool FDMDModel::Load(const char * path, int, const char * buffer, int length)
|
|||
for(i = 0; i < info.numLODs; i++)
|
||||
{
|
||||
lodInfo[i].numTriangles = LittleLong(lodInfo[i].numTriangles);
|
||||
lodInfo[i].numGlCommands = LittleLong(lodInfo[i].numGlCommands);
|
||||
lodInfo[i].offsetTriangles = LittleLong(lodInfo[i].offsetTriangles);
|
||||
lodInfo[i].offsetGlCommands = LittleLong(lodInfo[i].offsetGlCommands);
|
||||
|
||||
triangles[i] = (FTriangle*)(buffer + lodInfo[i].offsetTriangles);
|
||||
|
||||
lods[i].glCommands = new int[lodInfo[i].numGlCommands];
|
||||
memcpy(lods[i].glCommands, buffer + lodInfo[i].offsetGlCommands, sizeof(int) * lodInfo[i].numGlCommands);
|
||||
lods[i].triangles = triangles[i] = (FTriangle*)(buffer + lodInfo[i].offsetTriangles);
|
||||
}
|
||||
|
||||
// Determine vertex usage at each LOD level.
|
||||
vertexUsage = new char[info.numVertices];
|
||||
memset(vertexUsage, 0, info.numVertices);
|
||||
|
||||
for(i = 0; i < info.numLODs; i++)
|
||||
for(k = 0; k < lodInfo[i].numTriangles; k++)
|
||||
for(c = 0; c < 3; c++)
|
||||
vertexUsage[short(triangles[i][k].vertexIndices[c])] |= 1 << i;
|
||||
|
||||
loaded=true;
|
||||
return true;
|
||||
}
|
||||
|
|
@ -238,12 +229,47 @@ FDMDModel::~FDMDModel()
|
|||
|
||||
for(i = 0; i < info.numLODs; i++)
|
||||
{
|
||||
delete [] lods[i].glCommands;
|
||||
if (lods[i].triangles != NULL) delete[] lods[i].triangles;
|
||||
}
|
||||
|
||||
if (vertexUsage != NULL) delete [] vertexUsage;
|
||||
if (texCoords != NULL) delete[] texCoords;
|
||||
}
|
||||
|
||||
|
||||
void FDMDModel::BuildVertexBuffer(FModelVertexBuffer *buf)
|
||||
{
|
||||
for (int i = 0; i < info.numFrames; i++)
|
||||
{
|
||||
ModelFrame *frame = &frames[i];
|
||||
DMDModelVertex *vert = frame->vertices;
|
||||
DMDModelVertex *norm = frame->normals;
|
||||
|
||||
frame->vindex = buf->vbo_shadowdata.Size();
|
||||
|
||||
|
||||
FTriangle *tri = lods[0].triangles;
|
||||
|
||||
for (int i = 0; i < lodInfo[0].numTriangles; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
FModelVertex bvert;
|
||||
|
||||
int ti = tri->textureIndices[j];
|
||||
int vi = tri->vertexIndices[j];
|
||||
|
||||
bvert.Set(vert[vi].xyz[0], vert[vi].xyz[1], vert[vi].xyz[2], (float)texCoords[ti].s /info.skinWidth, (float)texCoords[ti].t/info.skinHeight);
|
||||
bvert.SetNormal(norm[vi].xyz[0], norm[vi].xyz[1], norm[vi].xyz[2]);
|
||||
buf->vbo_shadowdata.Push(bvert);
|
||||
}
|
||||
tri++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FDMDModel::FindFrame
|
||||
|
|
@ -260,115 +286,28 @@ int FDMDModel::FindFrame(const char * name)
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// Render a set of GL commands using the given data.
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
void FDMDModel::RenderGLCommands(void *glCommands, unsigned int numVertices,FModelVertex * vertices)
|
||||
|
||||
void FDMDModel::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation)
|
||||
{
|
||||
char *pos;
|
||||
FGLCommandVertex * v;
|
||||
int count;
|
||||
if (frameno >= info.numFrames || frameno2 >= info.numFrames) return;
|
||||
|
||||
if (!skin)
|
||||
{
|
||||
if (info.numSkins == 0) return;
|
||||
skin = skins[0];
|
||||
if (!skin) return;
|
||||
}
|
||||
|
||||
FMaterial * tex = FMaterial::ValidateTexture(skin, false);
|
||||
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false);
|
||||
|
||||
gl_RenderState.Apply();
|
||||
for(pos = (char*)glCommands; *pos;)
|
||||
{
|
||||
count = *(int *) pos;
|
||||
pos += 4;
|
||||
|
||||
// The type of primitive depends on the sign.
|
||||
glBegin(count > 0 ? GL_TRIANGLE_STRIP : GL_TRIANGLE_FAN);
|
||||
count = abs(count);
|
||||
|
||||
while(count--)
|
||||
{
|
||||
v = (FGLCommandVertex *) pos;
|
||||
pos += sizeof(FGLCommandVertex);
|
||||
|
||||
glTexCoord2fv(&v->s);
|
||||
glVertex3fv((float*)&vertices[v->index]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FDMDModel::RenderFrame(FTexture * skin, int frameno, int cm, int translation)
|
||||
{
|
||||
int activeLod;
|
||||
|
||||
if (frameno>=info.numFrames) return;
|
||||
|
||||
ModelFrame * frame = &frames[frameno];
|
||||
//int mainFlags = mf->flags;
|
||||
|
||||
if (!skin)
|
||||
{
|
||||
if (info.numSkins==0) return;
|
||||
skin = skins[0];
|
||||
if (!skin) return;
|
||||
}
|
||||
|
||||
FMaterial * tex = FMaterial::ValidateTexture(skin);
|
||||
|
||||
tex->Bind(cm, 0, translation);
|
||||
|
||||
int numVerts = info.numVertices;
|
||||
|
||||
// Determine the suitable LOD.
|
||||
/*
|
||||
if(info.numLODs > 1 && rend_model_lod != 0)
|
||||
{
|
||||
float lodFactor = rend_model_lod * screen->Width() / 640.0f / (GLRenderer->mCurrentFoV / 90.0f);
|
||||
if(lodFactor) lodFactor = 1 / lodFactor;
|
||||
|
||||
// Determine the LOD we will be using.
|
||||
activeLod = (int) (lodFactor * spr->distance);
|
||||
if(activeLod < 0) activeLod = 0;
|
||||
if(activeLod >= mdl->info.numLODs) activeLod = mdl->info.numLODs - 1;
|
||||
vertexUsage = mdl->vertexUsage;
|
||||
}
|
||||
else
|
||||
*/
|
||||
{
|
||||
activeLod = 0;
|
||||
}
|
||||
|
||||
RenderGLCommands(lods[activeLod].glCommands, numVerts, frame->vertices/*, modelColors, NULL*/);
|
||||
}
|
||||
|
||||
void FDMDModel::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int cm, int translation)
|
||||
{
|
||||
int activeLod = 0;
|
||||
|
||||
if (frameno>=info.numFrames || frameno2>=info.numFrames) return;
|
||||
|
||||
FModelVertex *vertices1 = frames[frameno].vertices;
|
||||
FModelVertex *vertices2 = frames[frameno2].vertices;
|
||||
|
||||
if (!skin)
|
||||
{
|
||||
if (info.numSkins==0) return;
|
||||
skin = skins[0];
|
||||
if (!skin) return;
|
||||
}
|
||||
|
||||
FMaterial * tex = FMaterial::ValidateTexture(skin);
|
||||
|
||||
tex->Bind(cm, 0, translation);
|
||||
|
||||
int numVerts = info.numVertices;
|
||||
|
||||
// [BB] Calculate the interpolated vertices by linear interpolation.
|
||||
FModelVertex *verticesInterpolated = new FModelVertex[numVerts];
|
||||
for( int k = 0; k < numVerts; k++ )
|
||||
{
|
||||
for ( int i = 0; i < 3; i++ )
|
||||
verticesInterpolated[k].xyz[i] = (1-inter)*vertices1[k].xyz[i]+ (inter)*vertices2[k].xyz[i];
|
||||
}
|
||||
|
||||
RenderGLCommands(lods[activeLod].glCommands, numVerts, verticesInterpolated/*, modelColors, NULL*/);
|
||||
delete[] verticesInterpolated;
|
||||
GLRenderer->mModelVBO->SetupFrame(frames[frameno].vindex, frames[frameno2].vindex, inter);
|
||||
glDrawArrays(GL_TRIANGLES, 0, lodInfo[0].numTriangles * 3);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -426,7 +365,6 @@ bool FMD2Model::Load(const char * path, int, const char * buffer, int length)
|
|||
header.magic = MD2_MAGIC;
|
||||
header.version = 8;
|
||||
header.flags = 0;
|
||||
vertexUsage = NULL;
|
||||
info.skinWidth = LittleLong(md2header->skinWidth);
|
||||
info.skinHeight = LittleLong(md2header->skinHeight);
|
||||
info.frameSize = LittleLong(md2header->frameSize);
|
||||
|
|
@ -458,17 +396,21 @@ bool FMD2Model::Load(const char * path, int, const char * buffer, int length)
|
|||
|
||||
// The frames need to be unpacked.
|
||||
md2_frames = (byte*)buffer + info.offsetFrames;
|
||||
|
||||
frames = new ModelFrame[info.numFrames];
|
||||
|
||||
texCoords = new FTexCoord[info.numTexCoords];
|
||||
memcpy(texCoords, (byte*)buffer + info.offsetTexCoords, info.numTexCoords * sizeof(FTexCoord));
|
||||
|
||||
|
||||
for(i = 0, frame = frames; i < info.numFrames; i++, frame++)
|
||||
{
|
||||
md2_packedFrame_t *pfr = (md2_packedFrame_t *) (md2_frames + info.frameSize * i);
|
||||
md2_triangleVertex_t *pVtx;
|
||||
|
||||
memcpy(frame->name, pfr->name, sizeof(pfr->name));
|
||||
frame->vertices = new FModelVertex[info.numVertices];
|
||||
frame->normals = new FModelVertex[info.numVertices];
|
||||
frame->vertices = new DMDModelVertex[info.numVertices];
|
||||
frame->normals = new DMDModelVertex[info.numVertices];
|
||||
frame->vindex = UINT_MAX;
|
||||
|
||||
// Translate each vertex.
|
||||
for(k = 0, pVtx = pfr->vertices; k < info.numVertices; k++, pVtx++)
|
||||
|
|
@ -487,8 +429,9 @@ bool FMD2Model::Load(const char * path, int, const char * buffer, int length)
|
|||
}
|
||||
|
||||
|
||||
lods[0].glCommands = new int[lodInfo[0].numGlCommands];
|
||||
memcpy(lods[0].glCommands, buffer + lodInfo[0].offsetGlCommands, sizeof(int) * lodInfo[0].numGlCommands);
|
||||
lods[0].triangles = new FTriangle[lodInfo[0].numTriangles];
|
||||
|
||||
memcpy(lods[0].triangles, buffer + lodInfo[0].offsetTriangles, sizeof(FTriangle) * lodInfo[0].numTriangles);
|
||||
|
||||
skins = new FTexture *[info.numSkins];
|
||||
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "m_crc32.h"
|
||||
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/models/gl_models.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
|
|
@ -206,6 +207,37 @@ bool FMD3Model::Load(const char * path, int, const char * buffer, int length)
|
|||
return true;
|
||||
}
|
||||
|
||||
void FMD3Model::BuildVertexBuffer(FModelVertexBuffer *buf)
|
||||
{
|
||||
for (int i = 0; i < numSurfaces; i++)
|
||||
{
|
||||
MD3Surface * surf = &surfaces[i];
|
||||
|
||||
surf->vindex = buf->vbo_shadowdata.Size();
|
||||
surf->iindex = buf->ibo_shadowdata.Size();
|
||||
for (int j = 0; j < numFrames * surf->numVertices; j++)
|
||||
{
|
||||
MD3Vertex* vert = surf->vertices + j;
|
||||
|
||||
FModelVertex bvert;
|
||||
|
||||
int tc = j % surf->numVertices;
|
||||
bvert.Set(vert->x, vert->z, vert->y, surf->texcoords[tc].s, surf->texcoords[tc].t);
|
||||
bvert.SetNormal(vert->nx, vert->nz, vert->ny);
|
||||
buf->vbo_shadowdata.Push(bvert);
|
||||
}
|
||||
|
||||
for (int k = 0; k < surf->numTriangles; k++)
|
||||
{
|
||||
for (int l = 0; l < 3; l++)
|
||||
{
|
||||
buf->ibo_shadowdata.Push(surf->tris[k].VertIndex[l]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int FMD3Model::FindFrame(const char * name)
|
||||
{
|
||||
for (int i=0;i<numFrames;i++)
|
||||
|
|
@ -215,55 +247,7 @@ int FMD3Model::FindFrame(const char * name)
|
|||
return -1;
|
||||
}
|
||||
|
||||
void FMD3Model::RenderTriangles(MD3Surface * surf, MD3Vertex * vert)
|
||||
{
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLES);
|
||||
for(int i=0; i<surf->numTriangles;i++)
|
||||
{
|
||||
for(int j=0;j<3;j++)
|
||||
{
|
||||
int x = surf->tris[i].VertIndex[j];
|
||||
|
||||
glTexCoord2fv(&surf->texcoords[x].s);
|
||||
glVertex3f(vert[x].x, vert[x].z, vert[x].y);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
void FMD3Model::RenderFrame(FTexture * skin, int frameno, int cm, int translation)
|
||||
{
|
||||
if (frameno>=numFrames) return;
|
||||
|
||||
MD3Frame * frame = &frames[frameno];
|
||||
|
||||
// I can't confirm correctness of this because no model I have tested uses this information
|
||||
// glMatrixMode(GL_MODELVIEW);
|
||||
// glTranslatef(frame->origin[0], frame->origin[1], frame->origin[2]);
|
||||
|
||||
for(int i=0;i<numSurfaces;i++)
|
||||
{
|
||||
MD3Surface * surf = &surfaces[i];
|
||||
|
||||
// [BB] In case no skin is specified via MODELDEF, check if the MD3 has a skin for the current surface.
|
||||
// Note: Each surface may have a different skin.
|
||||
FTexture *surfaceSkin = skin;
|
||||
if (!surfaceSkin)
|
||||
{
|
||||
if (surf->numSkins==0) return;
|
||||
surfaceSkin = surf->skins[0];
|
||||
if (!surfaceSkin) return;
|
||||
}
|
||||
|
||||
FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin);
|
||||
|
||||
tex->Bind(cm, 0, translation);
|
||||
RenderTriangles(surf, surf->vertices + frameno * surf->numVertices);
|
||||
}
|
||||
}
|
||||
|
||||
void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int frameno2, double inter, int cm, int translation)
|
||||
void FMD3Model::RenderFrame(FTexture * skin, int frameno, int frameno2, double inter, int translation)
|
||||
{
|
||||
if (frameno>=numFrames || frameno2>=numFrames) return;
|
||||
|
||||
|
|
@ -281,26 +265,13 @@ void FMD3Model::RenderFrameInterpolated(FTexture * skin, int frameno, int framen
|
|||
if (!surfaceSkin) return;
|
||||
}
|
||||
|
||||
FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin);
|
||||
FMaterial * tex = FMaterial::ValidateTexture(surfaceSkin, false);
|
||||
|
||||
tex->Bind(cm, 0, translation);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_NONE, translation, -1, false);
|
||||
|
||||
MD3Vertex* verticesInterpolated = new MD3Vertex[surfaces[i].numVertices];
|
||||
MD3Vertex* vertices1 = surf->vertices + frameno * surf->numVertices;
|
||||
MD3Vertex* vertices2 = surf->vertices + frameno2 * surf->numVertices;
|
||||
|
||||
// [BB] Calculate the interpolated vertices by linear interpolation.
|
||||
for( int k = 0; k < surf->numVertices; k++ )
|
||||
{
|
||||
verticesInterpolated[k].x = (1-inter)*vertices1[k].x+ (inter)*vertices2[k].x;
|
||||
verticesInterpolated[k].y = (1-inter)*vertices1[k].y+ (inter)*vertices2[k].y;
|
||||
verticesInterpolated[k].z = (1-inter)*vertices1[k].z+ (inter)*vertices2[k].z;
|
||||
// [BB] Apparently RenderTriangles doesn't use nx, ny, nz, so don't interpolate them.
|
||||
}
|
||||
|
||||
RenderTriangles(surf, verticesInterpolated);
|
||||
|
||||
delete[] verticesInterpolated;
|
||||
gl_RenderState.Apply();
|
||||
GLRenderer->mModelVBO->SetupFrame(surf->vindex + frameno * surf->numVertices, surf->vindex + frameno2 * surf->numVertices, inter);
|
||||
glDrawElements(GL_TRIANGLES, surf->numTriangles * 3, GL_UNSIGNED_INT, (void*)(intptr_t)(surf->iindex * sizeof(unsigned int)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -203,92 +203,6 @@ int FVoxelTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, F
|
|||
return 0;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
|
||||
class FVoxelVertexBuffer : public FVertexBuffer
|
||||
{
|
||||
unsigned int ibo_id;
|
||||
bool isint;
|
||||
|
||||
public:
|
||||
FVoxelVertexBuffer(TArray<FVoxelVertex> &verts, TArray<unsigned int> &indices);
|
||||
~FVoxelVertexBuffer();
|
||||
void BindVBO();
|
||||
bool IsInt() const { return isint; }
|
||||
};
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FVoxelVertexBuffer::FVoxelVertexBuffer(TArray<FVoxelVertex> &verts, TArray<unsigned int> &indices)
|
||||
{
|
||||
ibo_id = 0;
|
||||
glGenBuffers(1, &ibo_id);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, verts.Size() * sizeof(FVoxelVertex), &verts[0], GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
|
||||
if (verts.Size() > 65535)
|
||||
{
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.Size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||
isint = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned short *sbuffer = new unsigned short[indices.Size()];
|
||||
for(unsigned i=0;i<indices.Size();i++)
|
||||
{
|
||||
sbuffer[i] = (unsigned short)indices[i];
|
||||
}
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.Size() * sizeof(unsigned short), sbuffer, GL_STATIC_DRAW);
|
||||
delete [] sbuffer;
|
||||
isint = false;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FVoxelVertexBuffer::~FVoxelVertexBuffer()
|
||||
{
|
||||
if (ibo_id != 0)
|
||||
{
|
||||
glDeleteBuffers(1, &ibo_id);
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
#define VVO ((FVoxelVertex*)NULL)
|
||||
|
||||
void FVoxelVertexBuffer::BindVBO()
|
||||
{
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo_id);
|
||||
glVertexPointer(3,GL_FLOAT, sizeof(FVoxelVertex), &VVO->x);
|
||||
glTexCoordPointer(2,GL_FLOAT, sizeof(FVoxelVertex), &VVO->u);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_INDEX_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -299,9 +213,9 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned)
|
|||
{
|
||||
mVoxel = voxel;
|
||||
mOwningVoxel = owned;
|
||||
mVBO = NULL;
|
||||
mPalette = new FVoxelTexture(voxel);
|
||||
Initialize();
|
||||
iindex = vindex = UINT_MAX;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -312,25 +226,43 @@ FVoxelModel::FVoxelModel(FVoxel *voxel, bool owned)
|
|||
|
||||
FVoxelModel::~FVoxelModel()
|
||||
{
|
||||
CleanGLData();
|
||||
delete mPalette;
|
||||
if (mOwningVoxel) delete mVoxel;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FVoxelModel::BuildVertexBuffer(FModelVertexBuffer *buf)
|
||||
{
|
||||
vindex = buf->vbo_shadowdata.Size();
|
||||
iindex = buf->ibo_shadowdata.Size();
|
||||
|
||||
FModelVertex *mv = &buf->vbo_shadowdata[buf->vbo_shadowdata.Reserve(mVertices.Size())];
|
||||
unsigned int *mi = &buf->ibo_shadowdata[buf->ibo_shadowdata.Reserve(mIndices.Size())];
|
||||
|
||||
memcpy(mv, &mVertices[0], sizeof(FModelVertex)* mVertices.Size());
|
||||
memcpy(mi, &mIndices[0], sizeof(unsigned int)* mIndices.Size());
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FVoxelModel::AddVertex(FVoxelVertex &vert, FVoxelMap &check)
|
||||
unsigned int FVoxelModel::AddVertex(FModelVertex &vert, FVoxelMap &check)
|
||||
{
|
||||
unsigned int index = check[vert];
|
||||
if (index == 0xffffffff)
|
||||
{
|
||||
index = check[vert] =mVertices.Push(vert);
|
||||
}
|
||||
mIndices.Push(index);
|
||||
return index;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -345,8 +277,8 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3
|
|||
float PivotY = mVoxel->Mips[0].PivotY / 256.f;
|
||||
float PivotZ = mVoxel->Mips[0].PivotZ / 256.f;
|
||||
int h = mVoxel->Mips[0].SizeZ;
|
||||
FVoxelVertex vert;
|
||||
|
||||
FModelVertex vert;
|
||||
unsigned int indx[4];
|
||||
|
||||
vert.u = (((col & 15) * 255 / 16) + 7) / 255.f;
|
||||
vert.v = (((col / 16) * 255 / 16) + 7) / 255.f;
|
||||
|
|
@ -354,23 +286,29 @@ void FVoxelModel::AddFace(int x1, int y1, int z1, int x2, int y2, int z2, int x3
|
|||
vert.x = x1 - PivotX;
|
||||
vert.z = -y1 + PivotY;
|
||||
vert.y = -z1 + PivotZ;
|
||||
AddVertex(vert, check);
|
||||
indx[0] = AddVertex(vert, check);
|
||||
|
||||
vert.x = x2 - PivotX;
|
||||
vert.z = -y2 + PivotY;
|
||||
vert.y = -z2 + PivotZ;
|
||||
AddVertex(vert, check);
|
||||
indx[1] = AddVertex(vert, check);
|
||||
|
||||
vert.x = x4 - PivotX;
|
||||
vert.z = -y4 + PivotY;
|
||||
vert.y = -z4 + PivotZ;
|
||||
AddVertex(vert, check);
|
||||
indx[2] = AddVertex(vert, check);
|
||||
|
||||
vert.x = x3 - PivotX;
|
||||
vert.z = -y3 + PivotY;
|
||||
vert.y = -z3 + PivotZ;
|
||||
AddVertex(vert, check);
|
||||
indx[3] = AddVertex(vert, check);
|
||||
|
||||
mIndices.Push(indx[0]);
|
||||
mIndices.Push(indx[1]);
|
||||
mIndices.Push(indx[3]);
|
||||
mIndices.Push(indx[1]);
|
||||
mIndices.Push(indx[3]);
|
||||
mIndices.Push(indx[2]);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -459,32 +397,6 @@ bool FVoxelModel::Load(const char * fn, int lumpnum, const char * buffer, int le
|
|||
return false; // not needed
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FVoxelModel::MakeGLData()
|
||||
{
|
||||
mVBO = new FVoxelVertexBuffer(mVertices, mIndices);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FVoxelModel::CleanGLData()
|
||||
{
|
||||
if (mVBO != NULL)
|
||||
{
|
||||
delete mVBO;
|
||||
mVBO = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Voxels don't have frames so always return 0
|
||||
|
|
@ -498,43 +410,17 @@ int FVoxelModel::FindFrame(const char * name)
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
// Voxels never interpolate between frames, they only have one.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FVoxelModel::RenderFrame(FTexture * skin, int frame, int cm, int translation)
|
||||
void FVoxelModel::RenderFrame(FTexture * skin, int frame, int frame2, double inter, int translation)
|
||||
{
|
||||
FMaterial * tex = FMaterial::ValidateTexture(skin);
|
||||
tex->Bind(cm, 0, translation);
|
||||
FMaterial * tex = FMaterial::ValidateTexture(skin, false);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_NOFILTER, translation, -1, false);
|
||||
|
||||
gl_RenderState.Apply();
|
||||
|
||||
if (mVBO == NULL) MakeGLData();
|
||||
if (mVBO != NULL)
|
||||
{
|
||||
mVBO->BindVBO();
|
||||
glDrawElements(GL_QUADS, mIndices.Size(), mVBO->IsInt()? GL_UNSIGNED_INT:GL_UNSIGNED_SHORT, 0);
|
||||
GLRenderer->mVBO->BindVBO();
|
||||
return;
|
||||
}
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
for(unsigned i=0;i < mIndices.Size(); i++)
|
||||
{
|
||||
FVoxelVertex *vert = &mVertices[mIndices[i]];
|
||||
glTexCoord2fv(&vert->u);
|
||||
glVertex3fv(&vert->x);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Voxels never interpolate between frames
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FVoxelModel::RenderFrameInterpolated(FTexture * skin, int frame, int frame2, double inter, int cm, int translation)
|
||||
{
|
||||
RenderFrame(skin, frame, cm, translation);
|
||||
GLRenderer->mModelVBO->SetupFrame(vindex, vindex, 0.f);
|
||||
glDrawElements(GL_TRIANGLES, mIndices.Size(), GL_UNSIGNED_INT, (void*)(intptr_t)(iindex * sizeof(unsigned int)));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,18 +13,13 @@ enum EColorManipulation
|
|||
|
||||
CM_INVALID=-1,
|
||||
CM_DEFAULT=0, // untranslated
|
||||
CM_DESAT0=CM_DEFAULT,
|
||||
CM_DESAT1, // minimum desaturation
|
||||
CM_DESAT31=CM_DESAT1+30, // maximum desaturation = grayscale
|
||||
CM_FIRSTSPECIALCOLORMAP, // first special fixed colormap
|
||||
|
||||
// special internal values for texture creation
|
||||
CM_SHADE= 0x10000002, // alpha channel texture
|
||||
CM_FOGLAYER = 0x10000000, // Sprite shaped fog layer
|
||||
|
||||
// These are not to be passed to the texture manager
|
||||
CM_LITE = 0x20000000, // special values to handle these items without excessive hacking
|
||||
CM_TORCH= 0x20000010, // These are not real color manipulations
|
||||
CM_FOGLAYER= 0x20000020, // Sprite shaped fog layer - this is only used as a parameter to FMaterial::BindPatch
|
||||
};
|
||||
|
||||
#define CM_MAXCOLORMAP int(CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size())
|
||||
|
|
@ -34,14 +29,14 @@ struct FColormap
|
|||
{
|
||||
PalEntry LightColor; // a is saturation (0 full, 31=b/w, other=custom colormap)
|
||||
PalEntry FadeColor; // a is fadedensity>>1
|
||||
int colormap;
|
||||
int desaturation;
|
||||
int blendfactor;
|
||||
|
||||
void Clear()
|
||||
{
|
||||
LightColor=0xffffff;
|
||||
FadeColor=0;
|
||||
colormap = CM_DEFAULT;
|
||||
desaturation = 0;
|
||||
blendfactor=0;
|
||||
}
|
||||
|
||||
|
|
@ -49,19 +44,14 @@ struct FColormap
|
|||
{
|
||||
LightColor.r=LightColor.g=LightColor.b=0xff;
|
||||
blendfactor=0;
|
||||
desaturation = 0;
|
||||
}
|
||||
|
||||
|
||||
void GetFixedColormap()
|
||||
{
|
||||
Clear();
|
||||
colormap = gl_fixedcolormap >= (int)CM_LITE? (int)CM_DEFAULT : gl_fixedcolormap;
|
||||
}
|
||||
|
||||
FColormap & operator=(FDynamicColormap * from)
|
||||
{
|
||||
LightColor = from->Color;
|
||||
colormap = from->Desaturate>>3;
|
||||
desaturation = from->Desaturate;
|
||||
FadeColor = from->Fade;
|
||||
blendfactor = from->Color.a;
|
||||
return * this;
|
||||
|
|
@ -70,9 +60,15 @@ struct FColormap
|
|||
void CopyLightColor(FDynamicColormap * from)
|
||||
{
|
||||
LightColor = from->Color;
|
||||
colormap = from->Desaturate>>3;
|
||||
desaturation = from->Desaturate;
|
||||
blendfactor = from->Color.a;
|
||||
}
|
||||
|
||||
void Decolorize() // this for 'nocoloredspritelighting' and not the same as desaturation. The normal formula results in a value that's too dark.
|
||||
{
|
||||
int v = (LightColor.r + LightColor.g + LightColor.b) / 3;
|
||||
LightColor.r = LightColor.g = LightColor.b = (255 + v + v) / 3;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -72,22 +72,6 @@ CVAR(Bool, gl_brightfog, false, CVAR_ARCHIVE);
|
|||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_BrightmapsActive()
|
||||
{
|
||||
return gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_brightmap_shader);
|
||||
}
|
||||
|
||||
bool gl_GlowActive()
|
||||
{
|
||||
return gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_glow_shader);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the fog tables
|
||||
|
|
@ -125,7 +109,6 @@ CUSTOM_CVAR(Int,gl_fogmode,1,CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|||
{
|
||||
if (self>2) self=2;
|
||||
if (self<0) self=0;
|
||||
if (self == 2 && gl.shadermodel < 4) self = 1;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL)
|
||||
|
|
@ -133,7 +116,6 @@ CUSTOM_CVAR(Int, gl_lightmode, 3 ,CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|||
int newself = self;
|
||||
if (newself > 4) newself=8; // use 8 for software lighting to avoid conflicts with the bit mask
|
||||
if (newself < 0) newself=0;
|
||||
if ((newself == 2 || newself == 8) && gl.shadermodel < 4) newself = 3;
|
||||
if (self != newself) self = newself;
|
||||
glset.lightmode = newself;
|
||||
}
|
||||
|
|
@ -160,13 +142,18 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
|
|||
int blendequation = renderops[style.BlendOp&15];
|
||||
int texturemode = drawopaque? TM_OPAQUE : TM_MODULATE;
|
||||
|
||||
if (style.Flags & STYLEF_ColorIsFixed)
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
texturemode = TM_REDTOALPHA;
|
||||
}
|
||||
else if (style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
texturemode = TM_MASK;
|
||||
}
|
||||
else if (style.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
texturemode = drawopaque? TM_INVERTOPAQUE : TM_INVERT;
|
||||
// The only place where InvertSource is used is for inverted sprites with the infrared powerup.
|
||||
texturemode = TM_INVERSE;
|
||||
}
|
||||
|
||||
if (blendequation == -1)
|
||||
|
|
@ -240,11 +227,11 @@ int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force)
|
||||
static PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor)
|
||||
{
|
||||
int r,g,b;
|
||||
|
||||
if (glset.lightmode == 8 && !force)
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
return pe;
|
||||
}
|
||||
|
|
@ -256,52 +243,15 @@ PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force)
|
|||
}
|
||||
else
|
||||
{
|
||||
// This is what Legacy does with colored light in 3D volumes. No, it doesn't really make sense...
|
||||
// It also doesn't translate well to software style lighting.
|
||||
int mixlight = light * (255 - blendfactor);
|
||||
|
||||
r = (mixlight + pe.r * blendfactor) / 255;
|
||||
g = (mixlight + pe.g * blendfactor) / 255;
|
||||
b = (mixlight + pe.b * blendfactor) / 255;
|
||||
}
|
||||
return PalEntry(BYTE(r), BYTE(g), BYTE(b));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Get current light color
|
||||
//
|
||||
//==========================================================================
|
||||
void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float * pred, float * pgreen, float * pblue, bool weapon)
|
||||
{
|
||||
float & r=*pred,& g=*pgreen,& b=*pblue;
|
||||
int torch=0;
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
if (gl_fixedcolormap==CM_LITE)
|
||||
{
|
||||
if (gl_enhanced_nightvision) r=0.375f, g=1.0f, b=0.375f;
|
||||
else r=g=b=1.0f;
|
||||
}
|
||||
else if (gl_fixedcolormap>=CM_TORCH)
|
||||
{
|
||||
int flicker=gl_fixedcolormap-CM_TORCH;
|
||||
r=(0.8f+(7-flicker)/70.0f);
|
||||
if (r>1.0f) r=1.0f;
|
||||
b=g=r;
|
||||
if (gl_enhanced_nightvision) b*=0.75f;
|
||||
}
|
||||
else r=g=b=1.0f;
|
||||
return;
|
||||
}
|
||||
|
||||
PalEntry lightcolor = cm? cm->LightColor : PalEntry(255,255,255);
|
||||
int blendfactor = cm? cm->blendfactor : 0;
|
||||
|
||||
lightlevel = gl_CalcLightLevel(lightlevel, rellight, weapon);
|
||||
PalEntry pe = gl_CalcLightColor(lightlevel, lightcolor, blendfactor);
|
||||
r = pe.r/255.f;
|
||||
g = pe.g/255.f;
|
||||
b = pe.b/255.f;
|
||||
return PalEntry(255, BYTE(r), BYTE(g), BYTE(b));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -309,44 +259,19 @@ void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float
|
|||
// set current light color
|
||||
//
|
||||
//==========================================================================
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, float *green, float *blue, PalEntry ThingColor, bool weapon)
|
||||
void gl_SetColor(int sectorlightlevel, int rellight, const FColormap &cm, float alpha, bool weapon)
|
||||
{
|
||||
float r,g,b;
|
||||
gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon);
|
||||
|
||||
*red = r * ThingColor.r/255.0f;
|
||||
*green = g * ThingColor.g/255.0f;
|
||||
*blue = b * ThingColor.b/255.0f;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// set current light color
|
||||
//
|
||||
//==========================================================================
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, PalEntry ThingColor, bool weapon)
|
||||
{
|
||||
float r,g,b;
|
||||
|
||||
gl_GetLightColor(light, rellight, cm, &r, &g, &b, weapon);
|
||||
|
||||
if (glset.lightmode != 8)
|
||||
if (gl_fixedcolormap != CM_DEFAULT)
|
||||
{
|
||||
glColor4f(r * ThingColor.r/255.0f, g * ThingColor.g/255.0f, b * ThingColor.b/255.0f, alpha);
|
||||
gl_RenderState.SetColorAlpha(0xffffff, alpha, 0);
|
||||
gl_RenderState.SetSoftLightLevel(255);
|
||||
}
|
||||
else
|
||||
{
|
||||
glColor4f(r, g, b, alpha);
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
float lightlevel = gl_CalcLightLevel(light, rellight, weapon) / 255.0f;
|
||||
glVertexAttrib1f(VATTR_LIGHTLEVEL, lightlevel);
|
||||
}
|
||||
{
|
||||
int hwlightlevel = gl_CalcLightLevel(sectorlightlevel, rellight, weapon);
|
||||
PalEntry pe = gl_CalcLightColor(hwlightlevel, cm.LightColor, cm.blendfactor);
|
||||
gl_RenderState.SetColorAlpha(pe, alpha, cm.desaturation);
|
||||
gl_RenderState.SetSoftLightLevel(gl_ClampLight(sectorlightlevel + rellight));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -450,60 +375,61 @@ bool gl_CheckFog(FColormap *cm, int lightlevel)
|
|||
//
|
||||
// Check if the current linedef is a candidate for a fog boundary
|
||||
//
|
||||
// Requirements for a fog boundary:
|
||||
// - front sector has no fog
|
||||
// - back sector has fog
|
||||
// - at least one of both does not have a sky ceiling.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_CheckFog(sector_t *frontsector, sector_t *backsector)
|
||||
{
|
||||
if (gl_fixedcolormap) return false;
|
||||
if (frontsector == backsector) return false; // there can't be a boundary if both sides are in the same sector.
|
||||
|
||||
// Check for fog boundaries. This needs a few more checks for the sectors
|
||||
bool frontfog, backfog;
|
||||
|
||||
PalEntry fogcolor = frontsector->ColorMap->Fade;
|
||||
|
||||
if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
frontfog = false;
|
||||
return false;
|
||||
}
|
||||
else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff))
|
||||
{
|
||||
frontfog = true;
|
||||
}
|
||||
else if (fogdensity!=0 || (glset.lightmode & 4))
|
||||
{
|
||||
// case 3: level has fog density set
|
||||
frontfog = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 4: use light level
|
||||
frontfog = frontsector->lightlevel < 248;
|
||||
if (frontsector->lightlevel >= 248) return false;
|
||||
}
|
||||
|
||||
if (backsector == NULL) return frontfog;
|
||||
|
||||
fogcolor = backsector->ColorMap->Fade;
|
||||
|
||||
if ((fogcolor.d & 0xffffff) == 0)
|
||||
{
|
||||
backfog = false;
|
||||
}
|
||||
else if (outsidefogdensity != 0 && outsidefogcolor.a!=0xff && (fogcolor.d & 0xffffff) == (outsidefogcolor.d & 0xffffff))
|
||||
{
|
||||
backfog = true;
|
||||
return false;
|
||||
}
|
||||
else if (fogdensity!=0 || (glset.lightmode & 4))
|
||||
{
|
||||
// case 3: level has fog density set
|
||||
backfog = true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 4: use light level
|
||||
backfog = backsector->lightlevel < 248;
|
||||
if (backsector->lightlevel < 248) return false;
|
||||
}
|
||||
|
||||
// in all other cases this might create more problems than it solves.
|
||||
return (frontfog && !backfog && !gl_fixedcolormap &&
|
||||
(frontsector->GetTexture(sector_t::ceiling)!=skyflatnum ||
|
||||
return ((frontsector->GetTexture(sector_t::ceiling)!=skyflatnum ||
|
||||
backsector->GetTexture(sector_t::ceiling)!=skyflatnum));
|
||||
}
|
||||
|
||||
|
|
@ -515,15 +441,9 @@ bool gl_CheckFog(sector_t *frontsector, sector_t *backsector)
|
|||
|
||||
void gl_SetShaderLight(float level, float olight)
|
||||
{
|
||||
#if 1 //ndef _DEBUG
|
||||
const float MAXDIST = 256.f;
|
||||
const float THRESHOLD = 96.f;
|
||||
const float FACTOR = 0.75f;
|
||||
#else
|
||||
const float MAXDIST = 256.f;
|
||||
const float THRESHOLD = 96.f;
|
||||
const float FACTOR = 2.75f;
|
||||
#endif
|
||||
|
||||
if (level > 0)
|
||||
{
|
||||
|
|
@ -603,42 +523,18 @@ void gl_SetFog(int lightlevel, int rellight, const FColormap *cmap, bool isaddit
|
|||
{
|
||||
fogcolor=0;
|
||||
}
|
||||
// Handle desaturation
|
||||
if (cmap->colormap != CM_DEFAULT)
|
||||
gl_ModifyColor(fogcolor.r, fogcolor.g, fogcolor.b, cmap->colormap);
|
||||
|
||||
gl_RenderState.EnableFog(true);
|
||||
gl_RenderState.SetFog(fogcolor, fogdensity);
|
||||
|
||||
// Korshun: fullbright fog like in software renderer.
|
||||
if (glset.lightmode == 8 && glset.brightfog && fogdensity != 0 && fogcolor != 0)
|
||||
glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0);
|
||||
{
|
||||
gl_RenderState.SetSoftLightLevel(255);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Modifies a color according to a specified colormap
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_ModifyColor(BYTE & red, BYTE & green, BYTE & blue, int cm)
|
||||
{
|
||||
int gray = (red*77 + green*143 + blue*36)>>8;
|
||||
if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_MAXCOLORMAP)
|
||||
{
|
||||
PalEntry pe = SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP].GrayscaleToColor[gray];
|
||||
red = pe.r;
|
||||
green = pe.g;
|
||||
blue = pe.b;
|
||||
}
|
||||
else if (cm >= CM_DESAT1 && cm <= CM_DESAT31)
|
||||
{
|
||||
gl_Desaturate(gray, red, green, blue, red, green, blue, cm - CM_DESAT0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
|
|||
|
|
@ -5,9 +5,6 @@
|
|||
#include "r_data/renderstyle.h"
|
||||
#include "gl/renderer/gl_colormap.h"
|
||||
|
||||
bool gl_BrightmapsActive();
|
||||
bool gl_GlowActive();
|
||||
|
||||
inline int gl_ClampLight(int lightlevel)
|
||||
{
|
||||
return clamp(lightlevel, 0, 255);
|
||||
|
|
@ -18,10 +15,7 @@ void gl_GetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
|
|||
void gl_SetFogParams(int _fogdensity, PalEntry _outsidefogcolor, int _outsidefogdensity, int _skyfog);
|
||||
|
||||
int gl_CalcLightLevel(int lightlevel, int rellight, bool weapon);
|
||||
PalEntry gl_CalcLightColor(int light, PalEntry pe, int blendfactor, bool force = false);
|
||||
void gl_GetLightColor(int lightlevel, int rellight, const FColormap * cm, float * pred, float * pgreen, float * pblue, bool weapon=false);
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float alpha, PalEntry ThingColor = 0xffffff, bool weapon=false);
|
||||
void gl_SetColor(int light, int rellight, const FColormap * cm, float *red, float *green, float *blue, PalEntry ThingColor=0xffffff, bool weapon=false);
|
||||
void gl_SetColor(int light, int rellight, const FColormap &cm, float alpha, bool weapon=false);
|
||||
|
||||
float gl_GetFogDensity(int lightlevel, PalEntry fogcolor);
|
||||
struct sector_t;
|
||||
|
|
@ -47,14 +41,6 @@ inline bool gl_isFullbright(PalEntry color, int lightlevel)
|
|||
return gl_fixedcolormap || (gl_isWhite(color) && lightlevel==255);
|
||||
}
|
||||
|
||||
__forceinline void gl_Desaturate(int gray, int ired, int igreen, int iblue, BYTE & red, BYTE & green, BYTE & blue, int fac)
|
||||
{
|
||||
red = (ired*(31-fac) + gray*fac)/31;
|
||||
green = (igreen*(31-fac) + gray*fac)/31;
|
||||
blue = (iblue*(31-fac) + gray*fac)/31;
|
||||
}
|
||||
|
||||
void gl_ModifyColor(BYTE & red, BYTE & green, BYTE & blue, int cm);
|
||||
void gl_DeleteAllAttachedLights();
|
||||
void gl_RecreateAllAttachedLights();
|
||||
|
||||
|
|
|
|||
|
|
@ -52,21 +52,22 @@
|
|||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/system/gl_threads.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/textures/gl_texture.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
#include "gl/models/gl_models.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
@ -74,8 +75,6 @@
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
EXTERN_CVAR(Bool, gl_render_segs)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Initialize
|
||||
|
|
@ -93,9 +92,11 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mViewVector = FVector2(0,0);
|
||||
mCameraPos = FVector3(0,0,0);
|
||||
mVBO = NULL;
|
||||
mSkyVBO = NULL;
|
||||
gl_spriteindex = 0;
|
||||
mShaderManager = NULL;
|
||||
glpart2 = glpart = gllight = mirrortexture = NULL;
|
||||
glpart2 = glpart = mirrortexture = NULL;
|
||||
mLights = NULL;
|
||||
}
|
||||
|
||||
void FGLRenderer::Initialize()
|
||||
|
|
@ -103,27 +104,31 @@ void FGLRenderer::Initialize()
|
|||
glpart2 = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart2.png"), FTexture::TEX_MiscPatch);
|
||||
glpart = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/glpart.png"), FTexture::TEX_MiscPatch);
|
||||
mirrortexture = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/mirror.png"), FTexture::TEX_MiscPatch);
|
||||
gllight = FTexture::CreateTexture(Wads.GetNumForFullName("glstuff/gllight.png"), FTexture::TEX_MiscPatch);
|
||||
|
||||
mVBO = new FFlatVertexBuffer;
|
||||
mSkyVBO = new FSkyVertexBuffer;
|
||||
mModelVBO = new FModelVertexBuffer;
|
||||
mLights = new FLightBuffer();
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
mFBID = 0;
|
||||
SetupLevel();
|
||||
mShaderManager = new FShaderManager;
|
||||
//mThreadManager = new FGLThreadManager;
|
||||
mSamplerManager = new FSamplerManager;
|
||||
}
|
||||
|
||||
FGLRenderer::~FGLRenderer()
|
||||
{
|
||||
gl_CleanModelData();
|
||||
gl_DeleteAllAttachedLights();
|
||||
FMaterial::FlushAll();
|
||||
//if (mThreadManager != NULL) delete mThreadManager;
|
||||
if (mShaderManager != NULL) delete mShaderManager;
|
||||
if (mSamplerManager != NULL) delete mSamplerManager;
|
||||
if (mVBO != NULL) delete mVBO;
|
||||
if (mModelVBO) delete mModelVBO;
|
||||
if (mSkyVBO != NULL) delete mSkyVBO;
|
||||
if (mLights != NULL) delete mLights;
|
||||
if (glpart2) delete glpart2;
|
||||
if (glpart) delete glpart;
|
||||
if (mirrortexture) delete mirrortexture;
|
||||
if (gllight) delete gllight;
|
||||
if (mFBID != 0) glDeleteFramebuffers(1, &mFBID);
|
||||
}
|
||||
|
||||
|
|
@ -212,13 +217,9 @@ void FGLRenderer::FlushTextures()
|
|||
|
||||
bool FGLRenderer::StartOffscreen()
|
||||
{
|
||||
if (gl.flags & RFL_FRAMEBUFFER)
|
||||
{
|
||||
if (mFBID == 0) glGenFramebuffers(1, &mFBID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBID);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (mFBID == 0) glGenFramebuffers(1, &mFBID);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, mFBID);
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -229,10 +230,7 @@ bool FGLRenderer::StartOffscreen()
|
|||
|
||||
void FGLRenderer::EndOffscreen()
|
||||
{
|
||||
if (gl.flags & RFL_FRAMEBUFFER)
|
||||
{
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -243,10 +241,10 @@ void FGLRenderer::EndOffscreen()
|
|||
|
||||
unsigned char *FGLRenderer::GetTextureBuffer(FTexture *tex, int &w, int &h)
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex);
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
|
||||
if (gltex)
|
||||
{
|
||||
return gltex->CreateTexBuffer(CM_DEFAULT, 0, w, h);
|
||||
return gltex->CreateTexBuffer(0, w, h);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -269,29 +267,25 @@ void FGLRenderer::ClearBorders()
|
|||
int borderHeight = (trueHeight - height) / 2;
|
||||
|
||||
glViewport(0, 0, width, trueHeight);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(0.0, width * 1.0, 0.0, trueHeight, -1.0, 1.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glColor3f(0.f, 0.f, 0.f);
|
||||
gl_RenderState.mProjectionMatrix.loadIdentity();
|
||||
gl_RenderState.mProjectionMatrix.ortho(0.0f, width * 1.0f, 0.0f, trueHeight, -1.0f, 1.0f);
|
||||
gl_RenderState.SetColor(0.f ,0.f ,0.f ,1.f);
|
||||
gl_RenderState.Set2DMode(true);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply(true);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
// upper quad
|
||||
glVertex2i(0, borderHeight);
|
||||
glVertex2i(0, 0);
|
||||
glVertex2i(width, 0);
|
||||
glVertex2i(width, borderHeight);
|
||||
|
||||
// lower quad
|
||||
glVertex2i(0, trueHeight);
|
||||
glVertex2i(0, trueHeight - borderHeight);
|
||||
glVertex2i(width, trueHeight - borderHeight);
|
||||
glVertex2i(width, trueHeight);
|
||||
glEnd();
|
||||
gl_RenderState.Apply();
|
||||
gl_RenderState.ApplyMatrices();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(0, borderHeight, 0, 0, 0); ptr++;
|
||||
ptr->Set(0, 0, 0, 0, 0); ptr++;
|
||||
ptr->Set(width, 0, 0, 0, 0); ptr++;
|
||||
ptr->Set(width, borderHeight, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
ptr->Set(0, trueHeight, 0, 0, 0); ptr++;
|
||||
ptr->Set(0, trueHeight - borderHeight, 0, 0, 0); ptr++;
|
||||
ptr->Set(width, trueHeight - borderHeight, 0, 0, 0); ptr++;
|
||||
ptr->Set(width, trueHeight, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
|
||||
glViewport(0, (trueHeight - height) / 2, width, height);
|
||||
|
|
@ -311,47 +305,45 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
|
|||
double y = parms.y - parms.top * yscale;
|
||||
double w = parms.destwidth;
|
||||
double h = parms.destheight;
|
||||
float u1, v1, u2, v2, r, g, b;
|
||||
float light = 1.f;
|
||||
float u1, v1, u2, v2;
|
||||
int light = 255;
|
||||
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(img);
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(img, false);
|
||||
|
||||
if (parms.colorOverlay && (parms.colorOverlay & 0xffffff) == 0)
|
||||
{
|
||||
// Right now there's only black. Should be implemented properly later
|
||||
light = 1.f - APART(parms.colorOverlay)/255.f;
|
||||
light = 255 - APART(parms.colorOverlay);
|
||||
parms.colorOverlay = 0;
|
||||
}
|
||||
|
||||
if (!img->bHasCanvas)
|
||||
{
|
||||
if (!parms.alphaChannel)
|
||||
int translation = 0;
|
||||
if (!parms.alphaChannel)
|
||||
{
|
||||
int translation = 0;
|
||||
if (parms.remap != NULL && !parms.remap->Inactive)
|
||||
{
|
||||
GLTranslationPalette * pal = static_cast<GLTranslationPalette*>(parms.remap->GetNative());
|
||||
if (pal) translation = -pal->GetIndex();
|
||||
}
|
||||
gltex->BindPatch(CM_DEFAULT, translation);
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is an alpha texture
|
||||
gltex->BindPatch(CM_SHADE, 0);
|
||||
}
|
||||
gl_SetRenderStyle(parms.style, !parms.masked, false);
|
||||
gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, translation, 0, !!(parms.style.Flags & STYLEF_RedIsAlpha));
|
||||
|
||||
u1 = gltex->GetUL();
|
||||
v1 = gltex->GetVT();
|
||||
u2 = gltex->GetUR();
|
||||
v2 = gltex->GetVB();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
gltex->Bind(CM_DEFAULT, 0, 0);
|
||||
u2=1.f;
|
||||
v2=-1.f;
|
||||
u1 = v1 = 0.f;
|
||||
gl_RenderState.SetMaterial(gltex, CLAMP_XY_NOMIP, 0, -1, false);
|
||||
u1 = 0.f;
|
||||
v1 = 1.f;
|
||||
u2 = 1.f;
|
||||
v2 = 0.f;
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
}
|
||||
|
||||
|
|
@ -372,17 +364,17 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
|
|||
u2 = float(u2 - (parms.texwidth - parms.windowright) / parms.texwidth);
|
||||
}
|
||||
|
||||
PalEntry color;
|
||||
if (parms.style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
r = RPART(parms.fillcolor)/255.0f;
|
||||
g = GPART(parms.fillcolor)/255.0f;
|
||||
b = BPART(parms.fillcolor)/255.0f;
|
||||
color = parms.fillcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
r = g = b = light;
|
||||
color = PalEntry(light, light, light);
|
||||
}
|
||||
|
||||
color.a = Scale(parms.alpha, 255, FRACUNIT);
|
||||
|
||||
// scissor test doesn't use the current viewport for the coordinates, so use real screen coordinates
|
||||
int btm = (SCREENHEIGHT - screen->GetHeight()) / 2;
|
||||
btm = SCREENHEIGHT - btm;
|
||||
|
|
@ -391,48 +383,33 @@ void FGLRenderer::DrawTexture(FTexture *img, DCanvas::DrawParms &parms)
|
|||
int space = (static_cast<OpenGLFrameBuffer*>(screen)->GetTrueHeight()-screen->GetHeight())/2;
|
||||
glScissor(parms.lclip, btm - parms.dclip + space, parms.rclip - parms.lclip, parms.dclip - parms.uclip);
|
||||
|
||||
gl_SetRenderStyle(parms.style, !parms.masked, false);
|
||||
if (img->bHasCanvas)
|
||||
{
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
}
|
||||
|
||||
glColor4f(r, g, b, FIXED2FLOAT(parms.alpha));
|
||||
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.SetColor(color);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(u1, v1);
|
||||
glVertex2d(x, y);
|
||||
glTexCoord2f(u1, v2);
|
||||
glVertex2d(x, y + h);
|
||||
glTexCoord2f(u2, v1);
|
||||
glVertex2d(x + w, y);
|
||||
glTexCoord2f(u2, v2);
|
||||
glVertex2d(x + w, y + h);
|
||||
glEnd();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x, y, 0, u1, v1); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
if (parms.colorOverlay)
|
||||
{
|
||||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
gl_RenderState.SetColor(PalEntry(parms.colorOverlay));
|
||||
gl_RenderState.Apply();
|
||||
glColor4ub(RPART(parms.colorOverlay),GPART(parms.colorOverlay),BPART(parms.colorOverlay),APART(parms.colorOverlay));
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(u1, v1);
|
||||
glVertex2d(x, y);
|
||||
glTexCoord2f(u1, v2);
|
||||
glVertex2d(x, y + h);
|
||||
glTexCoord2f(u2, v1);
|
||||
glVertex2d(x + w, y);
|
||||
glTexCoord2f(u2, v2);
|
||||
glVertex2d(x + w, y + h);
|
||||
glEnd();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x, y, 0, u1, v1); ptr++;
|
||||
ptr->Set(x, y + h, 0, u1, v2); ptr++;
|
||||
ptr->Set(x + w, y, 0, u2, v1); ptr++;
|
||||
ptr->Set(x + w, y + h, 0, u2, v2); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
|
||||
glScissor(0, 0, screen->GetWidth(), screen->GetHeight());
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
|
@ -449,12 +426,14 @@ void FGLRenderer::DrawLine(int x1, int y1, int x2, int y2, int palcolor, uint32
|
|||
{
|
||||
PalEntry p = color? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply(true);
|
||||
glColor3ub(p.r, p.g, p.b);
|
||||
glBegin(GL_LINES);
|
||||
glVertex2i(x1, y1);
|
||||
glVertex2i(x2, y2);
|
||||
glEnd();
|
||||
gl_RenderState.SetColorAlpha(p, 1.f);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x1, y1, 0, 0, 0); ptr++;
|
||||
ptr->Set(x2, y2, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_LINES);
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
|
|
@ -467,11 +446,13 @@ void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color)
|
|||
{
|
||||
PalEntry p = color? (PalEntry)color : GPalette.BaseColors[palcolor];
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply(true);
|
||||
glColor3ub(p.r, p.g, p.b);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex2i(x1, y1);
|
||||
glEnd();
|
||||
gl_RenderState.SetColorAlpha(p, 1.f);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x1, y1, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_POINTS);
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
|
|
@ -483,25 +464,19 @@ void FGLRenderer::DrawPixel(int x1, int y1, int palcolor, uint32 color)
|
|||
|
||||
void FGLRenderer::Dim(PalEntry color, float damount, int x1, int y1, int w, int h)
|
||||
{
|
||||
float r, g, b;
|
||||
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.AlphaFunc(GL_GREATER,0);
|
||||
gl_RenderState.Apply(true);
|
||||
|
||||
r = color.r/255.0f;
|
||||
g = color.g/255.0f;
|
||||
b = color.b/255.0f;
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glColor4f(r, g, b, damount);
|
||||
glVertex2i(x1, y1);
|
||||
glVertex2i(x1, y1 + h);
|
||||
glVertex2i(x1 + w, y1 + h);
|
||||
glVertex2i(x1 + w, y1);
|
||||
glEnd();
|
||||
gl_RenderState.SetColorAlpha(color, damount);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x1, y1, 0, 0, 0); ptr++;
|
||||
ptr->Set(x1, y1+h, 0, 0, 0); ptr++;
|
||||
ptr->Set(x1+w, y1+h, 0, 0, 0); ptr++;
|
||||
ptr->Set(x1+w, y1, 0, 0, 0); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
|
||||
|
|
@ -514,11 +489,11 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture *
|
|||
{
|
||||
float fU1,fU2,fV1,fV2;
|
||||
|
||||
FMaterial *gltexture=FMaterial::ValidateTexture(src);
|
||||
FMaterial *gltexture=FMaterial::ValidateTexture(src, false);
|
||||
|
||||
if (!gltexture) return;
|
||||
|
||||
gltexture->Bind(CM_DEFAULT, 0, 0);
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
|
||||
// scaling is not used here.
|
||||
if (!local_origin)
|
||||
|
|
@ -535,14 +510,15 @@ void FGLRenderer::FlatFill (int left, int top, int right, int bottom, FTexture *
|
|||
fU2 = float(right-left) / src->GetWidth();
|
||||
fV2 = float(bottom-top) / src->GetHeight();
|
||||
}
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glColor4f(1, 1, 1, 1);
|
||||
glTexCoord2f(fU1, fV1); glVertex2f(left, top);
|
||||
glTexCoord2f(fU1, fV2); glVertex2f(left, bottom);
|
||||
glTexCoord2f(fU2, fV1); glVertex2f(right, top);
|
||||
glTexCoord2f(fU2, fV2); glVertex2f(right, bottom);
|
||||
glEnd();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(left, top, 0, fU1, fV1); ptr++;
|
||||
ptr->Set(left, bottom, 0, fU1, fV2); ptr++;
|
||||
ptr->Set(right, top, 0, fU2, fV1); ptr++;
|
||||
ptr->Set(right, bottom, 0, fU2, fV2); ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -598,7 +574,7 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint
|
|||
return;
|
||||
}
|
||||
|
||||
FMaterial *gltexture = FMaterial::ValidateTexture(texture);
|
||||
FMaterial *gltexture = FMaterial::ValidateTexture(texture, false);
|
||||
|
||||
if (gltexture == NULL)
|
||||
{
|
||||
|
|
@ -608,11 +584,9 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint
|
|||
FColormap cm;
|
||||
cm = colormap;
|
||||
|
||||
lightlevel = gl_CalcLightLevel(lightlevel, 0, true);
|
||||
PalEntry pe = gl_CalcLightColor(lightlevel, cm.LightColor, cm.blendfactor, true);
|
||||
glColor3ub(pe.r, pe.g, pe.b);
|
||||
gl_SetColor(lightlevel, 0, cm, 1.f);
|
||||
|
||||
gltexture->Bind(cm.colormap);
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
|
||||
int i;
|
||||
float rot = float(rotation * M_PI / float(1u << 31));
|
||||
|
|
@ -632,7 +606,8 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint
|
|||
float oy = float(originy);
|
||||
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
for (i = 0; i < npoints; ++i)
|
||||
{
|
||||
float u = points[i].X - 0.5f - ox;
|
||||
|
|
@ -643,9 +618,9 @@ void FGLRenderer::FillSimplePoly(FTexture *texture, FVector2 *points, int npoint
|
|||
u = t * cosrot - v * sinrot;
|
||||
v = v * cosrot + t * sinrot;
|
||||
}
|
||||
glTexCoord2f(u * uscale, v * vscale);
|
||||
glVertex3f(points[i].X, points[i].Y /* + yoffs */, 0);
|
||||
ptr->Set(points[i].X, points[i].Y, 0, u*uscale, v*vscale);
|
||||
ptr++;
|
||||
}
|
||||
glEnd();
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,12 +9,15 @@
|
|||
struct particle_t;
|
||||
class FCanvasTexture;
|
||||
class FFlatVertexBuffer;
|
||||
class FSkyVertexBuffer;
|
||||
class FModelVertexBuffer;
|
||||
class OpenGLFrameBuffer;
|
||||
struct FDrawInfo;
|
||||
struct pspdef_t;
|
||||
class FShaderManager;
|
||||
class GLPortal;
|
||||
class FGLThreadManager;
|
||||
class FLightBuffer;
|
||||
class FSamplerManager;
|
||||
|
||||
enum SectorRenderFlags
|
||||
{
|
||||
|
|
@ -53,15 +56,14 @@ public:
|
|||
float mCurrentFoV;
|
||||
AActor *mViewActor;
|
||||
FShaderManager *mShaderManager;
|
||||
FGLThreadManager *mThreadManager;
|
||||
FSamplerManager *mSamplerManager;
|
||||
int gl_spriteindex;
|
||||
unsigned int mFBID;
|
||||
|
||||
FTexture *glpart2;
|
||||
FTexture *glpart;
|
||||
FTexture *mirrortexture;
|
||||
FTexture *gllight;
|
||||
|
||||
|
||||
float mSky1Pos, mSky2Pos;
|
||||
|
||||
FRotator mAngles;
|
||||
|
|
@ -69,6 +71,9 @@ public:
|
|||
FVector3 mCameraPos;
|
||||
|
||||
FFlatVertexBuffer *mVBO;
|
||||
FSkyVertexBuffer *mSkyVBO;
|
||||
FModelVertexBuffer *mModelVBO;
|
||||
FLightBuffer *mLights;
|
||||
|
||||
|
||||
FGLRenderer(OpenGLFrameBuffer *fb);
|
||||
|
|
@ -91,7 +96,7 @@ public:
|
|||
void DrawScene(bool toscreen = false);
|
||||
void DrawBlend(sector_t * viewsector);
|
||||
|
||||
void DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep, int OverrideShader);
|
||||
void DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, bool hudModelStep, int OverrideShader, bool alphatexture);
|
||||
void DrawPlayerSprites(sector_t * viewsector, bool hudModelStep);
|
||||
void DrawTargeterSprites();
|
||||
|
||||
|
|
|
|||
|
|
@ -38,23 +38,28 @@
|
|||
**
|
||||
*/
|
||||
|
||||
#include "templates.h"
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_colormap.h"
|
||||
#include "gl/dynlights//gl_lightbuffer.h"
|
||||
|
||||
void gl_SetTextureMode(int type);
|
||||
|
||||
FRenderState gl_RenderState;
|
||||
int FStateAttr::ChangeCounter;
|
||||
|
||||
CVAR(Bool, gl_direct_state_change, true, 0)
|
||||
|
||||
|
||||
static VSMatrix identityMatrix(1);
|
||||
TArray<VSMatrix> gl_MatrixStack;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -64,78 +69,29 @@ CVAR(Bool, gl_direct_state_change, true, 0)
|
|||
void FRenderState::Reset()
|
||||
{
|
||||
mTextureEnabled = true;
|
||||
mBrightmapEnabled = mFogEnabled = mGlowEnabled = mLightEnabled = false;
|
||||
ffTextureEnabled = ffFogEnabled = false;
|
||||
mSpecialEffect = ffSpecialEffect = EFF_NONE;
|
||||
mFogColor.d = ffFogColor.d = -1;
|
||||
mFogDensity = ffFogDensity = 0;
|
||||
mTextureMode = ffTextureMode = -1;
|
||||
mBrightmapEnabled = mFogEnabled = mGlowEnabled = false;
|
||||
mFogColor.d = -1;
|
||||
mTextureMode = -1;
|
||||
mLightIndex = -1;
|
||||
mDesaturation = 0;
|
||||
mSrcBlend = GL_SRC_ALPHA;
|
||||
mDstBlend = GL_ONE_MINUS_SRC_ALPHA;
|
||||
glSrcBlend = glDstBlend = -1;
|
||||
glAlphaFunc = -1;
|
||||
mAlphaFunc = GL_GEQUAL;
|
||||
mAlphaThreshold = 0.5f;
|
||||
mBlendEquation = GL_FUNC_ADD;
|
||||
glBlendEquation = -1;
|
||||
mObjectColor = 0xffffffff;
|
||||
m2D = true;
|
||||
mVertexBuffer = mCurrentVertexBuffer = NULL;
|
||||
mColormapState = CM_DEFAULT;
|
||||
mLightParms[3] = -1.f;
|
||||
mSpecialEffect = EFF_NONE;
|
||||
mClipHeightTop = 65536.f;
|
||||
mClipHeightBottom = -65536.f;
|
||||
|
||||
stSrcBlend = stDstBlend = -1;
|
||||
stBlendEquation = -1;
|
||||
stAlphaThreshold = -1.f;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Set texture shader info
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FRenderState::SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime)
|
||||
{
|
||||
bool usecmshader;
|
||||
int softwarewarp = 0;
|
||||
|
||||
if (shaderindex == 3)
|
||||
{
|
||||
// Brightmap should not be used.
|
||||
if (!mBrightmapEnabled || cm >= CM_FIRSTSPECIALCOLORMAP)
|
||||
{
|
||||
shaderindex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (gl.shadermodel == 4)
|
||||
{
|
||||
usecmshader = cm > CM_DEFAULT && cm < CM_MAXCOLORMAP && mTextureMode != TM_MASK;
|
||||
}
|
||||
else if (gl.shadermodel == 3)
|
||||
{
|
||||
usecmshader = (cameratexture || gl_colormap_shader) &&
|
||||
cm > CM_DEFAULT && cm < CM_MAXCOLORMAP && mTextureMode != TM_MASK;
|
||||
|
||||
if (!gl_brightmap_shader && shaderindex == 3)
|
||||
{
|
||||
shaderindex = 0;
|
||||
}
|
||||
else if (!gl_warp_shader && shaderindex !=3)
|
||||
{
|
||||
if (shaderindex <= 2) softwarewarp = shaderindex;
|
||||
shaderindex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
usecmshader = cameratexture;
|
||||
softwarewarp = shaderindex > 0 && shaderindex < 3? shaderindex : 0;
|
||||
shaderindex = 0;
|
||||
}
|
||||
|
||||
mEffectState = shaderindex;
|
||||
mColormapState = usecmshader? cm : CM_DEFAULT;
|
||||
if (usecmshader) cm = CM_DEFAULT;
|
||||
mWarpTime = warptime;
|
||||
return softwarewarp;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Apply shader settings
|
||||
|
|
@ -144,124 +100,134 @@ int FRenderState::SetupShader(bool cameratexture, int &shaderindex, int &cm, flo
|
|||
|
||||
bool FRenderState::ApplyShader()
|
||||
{
|
||||
bool useshaders = false;
|
||||
FShader *activeShader = NULL;
|
||||
|
||||
if (mSpecialEffect > 0 && gl.shadermodel > 2)
|
||||
if (mSpecialEffect > EFF_NONE)
|
||||
{
|
||||
activeShader = GLRenderer->mShaderManager->BindEffect(mSpecialEffect);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (gl.shadermodel)
|
||||
activeShader = GLRenderer->mShaderManager->Get(mTextureEnabled ? mEffectState : 4, mAlphaThreshold >= 0.f);
|
||||
activeShader->Bind();
|
||||
}
|
||||
|
||||
int fogset = 0;
|
||||
|
||||
if (mFogEnabled)
|
||||
{
|
||||
if ((mFogColor & 0xffffff) == 0)
|
||||
{
|
||||
case 2:
|
||||
useshaders = (mTextureEnabled && mColormapState != CM_DEFAULT);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
useshaders = (
|
||||
mEffectState != 0 || // special shaders
|
||||
(mFogEnabled && (gl_fogmode == 2 || gl_fog_shader) && gl_fogmode != 0) || // fog requires a shader
|
||||
(mTextureEnabled && (mEffectState != 0 || mColormapState)) || // colormap
|
||||
mGlowEnabled // glow requires a shader
|
||||
);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
useshaders = (!m2D || mEffectState != 0 || mColormapState); // all 3D rendering and 2D with texture effects.
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
fogset = gl_fogmode;
|
||||
}
|
||||
|
||||
if (useshaders)
|
||||
else
|
||||
{
|
||||
FShaderContainer *shd = GLRenderer->mShaderManager->Get(mTextureEnabled? mEffectState : 4);
|
||||
|
||||
if (shd != NULL)
|
||||
{
|
||||
activeShader = shd->Bind(mColormapState, mGlowEnabled, mWarpTime, mLightEnabled);
|
||||
}
|
||||
fogset = -gl_fogmode;
|
||||
}
|
||||
}
|
||||
|
||||
if (activeShader)
|
||||
glVertexAttrib4fv(VATTR_COLOR, mColor.vec);
|
||||
|
||||
activeShader->muDesaturation.Set(mDesaturation / 255.f);
|
||||
activeShader->muFogEnabled.Set(fogset);
|
||||
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->muClipHeightTop.Set(mClipHeightTop);
|
||||
activeShader->muClipHeightBottom.Set(mClipHeightBottom);
|
||||
activeShader->muTimer.Set(gl_frameMS * mShaderTimer / 1000.f);
|
||||
activeShader->muAlphaThreshold.Set(mAlphaThreshold);
|
||||
activeShader->muLightIndex.Set(mLightIndex); // will always be -1 for now
|
||||
|
||||
if (mGlowEnabled)
|
||||
{
|
||||
int fogset = 0;
|
||||
if (mFogEnabled)
|
||||
activeShader->muGlowTopColor.Set(mGlowTop.vec);
|
||||
activeShader->muGlowBottomColor.Set(mGlowBottom.vec);
|
||||
activeShader->muGlowTopPlane.Set(mGlowTopPlane.vec);
|
||||
activeShader->muGlowBottomPlane.Set(mGlowBottomPlane.vec);
|
||||
activeShader->currentglowstate = 1;
|
||||
}
|
||||
else if (activeShader->currentglowstate)
|
||||
{
|
||||
// if glowing is on, disable it.
|
||||
static const float nulvec[] = { 0.f, 0.f, 0.f, 0.f };
|
||||
activeShader->muGlowTopColor.Set(nulvec);
|
||||
activeShader->muGlowBottomColor.Set(nulvec);
|
||||
activeShader->muGlowTopPlane.Set(nulvec);
|
||||
activeShader->muGlowBottomPlane.Set(nulvec);
|
||||
activeShader->currentglowstate = 0;
|
||||
}
|
||||
|
||||
if (mColormapState != activeShader->currentfixedcolormap)
|
||||
{
|
||||
float r, g, b;
|
||||
activeShader->currentfixedcolormap = mColormapState;
|
||||
if (mColormapState == CM_DEFAULT)
|
||||
{
|
||||
if ((mFogColor & 0xffffff) == 0)
|
||||
activeShader->muFixedColormap.Set(0);
|
||||
}
|
||||
else if (mColormapState < CM_MAXCOLORMAP)
|
||||
{
|
||||
FSpecialColormap *scm = &SpecialColormaps[gl_fixedcolormap - 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)
|
||||
{
|
||||
fogset = gl_fogmode;
|
||||
r = 0.375f, g = 1.0f, b = 0.375f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fogset = -gl_fogmode;
|
||||
r = g = b = 1.f;
|
||||
}
|
||||
activeShader->muFixedColormap.Set(2);
|
||||
activeShader->muColormapStart.Set(r, g, b, 1.f);
|
||||
}
|
||||
|
||||
if (fogset != activeShader->currentfogenabled)
|
||||
else if (mColormapState >= CM_TORCH)
|
||||
{
|
||||
glUniform1i(activeShader->fogenabled_index, (activeShader->currentfogenabled = fogset));
|
||||
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 (mTextureMode != activeShader->currenttexturemode)
|
||||
{
|
||||
glUniform1i(activeShader->texturemode_index, (activeShader->currenttexturemode = mTextureMode));
|
||||
}
|
||||
if (activeShader->currentcamerapos.Update(&mCameraPos))
|
||||
{
|
||||
glUniform3fv(activeShader->camerapos_index, 1, mCameraPos.vec);
|
||||
}
|
||||
/*if (mLightParms[0] != activeShader->currentlightfactor ||
|
||||
mLightParms[1] != activeShader->currentlightdist ||
|
||||
mFogDensity != activeShader->currentfogdensity)*/
|
||||
{
|
||||
const float LOG2E = 1.442692f; // = 1/log(2)
|
||||
//activeShader->currentlightdist = mLightParms[1];
|
||||
//activeShader->currentlightfactor = mLightParms[0];
|
||||
//activeShader->currentfogdensity = mFogDensity;
|
||||
// premultiply the density with as much as possible here to reduce shader
|
||||
// execution time.
|
||||
glVertexAttrib4f(VATTR_FOGPARAMS, mLightParms[0], mLightParms[1], mFogDensity * (-LOG2E / 64000.f), 0);
|
||||
}
|
||||
if (mFogColor != activeShader->currentfogcolor)
|
||||
{
|
||||
activeShader->currentfogcolor = mFogColor;
|
||||
|
||||
glUniform4f (activeShader->fogcolor_index, mFogColor.r/255.f, mFogColor.g/255.f,
|
||||
mFogColor.b/255.f, 0);
|
||||
}
|
||||
if (mGlowEnabled)
|
||||
{
|
||||
glUniform4fv(activeShader->glowtopcolor_index, 1, mGlowTop.vec);
|
||||
glUniform4fv(activeShader->glowbottomcolor_index, 1, mGlowBottom.vec);
|
||||
glUniform4fv(activeShader->glowtopplane_index, 1, mGlowTopPlane.vec);
|
||||
glUniform4fv(activeShader->glowbottomplane_index, 1, mGlowBottomPlane.vec);
|
||||
activeShader->currentglowstate = 1;
|
||||
}
|
||||
else if (activeShader->currentglowstate)
|
||||
{
|
||||
// if glowing is on, disable it.
|
||||
glUniform4f(activeShader->glowtopcolor_index, 0.f, 0.f, 0.f, 0.f);
|
||||
glUniform4f(activeShader->glowbottomcolor_index, 0.f, 0.f, 0.f, 0.f);
|
||||
activeShader->currentglowstate = 0;
|
||||
}
|
||||
|
||||
if (mLightEnabled)
|
||||
{
|
||||
glUniform3iv(activeShader->lightrange_index, 1, mNumLights);
|
||||
glUniform4fv(activeShader->lights_index, mNumLights[2], mLightData);
|
||||
}
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
glUniform3fv(activeShader->dlightcolor_index, 1, mDynLight);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
if (mTextureMatrixEnabled)
|
||||
{
|
||||
mTextureMatrix.matrixToGL(activeShader->texturematrix_index);
|
||||
activeShader->currentTextureMatrixState = true;
|
||||
}
|
||||
else if (activeShader->currentTextureMatrixState)
|
||||
{
|
||||
activeShader->currentTextureMatrixState = false;
|
||||
identityMatrix.matrixToGL(activeShader->texturematrix_index);
|
||||
}
|
||||
|
||||
if (mModelMatrixEnabled)
|
||||
{
|
||||
mModelMatrix.matrixToGL(activeShader->modelmatrix_index);
|
||||
activeShader->currentModelMatrixState = true;
|
||||
}
|
||||
else if (activeShader->currentModelMatrixState)
|
||||
{
|
||||
activeShader->currentModelMatrixState = false;
|
||||
identityMatrix.matrixToGL(activeShader->modelmatrix_index);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -271,96 +237,47 @@ bool FRenderState::ApplyShader()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FRenderState::Apply(bool forcenoshader)
|
||||
void FRenderState::Apply()
|
||||
{
|
||||
if (!gl_direct_state_change)
|
||||
{
|
||||
if (mSrcBlend != glSrcBlend || mDstBlend != glDstBlend)
|
||||
if (mSrcBlend != stSrcBlend || mDstBlend != stDstBlend)
|
||||
{
|
||||
glSrcBlend = mSrcBlend;
|
||||
glDstBlend = mDstBlend;
|
||||
stSrcBlend = mSrcBlend;
|
||||
stDstBlend = mDstBlend;
|
||||
glBlendFunc(mSrcBlend, mDstBlend);
|
||||
}
|
||||
if (mAlphaFunc != glAlphaFunc || mAlphaThreshold != glAlphaThreshold)
|
||||
if (mBlendEquation != stBlendEquation)
|
||||
{
|
||||
glAlphaFunc = mAlphaFunc;
|
||||
glAlphaThreshold = mAlphaThreshold;
|
||||
::glAlphaFunc(mAlphaFunc, mAlphaThreshold);
|
||||
}
|
||||
if (mAlphaTest != glAlphaTest)
|
||||
{
|
||||
glAlphaTest = mAlphaTest;
|
||||
if (mAlphaTest) glEnable(GL_ALPHA_TEST);
|
||||
else glDisable(GL_ALPHA_TEST);
|
||||
}
|
||||
if (mBlendEquation != glBlendEquation)
|
||||
{
|
||||
glBlendEquation = mBlendEquation;
|
||||
::glBlendEquation(mBlendEquation);
|
||||
stBlendEquation = mBlendEquation;
|
||||
glBlendEquation(mBlendEquation);
|
||||
}
|
||||
}
|
||||
|
||||
if (forcenoshader || !ApplyShader())
|
||||
if (mVertexBuffer != mCurrentVertexBuffer)
|
||||
{
|
||||
GLRenderer->mShaderManager->SetActiveShader(NULL);
|
||||
if (mTextureMode != ffTextureMode)
|
||||
{
|
||||
gl_SetTextureMode((ffTextureMode = mTextureMode));
|
||||
}
|
||||
if (mTextureEnabled != ffTextureEnabled)
|
||||
{
|
||||
if ((ffTextureEnabled = mTextureEnabled)) glEnable(GL_TEXTURE_2D);
|
||||
else glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
if (mFogEnabled != ffFogEnabled)
|
||||
{
|
||||
if ((ffFogEnabled = mFogEnabled))
|
||||
{
|
||||
glEnable(GL_FOG);
|
||||
}
|
||||
else glDisable(GL_FOG);
|
||||
}
|
||||
if (mFogEnabled)
|
||||
{
|
||||
if (ffFogColor != mFogColor)
|
||||
{
|
||||
ffFogColor = mFogColor;
|
||||
GLfloat FogColor[4]={mFogColor.r/255.0f,mFogColor.g/255.0f,mFogColor.b/255.0f,0.0f};
|
||||
glFogfv(GL_FOG_COLOR, FogColor);
|
||||
}
|
||||
if (ffFogDensity != mFogDensity)
|
||||
{
|
||||
glFogf(GL_FOG_DENSITY, mFogDensity/64000.f);
|
||||
ffFogDensity=mFogDensity;
|
||||
}
|
||||
}
|
||||
if (mSpecialEffect != ffSpecialEffect)
|
||||
{
|
||||
switch (ffSpecialEffect)
|
||||
{
|
||||
case EFF_SPHEREMAP:
|
||||
glDisable(GL_TEXTURE_GEN_T);
|
||||
glDisable(GL_TEXTURE_GEN_S);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (mSpecialEffect)
|
||||
{
|
||||
case EFF_SPHEREMAP:
|
||||
// Use sphere mapping for this
|
||||
glEnable(GL_TEXTURE_GEN_T);
|
||||
glEnable(GL_TEXTURE_GEN_S);
|
||||
glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
|
||||
glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ffSpecialEffect = mSpecialEffect;
|
||||
}
|
||||
if (mVertexBuffer == NULL) glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
else mVertexBuffer->BindVBO();
|
||||
mCurrentVertexBuffer = mVertexBuffer;
|
||||
}
|
||||
|
||||
ApplyShader();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void FRenderState::ApplyMatrices()
|
||||
{
|
||||
if (GLRenderer->mShaderManager != NULL)
|
||||
{
|
||||
GLRenderer->mShaderManager->ApplyMatrices(&mProjectionMatrix, &mViewMatrix);
|
||||
}
|
||||
}
|
||||
|
||||
void FRenderState::ApplyLightIndex(int index)
|
||||
{
|
||||
if (GLRenderer->mLights->GetBufferType() == GL_UNIFORM_BUFFER && index > -1)
|
||||
{
|
||||
index = GLRenderer->mLights->BindUBO(index);
|
||||
}
|
||||
activeShader->muLightIndex.Set(index);
|
||||
}
|
||||
|
|
@ -2,86 +2,43 @@
|
|||
#define __GL_RENDERSTATE_H
|
||||
|
||||
#include <string.h>
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_matrix.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "c_cvars.h"
|
||||
#include "r_defs.h"
|
||||
#include "r_data/r_translate.h"
|
||||
|
||||
class FVertexBuffer;
|
||||
class FShader;
|
||||
extern TArray<VSMatrix> gl_MatrixStack;
|
||||
|
||||
EXTERN_CVAR(Bool, gl_direct_state_change)
|
||||
|
||||
struct FStateAttr
|
||||
{
|
||||
static int ChangeCounter;
|
||||
int mLastChange;
|
||||
|
||||
FStateAttr()
|
||||
{
|
||||
mLastChange = -1;
|
||||
}
|
||||
|
||||
bool operator == (const FStateAttr &other)
|
||||
{
|
||||
return mLastChange == other.mLastChange;
|
||||
}
|
||||
|
||||
bool operator != (const FStateAttr &other)
|
||||
{
|
||||
return mLastChange != other.mLastChange;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct FStateVec3 : public FStateAttr
|
||||
{
|
||||
float vec[3];
|
||||
|
||||
bool Update(FStateVec3 *other)
|
||||
{
|
||||
if (mLastChange != other->mLastChange)
|
||||
{
|
||||
*this = *other;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Set(float x, float y, float z)
|
||||
{
|
||||
vec[0] = x;
|
||||
vec[1] = z;
|
||||
vec[2] = y;
|
||||
mLastChange = ++ChangeCounter;
|
||||
}
|
||||
};
|
||||
|
||||
struct FStateVec4 : public FStateAttr
|
||||
struct FStateVec4
|
||||
{
|
||||
float vec[4];
|
||||
|
||||
bool Update(FStateVec4 *other)
|
||||
{
|
||||
if (mLastChange != other->mLastChange)
|
||||
{
|
||||
*this = *other;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Set(float r, float g, float b, float a)
|
||||
{
|
||||
vec[0] = r;
|
||||
vec[1] = g;
|
||||
vec[2] = b;
|
||||
vec[3] = a;
|
||||
mLastChange = ++ChangeCounter;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
enum EEffect
|
||||
{
|
||||
EFF_NONE,
|
||||
EFF_NONE=-1,
|
||||
EFF_FOGBOUNDARY,
|
||||
EFF_SPHEREMAP,
|
||||
EFF_BURN,
|
||||
EFF_STENCIL,
|
||||
|
||||
MAX_EFFECTS
|
||||
};
|
||||
|
||||
class FRenderState
|
||||
|
|
@ -89,47 +46,52 @@ class FRenderState
|
|||
bool mTextureEnabled;
|
||||
bool mFogEnabled;
|
||||
bool mGlowEnabled;
|
||||
bool mLightEnabled;
|
||||
bool mBrightmapEnabled;
|
||||
int mLightIndex;
|
||||
int mSpecialEffect;
|
||||
int mTextureMode;
|
||||
float mDynLight[3];
|
||||
float mLightParms[2];
|
||||
int mNumLights[3];
|
||||
float *mLightData;
|
||||
int mDesaturation;
|
||||
int mSoftLight;
|
||||
float mLightParms[4];
|
||||
int mSrcBlend, mDstBlend;
|
||||
int mAlphaFunc;
|
||||
float mAlphaThreshold;
|
||||
bool mAlphaTest;
|
||||
int mBlendEquation;
|
||||
bool mAlphaTest;
|
||||
bool m2D;
|
||||
bool mModelMatrixEnabled;
|
||||
bool mTextureMatrixEnabled;
|
||||
float mInterpolationFactor;
|
||||
float mClipHeightTop, mClipHeightBottom;
|
||||
float mShaderTimer;
|
||||
|
||||
FStateVec3 mCameraPos;
|
||||
FVertexBuffer *mVertexBuffer, *mCurrentVertexBuffer;
|
||||
FStateVec4 mColor;
|
||||
FStateVec4 mCameraPos;
|
||||
FStateVec4 mGlowTop, mGlowBottom;
|
||||
FStateVec4 mGlowTopPlane, mGlowBottomPlane;
|
||||
PalEntry mFogColor;
|
||||
float mFogDensity;
|
||||
PalEntry mObjectColor;
|
||||
FStateVec4 mDynColor;
|
||||
|
||||
int mEffectState;
|
||||
int mColormapState;
|
||||
float mWarpTime;
|
||||
|
||||
int glSrcBlend, glDstBlend;
|
||||
int glAlphaFunc;
|
||||
float glAlphaThreshold;
|
||||
bool glAlphaTest;
|
||||
int glBlendEquation;
|
||||
float stAlphaThreshold;
|
||||
int stSrcBlend, stDstBlend;
|
||||
bool stAlphaTest;
|
||||
int stBlendEquation;
|
||||
|
||||
bool ffTextureEnabled;
|
||||
bool ffFogEnabled;
|
||||
int ffTextureMode;
|
||||
int ffSpecialEffect;
|
||||
PalEntry ffFogColor;
|
||||
float ffFogDensity;
|
||||
FShader *activeShader;
|
||||
|
||||
bool ApplyShader();
|
||||
|
||||
public:
|
||||
|
||||
VSMatrix mProjectionMatrix;
|
||||
VSMatrix mViewMatrix;
|
||||
VSMatrix mModelMatrix;
|
||||
VSMatrix mTextureMatrix;
|
||||
|
||||
FRenderState()
|
||||
{
|
||||
Reset();
|
||||
|
|
@ -137,8 +99,78 @@ public:
|
|||
|
||||
void Reset();
|
||||
|
||||
int SetupShader(bool cameratexture, int &shaderindex, int &cm, float warptime);
|
||||
void Apply(bool forcenoshader = false);
|
||||
void SetMaterial(FMaterial *mat, int clampmode, int translation, int overrideshader, bool alphatexture)
|
||||
{
|
||||
// textures without their own palette are a special case for use as an alpha texture:
|
||||
// They use the color index directly as an alpha value instead of using the palette's red.
|
||||
// To handle this case, we need to set a special translation for such textures.
|
||||
if (alphatexture)
|
||||
{
|
||||
if (mat->tex->UseBasePalette()) translation = TRANSLATION(TRANSLATION_Standard, 8);
|
||||
}
|
||||
mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex;
|
||||
mShaderTimer = mat->tex->gl_info.shaderspeed;
|
||||
mat->Bind(clampmode, translation);
|
||||
}
|
||||
|
||||
void Apply();
|
||||
void ApplyMatrices();
|
||||
void ApplyLightIndex(int index);
|
||||
|
||||
void SetVertexBuffer(FVertexBuffer *vb)
|
||||
{
|
||||
mVertexBuffer = vb;
|
||||
}
|
||||
|
||||
void ResetVertexBuffer()
|
||||
{
|
||||
// forces rebinding with the next 'apply' call.
|
||||
mCurrentVertexBuffer = NULL;
|
||||
}
|
||||
|
||||
void SetClipHeightTop(float clip)
|
||||
{
|
||||
mClipHeightTop = clip;
|
||||
}
|
||||
|
||||
float GetClipHeightTop()
|
||||
{
|
||||
return mClipHeightTop;
|
||||
}
|
||||
|
||||
void SetClipHeightBottom(float clip)
|
||||
{
|
||||
mClipHeightBottom = clip;
|
||||
}
|
||||
|
||||
float GetClipHeightBottom()
|
||||
{
|
||||
return mClipHeightBottom;
|
||||
}
|
||||
|
||||
void SetColor(float r, float g, float b, float a = 1.f, int desat = 0)
|
||||
{
|
||||
mColor.Set(r, g, b, a);
|
||||
mDesaturation = desat;
|
||||
}
|
||||
|
||||
void SetColor(PalEntry pe, int desat = 0)
|
||||
{
|
||||
mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, pe.a/255.f);
|
||||
mDesaturation = desat;
|
||||
}
|
||||
|
||||
void SetColorAlpha(PalEntry pe, float alpha = 1.f, int desat = 0)
|
||||
{
|
||||
mColor.Set(pe.r/255.f, pe.g/255.f, pe.b/255.f, alpha);
|
||||
mDesaturation = desat;
|
||||
}
|
||||
|
||||
void ResetColor()
|
||||
{
|
||||
mColor.Set(1,1,1,1);
|
||||
mDesaturation = 0;
|
||||
}
|
||||
|
||||
void SetTextureMode(int mode)
|
||||
{
|
||||
|
|
@ -165,9 +197,9 @@ public:
|
|||
mGlowEnabled = on;
|
||||
}
|
||||
|
||||
void EnableLight(bool on)
|
||||
void SetLightIndex(int n)
|
||||
{
|
||||
mLightEnabled = on;
|
||||
mLightIndex = n;
|
||||
}
|
||||
|
||||
void EnableBrightmap(bool on)
|
||||
|
|
@ -175,9 +207,19 @@ public:
|
|||
mBrightmapEnabled = on;
|
||||
}
|
||||
|
||||
void EnableModelMatrix(bool on)
|
||||
{
|
||||
mModelMatrixEnabled = on;
|
||||
}
|
||||
|
||||
void EnableTextureMatrix(bool on)
|
||||
{
|
||||
mTextureMatrixEnabled = on;
|
||||
}
|
||||
|
||||
void SetCameraPos(float x, float y, float z)
|
||||
{
|
||||
mCameraPos.Set(x,y,z);
|
||||
mCameraPos.Set(x, z, y, 0);
|
||||
}
|
||||
|
||||
void SetGlowParams(float *t, float *b)
|
||||
|
|
@ -186,6 +228,12 @@ public:
|
|||
mGlowBottom.Set(b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
|
||||
void SetSoftLightLevel(int level)
|
||||
{
|
||||
if (glset.lightmode == 8) mLightParms[3] = level / 255.f;
|
||||
else mLightParms[3] = -1.f;
|
||||
}
|
||||
|
||||
void SetGlowPlanes(const secplane_t &top, const secplane_t &bottom)
|
||||
{
|
||||
mGlowTopPlane.Set(FIXED2FLOAT(top.a), FIXED2FLOAT(top.b), FIXED2FLOAT(top.ic), FIXED2FLOAT(top.d));
|
||||
|
|
@ -194,29 +242,25 @@ public:
|
|||
|
||||
void SetDynLight(float r, float g, float b)
|
||||
{
|
||||
mDynLight[0] = r;
|
||||
mDynLight[1] = g;
|
||||
mDynLight[2] = b;
|
||||
mDynColor.Set(r, g, b, 0);
|
||||
}
|
||||
|
||||
void SetObjectColor(PalEntry pe)
|
||||
{
|
||||
mObjectColor = pe;
|
||||
}
|
||||
|
||||
void SetFog(PalEntry c, float d)
|
||||
{
|
||||
const float LOG2E = 1.442692f; // = 1/log(2)
|
||||
mFogColor = c;
|
||||
if (d >= 0.0f) mFogDensity = d;
|
||||
if (d >= 0.0f) mLightParms[2] = d * (-LOG2E / 64000.f);
|
||||
}
|
||||
|
||||
void SetLightParms(float f, float d)
|
||||
{
|
||||
mLightParms[0] = f;
|
||||
mLightParms[1] = d;
|
||||
}
|
||||
|
||||
void SetLights(int *numlights, float *lightdata)
|
||||
{
|
||||
mNumLights[0] = numlights[0];
|
||||
mNumLights[1] = numlights[1];
|
||||
mNumLights[2] = numlights[2];
|
||||
mLightData = lightdata; // caution: the data must be preserved by the caller until the 'apply' call!
|
||||
mLightParms[1] = f;
|
||||
mLightParms[0] = d;
|
||||
}
|
||||
|
||||
void SetFixedColormap(int cm)
|
||||
|
|
@ -244,28 +288,8 @@ public:
|
|||
|
||||
void AlphaFunc(int func, float thresh)
|
||||
{
|
||||
if (!gl_direct_state_change)
|
||||
{
|
||||
mAlphaFunc = func;
|
||||
mAlphaThreshold = thresh;
|
||||
}
|
||||
else
|
||||
{
|
||||
::glAlphaFunc(func, thresh);
|
||||
}
|
||||
}
|
||||
|
||||
void EnableAlphaTest(bool on)
|
||||
{
|
||||
if (!gl_direct_state_change)
|
||||
{
|
||||
mAlphaTest = on;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (on) glEnable(GL_ALPHA_TEST);
|
||||
else glDisable(GL_ALPHA_TEST);
|
||||
}
|
||||
if (func == GL_GREATER) mAlphaThreshold = thresh;
|
||||
else mAlphaThreshold = thresh - 0.001f;
|
||||
}
|
||||
|
||||
void BlendEquation(int eq)
|
||||
|
|
@ -276,7 +300,7 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
::glBlendEquation(eq);
|
||||
glBlendEquation(eq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -284,6 +308,11 @@ public:
|
|||
{
|
||||
m2D = on;
|
||||
}
|
||||
|
||||
void SetInterpolationFactor(float fac)
|
||||
{
|
||||
mInterpolationFactor = fac;
|
||||
}
|
||||
};
|
||||
|
||||
extern FRenderState gl_RenderState;
|
||||
|
|
|
|||
|
|
@ -186,20 +186,9 @@ static void AddLine (seg_t *seg)
|
|||
{
|
||||
SetupWall.Clock();
|
||||
|
||||
//if (!gl_multithreading)
|
||||
{
|
||||
GLWall wall;
|
||||
wall.sub = currentsubsector;
|
||||
wall.Process(seg, currentsector, backsector);
|
||||
}
|
||||
/*
|
||||
else
|
||||
{
|
||||
FJob *job = new FGLJobProcessWall(currentsubsector, seg,
|
||||
currentsector->sectornum, backsector != NULL? backsector->sectornum : -1);
|
||||
GLRenderer->mThreadManager->AddJob(job);
|
||||
}
|
||||
*/
|
||||
GLWall wall;
|
||||
wall.sub = currentsubsector;
|
||||
wall.Process(seg, currentsector, backsector);
|
||||
rendered_lines++;
|
||||
|
||||
SetupWall.Unclock();
|
||||
|
|
@ -341,21 +330,11 @@ static inline void RenderThings(subsector_t * sub, sector_t * sector)
|
|||
sector_t * sec=sub->sector;
|
||||
if (sec->thinglist != NULL)
|
||||
{
|
||||
//if (!gl_multithreading)
|
||||
// Handle all things in sector.
|
||||
for (AActor * thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
// Handle all things in sector.
|
||||
for (AActor * thing = sec->thinglist; thing; thing = thing->snext)
|
||||
{
|
||||
GLRenderer->ProcessSprite(thing, sector);
|
||||
}
|
||||
GLRenderer->ProcessSprite(thing, sector);
|
||||
}
|
||||
/*
|
||||
else if (sec->thinglist != NULL)
|
||||
{
|
||||
FJob *job = new FGLJobProcessSprites(sector);
|
||||
GLRenderer->mThreadManager->AddJob(job);
|
||||
}
|
||||
*/
|
||||
}
|
||||
SetupSprite.Unclock();
|
||||
}
|
||||
|
|
@ -416,20 +395,10 @@ static void DoSubsector(subsector_t * sub)
|
|||
{
|
||||
SetupSprite.Clock();
|
||||
|
||||
//if (!gl_multithreading)
|
||||
for (i = ParticlesInSubsec[DWORD(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||
{
|
||||
for (i = ParticlesInSubsec[DWORD(sub-subsectors)]; i != NO_PARTICLE; i = Particles[i].snext)
|
||||
{
|
||||
GLRenderer->ProcessParticle(&Particles[i], fakesector);
|
||||
}
|
||||
GLRenderer->ProcessParticle(&Particles[i], fakesector);
|
||||
}
|
||||
/*
|
||||
else if (ParticlesInSubsec[DWORD(sub-subsectors)] != NO_PARTICLE)
|
||||
{
|
||||
FJob job = new FGLJobProcessParticles(sub);
|
||||
GLRenderer->mThreadManager->AddJob(job);
|
||||
}
|
||||
*/
|
||||
SetupSprite.Unclock();
|
||||
}
|
||||
|
||||
|
|
@ -476,17 +445,7 @@ static void DoSubsector(subsector_t * sub)
|
|||
srf |= SSRF_PROCESSED;
|
||||
|
||||
SetupFlat.Clock();
|
||||
//if (!gl_multithreading)
|
||||
{
|
||||
GLRenderer->ProcessSector(fakesector);
|
||||
}
|
||||
/*
|
||||
else
|
||||
{
|
||||
FJob *job = new FGLJobProcessFlats(sub);
|
||||
GLRenderer->mThreadManager->AddJob(job);
|
||||
}
|
||||
*/
|
||||
GLRenderer->ProcessSector(fakesector);
|
||||
SetupFlat.Unclock();
|
||||
}
|
||||
// mark subsector as processed - but mark for rendering only if it has an actual area.
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
|
|
@ -74,7 +75,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
int light;
|
||||
int rel;
|
||||
float a;
|
||||
bool flipx, flipy, loadAlpha;
|
||||
bool flipx, flipy;
|
||||
DecalVertex dv[4];
|
||||
FTextureID decalTile;
|
||||
|
||||
|
|
@ -102,17 +103,7 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
FMaterial *tex;
|
||||
|
||||
|
||||
if (texture->UseType == FTexture::TEX_MiscPatch)
|
||||
{
|
||||
// We need to create a clone of this texture where we can force the
|
||||
// texture filtering offset in.
|
||||
if (texture->gl_info.DecalTexture == NULL)
|
||||
{
|
||||
texture->gl_info.DecalTexture = new FCloneTexture(texture, FTexture::TEX_Decal);
|
||||
}
|
||||
tex = FMaterial::ValidateTexture(texture->gl_info.DecalTexture);
|
||||
}
|
||||
else tex = FMaterial::ValidateTexture(texture);
|
||||
tex = FMaterial::ValidateTexture(texture, true);
|
||||
|
||||
|
||||
// the sectors are only used for their texture origin coordinates
|
||||
|
|
@ -179,78 +170,22 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
rel = rellight + getExtraLight();
|
||||
}
|
||||
|
||||
int r = RPART(decal->AlphaColor);
|
||||
int g = GPART(decal->AlphaColor);
|
||||
int b = BPART(decal->AlphaColor);
|
||||
FColormap p = Colormap;
|
||||
|
||||
if (glset.nocoloredspritelighting)
|
||||
{
|
||||
int v = (Colormap.LightColor.r * 77 + Colormap.LightColor.g*143 + Colormap.LightColor.b*35)/255;
|
||||
p.LightColor = PalEntry(p.colormap, v, v, v);
|
||||
p.Decolorize();
|
||||
}
|
||||
|
||||
float red, green, blue;
|
||||
|
||||
if (decal->RenderStyle.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
loadAlpha = true;
|
||||
p.colormap=CM_SHADE;
|
||||
|
||||
if (glset.lightmode != 8)
|
||||
{
|
||||
gl_GetLightColor(light, rel, &p, &red, &green, &blue);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_GetLightColor(lightlevel, rellight, &p, &red, &green, &blue);
|
||||
}
|
||||
|
||||
if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && gl_light_sprites)
|
||||
{
|
||||
float result[3];
|
||||
fixed_t x, y;
|
||||
decal->GetXY(seg->sidedef, x, y);
|
||||
gl_GetSpriteLight(NULL, x, y, zpos, sub, Colormap.colormap-CM_DESAT0, result, line, side == line->sidedef[0]? 0:1);
|
||||
if (glset.lightmode != 8)
|
||||
{
|
||||
red = clamp<float>(result[0]+red, 0, 1.0f);
|
||||
green = clamp<float>(result[1]+green, 0, 1.0f);
|
||||
blue = clamp<float>(result[2]+blue, 0, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.SetDynLight(result[0], result[1], result[2]);
|
||||
}
|
||||
}
|
||||
|
||||
BYTE R = xs_RoundToInt(r * red);
|
||||
BYTE G = xs_RoundToInt(g * green);
|
||||
BYTE B = xs_RoundToInt(b * blue);
|
||||
|
||||
gl_ModifyColor(R,G,B, Colormap.colormap);
|
||||
|
||||
red = R/255.f;
|
||||
green = G/255.f;
|
||||
blue = B/255.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
loadAlpha = false;
|
||||
|
||||
red = 1.f;
|
||||
green = 1.f;
|
||||
blue = 1.f;
|
||||
}
|
||||
|
||||
|
||||
a = FIXED2FLOAT(decal->Alpha);
|
||||
|
||||
// now clip the decal to the actual polygon
|
||||
float decalwidth = tex->TextureWidth(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleX);
|
||||
float decalheight= tex->TextureHeight(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleY);
|
||||
float decallefto = tex->GetLeftOffset(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleX);
|
||||
float decaltopo = tex->GetTopOffset(GLUSE_PATCH) * FIXED2FLOAT(decal->ScaleY);
|
||||
float decalwidth = tex->TextureWidth() * FIXED2FLOAT(decal->ScaleX);
|
||||
float decalheight= tex->TextureHeight() * FIXED2FLOAT(decal->ScaleY);
|
||||
float decallefto = tex->GetLeftOffset() * FIXED2FLOAT(decal->ScaleX);
|
||||
float decaltopo = tex->GetTopOffset() * FIXED2FLOAT(decal->ScaleY);
|
||||
|
||||
|
||||
float leftedge = glseg.fracleft * side->TexelLength;
|
||||
|
|
@ -299,8 +234,6 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
|
||||
zpos+= FRACUNIT*(flipy? decalheight-decaltopo : decaltopo);
|
||||
|
||||
tex->BindPatch(p.colormap, decal->Translation);
|
||||
|
||||
dv[1].z=dv[2].z = FIXED2FLOAT(zpos);
|
||||
dv[0].z=dv[3].z = dv[1].z - decalheight;
|
||||
dv[1].v=dv[2].v = tex->GetVT();
|
||||
|
|
@ -359,32 +292,25 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
float vb = tex->GetVB();
|
||||
for(i=0;i<4;i++) dv[i].v=vb-dv[i].v;
|
||||
}
|
||||
// fog is set once per wall in the calling function and not per decal!
|
||||
|
||||
if (loadAlpha)
|
||||
// calculate dynamic light effect.
|
||||
if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap && gl_light_sprites)
|
||||
{
|
||||
glColor4f(red, green, blue, a);
|
||||
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
if (gl_fixedcolormap)
|
||||
glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0);
|
||||
else
|
||||
glVertexAttrib1f(VATTR_LIGHTLEVEL, gl_CalcLightLevel(light, rel, false) / 255.0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
gl_SetColor(light, rel, &p, a, extralight); // Korshun.
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_SetColor(light, rel, &p, a);
|
||||
}
|
||||
// Note: This should be replaced with proper shader based lighting.
|
||||
fixed_t x, y;
|
||||
decal->GetXY(seg->sidedef, x, y);
|
||||
gl_SetDynSpriteLight(NULL, x, y, zpos, sub);
|
||||
}
|
||||
|
||||
// alpha color only has an effect when using an alpha texture.
|
||||
if (decal->RenderStyle.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
gl_RenderState.SetObjectColor(decal->AlphaColor);
|
||||
}
|
||||
|
||||
gl_SetColor(light, rel, p, a);
|
||||
|
||||
// for additively drawn decals we must temporarily set the fog color to black.
|
||||
PalEntry fc = gl_RenderState.GetFogColor();
|
||||
if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One)
|
||||
{
|
||||
|
|
@ -393,20 +319,25 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
|
||||
|
||||
gl_SetRenderStyle(decal->RenderStyle, false, false);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_XY, decal->Translation, 0, !!(decal->RenderStyle.Flags & STYLEF_RedIsAlpha));
|
||||
|
||||
|
||||
// If srcalpha is one it looks better with a higher alpha threshold
|
||||
if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
if (decal->RenderStyle.SrcAlpha == STYLEALPHA_One) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
|
||||
else gl_RenderState.AlphaFunc(GL_GREATER, 0.f);
|
||||
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
for(i=0;i<4;i++)
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
glTexCoord2f(dv[i].u,dv[i].v);
|
||||
glVertex3f(dv[i].x,dv[i].z,dv[i].y);
|
||||
ptr->Set(dv[i].x, dv[i].z, dv[i].y, dv[i].u, dv[i].v);
|
||||
ptr++;
|
||||
}
|
||||
glEnd();
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
rendered_decals++;
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
gl_RenderState.SetFog(fc,-1);
|
||||
gl_RenderState.SetDynLight(0,0,0);
|
||||
}
|
||||
|
|
@ -418,11 +349,15 @@ void GLWall::DrawDecal(DBaseDecal *decal)
|
|||
//==========================================================================
|
||||
void GLWall::DoDrawDecals()
|
||||
{
|
||||
DBaseDecal *decal = seg->sidedef->AttachedDecals;
|
||||
while (decal)
|
||||
if (seg->sidedef && seg->sidedef->AttachedDecals)
|
||||
{
|
||||
DrawDecal(decal);
|
||||
decal = decal->WallNext;
|
||||
gl_SetFog(lightlevel, rellight + getExtraLight(), &Colormap, false);
|
||||
DBaseDecal *decal = seg->sidedef->AttachedDecals;
|
||||
while (decal)
|
||||
{
|
||||
DrawDecal(decal);
|
||||
decal = decal->WallNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@
|
|||
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
|
|
@ -59,8 +59,6 @@
|
|||
|
||||
FDrawInfo * gl_drawinfo;
|
||||
|
||||
CVAR(Bool, gl_sort_textures, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -644,7 +642,6 @@ SortNode * GLDrawList::DoSort(SortNode * head)
|
|||
case GLDIT_SPRITE:
|
||||
SortSpriteIntoPlane(head,node);
|
||||
break;
|
||||
case GLDIT_POLY: break;
|
||||
}
|
||||
node=next;
|
||||
}
|
||||
|
|
@ -670,7 +667,7 @@ SortNode * GLDrawList::DoSort(SortNode * head)
|
|||
case GLDIT_SPRITE:
|
||||
SortSpriteIntoWall(head,node);
|
||||
break;
|
||||
case GLDIT_POLY: break;
|
||||
|
||||
case GLDIT_FLAT: break;
|
||||
}
|
||||
node=next;
|
||||
|
|
@ -692,7 +689,7 @@ SortNode * GLDrawList::DoSort(SortNode * head)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLDrawList::DoDraw(int pass, int i)
|
||||
void GLDrawList::DoDraw(int pass, int i, bool trans)
|
||||
{
|
||||
switch(drawitems[i].rendertype)
|
||||
{
|
||||
|
|
@ -700,7 +697,7 @@ void GLDrawList::DoDraw(int pass, int i)
|
|||
{
|
||||
GLFlat * f=&flats[drawitems[i].index];
|
||||
RenderFlat.Clock();
|
||||
f->Draw(pass);
|
||||
f->Draw(pass, trans);
|
||||
RenderFlat.Unclock();
|
||||
}
|
||||
break;
|
||||
|
|
@ -722,7 +719,6 @@ void GLDrawList::DoDraw(int pass, int i)
|
|||
RenderSprite.Unclock();
|
||||
}
|
||||
break;
|
||||
case GLDIT_POLY: break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -739,13 +735,13 @@ void GLDrawList::DoDrawSorted(SortNode * head)
|
|||
{
|
||||
DoDrawSorted(head->left);
|
||||
}
|
||||
DoDraw(GLPASS_TRANSLUCENT, head->itemindex);
|
||||
DoDraw(GLPASS_TRANSLUCENT, head->itemindex, true);
|
||||
if (head->equal)
|
||||
{
|
||||
SortNode * ehead=head->equal;
|
||||
while (ehead)
|
||||
{
|
||||
DoDraw(GLPASS_TRANSLUCENT, ehead->itemindex);
|
||||
DoDraw(GLPASS_TRANSLUCENT, ehead->itemindex, true);
|
||||
ehead=ehead->equal;
|
||||
}
|
||||
}
|
||||
|
|
@ -779,7 +775,50 @@ void GLDrawList::Draw(int pass)
|
|||
{
|
||||
for(unsigned i=0;i<drawitems.Size();i++)
|
||||
{
|
||||
DoDraw(pass, i);
|
||||
DoDraw(pass, i, false);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLDrawList::DrawWalls(int pass)
|
||||
{
|
||||
RenderWall.Clock();
|
||||
for(unsigned i=0;i<drawitems.Size();i++)
|
||||
{
|
||||
walls[drawitems[i].index].Draw(pass);
|
||||
}
|
||||
RenderWall.Unclock();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLDrawList::DrawFlats(int pass)
|
||||
{
|
||||
RenderFlat.Clock();
|
||||
for(unsigned i=0;i<drawitems.Size();i++)
|
||||
{
|
||||
flats[drawitems[i].index].Draw(pass, false);
|
||||
}
|
||||
RenderFlat.Unclock();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLDrawList::DrawDecals()
|
||||
{
|
||||
for(unsigned i=0;i<drawitems.Size();i++)
|
||||
{
|
||||
walls[drawitems[i].index].DoDrawDecals();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -790,61 +829,45 @@ void GLDrawList::Draw(int pass)
|
|||
//==========================================================================
|
||||
static GLDrawList * sortinfo;
|
||||
|
||||
static int __cdecl dicmp (const void *a, const void *b)
|
||||
static int __cdecl diwcmp (const void *a, const void *b)
|
||||
{
|
||||
const GLDrawItem * di[2];
|
||||
FMaterial * tx[2];
|
||||
int lights[2];
|
||||
int clamp[2];
|
||||
//colormap_t cm[2];
|
||||
di[0]=(const GLDrawItem *)a;
|
||||
di[1]=(const GLDrawItem *)b;
|
||||
const GLDrawItem * di1 = (const GLDrawItem *)a;
|
||||
GLWall * w1=&sortinfo->walls[di1->index];
|
||||
|
||||
for(int i=0;i<2;i++)
|
||||
{
|
||||
switch(di[i]->rendertype)
|
||||
{
|
||||
case GLDIT_FLAT:
|
||||
{
|
||||
GLFlat * f=&sortinfo->flats[di[i]->index];
|
||||
tx[i]=f->gltexture;
|
||||
lights[i]=f->lightlevel;
|
||||
clamp[i] = 0;
|
||||
}
|
||||
break;
|
||||
const GLDrawItem * di2 = (const GLDrawItem *)b;
|
||||
GLWall * w2=&sortinfo->walls[di2->index];
|
||||
|
||||
case GLDIT_WALL:
|
||||
{
|
||||
GLWall * w=&sortinfo->walls[di[i]->index];
|
||||
tx[i]=w->gltexture;
|
||||
lights[i]=w->lightlevel;
|
||||
clamp[i] = w->flags & 3;
|
||||
}
|
||||
break;
|
||||
if (w1->gltexture != w2->gltexture) return w1->gltexture - w2->gltexture;
|
||||
return ((w1->flags & 3) - (w2->flags & 3));
|
||||
}
|
||||
|
||||
case GLDIT_SPRITE:
|
||||
{
|
||||
GLSprite * s=&sortinfo->sprites[di[i]->index];
|
||||
tx[i]=s->gltexture;
|
||||
lights[i]=s->lightlevel;
|
||||
clamp[i] = 4;
|
||||
}
|
||||
break;
|
||||
case GLDIT_POLY: break;
|
||||
}
|
||||
}
|
||||
if (tx[0]!=tx[1]) return tx[0]-tx[1];
|
||||
if (clamp[0]!=clamp[1]) return clamp[0]-clamp[1]; // clamping forces different textures.
|
||||
return lights[0]-lights[1];
|
||||
static int __cdecl difcmp (const void *a, const void *b)
|
||||
{
|
||||
const GLDrawItem * di1 = (const GLDrawItem *)a;
|
||||
GLFlat * w1=&sortinfo->flats[di1->index];
|
||||
|
||||
const GLDrawItem * di2 = (const GLDrawItem *)b;
|
||||
GLFlat* w2=&sortinfo->flats[di2->index];
|
||||
|
||||
return w1->gltexture - w2->gltexture;
|
||||
}
|
||||
|
||||
|
||||
void GLDrawList::Sort()
|
||||
void GLDrawList::SortWalls()
|
||||
{
|
||||
if (drawitems.Size()!=0 && gl_sort_textures)
|
||||
if (drawitems.Size() > 1)
|
||||
{
|
||||
sortinfo=this;
|
||||
qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), dicmp);
|
||||
qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), diwcmp);
|
||||
}
|
||||
}
|
||||
|
||||
void GLDrawList::SortFlats()
|
||||
{
|
||||
if (drawitems.Size() > 1)
|
||||
{
|
||||
sortinfo=this;
|
||||
qsort(&drawitems[0], drawitems.Size(), sizeof(drawitems[0]), difcmp);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -982,17 +1005,22 @@ void FDrawInfo::SetupFloodStencil(wallseg * ws)
|
|||
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.EnableTexture(false);
|
||||
glColor3f(1,1,1);
|
||||
gl_RenderState.ResetColor();
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(true);
|
||||
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex3f(ws->x1, ws->z1, ws->y1);
|
||||
glVertex3f(ws->x1, ws->z2, ws->y1);
|
||||
glVertex3f(ws->x2, ws->z2, ws->y2);
|
||||
glVertex3f(ws->x2, ws->z1, ws->y2);
|
||||
glEnd();
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
|
||||
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); // this stage doesn't modify the stencil
|
||||
|
|
@ -1010,15 +1038,19 @@ void FDrawInfo::ClearFloodStencil(wallseg * ws)
|
|||
glStencilOp(GL_KEEP,GL_KEEP,GL_DECR);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
glColorMask(0,0,0,0); // don't write to the graphics buffer
|
||||
glColor3f(1,1,1);
|
||||
gl_RenderState.ResetColor();
|
||||
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex3f(ws->x1, ws->z1, ws->y1);
|
||||
glVertex3f(ws->x1, ws->z2, ws->y1);
|
||||
glVertex3f(ws->x2, ws->z2, ws->y2);
|
||||
glVertex3f(ws->x2, ws->z1, ws->y2);
|
||||
glEnd();
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(ws->x1, ws->z1, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x1, ws->z2, ws->y1, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z2, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(ws->x2, ws->z1, ws->y2, 0, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
// restore old stencil op.
|
||||
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);
|
||||
|
|
@ -1043,12 +1075,12 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
|
|||
|
||||
plane.GetFromSector(sec, ceiling);
|
||||
|
||||
gltexture=FMaterial::ValidateTexture(plane.texture, true);
|
||||
gltexture=FMaterial::ValidateTexture(plane.texture, false, true);
|
||||
if (!gltexture) return;
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
Colormap.GetFixedColormap();
|
||||
Colormap.Clear();
|
||||
lightlevel=255;
|
||||
}
|
||||
else
|
||||
|
|
@ -1063,19 +1095,17 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
|
|||
}
|
||||
|
||||
int rel = getExtraLight();
|
||||
gl_SetColor(lightlevel, rel, &Colormap, 1.0f);
|
||||
gl_SetColor(lightlevel, rel, Colormap, 1.0f);
|
||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
gltexture->Bind(Colormap.colormap);
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
|
||||
float fviewx = FIXED2FLOAT(viewx);
|
||||
float fviewy = FIXED2FLOAT(viewy);
|
||||
float fviewz = FIXED2FLOAT(viewz);
|
||||
|
||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
float prj_fac1 = (planez-fviewz)/(ws->z1-fviewz);
|
||||
float prj_fac2 = (planez-fviewz)/(ws->z2-fviewz);
|
||||
|
||||
|
|
@ -1091,25 +1121,18 @@ void FDrawInfo::DrawFloodedPlane(wallseg * ws, float planez, sector_t * sec, boo
|
|||
float px4 = fviewx + prj_fac1 * (ws->x2-fviewx);
|
||||
float py4 = fviewy + prj_fac1 * (ws->y2-fviewy);
|
||||
|
||||
glTexCoord2f(px1 / 64, -py1 / 64);
|
||||
glVertex3f(px1, planez, py1);
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(px1, planez, py1, px1 / 64, -py1 / 64);
|
||||
ptr++;
|
||||
ptr->Set(px2, planez, py2, px2 / 64, -py2 / 64);
|
||||
ptr++;
|
||||
ptr->Set(px3, planez, py3, px3 / 64, -py3 / 64);
|
||||
ptr++;
|
||||
ptr->Set(px4, planez, py4, px4 / 64, -py4 / 64);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
glTexCoord2f(px2 / 64, -py2 / 64);
|
||||
glVertex3f(px2, planez, py2);
|
||||
|
||||
glTexCoord2f(px3 / 64, -py3 / 64);
|
||||
glVertex3f(px3, planez, py3);
|
||||
|
||||
glTexCoord2f(px4 / 64, -py4 / 64);
|
||||
glVertex3f(px4, planez, py4);
|
||||
|
||||
glEnd();
|
||||
|
||||
if (pushed)
|
||||
{
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
|||
|
|
@ -13,42 +13,26 @@ enum GLDrawItemType
|
|||
|
||||
enum DrawListType
|
||||
{
|
||||
// These are organized so that the various multipass rendering modes
|
||||
// have to be set as few times as possible
|
||||
GLDL_LIGHT,
|
||||
GLDL_LIGHTBRIGHT,
|
||||
GLDL_LIGHTMASKED,
|
||||
GLDL_LIGHTFOG,
|
||||
GLDL_LIGHTFOGMASKED,
|
||||
|
||||
GLDL_PLAIN,
|
||||
GLDL_MASKED,
|
||||
GLDL_FOG,
|
||||
GLDL_FOGMASKED,
|
||||
GLDL_PLAINWALLS,
|
||||
GLDL_PLAINFLATS,
|
||||
GLDL_MASKEDWALLS,
|
||||
GLDL_MASKEDFLATS,
|
||||
GLDL_MASKEDWALLSOFS,
|
||||
GLDL_MODELS,
|
||||
|
||||
GLDL_TRANSLUCENT,
|
||||
GLDL_TRANSLUCENTBORDER,
|
||||
|
||||
GLDL_TYPES,
|
||||
|
||||
GLDL_FIRSTLIGHT = GLDL_LIGHT,
|
||||
GLDL_LASTLIGHT = GLDL_LIGHTFOGMASKED,
|
||||
GLDL_FIRSTNOLIGHT = GLDL_PLAIN,
|
||||
GLDL_LASTNOLIGHT = GLDL_FOGMASKED,
|
||||
};
|
||||
|
||||
enum Drawpasses
|
||||
{
|
||||
GLPASS_BASE, // Draws the untextured surface only
|
||||
GLPASS_BASE_MASKED, // Draws an untextured surface that is masked by the texture
|
||||
GLPASS_PLAIN, // Draws a texture that isn't affected by dynamic lights with sector light settings
|
||||
GLPASS_LIGHT, // Draws dynamic lights
|
||||
GLPASS_LIGHT_ADDITIVE, // Draws additive dynamic lights
|
||||
GLPASS_TEXTURE, // Draws the texture to be modulated with the light information on the base surface
|
||||
GLPASS_ALL, // Main pass with dynamic lights
|
||||
GLPASS_LIGHTSONLY, // only collect dynamic lights
|
||||
GLPASS_PLAIN, // Main pass without dynamic lights
|
||||
GLPASS_DECALS, // Draws a decal
|
||||
GLPASS_DECALS_NOFOG,// Draws a decal without setting the fog (used for passes that need a fog layer)
|
||||
GLPASS_TRANSLUCENT, // Draws translucent objects
|
||||
GLPASS_ALL // Everything at once, using shaders for dynamic lights
|
||||
};
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -114,11 +98,17 @@ public:
|
|||
Reset();
|
||||
}
|
||||
|
||||
unsigned int Size()
|
||||
{
|
||||
return drawitems.Size();
|
||||
}
|
||||
|
||||
void AddWall(GLWall * wall);
|
||||
void AddFlat(GLFlat * flat);
|
||||
void AddSprite(GLSprite * sprite);
|
||||
void Reset();
|
||||
void Sort();
|
||||
void SortWalls();
|
||||
void SortFlats();
|
||||
|
||||
|
||||
void MakeSortList();
|
||||
|
|
@ -133,10 +123,13 @@ public:
|
|||
SortNode * SortSpriteList(SortNode * head);
|
||||
SortNode * DoSort(SortNode * head);
|
||||
|
||||
void DoDraw(int pass, int index);
|
||||
void DoDraw(int pass, int index, bool trans);
|
||||
void DoDrawSorted(SortNode * node);
|
||||
void DrawSorted();
|
||||
void Draw(int pass);
|
||||
void DrawWalls(int pass);
|
||||
void DrawFlats(int pass);
|
||||
void DrawDecals();
|
||||
|
||||
GLDrawList * next;
|
||||
} ;
|
||||
|
|
@ -273,7 +266,7 @@ public:
|
|||
|
||||
extern FDrawInfo * gl_drawinfo;
|
||||
|
||||
bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture);
|
||||
void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture);
|
||||
void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblending);
|
||||
|
||||
#endif
|
||||
|
|
@ -70,18 +70,18 @@
|
|||
// information
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture)
|
||||
static float tics;
|
||||
void gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture)
|
||||
{
|
||||
// only manipulate the texture matrix if needed.
|
||||
if (secplane->xoffs != 0 || secplane->yoffs != 0 ||
|
||||
secplane->xscale != FRACUNIT || secplane->yscale != FRACUNIT ||
|
||||
secplane->angle != 0 ||
|
||||
gltexture->TextureWidth(GLUSE_TEXTURE) != 64 ||
|
||||
gltexture->TextureHeight(GLUSE_TEXTURE) != 64)
|
||||
gltexture->TextureWidth() != 64 ||
|
||||
gltexture->TextureHeight() != 64)
|
||||
{
|
||||
float uoffs=FIXED2FLOAT(secplane->xoffs)/gltexture->TextureWidth(GLUSE_TEXTURE);
|
||||
float voffs=FIXED2FLOAT(secplane->yoffs)/gltexture->TextureHeight(GLUSE_TEXTURE);
|
||||
float uoffs = FIXED2FLOAT(secplane->xoffs) / gltexture->TextureWidth();
|
||||
float voffs = FIXED2FLOAT(secplane->yoffs) / gltexture->TextureHeight();
|
||||
|
||||
float xscale1=FIXED2FLOAT(secplane->xscale);
|
||||
float yscale1=FIXED2FLOAT(secplane->yscale);
|
||||
|
|
@ -91,41 +91,44 @@ bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
|
|||
}
|
||||
float angle=-ANGLE_TO_FLOAT(secplane->angle);
|
||||
|
||||
float xscale2=64.f/gltexture->TextureWidth(GLUSE_TEXTURE);
|
||||
float yscale2=64.f/gltexture->TextureHeight(GLUSE_TEXTURE);
|
||||
float xscale2=64.f/gltexture->TextureWidth();
|
||||
float yscale2=64.f/gltexture->TextureHeight();
|
||||
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPushMatrix();
|
||||
glScalef(xscale1 ,yscale1,1.0f);
|
||||
glTranslatef(uoffs,voffs,0.0f);
|
||||
glScalef(xscale2 ,yscale2,1.0f);
|
||||
glRotatef(angle,0.0f,0.0f,1.0f);
|
||||
return true;
|
||||
gl_RenderState.mTextureMatrix.loadIdentity();
|
||||
gl_RenderState.mTextureMatrix.scale(xscale1 ,yscale1,1.0f);
|
||||
gl_RenderState.mTextureMatrix.translate(uoffs,voffs,0.0f);
|
||||
gl_RenderState.mTextureMatrix.scale(xscale2 ,yscale2,1.0f);
|
||||
gl_RenderState.mTextureMatrix.rotate(angle,0.0f,0.0f,1.0f);
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Flats
|
||||
//
|
||||
//==========================================================================
|
||||
extern FDynLightData lightdata;
|
||||
|
||||
void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
|
||||
void GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, int *dli)
|
||||
{
|
||||
Plane p;
|
||||
Vector nearPt, up, right, t1;
|
||||
float scale;
|
||||
unsigned int k;
|
||||
seg_t *v;
|
||||
|
||||
FLightNode * node = sub->lighthead[pass==GLPASS_LIGHT_ADDITIVE];
|
||||
gl_RenderState.Apply();
|
||||
if (dli != NULL && *dli != -1)
|
||||
{
|
||||
gl_RenderState.ApplyLightIndex(GLRenderer->mLights->GetIndex(*dli));
|
||||
(*dli)++;
|
||||
return;
|
||||
}
|
||||
|
||||
lightdata.Clear();
|
||||
FLightNode * node = sub->lighthead;
|
||||
while (node)
|
||||
{
|
||||
ADynamicLight * light = node->lightsource;
|
||||
|
||||
|
||||
if (light->flags2&MF2_DORMANT)
|
||||
{
|
||||
node=node->nextLight;
|
||||
|
|
@ -143,91 +146,19 @@ void GLFlat::DrawSubsectorLights(subsector_t * sub, int pass)
|
|||
}
|
||||
|
||||
p.Set(plane.plane);
|
||||
if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.colormap, false, foggy))
|
||||
{
|
||||
node=node->nextLight;
|
||||
continue;
|
||||
}
|
||||
draw_dlightf++;
|
||||
|
||||
// Render the light
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
for(k = 0, v = sub->firstline; k < sub->numlines; k++, v++)
|
||||
{
|
||||
vertex_t *vt = v->v1;
|
||||
float zc = plane.plane.ZatPoint(vt->fx, vt->fy) + dz;
|
||||
|
||||
t1.Set(vt->fx, zc, vt->fy);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
glTexCoord2f( (nearToVert.Dot(right) * scale) + 0.5f, (nearToVert.Dot(up) * scale) + 0.5f);
|
||||
|
||||
glVertex3f(vt->fx, zc, vt->fy);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
gl_GetLight(p, light, false, false, lightdata);
|
||||
node = node->nextLight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Flats
|
||||
//
|
||||
//==========================================================================
|
||||
extern FDynLightData lightdata;
|
||||
|
||||
bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
|
||||
{
|
||||
Plane p;
|
||||
|
||||
lightdata.Clear();
|
||||
for(int i=0;i<2;i++)
|
||||
int d = GLRenderer->mLights->UploadLights(lightdata);
|
||||
if (pass == GLPASS_LIGHTSONLY)
|
||||
{
|
||||
FLightNode * node = sub->lighthead[i];
|
||||
while (node)
|
||||
{
|
||||
ADynamicLight * light = node->lightsource;
|
||||
|
||||
if (light->flags2&MF2_DORMANT)
|
||||
{
|
||||
node=node->nextLight;
|
||||
continue;
|
||||
}
|
||||
iter_dlightf++;
|
||||
|
||||
// we must do the side check here because gl_SetupLight needs the correct plane orientation
|
||||
// which we don't have for Legacy-style 3D-floors
|
||||
fixed_t planeh = plane.plane.ZatPoint(light->x, light->y);
|
||||
if (gl_lights_checkside && ((planeh<light->z && ceiling) || (planeh>light->z && !ceiling)))
|
||||
{
|
||||
node=node->nextLight;
|
||||
continue;
|
||||
}
|
||||
|
||||
p.Set(plane.plane);
|
||||
gl_GetLight(p, light, Colormap.colormap, false, false, lightdata);
|
||||
node = node->nextLight;
|
||||
}
|
||||
GLRenderer->mLights->StoreIndex(d);
|
||||
}
|
||||
|
||||
int numlights[3];
|
||||
|
||||
lightdata.Combine(numlights, gl.MaxLights());
|
||||
if (numlights[2] > 0)
|
||||
else
|
||||
{
|
||||
draw_dlightf+=numlights[2]/2;
|
||||
gl_RenderState.EnableLight(true);
|
||||
gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]);
|
||||
gl_RenderState.Apply();
|
||||
return true;
|
||||
gl_RenderState.ApplyLightIndex(d);
|
||||
}
|
||||
if (lightsapplied)
|
||||
{
|
||||
gl_RenderState.EnableLight(false);
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -238,52 +169,117 @@ bool GLFlat::SetupSubsectorLights(bool lightsapplied, subsector_t * sub)
|
|||
|
||||
void GLFlat::DrawSubsector(subsector_t * sub)
|
||||
{
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
|
||||
for(unsigned int k=0; k<sub->numlines; k++)
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
if (plane.plane.a | plane.plane.b)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[k].v1;
|
||||
glTexCoord2f(vt->fx/64.f, -vt->fy/64.f);
|
||||
float zc = plane.plane.ZatPoint(vt->fx, vt->fy) + dz;
|
||||
glVertex3f(vt->fx, zc, vt->fy);
|
||||
for (unsigned int k = 0; k < sub->numlines; k++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[k].v1;
|
||||
ptr->x = vt->fx;
|
||||
ptr->y = vt->fy;
|
||||
ptr->z = plane.plane.ZatPoint(vt->fx, vt->fy) + dz;
|
||||
ptr->u = vt->fx / 64.f;
|
||||
ptr->v = -vt->fy / 64.f;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
else
|
||||
{
|
||||
float zc = FIXED2FLOAT(plane.plane.Zat0()) + dz;
|
||||
for (unsigned int k = 0; k < sub->numlines; k++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[k].v1;
|
||||
ptr->x = vt->fx;
|
||||
ptr->y = vt->fy;
|
||||
ptr->z = zc;
|
||||
ptr->u = vt->fx / 64.f;
|
||||
ptr->v = -vt->fy / 64.f;
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_FAN);
|
||||
|
||||
flatvertices += sub->numlines;
|
||||
flatprimitives++;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLFlat::DrawSubsectors(int pass, bool istrans)
|
||||
void GLFlat::ProcessLights(bool istrans)
|
||||
{
|
||||
bool lightsapplied = false;
|
||||
dynlightindex = GLRenderer->mLights->GetIndexPtr();
|
||||
|
||||
if (sub)
|
||||
{
|
||||
// This represents a single subsector
|
||||
SetupSubsectorLights(GLPASS_LIGHTSONLY, sub);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (int i=0; i<sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = sector->subsectors[i];
|
||||
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
|
||||
{
|
||||
SetupSubsectorLights(GLPASS_LIGHTSONLY, sub);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the subsectors assigned to it due to missing textures
|
||||
if (!(renderflags&SSRF_RENDER3DPLANES))
|
||||
{
|
||||
gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)?
|
||||
gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) :
|
||||
gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum);
|
||||
|
||||
while (node)
|
||||
{
|
||||
SetupSubsectorLights(GLPASS_LIGHTSONLY, node->sub);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLFlat::DrawSubsectors(int pass, bool processlights, bool istrans)
|
||||
{
|
||||
int dli = dynlightindex;
|
||||
|
||||
gl_RenderState.Apply();
|
||||
if (sub)
|
||||
{
|
||||
// This represents a single subsector
|
||||
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
|
||||
if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli);
|
||||
DrawSubsector(sub);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (vboindex >= 0)
|
||||
{
|
||||
//glColor3f( 1.f,.5f,.5f);
|
||||
int index = vboindex;
|
||||
for (int i=0; i<sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = sector->subsectors[i];
|
||||
// This is just a quick hack to make translucent 3D floors and portals work.
|
||||
|
||||
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
|
||||
{
|
||||
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
|
||||
if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli);
|
||||
drawcalls.Clock();
|
||||
glDrawArrays(GL_TRIANGLE_FAN, index, sub->numlines);
|
||||
drawcalls.Unclock();
|
||||
flatvertices += sub->numlines;
|
||||
flatprimitives++;
|
||||
}
|
||||
|
|
@ -292,14 +288,13 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
|||
}
|
||||
else
|
||||
{
|
||||
//glColor3f( .5f,1.f,.5f); // these are for testing the VBO stuff.
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (int i=0; i<sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = sector->subsectors[i];
|
||||
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags || istrans)
|
||||
{
|
||||
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, sub);
|
||||
if (processlights) SetupSubsectorLights(GLPASS_ALL, sub, &dli);
|
||||
DrawSubsector(sub);
|
||||
}
|
||||
}
|
||||
|
|
@ -314,13 +309,12 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
|||
|
||||
while (node)
|
||||
{
|
||||
if (pass == GLPASS_ALL) lightsapplied = SetupSubsectorLights(lightsapplied, node->sub);
|
||||
if (processlights) SetupSubsectorLights(GLPASS_ALL, node->sub, &dli);
|
||||
DrawSubsector(node->sub);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
gl_RenderState.EnableLight(false);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -329,13 +323,12 @@ void GLFlat::DrawSubsectors(int pass, bool istrans)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLFlat::Draw(int pass)
|
||||
void GLFlat::Draw(int pass, bool trans) // trans only has meaning for GLPASS_LIGHTSONLY
|
||||
{
|
||||
int i;
|
||||
int rel = getExtraLight();
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (sector->sectornum == 2)
|
||||
if (sector->sectornum == 130)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
|
|
@ -344,93 +337,40 @@ void GLFlat::Draw(int pass)
|
|||
|
||||
switch (pass)
|
||||
{
|
||||
case GLPASS_BASE:
|
||||
gl_SetColor(lightlevel, rel, &Colormap,1.0f);
|
||||
if (!foggy) gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
DrawSubsectors(pass, false);
|
||||
break;
|
||||
|
||||
case GLPASS_PLAIN: // Single-pass rendering
|
||||
case GLPASS_ALL:
|
||||
case GLPASS_BASE_MASKED:
|
||||
gl_SetColor(lightlevel, rel, &Colormap,1.0f);
|
||||
if (!foggy || pass != GLPASS_BASE_MASKED) gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
// fall through
|
||||
case GLPASS_TEXTURE:
|
||||
{
|
||||
gltexture->Bind(Colormap.colormap);
|
||||
bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
DrawSubsectors(pass, false);
|
||||
if (pushed)
|
||||
{
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
gl_SetColor(lightlevel, rel, Colormap,1.0f);
|
||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
DrawSubsectors(pass, (pass == GLPASS_ALL || dynlightindex > -1), false);
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
break;
|
||||
}
|
||||
|
||||
case GLPASS_LIGHT:
|
||||
case GLPASS_LIGHT_ADDITIVE:
|
||||
|
||||
if (!foggy) gl_SetFog((255+lightlevel)>>1, 0, &Colormap, false);
|
||||
else gl_SetFog(lightlevel, 0, &Colormap, true);
|
||||
|
||||
if (sub)
|
||||
case GLPASS_LIGHTSONLY:
|
||||
if (!trans || gltexture)
|
||||
{
|
||||
DrawSubsectorLights(sub, pass);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Draw the subsectors belonging to this sector
|
||||
for (i=0; i<sector->subsectorcount; i++)
|
||||
{
|
||||
subsector_t * sub = sector->subsectors[i];
|
||||
|
||||
if (gl_drawinfo->ss_renderflags[sub-subsectors]&renderflags)
|
||||
{
|
||||
DrawSubsectorLights(sub, pass);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw the subsectors assigned to it due to missing textures
|
||||
if (!(renderflags&SSRF_RENDER3DPLANES))
|
||||
{
|
||||
gl_subsectorrendernode * node = (renderflags&SSRF_RENDERFLOOR)?
|
||||
gl_drawinfo->GetOtherFloorPlanes(sector->sectornum) :
|
||||
gl_drawinfo->GetOtherCeilingPlanes(sector->sectornum);
|
||||
|
||||
while (node)
|
||||
{
|
||||
DrawSubsectorLights(node->sub, pass);
|
||||
node = node->next;
|
||||
}
|
||||
}
|
||||
ProcessLights(trans);
|
||||
}
|
||||
break;
|
||||
|
||||
case GLPASS_TRANSLUCENT:
|
||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
gl_SetColor(lightlevel, rel, &Colormap, alpha);
|
||||
gl_SetColor(lightlevel, rel, Colormap, alpha);
|
||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_threshold*(alpha));
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
if (!gltexture)
|
||||
{
|
||||
gl_RenderState.EnableTexture(false);
|
||||
DrawSubsectors(pass, true);
|
||||
DrawSubsectors(pass, false, true);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (foggy) gl_RenderState.EnableBrightmap(false);
|
||||
gltexture->Bind(Colormap.colormap);
|
||||
bool pushed = gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
DrawSubsectors(pass, true);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
if (pushed)
|
||||
{
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
gl_SetPlaneTextureRotation(&plane, gltexture);
|
||||
DrawSubsectors(pass, true, true);
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
}
|
||||
if (renderstyle==STYLE_Add) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
break;
|
||||
|
|
@ -452,42 +392,19 @@ inline void GLFlat::PutFlat(bool fog)
|
|||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
Colormap.GetFixedColormap();
|
||||
Colormap.Clear();
|
||||
}
|
||||
if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog)
|
||||
if (renderstyle!=STYLE_Translucent || alpha < 1.f - FLT_EPSILON || fog || gltexture == NULL)
|
||||
{
|
||||
int list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
||||
gl_drawinfo->drawlists[list].AddFlat (this);
|
||||
// translucent 3D floors go into the regular translucent list, translucent portals go into the translucent border list.
|
||||
list = (renderflags&SSRF_RENDER3DPLANES) ? GLDL_TRANSLUCENT : GLDL_TRANSLUCENTBORDER;
|
||||
}
|
||||
else if (gltexture != NULL)
|
||||
else
|
||||
{
|
||||
static DrawListType list_indices[2][2][2]={
|
||||
{ { GLDL_PLAIN, GLDL_FOG }, { GLDL_MASKED, GLDL_FOGMASKED } },
|
||||
{ { GLDL_LIGHT, GLDL_LIGHTFOG }, { GLDL_LIGHTMASKED, GLDL_LIGHTFOGMASKED } }
|
||||
};
|
||||
|
||||
bool light = gl_forcemultipass;
|
||||
bool masked = gltexture->isMasked() && ((renderflags&SSRF_RENDER3DPLANES) || stack);
|
||||
|
||||
if (!gl_fixedcolormap)
|
||||
{
|
||||
foggy = gl_CheckFog(&Colormap, lightlevel) || level.flags&LEVEL_HASFADETABLE;
|
||||
|
||||
if (gl_lights && !gl_dynlight_shader && GLRenderer->mLightCount) // Are lights touching this sector?
|
||||
{
|
||||
for(int i=0;i<sector->subsectorcount;i++) if (sector->subsectors[i]->lighthead[0] != NULL)
|
||||
{
|
||||
light=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else foggy = false;
|
||||
|
||||
list = list_indices[light][masked][foggy];
|
||||
if (list == GLDL_LIGHT && gltexture->tex->gl_info.Brightmap && gl_BrightmapsActive()) list = GLDL_LIGHTBRIGHT;
|
||||
|
||||
gl_drawinfo->drawlists[list].AddFlat (this);
|
||||
list = masked ? GLDL_MASKEDFLATS : GLDL_PLAINFLATS;
|
||||
}
|
||||
gl_drawinfo->drawlists[list].AddFlat (this);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -507,7 +424,7 @@ void GLFlat::Process(sector_t * model, int whichplane, bool fog)
|
|||
{
|
||||
if (plane.texture==skyflatnum) return;
|
||||
|
||||
gltexture=FMaterial::ValidateTexture(plane.texture, true);
|
||||
gltexture=FMaterial::ValidateTexture(plane.texture, false, true);
|
||||
if (!gltexture) return;
|
||||
if (gltexture->tex->isFullbright())
|
||||
{
|
||||
|
|
@ -583,6 +500,7 @@ void GLFlat::ProcessSector(sector_t * frontsector)
|
|||
sector=§ors[frontsector->sectornum];
|
||||
extsector_t::xfloor &x = sector->e->XFloor;
|
||||
this->sub=NULL;
|
||||
dynlightindex = -1;
|
||||
|
||||
byte &srf = gl_drawinfo->sectorrenderflags[sector->sectornum];
|
||||
|
||||
|
|
|
|||
|
|
@ -50,9 +50,11 @@
|
|||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/scene/gl_clipper.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
|
|
@ -77,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;
|
||||
|
|
@ -114,17 +117,14 @@ void GLPortal::BeginScene()
|
|||
void GLPortal::ClearScreen()
|
||||
{
|
||||
bool multi = !!glIsEnabled(GL_MULTISAMPLE);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
gl_MatrixStack.Push(gl_RenderState.mViewMatrix);
|
||||
gl_MatrixStack.Push(gl_RenderState.mProjectionMatrix);
|
||||
screen->Begin2D(false);
|
||||
screen->Dim(0, 1.f, 0, 0, SCREENWIDTH, SCREENHEIGHT);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPopMatrix();
|
||||
gl_MatrixStack.Pop(gl_RenderState.mProjectionMatrix);
|
||||
gl_MatrixStack.Pop(gl_RenderState.mViewMatrix);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
if (multi) glEnable(GL_MULTISAMPLE);
|
||||
gl_RenderState.Set2DMode(false);
|
||||
}
|
||||
|
|
@ -137,33 +137,45 @@ void GLPortal::ClearScreen()
|
|||
//-----------------------------------------------------------------------------
|
||||
void GLPortal::DrawPortalStencil()
|
||||
{
|
||||
for(unsigned int i=0;i<lines.Size();i++)
|
||||
if (mPrimIndices.Size() == 0)
|
||||
{
|
||||
lines[i].RenderWall(0, NULL);
|
||||
bool cap = NeedCap() && lines.Size() > 1;
|
||||
mPrimIndices.Resize(2 * lines.Size() + 4 * cap);
|
||||
|
||||
for (unsigned int i = 0; i<lines.Size(); i++)
|
||||
{
|
||||
lines[i].RenderWall(GLWall::RWF_NORENDER, &mPrimIndices[i * 2]);
|
||||
}
|
||||
|
||||
if (cap)
|
||||
{
|
||||
// Cap the stencil at the top and bottom
|
||||
int n = lines.Size() * 2;
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(-32767.0f, 32767.0f, -32767.0f, 0, 0);
|
||||
ptr->Set(-32767.0f, 32767.0f, 32767.0f, 0, 0);
|
||||
ptr->Set(32767.0f, 32767.0f, 32767.0f, 0, 0);
|
||||
ptr->Set(32767.0f, 32767.0f, -32767.0f, 0, 0);
|
||||
mPrimIndices[n + 1] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n]);
|
||||
ptr->Set(-32767.0f, -32767.0f, -32767.0f, 0, 0);
|
||||
ptr->Set(-32767.0f, -32767.0f, 32767.0f, 0, 0);
|
||||
ptr->Set(32767.0f, -32767.0f, 32767.0f, 0, 0);
|
||||
ptr->Set(32767.0f, -32767.0f, -32767.0f, 0, 0);
|
||||
mPrimIndices[n + 3] = GLRenderer->mVBO->GetCount(ptr, &mPrimIndices[n + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (NeedCap() && lines.Size() > 1)
|
||||
gl_RenderState.Apply();
|
||||
for (unsigned int i = 0; i < mPrimIndices.Size(); i += 2)
|
||||
{
|
||||
// Cap the stencil at the top and bottom
|
||||
// (cheap ass version)
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex3f(-32767.0f,32767.0f,-32767.0f);
|
||||
glVertex3f(-32767.0f,32767.0f, 32767.0f);
|
||||
glVertex3f( 32767.0f,32767.0f, 32767.0f);
|
||||
glVertex3f( 32767.0f,32767.0f,-32767.0f);
|
||||
glEnd();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glVertex3f(-32767.0f,-32767.0f,-32767.0f);
|
||||
glVertex3f(-32767.0f,-32767.0f, 32767.0f);
|
||||
glVertex3f( 32767.0f,-32767.0f, 32767.0f);
|
||||
glVertex3f( 32767.0f,-32767.0f,-32767.0f);
|
||||
glEnd();
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, mPrimIndices[i], mPrimIndices[i + 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Start
|
||||
|
|
@ -186,8 +198,9 @@ 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);
|
||||
glColor3f(1,1,1);
|
||||
gl_RenderState.ResetColor();
|
||||
glDepthFunc(GL_LESS);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
|
|
@ -201,13 +214,13 @@ bool GLPortal::Start(bool usestencil, bool doquery)
|
|||
if (!QueryObject) glGenQueries(1, &QueryObject);
|
||||
if (QueryObject)
|
||||
{
|
||||
glBeginQuery(GL_SAMPLES_PASSED_ARB, QueryObject);
|
||||
glBeginQuery(GL_SAMPLES_PASSED, QueryObject);
|
||||
}
|
||||
else doquery = false; // some kind of error happened
|
||||
|
||||
DrawPortalStencil();
|
||||
|
||||
glEndQuery(GL_SAMPLES_PASSED_ARB);
|
||||
glEndQuery(GL_SAMPLES_PASSED);
|
||||
|
||||
// Clear Z-buffer
|
||||
glStencilFunc(GL_EQUAL,recursion+1,~0); // draw sky into stencil
|
||||
|
|
@ -221,11 +234,12 @@ 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;
|
||||
|
||||
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT_ARB, &sampleCount);
|
||||
glGetQueryObjectuiv(QueryObject, GL_QUERY_RESULT, &sampleCount);
|
||||
|
||||
if (sampleCount==0) // not visible
|
||||
{
|
||||
|
|
@ -250,6 +264,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!
|
||||
}
|
||||
|
|
@ -269,9 +284,12 @@ 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.GetClipHeightTop());
|
||||
planestack.Push(gl_RenderState.GetClipHeightBottom());
|
||||
glDisable(GL_CLIP_DISTANCE0);
|
||||
glDisable(GL_CLIP_DISTANCE1);
|
||||
gl_RenderState.SetClipHeightBottom(-65536.f);
|
||||
gl_RenderState.SetClipHeightTop(65536.f);
|
||||
|
||||
// save viewpoint
|
||||
savedviewx=viewx;
|
||||
|
|
@ -331,7 +349,15 @@ 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.SetClipHeightBottom(f);
|
||||
if (f > -65535.f) glEnable(GL_CLIP_DISTANCE0);
|
||||
planestack.Pop(f);
|
||||
gl_RenderState.SetClipHeightTop(f);
|
||||
if (f < 65535.f) glEnable(GL_CLIP_DISTANCE1);
|
||||
|
||||
if (usestencil)
|
||||
{
|
||||
if (needdepth) FDrawInfo::EndDrawInfo();
|
||||
|
|
@ -345,9 +371,9 @@ void GLPortal::End(bool usestencil)
|
|||
in_area=savedviewarea;
|
||||
GLRenderer->SetupView(viewx, viewy, viewz, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
||||
glColor4f(1,1,1,1);
|
||||
glColorMask(0,0,0,0); // no graphics
|
||||
glColor3f(1,1,1);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
|
|
@ -373,7 +399,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.
|
||||
|
|
@ -404,12 +431,14 @@ void GLPortal::End(bool usestencil)
|
|||
// This draws a valid z-buffer into the stencil's contents to ensure it
|
||||
// doesn't get overwritten by the level's geometry.
|
||||
|
||||
glColor4f(1,1,1,1);
|
||||
gl_RenderState.ResetColor();
|
||||
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);
|
||||
|
|
@ -604,7 +633,7 @@ void GLSkyboxPortal::DrawContents()
|
|||
|
||||
PlaneMirrorMode=0;
|
||||
|
||||
glDisable(GL_DEPTH_CLAMP_NV);
|
||||
glDisable(GL_DEPTH_CLAMP);
|
||||
|
||||
viewx = origin->PrevX + FixedMul(r_TicFrac, origin->x - origin->PrevX);
|
||||
viewy = origin->PrevY + FixedMul(r_TicFrac, origin->y - origin->PrevY);
|
||||
|
|
@ -634,7 +663,7 @@ void GLSkyboxPortal::DrawContents()
|
|||
GLRenderer->DrawScene();
|
||||
origin->flags&=~MF_JUSTHIT;
|
||||
inskybox=false;
|
||||
glEnable(GL_DEPTH_CLAMP_NV);
|
||||
glEnable(GL_DEPTH_CLAMP);
|
||||
skyboxrecursion--;
|
||||
|
||||
PlaneMirrorMode=old_pm;
|
||||
|
|
@ -769,14 +798,23 @@ void GLPlaneMirrorPortal::DrawContents()
|
|||
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);
|
||||
float f = FIXED2FLOAT(planez);
|
||||
if (PlaneMirrorMode < 0)
|
||||
{
|
||||
gl_RenderState.SetClipHeightTop(f); // ceiling mirror: clip everytihng with a z lower than the portal's ceiling
|
||||
glEnable(GL_CLIP_DISTANCE1);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.SetClipHeightBottom(f); // floor mirror: clip everything with a z higher than the portal's floor
|
||||
glEnable(GL_CLIP_DISTANCE0);
|
||||
}
|
||||
|
||||
GLRenderer->DrawScene();
|
||||
glDisable(GL_CLIP_PLANE0+renderdepth);
|
||||
glDisable(GL_CLIP_DISTANCE0);
|
||||
glDisable(GL_CLIP_DISTANCE1);
|
||||
gl_RenderState.SetClipHeightBottom(-65536.f);
|
||||
gl_RenderState.SetClipHeightTop(65536.f);
|
||||
PlaneMirrorFlag--;
|
||||
PlaneMirrorMode=old_pm;
|
||||
}
|
||||
|
|
@ -844,12 +882,12 @@ void GLMirrorPortal::DrawContents()
|
|||
// any mirror--use floats to avoid integer overflow.
|
||||
// Use doubles to avoid losing precision which is very important here.
|
||||
|
||||
double dx = FIXED2FLOAT(v2->x - v1->x);
|
||||
double dy = FIXED2FLOAT(v2->y - v1->y);
|
||||
double x1 = FIXED2FLOAT(v1->x);
|
||||
double y1 = FIXED2FLOAT(v1->y);
|
||||
double x = FIXED2FLOAT(startx);
|
||||
double y = FIXED2FLOAT(starty);
|
||||
double dx = FIXED2DBL(v2->x - v1->x);
|
||||
double dy = FIXED2DBL(v2->y - v1->y);
|
||||
double x1 = FIXED2DBL(v1->x);
|
||||
double y1 = FIXED2DBL(v1->y);
|
||||
double x = FIXED2DBL(startx);
|
||||
double y = FIXED2DBL(starty);
|
||||
|
||||
// the above two cases catch len == 0
|
||||
double r = ((x - x1)*dx + (y - y1)*dy) / (dx*dx + dy*dy);
|
||||
|
|
@ -947,7 +985,7 @@ void GLHorizonPortal::DrawContents()
|
|||
float z;
|
||||
player_t * player=&players[consoleplayer];
|
||||
|
||||
gltexture=FMaterial::ValidateTexture(sp->texture, true);
|
||||
gltexture=FMaterial::ValidateTexture(sp->texture, false, true);
|
||||
if (!gltexture)
|
||||
{
|
||||
ClearScreen();
|
||||
|
|
@ -962,50 +1000,45 @@ void GLHorizonPortal::DrawContents()
|
|||
if (gltexture && gltexture->tex->isFullbright())
|
||||
{
|
||||
// glowing textures are always drawn full bright without color
|
||||
gl_SetColor(255, 0, NULL, 1.f);
|
||||
gl_SetColor(255, 0, origin->colormap, 1.f);
|
||||
gl_SetFog(255, 0, &origin->colormap, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
int rel = getExtraLight();
|
||||
gl_SetColor(origin->lightlevel, rel, &origin->colormap, 1.0f);
|
||||
gl_SetColor(origin->lightlevel, rel, origin->colormap, 1.0f);
|
||||
gl_SetFog(origin->lightlevel, rel, &origin->colormap, false);
|
||||
}
|
||||
|
||||
|
||||
gltexture->Bind(origin->colormap.colormap);
|
||||
gl_RenderState.SetMaterial(gltexture, CLAMP_NONE, 0, -1, false);
|
||||
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_SetPlaneTextureRotation(sp, gltexture);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
|
||||
bool pushed = gl_SetPlaneTextureRotation(sp, gltexture);
|
||||
|
||||
float vx=FIXED2FLOAT(viewx);
|
||||
float vy=FIXED2FLOAT(viewy);
|
||||
|
||||
// Draw to some far away boundary
|
||||
// This is not drawn as larher strips because it causes visual glitches.
|
||||
for(float x=-32768+vx; x<32768+vx; x+=4096)
|
||||
{
|
||||
for(float y=-32768+vy; y<32768+vy;y+=4096)
|
||||
{
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
|
||||
glTexCoord2f(x/64, -y/64);
|
||||
glVertex3f(x, z, y);
|
||||
|
||||
glTexCoord2f(x/64 + 64, -y/64);
|
||||
glVertex3f(x + 4096, z, y);
|
||||
|
||||
glTexCoord2f(x/64 + 64, -y/64 - 64);
|
||||
glVertex3f(x + 4096, z, y + 4096);
|
||||
|
||||
glTexCoord2f(x/64, -y/64 - 64);
|
||||
glVertex3f(x, z, y + 4096);
|
||||
|
||||
glEnd();
|
||||
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x, z, y, x / 64, -y / 64);
|
||||
ptr++;
|
||||
ptr->Set(x + 4096, z, y, x / 64 + 64, -y / 64);
|
||||
ptr++;
|
||||
ptr->Set(x, z, y + 4096, x / 64, -y / 64 - 64);
|
||||
ptr++;
|
||||
ptr->Set(x + 4096, z, y + 4096, x / 64 + 64, -y / 64 - 64);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1016,41 +1049,30 @@ void GLHorizonPortal::DrawContents()
|
|||
// Since I can't draw into infinity there can always be a
|
||||
// small gap
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
|
||||
glTexCoord2f(512.f, 0);
|
||||
glVertex3f(-32768+vx, z, -32768+vy);
|
||||
glTexCoord2f(512.f, tz);
|
||||
glVertex3f(-32768+vx, vz, -32768+vy);
|
||||
|
||||
glTexCoord2f(-512.f, 0);
|
||||
glVertex3f(-32768+vx, z, 32768+vy);
|
||||
glTexCoord2f(-512.f, tz);
|
||||
glVertex3f(-32768+vx, vz, 32768+vy);
|
||||
|
||||
glTexCoord2f(512.f, 0);
|
||||
glVertex3f( 32768+vx, z, 32768+vy);
|
||||
glTexCoord2f(512.f, tz);
|
||||
glVertex3f( 32768+vx, vz, 32768+vy);
|
||||
|
||||
glTexCoord2f(-512.f, 0);
|
||||
glVertex3f( 32768+vx, z, -32768+vy);
|
||||
glTexCoord2f(-512.f, tz);
|
||||
glVertex3f( 32768+vx, vz, -32768+vy);
|
||||
|
||||
glTexCoord2f(512.f, 0);
|
||||
glVertex3f(-32768+vx, z, -32768+vy);
|
||||
glTexCoord2f(512.f, tz);
|
||||
glVertex3f(-32768+vx, vz, -32768+vy);
|
||||
|
||||
glEnd();
|
||||
|
||||
if (pushed)
|
||||
{
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0);
|
||||
ptr++;
|
||||
ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz);
|
||||
ptr++;
|
||||
ptr->Set(-32768 + vx, z, 32768 + vy, -512.f, 0);
|
||||
ptr++;
|
||||
ptr->Set(-32768 + vx, vz, 32768 + vy, -512.f, tz);
|
||||
ptr++;
|
||||
ptr->Set(32768 + vx, z, 32768 + vy, 512.f, 0);
|
||||
ptr++;
|
||||
ptr->Set(32768 + vx, vz, 32768 + vy, 512.f, tz);
|
||||
ptr++;
|
||||
ptr->Set(32768 + vx, z, -32768 + vy, -512.f, 0);
|
||||
ptr++;
|
||||
ptr->Set(32768 + vx, vz, -32768 + vy, -512.f, tz);
|
||||
ptr++;
|
||||
ptr->Set(-32768 + vx, z, -32768 + vy, 512.f, 0);
|
||||
ptr++;
|
||||
ptr->Set(-32768 + vx, vz, -32768 + vy, 512.f, tz);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
PortalAll.Unclock();
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,9 +102,9 @@ private:
|
|||
angle_t savedviewangle;
|
||||
AActor * savedviewactor;
|
||||
area_t savedviewarea;
|
||||
unsigned char clipsave;
|
||||
GLPortal *NextPortal;
|
||||
TArray<BYTE> savedmapsection;
|
||||
TArray<unsigned int> mPrimIndices;
|
||||
|
||||
protected:
|
||||
TArray<GLWall> lines;
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@
|
|||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/utility/gl_clock.h"
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@
|
|||
#include "p_local.h"
|
||||
#include "gl/gl_functions.h"
|
||||
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
|
|
@ -65,7 +66,6 @@
|
|||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/dynlights/gl_dynlight.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/models/gl_models.h"
|
||||
#include "gl/scene/gl_clipper.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
|
|
@ -85,7 +85,7 @@ CVAR(Bool, gl_texture, true, 0)
|
|||
CVAR(Bool, gl_no_skyclear, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, gl_mask_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(Float, gl_mask_sprite_threshold, 0.5f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, gl_forcemultipass, false, 0)
|
||||
CVAR(Bool, gl_sort_textures, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
EXTERN_CVAR (Int, screenblocks)
|
||||
EXTERN_CVAR (Bool, cl_capfps)
|
||||
|
|
@ -247,36 +247,11 @@ void FGLRenderer::SetCameraPos(fixed_t viewx, fixed_t viewy, fixed_t viewz, angl
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void setPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar)
|
||||
{
|
||||
GLdouble m[4][4];
|
||||
double sine, cotangent, deltaZ;
|
||||
double radians = fovy / 2 * M_PI / 180;
|
||||
|
||||
deltaZ = zFar - zNear;
|
||||
sine = sin(radians);
|
||||
if ((deltaZ == 0) || (sine == 0) || (aspect == 0)) {
|
||||
return;
|
||||
}
|
||||
cotangent = cos(radians) / sine;
|
||||
|
||||
memset(m, 0, sizeof(m));
|
||||
m[0][0] = cotangent / aspect;
|
||||
m[1][1] = cotangent;
|
||||
m[2][2] = -(zFar + zNear) / deltaZ;
|
||||
m[2][3] = -1;
|
||||
m[3][2] = -2 * zNear * zFar / deltaZ;
|
||||
m[3][3] = 0;
|
||||
glLoadMatrixd(&m[0][0]);
|
||||
}
|
||||
|
||||
|
||||
void FGLRenderer::SetProjection(float fov, float ratio, float fovratio)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
float fovy = 2 * RAD2DEG(atan(tan(DEG2RAD(fov) / 2) / fovratio));
|
||||
setPerspective(fovy, ratio, 5.f, 65536.f);
|
||||
gl_RenderState.mProjectionMatrix.perspective(fovy, ratio, 5.f, 65536.f);
|
||||
gl_RenderState.Set2DMode(false);
|
||||
}
|
||||
|
||||
|
|
@ -288,27 +263,15 @@ void FGLRenderer::SetProjection(float fov, float ratio, float fovratio)
|
|||
|
||||
void FGLRenderer::SetViewMatrix(bool mirror, bool planemirror)
|
||||
{
|
||||
if (gl.shadermodel >= 4)
|
||||
{
|
||||
glActiveTexture(GL_TEXTURE7);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
}
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
|
||||
float mult = mirror? -1:1;
|
||||
float planemult = planemirror? -1:1;
|
||||
|
||||
glRotatef(GLRenderer->mAngles.Roll, 0.0f, 0.0f, 1.0f);
|
||||
glRotatef(GLRenderer->mAngles.Pitch, 1.0f, 0.0f, 0.0f);
|
||||
glRotatef(GLRenderer->mAngles.Yaw, 0.0f, mult, 0.0f);
|
||||
glTranslatef( GLRenderer->mCameraPos.X * mult, -GLRenderer->mCameraPos.Z*planemult, -GLRenderer->mCameraPos.Y);
|
||||
glScalef(-mult, planemult, 1);
|
||||
gl_RenderState.mViewMatrix.loadIdentity();
|
||||
gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Roll, 0.0f, 0.0f, 1.0f);
|
||||
gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Pitch, 1.0f, 0.0f, 0.0f);
|
||||
gl_RenderState.mViewMatrix.rotate(GLRenderer->mAngles.Yaw, 0.0f, mult, 0.0f);
|
||||
gl_RenderState.mViewMatrix.translate( GLRenderer->mCameraPos.X * mult, -GLRenderer->mCameraPos.Z*planemult, -GLRenderer->mCameraPos.Y);
|
||||
gl_RenderState.mViewMatrix.scale(-mult, planemult, 1);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -322,6 +285,7 @@ void FGLRenderer::SetupView(fixed_t viewx, fixed_t viewy, fixed_t viewz, angle_t
|
|||
{
|
||||
SetCameraPos(viewx, viewy, viewz, viewangle);
|
||||
SetViewMatrix(mirror, planemirror);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -353,7 +317,6 @@ void FGLRenderer::CreateScene()
|
|||
gl_drawinfo->HandleHackedSubsectors(); // open sector hacks for deep water
|
||||
gl_drawinfo->ProcessSectorStacks(); // merge visplanes of sector stacks
|
||||
|
||||
GLRenderer->mVBO->UnmapVBO ();
|
||||
ProcessAll.Unclock();
|
||||
|
||||
}
|
||||
|
|
@ -378,150 +341,84 @@ void FGLRenderer::RenderScene(int recursion)
|
|||
gl_RenderState.EnableFog(true);
|
||||
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
||||
|
||||
// First draw all single-pass stuff
|
||||
if (gl_sort_textures)
|
||||
{
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].SortWalls();
|
||||
gl_drawinfo->drawlists[GLDL_PLAINFLATS].SortFlats();
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLS].SortWalls();
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].SortFlats();
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].SortWalls();
|
||||
}
|
||||
|
||||
// if we don't have a persistently mapped buffer, we have to process all the dynamic lights up front,
|
||||
// so that we don't have to do repeated map/unmap calls on the buffer.
|
||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && !(gl.flags & RFL_BUFFER_STORAGE))
|
||||
{
|
||||
GLRenderer->mLights->Begin();
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawWalls(GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLS].DrawWalls(GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].Draw(GLPASS_LIGHTSONLY);
|
||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].Draw(GLPASS_LIGHTSONLY);
|
||||
GLRenderer->mLights->Finish();
|
||||
}
|
||||
|
||||
// Part 1: solid geometry. This is set up so that there are no transparent parts
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
|
||||
glDisable(GL_POLYGON_OFFSET_FILL); // just in case
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
int pass;
|
||||
|
||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && gl_dynlight_shader)
|
||||
if (mLightCount > 0 && gl_fixedcolormap == CM_DEFAULT && gl_lights && (gl.flags & RFL_BUFFER_STORAGE))
|
||||
{
|
||||
pass = GLPASS_ALL;
|
||||
}
|
||||
else if (gl_texture)
|
||||
else
|
||||
{
|
||||
pass = GLPASS_PLAIN;
|
||||
}
|
||||
else
|
||||
{
|
||||
pass = GLPASS_BASE;
|
||||
}
|
||||
|
||||
gl_RenderState.EnableTexture(gl_texture);
|
||||
gl_RenderState.EnableBrightmap(gl_fixedcolormap == CM_DEFAULT);
|
||||
gl_drawinfo->drawlists[GLDL_PLAIN].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_PLAIN].Draw(pass);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_drawinfo->drawlists[GLDL_FOG].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_FOG].Draw(pass);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTFOG].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTFOG].Draw(pass);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawWalls(pass);
|
||||
gl_drawinfo->drawlists[GLDL_PLAINFLATS].DrawFlats(pass);
|
||||
|
||||
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
|
||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show
|
||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>gl_mask_threshold will show
|
||||
if (!gl_texture)
|
||||
{
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
}
|
||||
if (pass == GLPASS_BASE) pass = GLPASS_BASE_MASKED;
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_threshold);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_drawinfo->drawlists[GLDL_MASKED].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_MASKED].Draw(pass);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_drawinfo->drawlists[GLDL_FOGMASKED].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_FOGMASKED].Draw(pass);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTFOGMASKED].Draw(pass);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLS].DrawWalls(pass);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDFLATS].DrawFlats(pass);
|
||||
|
||||
// And now the multipass stuff
|
||||
if (!gl_dynlight_shader && gl_lights)
|
||||
// Part 3: masked geometry with polygon offset. This list is empty most of the time so only waste time on it when in use.
|
||||
if (gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].Size() > 0)
|
||||
{
|
||||
// First pass: empty background with sector light only
|
||||
|
||||
// Part 1: solid geometry. This is set up so that there are no transparent parts
|
||||
|
||||
// remove any remaining texture bindings and shaders whick may get in the way.
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_RenderState.Apply();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHT].Draw(GLPASS_BASE);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
|
||||
// Part 2: masked geometry. This is set up so that only pixels with alpha>0.5 will show
|
||||
// This creates a blank surface that only fills the nontransparent parts of the texture
|
||||
gl_RenderState.SetTextureMode(TM_MASK);
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Draw(GLPASS_BASE_MASKED);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Draw(GLPASS_BASE_MASKED);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
|
||||
// second pass: draw lights (on fogged surfaces they are added to the textures!)
|
||||
glDepthMask(false);
|
||||
if (mLightCount && !gl_fixedcolormap)
|
||||
{
|
||||
if (gl_SetupLightTexture())
|
||||
{
|
||||
gl_RenderState.BlendFunc(GL_ONE, GL_ONE);
|
||||
glDepthFunc(GL_EQUAL);
|
||||
if (glset.lightmode == 8) glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0f); // Korshun.
|
||||
for(int i=GLDL_FIRSTLIGHT; i<=GLDL_LASTLIGHT; i++)
|
||||
{
|
||||
gl_drawinfo->drawlists[i].Draw(GLPASS_LIGHT);
|
||||
}
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
else gl_lights=false;
|
||||
}
|
||||
|
||||
// third pass: modulated texture
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
gl_RenderState.EnableFog(false);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
if (gl_texture)
|
||||
{
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHT].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHT].Draw(GLPASS_TEXTURE);
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTBRIGHT].Draw(GLPASS_TEXTURE);
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Sort();
|
||||
gl_drawinfo->drawlists[GLDL_LIGHTMASKED].Draw(GLPASS_TEXTURE);
|
||||
}
|
||||
|
||||
// fourth pass: additive lights
|
||||
gl_RenderState.EnableFog(true);
|
||||
if (gl_lights && mLightCount && !gl_fixedcolormap)
|
||||
{
|
||||
gl_RenderState.BlendFunc(GL_ONE, GL_ONE);
|
||||
glDepthFunc(GL_EQUAL);
|
||||
if (gl_SetupLightTexture())
|
||||
{
|
||||
for(int i=0; i<GLDL_TRANSLUCENT; i++)
|
||||
{
|
||||
gl_drawinfo->drawlists[i].Draw(GLPASS_LIGHT_ADDITIVE);
|
||||
}
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
}
|
||||
else gl_lights=false;
|
||||
}
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
gl_drawinfo->drawlists[GLDL_MASKEDWALLSOFS].DrawWalls(pass);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(0, 0);
|
||||
}
|
||||
|
||||
gl_drawinfo->drawlists[GLDL_MODELS].Draw(pass);
|
||||
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
// Draw decals (not a real pass)
|
||||
// Part 4: Draw decals (not a real pass)
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
glDepthMask(false);
|
||||
|
||||
for(int i=0; i<GLDL_TRANSLUCENT; i++)
|
||||
{
|
||||
gl_drawinfo->drawlists[i].Draw(GLPASS_DECALS);
|
||||
}
|
||||
// this is the only geometry type on which decals can possibly appear
|
||||
gl_drawinfo->drawlists[GLDL_PLAINWALLS].DrawDecals();
|
||||
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
|
|
@ -532,21 +429,20 @@ void FGLRenderer::RenderScene(int recursion)
|
|||
// so they don't interfere with overlapping mid textures.
|
||||
glPolygonOffset(1.0f, 128.0f);
|
||||
|
||||
// flood all the gaps with the back sector's flat texture
|
||||
// This will always be drawn like GLDL_PLAIN or GLDL_FOG, depending on the fog settings
|
||||
// Part 5: flood all the gaps with the back sector's flat texture
|
||||
// This will always be drawn like GLDL_PLAIN, depending on the fog settings
|
||||
|
||||
glDepthMask(false); // don't write to Z-buffer!
|
||||
gl_RenderState.EnableFog(true);
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.BlendFunc(GL_ONE,GL_ZERO);
|
||||
gl_drawinfo->DrawUnhandledMissingTextures();
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
glDepthMask(true);
|
||||
|
||||
glPolygonOffset(0.0f, 0.0f);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
|
||||
RenderAll.Unclock();
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -565,8 +461,7 @@ void FGLRenderer::RenderTranslucent()
|
|||
gl_RenderState.SetCameraPos(FIXED2FLOAT(viewx), FIXED2FLOAT(viewy), FIXED2FLOAT(viewz));
|
||||
|
||||
// final pass: translucent stuff
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
|
|
@ -576,7 +471,7 @@ void FGLRenderer::RenderTranslucent()
|
|||
|
||||
glDepthMask(true);
|
||||
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,0.5f);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
|
||||
RenderAll.Unclock();
|
||||
}
|
||||
|
||||
|
|
@ -617,6 +512,23 @@ void FGLRenderer::DrawScene(bool toscreen)
|
|||
}
|
||||
|
||||
|
||||
static void FillScreen()
|
||||
{
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(0, 0, 0, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(0, (float)SCREENHEIGHT, 0, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set((float)SCREENWIDTH, 0, 0, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set((float)SCREENWIDTH, (float)SCREENHEIGHT, 0, 0, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Draws a blend over the entire view
|
||||
|
|
@ -643,12 +555,12 @@ void FGLRenderer::DrawBlend(sector_t * viewsector)
|
|||
{
|
||||
if (viewsector->heightsec && !(viewsector->MoreFlags&SECF_IGNOREHEIGHTSEC))
|
||||
{
|
||||
switch(in_area)
|
||||
switch (in_area)
|
||||
{
|
||||
default:
|
||||
case area_normal: blendv=viewsector->heightsec->midmap; break;
|
||||
case area_above: blendv=viewsector->heightsec->topmap; break;
|
||||
case area_below: blendv=viewsector->heightsec->bottommap; break;
|
||||
case area_normal: blendv = viewsector->heightsec->midmap; break;
|
||||
case area_above: blendv = viewsector->heightsec->topmap; break;
|
||||
case area_below: blendv = viewsector->heightsec->bottommap; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -656,70 +568,62 @@ void FGLRenderer::DrawBlend(sector_t * viewsector)
|
|||
{
|
||||
TArray<lightlist_t> & lightlist = viewsector->e->XFloor.lightlist;
|
||||
|
||||
for(unsigned int i=0;i<lightlist.Size();i++)
|
||||
for (unsigned int i = 0; i < lightlist.Size(); i++)
|
||||
{
|
||||
fixed_t lightbottom;
|
||||
if (i<lightlist.Size()-1)
|
||||
lightbottom=lightlist[i+1].plane.ZatPoint(viewx,viewy);
|
||||
else
|
||||
lightbottom=viewsector->floorplane.ZatPoint(viewx,viewy);
|
||||
if (i < lightlist.Size() - 1)
|
||||
lightbottom = lightlist[i + 1].plane.ZatPoint(viewx, viewy);
|
||||
else
|
||||
lightbottom = viewsector->floorplane.ZatPoint(viewx, viewy);
|
||||
|
||||
if (lightbottom<viewz && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS)))
|
||||
if (lightbottom < viewz && (!lightlist[i].caster || !(lightlist[i].caster->flags&FF_FADEWALLS)))
|
||||
{
|
||||
// 3d floor 'fog' is rendered as a blending value
|
||||
blendv=lightlist[i].blend;
|
||||
blendv = lightlist[i].blend;
|
||||
// If this is the same as the sector's it doesn't apply!
|
||||
if (blendv == viewsector->ColorMap->Fade) blendv=0;
|
||||
if (blendv == viewsector->ColorMap->Fade) blendv = 0;
|
||||
// a little hack to make this work for Legacy maps.
|
||||
if (blendv.a==0 && blendv!=0) blendv.a=128;
|
||||
if (blendv.a == 0 && blendv != 0) blendv.a = 128;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blendv.a==0)
|
||||
{
|
||||
blendv = R_BlendForColormap(blendv);
|
||||
if (blendv.a==255)
|
||||
if (blendv.a == 0)
|
||||
{
|
||||
// The calculated average is too dark so brighten it according to the palettes's overall brightness
|
||||
int maxcol = MAX<int>(MAX<int>(framebuffer->palette_brightness, blendv.r), MAX<int>(blendv.g, blendv.b));
|
||||
blendv.r = blendv.r * 255 / maxcol;
|
||||
blendv.g = blendv.g * 255 / maxcol;
|
||||
blendv.b = blendv.b * 255 / maxcol;
|
||||
blendv = R_BlendForColormap(blendv);
|
||||
if (blendv.a == 255)
|
||||
{
|
||||
// The calculated average is too dark so brighten it according to the palettes's overall brightness
|
||||
int maxcol = MAX<int>(MAX<int>(framebuffer->palette_brightness, blendv.r), MAX<int>(blendv.g, blendv.b));
|
||||
blendv.r = blendv.r * 255 / maxcol;
|
||||
blendv.g = blendv.g * 255 / maxcol;
|
||||
blendv.b = blendv.b * 255 / maxcol;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (blendv.a==255)
|
||||
{
|
||||
|
||||
extra_red = blendv.r / 255.0f;
|
||||
extra_green = blendv.g / 255.0f;
|
||||
extra_blue = blendv.b / 255.0f;
|
||||
|
||||
// If this is a multiplicative blend do it separately and add the additive ones on top of it!
|
||||
blendv=0;
|
||||
|
||||
// black multiplicative blends are ignored
|
||||
if (extra_red || extra_green || extra_blue)
|
||||
if (blendv.a == 255)
|
||||
{
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.BlendFunc(GL_DST_COLOR,GL_ZERO);
|
||||
glColor4f(extra_red, extra_green, extra_blue, 1.0f);
|
||||
gl_RenderState.Apply(true);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glVertex2f( 0.0f, 0.0f);
|
||||
glVertex2f( 0.0f, (float)SCREENHEIGHT);
|
||||
glVertex2f( (float)SCREENWIDTH, 0.0f);
|
||||
glVertex2f( (float)SCREENWIDTH, (float)SCREENHEIGHT);
|
||||
glEnd();
|
||||
|
||||
extra_red = blendv.r / 255.0f;
|
||||
extra_green = blendv.g / 255.0f;
|
||||
extra_blue = blendv.b / 255.0f;
|
||||
|
||||
// If this is a multiplicative blend do it separately and add the additive ones on top of it.
|
||||
blendv = 0;
|
||||
|
||||
// black multiplicative blends are ignored
|
||||
if (extra_red || extra_green || extra_blue)
|
||||
{
|
||||
gl_RenderState.BlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
gl_RenderState.SetColor(extra_red, extra_green, extra_blue, 1.0f);
|
||||
FillScreen();
|
||||
}
|
||||
}
|
||||
else if (blendv.a)
|
||||
{
|
||||
V_AddBlend(blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, blendv.a / 255.0f, blend);
|
||||
}
|
||||
}
|
||||
else if (blendv.a)
|
||||
{
|
||||
V_AddBlend (blendv.r / 255.f, blendv.g / 255.f, blendv.b / 255.f, blendv.a/255.0f,blend);
|
||||
}
|
||||
|
||||
// This mostly duplicates the code in shared_sbar.cpp
|
||||
|
|
@ -742,16 +646,8 @@ void FGLRenderer::DrawBlend(sector_t * viewsector)
|
|||
if (blend[3]>0.0f)
|
||||
{
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
glColor4fv(blend);
|
||||
gl_RenderState.Apply(true);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glVertex2f( 0.0f, 0.0f);
|
||||
glVertex2f( 0.0f, (float)SCREENHEIGHT);
|
||||
glVertex2f( (float)SCREENWIDTH, 0.0f);
|
||||
glVertex2f( (float)SCREENWIDTH, (float)SCREENHEIGHT);
|
||||
glEnd();
|
||||
gl_RenderState.SetColor(blend[0], blend[1], blend[2], blend[3]);
|
||||
FillScreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -779,7 +675,6 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector)
|
|||
}
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
glDisable(GL_POLYGON_SMOOTH);
|
||||
|
||||
framebuffer->Begin2D(false);
|
||||
|
||||
|
|
@ -789,14 +684,15 @@ void FGLRenderer::EndDrawScene(sector_t * viewsector)
|
|||
{
|
||||
DrawPlayerSprites (viewsector, false);
|
||||
}
|
||||
gl_RenderState.SetFixedColormap(CM_DEFAULT);
|
||||
gl_RenderState.SetSoftLightLevel(-1);
|
||||
DrawTargeterSprites();
|
||||
DrawBlend(viewsector);
|
||||
|
||||
// Restore standard rendering state
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor3f(1.0f,1.0f,1.0f);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
|
|
@ -862,6 +758,7 @@ void FGLRenderer::SetFixedColormap (player_t *player)
|
|||
}
|
||||
}
|
||||
}
|
||||
gl_RenderState.SetFixedColormap(gl_fixedcolormap);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -900,6 +797,8 @@ sector_t * FGLRenderer::RenderViewpoint (AActor * camera, GL_IRECT * bounds, flo
|
|||
SetProjection(fov, ratio, fovratio); // switch to perspective mode and set up clipper
|
||||
SetCameraPos(viewx, viewy, viewz, viewangle);
|
||||
SetViewMatrix(false, false);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
GLRenderer->mLights->Clear();
|
||||
|
||||
clipper.Clear();
|
||||
angle_t a1 = FrustumAngle();
|
||||
|
|
@ -924,6 +823,7 @@ void FGLRenderer::RenderView (player_t* player)
|
|||
OpenGLFrameBuffer* GLTarget = static_cast<OpenGLFrameBuffer*>(screen);
|
||||
AActor *&LastCamera = GLTarget->LastCamera;
|
||||
|
||||
checkBenchActive();
|
||||
if (player->camera != LastCamera)
|
||||
{
|
||||
// If the camera changed don't interpolate
|
||||
|
|
@ -932,7 +832,8 @@ void FGLRenderer::RenderView (player_t* player)
|
|||
LastCamera=player->camera;
|
||||
}
|
||||
|
||||
mVBO->BindVBO();
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
GLRenderer->mVBO->Reset();
|
||||
|
||||
// reset statistics counters
|
||||
ResetProfilingData();
|
||||
|
|
@ -993,6 +894,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei
|
|||
bounds.height=height;
|
||||
glFlush();
|
||||
SetFixedColormap(player);
|
||||
gl_RenderState.SetVertexBuffer(mVBO);
|
||||
GLRenderer->mVBO->Reset();
|
||||
|
||||
// Check if there's some lights. If not some code can be skipped.
|
||||
TThinkerIterator<ADynamicLight> it(STAT_DLIGHT);
|
||||
|
|
@ -1001,6 +904,8 @@ void FGLRenderer::WriteSavePic (player_t *player, FILE *file, int width, int hei
|
|||
sector_t *viewsector = RenderViewpoint(players[consoleplayer].camera, &bounds,
|
||||
FieldOfView * 360.0f / FINEANGLES, 1.6f, 1.6f, true, false);
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
gl_RenderState.SetFixedColormap(CM_DEFAULT);
|
||||
gl_RenderState.SetSoftLightLevel(-1);
|
||||
screen->Begin2D(false);
|
||||
DrawBlend(viewsector);
|
||||
glFlush();
|
||||
|
|
@ -1063,7 +968,7 @@ void FGLInterface::PrecacheTexture(FTexture *tex, int cache)
|
|||
{
|
||||
if (cache)
|
||||
{
|
||||
tex->PrecacheGL();
|
||||
tex->PrecacheGL(cache);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1158,6 +1063,7 @@ void FGLInterface::RenderView(player_t *player)
|
|||
void FGLInterface::Init()
|
||||
{
|
||||
gl_ParseDefs();
|
||||
gl_InitData();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -1170,22 +1076,15 @@ extern TexFilter_s TexFilter[];
|
|||
|
||||
void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, int FOV)
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex);
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(tex, false);
|
||||
|
||||
int width = gltex->TextureWidth(GLUSE_TEXTURE);
|
||||
int height = gltex->TextureHeight(GLUSE_TEXTURE);
|
||||
int width = gltex->TextureWidth();
|
||||
int height = gltex->TextureHeight();
|
||||
|
||||
gl_fixedcolormap=CM_DEFAULT;
|
||||
gl_RenderState.SetFixedColormap(CM_DEFAULT);
|
||||
|
||||
bool usefb;
|
||||
|
||||
if (gl.flags & RFL_FRAMEBUFFER)
|
||||
{
|
||||
usefb = gl_usefb || width > screen->GetWidth() || height > screen->GetHeight();
|
||||
}
|
||||
else usefb = false;
|
||||
|
||||
|
||||
bool usefb = gl_usefb || width > screen->GetWidth() || height > screen->GetHeight();
|
||||
if (!usefb)
|
||||
{
|
||||
glFlush();
|
||||
|
|
@ -1212,15 +1111,15 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in
|
|||
|
||||
GL_IRECT bounds;
|
||||
bounds.left=bounds.top=0;
|
||||
bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth(GLUSE_TEXTURE));
|
||||
bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight(GLUSE_TEXTURE));
|
||||
bounds.width=FHardwareTexture::GetTexDimension(gltex->GetWidth());
|
||||
bounds.height=FHardwareTexture::GetTexDimension(gltex->GetHeight());
|
||||
|
||||
GLRenderer->RenderViewpoint(Viewpoint, &bounds, FOV, (float)width/height, (float)width/height, false, false);
|
||||
|
||||
if (!usefb)
|
||||
{
|
||||
glFlush();
|
||||
gltex->Bind(CM_DEFAULT, 0, 0);
|
||||
gl_RenderState.SetMaterial(gltex, 0, 0, -1, false);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, bounds.width, bounds.height);
|
||||
}
|
||||
else
|
||||
|
|
@ -1228,8 +1127,6 @@ void FGLInterface::RenderTextureView (FCanvasTexture *tex, AActor *Viewpoint, in
|
|||
GLRenderer->EndOffscreen();
|
||||
}
|
||||
|
||||
gltex->Bind(CM_DEFAULT, 0, 0);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter);
|
||||
tex->SetUpdated();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
|
|||
}
|
||||
|
||||
FTextureID texno = s->GetTexture(pos);
|
||||
skyinfo.texture[0] = FMaterial::ValidateTexture(texno, true);
|
||||
skyinfo.texture[0] = FMaterial::ValidateTexture(texno, false, true);
|
||||
if (!skyinfo.texture[0] || skyinfo.texture[0]->tex->UseType == FTexture::TEX_Null) goto normalsky;
|
||||
skyinfo.skytexno1 = texno;
|
||||
skyinfo.x_offset[0] = ANGLE_TO_FLOAT(s->GetTextureXOffset(pos));
|
||||
|
|
@ -123,7 +123,7 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
|
|||
normalsky:
|
||||
if (level.flags&LEVEL_DOUBLESKY)
|
||||
{
|
||||
skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, true);
|
||||
skyinfo.texture[1]=FMaterial::ValidateTexture(sky1texture, false, true);
|
||||
skyinfo.x_offset[1] = GLRenderer->mSky1Pos;
|
||||
skyinfo.doublesky = true;
|
||||
}
|
||||
|
|
@ -131,14 +131,14 @@ void GLWall::SkyPlane(sector_t *sector, int plane, bool allowreflect)
|
|||
if ((level.flags&LEVEL_SWAPSKIES || (sky1==PL_SKYFLAT) || (level.flags&LEVEL_DOUBLESKY)) &&
|
||||
sky2texture!=sky1texture) // If both skies are equal use the scroll offset of the first!
|
||||
{
|
||||
skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, true);
|
||||
skyinfo.texture[0]=FMaterial::ValidateTexture(sky2texture, false, true);
|
||||
skyinfo.skytexno1=sky2texture;
|
||||
skyinfo.sky2 = true;
|
||||
skyinfo.x_offset[0] = GLRenderer->mSky2Pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, true);
|
||||
skyinfo.texture[0]=FMaterial::ValidateTexture(sky1texture, false, true);
|
||||
skyinfo.skytexno1=sky1texture;
|
||||
skyinfo.x_offset[0] = GLRenderer->mSky1Pos;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
|
|
@ -63,280 +64,245 @@
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
CVAR (Int, gl_sky_detail, 16, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
EXTERN_CVAR (Bool, r_stretchsky)
|
||||
CVAR(Float, skyoffset, 0, 0) // for testing
|
||||
|
||||
extern int skyfog;
|
||||
|
||||
// The texture offset to be applied to the texture coordinates in SkyVertex().
|
||||
|
||||
static angle_t maxSideAngle = ANGLE_180 / 3;
|
||||
static int rows, columns;
|
||||
static fixed_t scale = 10000 << FRACBITS;
|
||||
static bool yflip;
|
||||
static int texw;
|
||||
static float yAdd;
|
||||
static bool foglayer;
|
||||
static bool secondlayer;
|
||||
static float R,G,B;
|
||||
static bool skymirror;
|
||||
|
||||
#define SKYHEMI_UPPER 0x1
|
||||
#define SKYHEMI_LOWER 0x2
|
||||
#define SKYHEMI_JUST_CAP 0x4 // Just draw the top or bottom cap.
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void SkyVertex(int r, int c)
|
||||
FSkyVertexBuffer::FSkyVertexBuffer()
|
||||
{
|
||||
angle_t topAngle= (angle_t)(c / (float)columns * ANGLE_MAX);
|
||||
angle_t sideAngle = maxSideAngle * (rows - r) / rows;
|
||||
CreateDome();
|
||||
|
||||
glBindVertexArray(vao_id);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glVertexAttribPointer(VATTR_VERTEX, 3, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->x);
|
||||
glVertexAttribPointer(VATTR_TEXCOORD, 2, GL_FLOAT, false, sizeof(FSkyVertex), &VSO->u);
|
||||
glVertexAttribPointer(VATTR_COLOR, 4, GL_UNSIGNED_BYTE, true, sizeof(FSkyVertex), &VSO->color);
|
||||
glEnableVertexAttribArray(VATTR_VERTEX);
|
||||
glEnableVertexAttribArray(VATTR_TEXCOORD);
|
||||
glEnableVertexAttribArray(VATTR_COLOR);
|
||||
glBindVertexArray(0);
|
||||
|
||||
}
|
||||
|
||||
FSkyVertexBuffer::~FSkyVertexBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::SkyVertex(int r, int c, bool yflip)
|
||||
{
|
||||
static const angle_t maxSideAngle = ANGLE_180 / 3;
|
||||
static const fixed_t scale = 10000 << FRACBITS;
|
||||
|
||||
angle_t topAngle= (angle_t)(c / (float)mColumns * ANGLE_MAX);
|
||||
angle_t sideAngle = maxSideAngle * (mRows - r) / mRows;
|
||||
fixed_t height = finesine[sideAngle>>ANGLETOFINESHIFT];
|
||||
fixed_t realRadius = FixedMul(scale, finecosine[sideAngle>>ANGLETOFINESHIFT]);
|
||||
fixed_t x = FixedMul(realRadius, finecosine[topAngle>>ANGLETOFINESHIFT]);
|
||||
fixed_t y = (!yflip) ? FixedMul(scale, height) : FixedMul(scale, height) * -1;
|
||||
fixed_t z = FixedMul(realRadius, finesine[topAngle>>ANGLETOFINESHIFT]);
|
||||
float fx, fy, fz;
|
||||
float color = r * 1.f / rows;
|
||||
float u, v;
|
||||
float timesRepeat;
|
||||
|
||||
FSkyVertex vert;
|
||||
|
||||
timesRepeat = (short)(4 * (256.f / texw));
|
||||
if (timesRepeat == 0.f) timesRepeat = 1.f;
|
||||
|
||||
if (!foglayer)
|
||||
vert.color = r == 0 ? 0xffffff : 0xffffffff;
|
||||
|
||||
// And the texture coordinates.
|
||||
if(!yflip) // Flipped Y is for the lower hemisphere.
|
||||
{
|
||||
gl_SetColor(255, 0, NULL, r==0? 0.0f : 1.0f);
|
||||
|
||||
// And the texture coordinates.
|
||||
if(!yflip) // Flipped Y is for the lower hemisphere.
|
||||
{
|
||||
u = (-timesRepeat * c / (float)columns) ;
|
||||
v = (r / (float)rows) + yAdd;
|
||||
}
|
||||
else
|
||||
{
|
||||
u = (-timesRepeat * c / (float)columns) ;
|
||||
v = 1.0f + ((rows-r)/(float)rows) + yAdd;
|
||||
}
|
||||
|
||||
|
||||
glTexCoord2f(skymirror? -u:u, v);
|
||||
vert.u = (-c / (float)mColumns) ;
|
||||
vert.v = (r / (float)mRows);
|
||||
}
|
||||
else
|
||||
{
|
||||
vert.u = (-c / (float)mColumns);
|
||||
vert.v = 1.0f + ((mRows - r) / (float)mRows);
|
||||
}
|
||||
|
||||
if (r != 4) y+=FRACUNIT*300;
|
||||
// And finally the vertex.
|
||||
fx =-FIXED2FLOAT(x); // Doom mirrors the sky vertically!
|
||||
fy = FIXED2FLOAT(y);
|
||||
fz = FIXED2FLOAT(z);
|
||||
glVertex3f(fx, fy - 1.f, fz);
|
||||
vert.x =-FIXED2FLOAT(x); // Doom mirrors the sky vertically!
|
||||
vert.y = FIXED2FLOAT(y) - 1.f;
|
||||
vert.z = FIXED2FLOAT(z);
|
||||
|
||||
mVertices.Push(vert);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Hemi is Upper or Lower. Zero is not acceptable.
|
||||
// The current texture is used. SKYHEMI_NO_TOPCAP can be used.
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void RenderSkyHemisphere(int hemi, bool mirror)
|
||||
void FSkyVertexBuffer::CreateSkyHemisphere(int hemi)
|
||||
{
|
||||
int r, c;
|
||||
|
||||
if (hemi & SKYHEMI_LOWER)
|
||||
bool yflip = !!(hemi & SKYHEMI_LOWER);
|
||||
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
|
||||
for (c = 0; c < mColumns; c++)
|
||||
{
|
||||
yflip = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
yflip = false;
|
||||
SkyVertex(1, c, yflip);
|
||||
}
|
||||
|
||||
skymirror = mirror;
|
||||
|
||||
// The top row (row 0) is the one that's faded out.
|
||||
// There must be at least 4 columns. The preferable number
|
||||
// is 4n, where n is 1, 2, 3... There should be at least
|
||||
// two rows because the first one is always faded.
|
||||
rows = 4;
|
||||
|
||||
if (hemi & SKYHEMI_JUST_CAP)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Draw the cap as one solid color polygon
|
||||
if (!foglayer)
|
||||
{
|
||||
columns = 4 * (gl_sky_detail > 0 ? gl_sky_detail : 1);
|
||||
foglayer=true;
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply(true);
|
||||
|
||||
|
||||
if (!secondlayer)
|
||||
{
|
||||
glColor3f(R, G ,B);
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
for(c = 0; c < columns; c++)
|
||||
{
|
||||
SkyVertex(1, c);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
gl_RenderState.EnableTexture(true);
|
||||
foglayer=false;
|
||||
gl_RenderState.Apply();
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.Apply(true);
|
||||
columns=4; // no need to do more!
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
for(c = 0; c < columns; c++)
|
||||
{
|
||||
SkyVertex(0, c);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// The total number of triangles per hemisphere can be calculated
|
||||
// as follows: rows * columns * 2 + 2 (for the top cap).
|
||||
for(r = 0; r < rows; r++)
|
||||
for (r = 0; r < mRows; r++)
|
||||
{
|
||||
if (yflip)
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
for (c = 0; c <= mColumns; c++)
|
||||
{
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
SkyVertex(r + 1, 0);
|
||||
SkyVertex(r, 0);
|
||||
for(c = 1; c <= columns; c++)
|
||||
{
|
||||
SkyVertex(r + 1, c);
|
||||
SkyVertex(r, c);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
SkyVertex(r, 0);
|
||||
SkyVertex(r + 1, 0);
|
||||
for(c = 1; c <= columns; c++)
|
||||
{
|
||||
SkyVertex(r, c);
|
||||
SkyVertex(r + 1, c);
|
||||
}
|
||||
glEnd();
|
||||
SkyVertex(r + yflip, c, yflip);
|
||||
SkyVertex(r + 1 - yflip, c, yflip);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::CreateDome()
|
||||
{
|
||||
// the first thing we put into the buffer is the fog layer object which is just 4 triangles around the viewpoint.
|
||||
|
||||
mVertices.Reserve(12);
|
||||
mVertices[0].Set( 1.0f, 1.0f, -1.0f);
|
||||
mVertices[1].Set( 1.0f, -1.0f, -1.0f);
|
||||
mVertices[2].Set(-1.0f, 0.0f, -1.0f);
|
||||
|
||||
mVertices[3].Set( 1.0f, 1.0f, -1.0f);
|
||||
mVertices[4].Set( 1.0f, -1.0f, -1.0f);
|
||||
mVertices[5].Set( 0.0f, 0.0f, 1.0f);
|
||||
|
||||
mVertices[6].Set(-1.0f, 0.0f, -1.0f);
|
||||
mVertices[7].Set( 1.0f, 1.0f, -1.0f);
|
||||
mVertices[8].Set( 0.0f, 0.0f, 1.0f);
|
||||
|
||||
mVertices[9].Set(1.0f, -1.0f, -1.0f);
|
||||
mVertices[10].Set(-1.0f, 0.0f, -1.0f);
|
||||
mVertices[11].Set( 0.0f, 0.0f, 1.0f);
|
||||
|
||||
mColumns = 128;
|
||||
mRows = 4;
|
||||
CreateSkyHemisphere(SKYHEMI_UPPER);
|
||||
CreateSkyHemisphere(SKYHEMI_LOWER);
|
||||
mPrimStart.Push(mVertices.Size());
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
|
||||
glBufferData(GL_ARRAY_BUFFER, mVertices.Size() * sizeof(FSkyVertex), &mVertices[0], GL_STATIC_DRAW);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
inline void FSkyVertexBuffer::RenderRow(int prim, int row)
|
||||
{
|
||||
glDrawArrays(prim, mPrimStart[row], mPrimStart[row + 1] - mPrimStart[row]);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyVertexBuffer::RenderDome(FMaterial *tex, int mode)
|
||||
{
|
||||
int rc = mRows + 1;
|
||||
|
||||
// The caps only get drawn for the main layer but not for the overlay.
|
||||
if (mode == SKYMODE_MAINLAYER && tex != NULL)
|
||||
{
|
||||
PalEntry pe = tex->tex->GetSkyCapColor(false);
|
||||
gl_RenderState.SetObjectColor(pe);
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.Apply();
|
||||
RenderRow(GL_TRIANGLE_FAN, 0);
|
||||
|
||||
pe = tex->tex->GetSkyCapColor(true);
|
||||
gl_RenderState.SetObjectColor(pe);
|
||||
gl_RenderState.Apply();
|
||||
RenderRow(GL_TRIANGLE_FAN, rc);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
gl_RenderState.Apply();
|
||||
for (int i = 1; i <= mRows; i++)
|
||||
{
|
||||
RenderRow(GL_TRIANGLE_STRIP, i);
|
||||
RenderRow(GL_TRIANGLE_STRIP, rc + i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
CVAR(Float, skyoffset, 0, 0) // for testing
|
||||
|
||||
static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float y_offset, bool mirror, int CM_Index)
|
||||
void RenderDome(FMaterial * tex, float x_offset, float y_offset, bool mirror, int mode)
|
||||
{
|
||||
int texh = 0;
|
||||
bool texscale = false;
|
||||
int texw = 0;
|
||||
|
||||
// 57 worls units roughly represent one sky texel for the glTranslate call.
|
||||
// 57 world units roughly represent one sky texel for the glTranslate call.
|
||||
const float skyoffsetfactor = 57;
|
||||
|
||||
if (tex)
|
||||
{
|
||||
glPushMatrix();
|
||||
tex->Bind(CM_Index, 0, 0);
|
||||
texw = tex->TextureWidth(GLUSE_TEXTURE);
|
||||
texh = tex->TextureHeight(GLUSE_TEXTURE);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_NONE, 0, -1, false);
|
||||
texw = tex->TextureWidth();
|
||||
texh = tex->TextureHeight();
|
||||
gl_RenderState.EnableModelMatrix(true);
|
||||
|
||||
glRotatef(-180.0f+x_offset, 0.f, 1.f, 0.f);
|
||||
yAdd = y_offset/texh;
|
||||
gl_RenderState.mModelMatrix.loadIdentity();
|
||||
gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, 0.f, 1.f, 0.f);
|
||||
|
||||
float xscale = 1024.f / float(texw);
|
||||
float yscale = 1.f;
|
||||
if (texh < 200)
|
||||
{
|
||||
glTranslatef(0.f, -1250.f, 0.f);
|
||||
glScalef(1.f, texh/230.f, 1.f);
|
||||
gl_RenderState.mModelMatrix.translate(0.f, -1250.f, 0.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, texh/230.f, 1.f);
|
||||
}
|
||||
else if (texh <= 240)
|
||||
{
|
||||
glTranslatef(0.f, (200 - texh + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f);
|
||||
glScalef(1.f, 1.f + ((texh-200.f)/200.f) * 1.17f, 1.f);
|
||||
gl_RenderState.mModelMatrix.translate(0.f, (200 - texh + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, 1.f + ((texh-200.f)/200.f) * 1.17f, 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTranslatef(0.f, (-40 + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f);
|
||||
glScalef(1.f, 1.2f * 1.17f, 1.f);
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glScalef(1.f, 240.f / texh, 1.f);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
texscale = true;
|
||||
gl_RenderState.mModelMatrix.translate(0.f, (-40 + tex->tex->SkyOffset + skyoffset)*skyoffsetfactor, 0.f);
|
||||
gl_RenderState.mModelMatrix.scale(1.f, 1.2f * 1.17f, 1.f);
|
||||
yscale = 240.f / texh;
|
||||
}
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
gl_RenderState.mTextureMatrix.loadIdentity();
|
||||
gl_RenderState.mTextureMatrix.scale(mirror? -xscale : xscale, yscale, 1.f);
|
||||
gl_RenderState.mTextureMatrix.translate(1.f, y_offset / texh, 1.f);
|
||||
}
|
||||
|
||||
if (tex && !secondlayer)
|
||||
{
|
||||
PalEntry pe = tex->tex->GetSkyCapColor(false);
|
||||
if (CM_Index!=CM_DEFAULT) ModifyPalette(&pe, &pe, CM_Index, 1);
|
||||
|
||||
R=pe.r/255.0f;
|
||||
G=pe.g/255.0f;
|
||||
B=pe.b/255.0f;
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
float rr, gg, bb;
|
||||
|
||||
gl_GetLightColor(255, 0, NULL, &rr, &gg, &bb);
|
||||
R*=rr;
|
||||
G*=gg;
|
||||
B*=bb;
|
||||
}
|
||||
}
|
||||
|
||||
RenderSkyHemisphere(SKYHEMI_UPPER, mirror);
|
||||
|
||||
if (tex && !secondlayer)
|
||||
{
|
||||
PalEntry pe = tex->tex->GetSkyCapColor(true);
|
||||
if (CM_Index!=CM_DEFAULT) ModifyPalette(&pe, &pe, CM_Index, 1);
|
||||
R=pe.r/255.0f;
|
||||
G=pe.g/255.0f;
|
||||
B=pe.b/255.0f;
|
||||
|
||||
if (gl_fixedcolormap != CM_DEFAULT)
|
||||
{
|
||||
float rr,gg,bb;
|
||||
|
||||
gl_GetLightColor(255, 0, NULL, &rr, &gg, &bb);
|
||||
R*=rr;
|
||||
G*=gg;
|
||||
B*=bb;
|
||||
}
|
||||
}
|
||||
|
||||
RenderSkyHemisphere(SKYHEMI_LOWER, mirror);
|
||||
if (texscale)
|
||||
{
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
if (tex) glPopMatrix();
|
||||
|
||||
GLRenderer->mSkyVBO->RenderDome(tex, mode);
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
gl_RenderState.EnableModelMatrix(false);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -346,185 +312,149 @@ static void RenderDome(FTextureID texno, FMaterial * tex, float x_offset, float
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int CM_Index, bool sky2)
|
||||
static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, bool sky2)
|
||||
{
|
||||
FSkyBox * sb = static_cast<FSkyBox*>(gltex->tex);
|
||||
int faces;
|
||||
FMaterial * tex;
|
||||
|
||||
gl_RenderState.EnableModelMatrix(true);
|
||||
gl_RenderState.mModelMatrix.loadIdentity();
|
||||
|
||||
if (!sky2)
|
||||
glRotatef(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y);
|
||||
gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector.X, glset.skyrotatevector.Z, glset.skyrotatevector.Y);
|
||||
else
|
||||
glRotatef(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y);
|
||||
|
||||
glColor3f(R, G ,B);
|
||||
gl_RenderState.mModelMatrix.rotate(-180.0f+x_offset, glset.skyrotatevector2.X, glset.skyrotatevector2.Z, glset.skyrotatevector2.Y);
|
||||
|
||||
FFlatVertex *ptr;
|
||||
if (sb->faces[5])
|
||||
{
|
||||
faces=4;
|
||||
|
||||
// north
|
||||
tex = FMaterial::ValidateTexture(sb->faces[0]);
|
||||
tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
|
||||
tex = FMaterial::ValidateTexture(sb->faces[0], false);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(128.f, 128.f, -128.f);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3f(-128.f, 128.f, -128.f);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3f(-128.f, -128.f, -128.f);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3f(128.f, -128.f, -128.f);
|
||||
glEnd();
|
||||
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(128.f, 128.f, -128.f, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, 128.f, -128.f, 1, 0);
|
||||
ptr++;
|
||||
ptr->Set(128.f, -128.f, -128.f, 0, 1);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, -128.f, -128.f, 1, 1);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
// east
|
||||
tex = FMaterial::ValidateTexture(sb->faces[1]);
|
||||
tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
|
||||
tex = FMaterial::ValidateTexture(sb->faces[1], false);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(-128.f, 128.f, -128.f);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3f(-128.f, 128.f, 128.f);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3f(-128.f, -128.f, 128.f);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3f(-128.f, -128.f, -128.f);
|
||||
glEnd();
|
||||
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(-128.f, 128.f, -128.f, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, 128.f, 128.f, 1, 0);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, -128.f, -128.f, 0, 1);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, -128.f, 128.f, 1, 1);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
// south
|
||||
tex = FMaterial::ValidateTexture(sb->faces[2]);
|
||||
tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
|
||||
tex = FMaterial::ValidateTexture(sb->faces[2], false);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(-128.f, 128.f, 128.f);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3f(128.f, 128.f, 128.f);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3f(128.f, -128.f, 128.f);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3f(-128.f, -128.f, 128.f);
|
||||
glEnd();
|
||||
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(-128.f, 128.f, 128.f, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(128.f, 128.f, 128.f, 1, 0);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, -128.f, 128.f, 0, 1);
|
||||
ptr++;
|
||||
ptr->Set(128.f, -128.f, 128.f, 1, 1);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
// west
|
||||
tex = FMaterial::ValidateTexture(sb->faces[3]);
|
||||
tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
|
||||
tex = FMaterial::ValidateTexture(sb->faces[3], false);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(128.f, 128.f, 128.f);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3f(128.f, 128.f, -128.f);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3f(128.f, -128.f, -128.f);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3f(128.f, -128.f, 128.f);
|
||||
glEnd();
|
||||
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(128.f, 128.f, 128.f, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(128.f, 128.f, -128.f, 1, 0);
|
||||
ptr++;
|
||||
ptr->Set(128.f, -128.f, 128.f, 0, 1);
|
||||
ptr++;
|
||||
ptr->Set(128.f, -128.f, -128.f, 1, 1);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
else
|
||||
{
|
||||
faces=1;
|
||||
// all 4 sides
|
||||
tex = FMaterial::ValidateTexture(sb->faces[0]);
|
||||
tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
|
||||
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(128.f, 128.f, -128.f);
|
||||
glTexCoord2f(.25f, 0);
|
||||
glVertex3f(-128.f, 128.f, -128.f);
|
||||
glTexCoord2f(.25f, 1);
|
||||
glVertex3f(-128.f, -128.f, -128.f);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3f(128.f, -128.f, -128.f);
|
||||
glEnd();
|
||||
|
||||
// east
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(.25f, 0);
|
||||
glVertex3f(-128.f, 128.f, -128.f);
|
||||
glTexCoord2f(.5f, 0);
|
||||
glVertex3f(-128.f, 128.f, 128.f);
|
||||
glTexCoord2f(.5f, 1);
|
||||
glVertex3f(-128.f, -128.f, 128.f);
|
||||
glTexCoord2f(.25f, 1);
|
||||
glVertex3f(-128.f, -128.f, -128.f);
|
||||
glEnd();
|
||||
|
||||
// south
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(.5f, 0);
|
||||
glVertex3f(-128.f, 128.f, 128.f);
|
||||
glTexCoord2f(.75f, 0);
|
||||
glVertex3f(128.f, 128.f, 128.f);
|
||||
glTexCoord2f(.75f, 1);
|
||||
glVertex3f(128.f, -128.f, 128.f);
|
||||
glTexCoord2f(.5f, 1);
|
||||
glVertex3f(-128.f, -128.f, 128.f);
|
||||
glEnd();
|
||||
|
||||
// west
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(.75f, 0);
|
||||
glVertex3f(128.f, 128.f, 128.f);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3f(128.f, 128.f, -128.f);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3f(128.f, -128.f, -128.f);
|
||||
glTexCoord2f(.75f, 1);
|
||||
glVertex3f(128.f, -128.f, 128.f);
|
||||
glEnd();
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(128.f, 128.f, -128.f, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(128.f, -128.f, -128.f, 0, 1);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, 128.f, -128.f, 0.25f, 0);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, -128.f, -128.f, 0.25f, 1);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, 128.f, 128.f, 0.5f, 0);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, -128.f, 128.f, 0.5f, 1);
|
||||
ptr++;
|
||||
ptr->Set(128.f, 128.f, 128.f, 0.75f, 0);
|
||||
ptr++;
|
||||
ptr->Set(128.f, -128.f, 128.f, 0.75f, 1);
|
||||
ptr++;
|
||||
ptr->Set(128.f, 128.f, -128.f, 1, 0);
|
||||
ptr++;
|
||||
ptr->Set(128.f, -128.f, -128.f, 1, 1);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
// top
|
||||
tex = FMaterial::ValidateTexture(sb->faces[faces]);
|
||||
tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
|
||||
tex = FMaterial::ValidateTexture(sb->faces[faces], false);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
if (!sb->fliptop)
|
||||
{
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(128.f, 128.f, -128.f);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3f(-128.f, 128.f, -128.f);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3f(-128.f, 128.f, 128.f);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3f(128.f, 128.f, 128.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(128.f, 128.f, 128.f);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3f(-128.f, 128.f, 128.f);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3f(-128.f, 128.f, -128.f);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3f(128.f, 128.f, -128.f);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(128.f, 128.f, -128.f, 0, sb->fliptop);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, 128.f, -128.f, 1, sb->fliptop);
|
||||
ptr++;
|
||||
ptr->Set(128.f, 128.f, 128.f, 0, !sb->fliptop);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, 128.f, 128.f, 1, !sb->fliptop);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
// bottom
|
||||
tex = FMaterial::ValidateTexture(sb->faces[faces+1]);
|
||||
tex->Bind(CM_Index, GLT_CLAMPX|GLT_CLAMPY, 0);
|
||||
tex = FMaterial::ValidateTexture(sb->faces[faces+1], false);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_XY, 0, -1, false);
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex3f(128.f, -128.f, -128.f);
|
||||
glTexCoord2f(1, 0);
|
||||
glVertex3f(-128.f, -128.f, -128.f);
|
||||
glTexCoord2f(1, 1);
|
||||
glVertex3f(-128.f, -128.f, 128.f);
|
||||
glTexCoord2f(0, 1);
|
||||
glVertex3f(128.f, -128.f, 128.f);
|
||||
glEnd();
|
||||
|
||||
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(128.f, -128.f, -128.f, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, -128.f, -128.f, 1, 0);
|
||||
ptr++;
|
||||
ptr->Set(128.f, -128.f, 128.f, 0, 1);
|
||||
ptr++;
|
||||
ptr->Set(-128.f, -128.f, 128.f, 1, 1);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
gl_RenderState.EnableModelMatrix(false);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
@ -535,80 +465,59 @@ static void RenderBox(FTextureID texno, FMaterial * gltex, float x_offset, int C
|
|||
void GLSkyPortal::DrawContents()
|
||||
{
|
||||
bool drawBoth = false;
|
||||
int CM_Index;
|
||||
PalEntry FadeColor(0,0,0,0);
|
||||
|
||||
// We have no use for Doom lighting special handling here, so disable it for this function.
|
||||
int oldlightmode = glset.lightmode;
|
||||
if (glset.lightmode == 8) glset.lightmode = 2;
|
||||
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
CM_Index=gl_fixedcolormap<CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size()? gl_fixedcolormap:CM_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
CM_Index=CM_DEFAULT;
|
||||
FadeColor=origin->fadecolor;
|
||||
}
|
||||
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.EnableFog(false);
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
gl_MatrixStack.Push(gl_RenderState.mViewMatrix);
|
||||
GLRenderer->SetupView(0, 0, 0, viewangle, !!(MirrorFlag&1), !!(PlaneMirrorFlag&1));
|
||||
|
||||
if (origin->texture[0] && origin->texture[0]->tex->gl_info.bSkybox)
|
||||
{
|
||||
if (gl_fixedcolormap != CM_DEFAULT)
|
||||
{
|
||||
float rr,gg,bb;
|
||||
|
||||
gl_GetLightColor(255, 0, NULL, &rr, &gg, &bb);
|
||||
R=rr;
|
||||
G=gg;
|
||||
B=bb;
|
||||
}
|
||||
else R=G=B=1.f;
|
||||
|
||||
RenderBox(origin->skytexno1, origin->texture[0], origin->x_offset[0], CM_Index, origin->sky2);
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
RenderBox(origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->sky2);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mSkyVBO);
|
||||
if (origin->texture[0]==origin->texture[1] && origin->doublesky) origin->doublesky=false;
|
||||
|
||||
if (origin->texture[0])
|
||||
{
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
RenderDome(origin->skytexno1, origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, CM_Index);
|
||||
RenderDome(origin->texture[0], origin->x_offset[0], origin->y_offset, origin->mirrored, FSkyVertexBuffer::SKYMODE_MAINLAYER);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
}
|
||||
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,0.05f);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.05f);
|
||||
|
||||
if (origin->doublesky && origin->texture[1])
|
||||
{
|
||||
secondlayer=true;
|
||||
RenderDome(FNullTextureID(), origin->texture[1], origin->x_offset[1], origin->y_offset, false, CM_Index);
|
||||
secondlayer=false;
|
||||
RenderDome(origin->texture[1], origin->x_offset[1], origin->y_offset, false, FSkyVertexBuffer::SKYMODE_SECONDLAYER);
|
||||
}
|
||||
|
||||
if (skyfog>0 && (FadeColor.r ||FadeColor.g || FadeColor.b))
|
||||
if (skyfog>0 && gl_fixedcolormap == CM_DEFAULT && (origin->fadecolor & 0xffffff) != 0)
|
||||
{
|
||||
PalEntry FadeColor = origin->fadecolor;
|
||||
FadeColor.a = clamp<int>(skyfog, 0, 255);
|
||||
|
||||
gl_RenderState.EnableTexture(false);
|
||||
foglayer=true;
|
||||
glColor4f(FadeColor.r/255.0f,FadeColor.g/255.0f,FadeColor.b/255.0f,skyfog/255.0f);
|
||||
RenderDome(FNullTextureID(), NULL, 0, 0, false, CM_DEFAULT);
|
||||
gl_RenderState.SetObjectColor(FadeColor);
|
||||
gl_RenderState.Apply();
|
||||
glDrawArrays(GL_TRIANGLES, 0, 12);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
foglayer=false;
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
}
|
||||
gl_RenderState.SetVertexBuffer(GLRenderer->mVBO);
|
||||
}
|
||||
glPopMatrix();
|
||||
gl_MatrixStack.Pop(gl_RenderState.mViewMatrix);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
glset.lightmode = oldlightmode;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
|
|
@ -60,6 +61,7 @@
|
|||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/utility/gl_clock.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
||||
CVAR(Bool, gl_usecolorblending, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, gl_spritebrightfog, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG);
|
||||
|
|
@ -110,12 +112,8 @@ CVAR(Bool, gl_nolayer, false, 0)
|
|||
//==========================================================================
|
||||
void GLSprite::Draw(int pass)
|
||||
{
|
||||
if (pass!=GLPASS_PLAIN && pass != GLPASS_ALL && pass!=GLPASS_TRANSLUCENT) return;
|
||||
if (pass == GLPASS_DECALS || pass == GLPASS_LIGHTSONLY) return;
|
||||
|
||||
// Hack to enable bright sprites in faded maps
|
||||
uint32 backupfade = Colormap.FadeColor.d;
|
||||
if (gl_spritebrightfog && fullbright)
|
||||
Colormap.FadeColor = 0;
|
||||
|
||||
|
||||
bool additivefog = false;
|
||||
|
|
@ -126,25 +124,24 @@ void GLSprite::Draw(int pass)
|
|||
{
|
||||
// The translucent pass requires special setup for the various modes.
|
||||
|
||||
// Brightmaps will only be used when doing regular drawing ops and having no fog
|
||||
if (!gl_spritebrightfog && (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE ||
|
||||
RenderStyle.BlendOp != STYLEOP_Add))
|
||||
// for special render styles brightmaps would not look good - especially for subtractive.
|
||||
if (RenderStyle.BlendOp != STYLEOP_Add)
|
||||
{
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
}
|
||||
|
||||
gl_SetRenderStyle(RenderStyle, false,
|
||||
// The rest of the needed checks are done inside gl_SetRenderStyle
|
||||
trans > 1.f - FLT_EPSILON && gl_usecolorblending && gl_fixedcolormap < CM_FIRSTSPECIALCOLORMAP && actor &&
|
||||
trans > 1.f - FLT_EPSILON && gl_usecolorblending && gl_fixedcolormap == CM_DEFAULT && actor &&
|
||||
fullbright && gltexture && !gltexture->GetTransparent());
|
||||
|
||||
if (hw_styleflags == STYLEHW_NoAlphaTest)
|
||||
{
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,trans*gl_mask_sprite_threshold);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
|
||||
}
|
||||
|
||||
if (RenderStyle.BlendOp == STYLEOP_Shadow)
|
||||
|
|
@ -168,8 +165,8 @@ void GLSprite::Draw(int pass)
|
|||
minalpha*=factor;
|
||||
}
|
||||
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,minalpha*gl_mask_sprite_threshold);
|
||||
glColor4f(0.2f,0.2f,0.2f,fuzzalpha);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
|
||||
gl_RenderState.SetColor(0.2f,0.2f,0.2f,fuzzalpha, Colormap.desaturation);
|
||||
additivefog = true;
|
||||
}
|
||||
else if (RenderStyle.BlendOp == STYLEOP_Add && RenderStyle.DestAlpha == STYLEALPHA_One)
|
||||
|
|
@ -179,24 +176,13 @@ void GLSprite::Draw(int pass)
|
|||
}
|
||||
if (RenderStyle.BlendOp!=STYLEOP_Shadow)
|
||||
{
|
||||
if (actor)
|
||||
if (gl_lights && GLRenderer->mLightCount && !gl_fixedcolormap)
|
||||
{
|
||||
lightlevel = gl_SetSpriteLighting(RenderStyle, actor, lightlevel, rel, &Colormap, ThingColor, trans,
|
||||
fullbright || gl_fixedcolormap >= CM_FIRSTSPECIALCOLORMAP, false);
|
||||
gl_SetDynSpriteLight(gl_light_sprites ? actor : NULL, gl_light_particles ? particle : NULL);
|
||||
}
|
||||
else if (particle)
|
||||
{
|
||||
if (gl_light_particles)
|
||||
{
|
||||
lightlevel = gl_SetSpriteLight(particle, lightlevel, rel, &Colormap, trans, ThingColor);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_SetColor(lightlevel, rel, &Colormap, trans, ThingColor);
|
||||
}
|
||||
}
|
||||
else return;
|
||||
gl_SetColor(lightlevel, rel, Colormap, trans);
|
||||
}
|
||||
gl_RenderState.SetObjectColor(ThingColor);
|
||||
|
||||
if (gl_isBlack(Colormap.FadeColor)) foglevel=lightlevel;
|
||||
|
||||
|
|
@ -206,11 +192,6 @@ void GLSprite::Draw(int pass)
|
|||
additivefog = true;
|
||||
}
|
||||
|
||||
if (RenderStyle.Flags & STYLEF_InvertOverlay)
|
||||
{
|
||||
Colormap.FadeColor = Colormap.FadeColor.InverseColor();
|
||||
additivefog=false;
|
||||
}
|
||||
if (RenderStyle.BlendOp == STYLEOP_RevSub || RenderStyle.BlendOp == STYLEOP_Sub)
|
||||
{
|
||||
if (!modelframe)
|
||||
|
|
@ -218,18 +199,9 @@ void GLSprite::Draw(int pass)
|
|||
// non-black fog with subtractive style needs special treatment
|
||||
if (!gl_isBlack(Colormap.FadeColor))
|
||||
{
|
||||
if (gl.shadermodel >= 4 && !gl_nolayer)
|
||||
{
|
||||
// fog layer only works on modern hardware.
|
||||
foglayer = true;
|
||||
// Due to the two-layer approach we need to force an alpha test that lets everything pass
|
||||
gl_RenderState.AlphaFunc(GL_GREATER, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// this at least partially handles the fog issue
|
||||
Colormap.FadeColor = Colormap.FadeColor.InverseColor();
|
||||
}
|
||||
foglayer = true;
|
||||
// Due to the two-layer approach we need to force an alpha test that lets everything pass
|
||||
gl_RenderState.AlphaFunc(GL_GREATER, 0);
|
||||
}
|
||||
}
|
||||
else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work.
|
||||
|
|
@ -242,7 +214,7 @@ void GLSprite::Draw(int pass)
|
|||
gl_RenderState.SetFog(0, 0);
|
||||
}
|
||||
|
||||
if (gltexture) gltexture->BindPatch(Colormap.colormap, translation, OverrideShader);
|
||||
if (gltexture) gl_RenderState.SetMaterial(gltexture, CLAMP_XY, translation, OverrideShader, !!(RenderStyle.Flags & STYLEF_RedIsAlpha));
|
||||
else if (!modelframe) gl_RenderState.EnableTexture(false);
|
||||
|
||||
if (!modelframe)
|
||||
|
|
@ -286,23 +258,18 @@ void GLSprite::Draw(int pass)
|
|||
v4 = Vector(x2, z2, y2);
|
||||
}
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
if (gltexture)
|
||||
{
|
||||
glTexCoord2f(ul, vt); glVertex3fv(&v1[0]);
|
||||
glTexCoord2f(ur, vt); glVertex3fv(&v2[0]);
|
||||
glTexCoord2f(ul, vb); glVertex3fv(&v3[0]);
|
||||
glTexCoord2f(ur, vb); glVertex3fv(&v4[0]);
|
||||
}
|
||||
else // Particle
|
||||
{
|
||||
glVertex3fv(&v1[0]);
|
||||
glVertex3fv(&v2[0]);
|
||||
glVertex3fv(&v3[0]);
|
||||
glVertex3fv(&v4[0]);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
FFlatVertex *ptr;
|
||||
unsigned int offset, count;
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(v1[0], v1[1], v1[2], ul, vt);
|
||||
ptr++;
|
||||
ptr->Set(v2[0], v2[1], v2[2], ur, vt);
|
||||
ptr++;
|
||||
ptr->Set(v3[0], v3[1], v3[2], ul, vb);
|
||||
ptr++;
|
||||
ptr->Set(v4[0], v4[1], v4[2], ur, vb);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);
|
||||
|
||||
if (foglayer)
|
||||
{
|
||||
|
|
@ -312,29 +279,13 @@ void GLSprite::Draw(int pass)
|
|||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.Apply();
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
if (gltexture)
|
||||
{
|
||||
glTexCoord2f(ul, vt); glVertex3fv(&v1[0]);
|
||||
glTexCoord2f(ur, vt); glVertex3fv(&v2[0]);
|
||||
glTexCoord2f(ul, vb); glVertex3fv(&v3[0]);
|
||||
glTexCoord2f(ur, vb); glVertex3fv(&v4[0]);
|
||||
}
|
||||
else // Particle
|
||||
{
|
||||
glVertex3fv(&v1[0]);
|
||||
glVertex3fv(&v2[0]);
|
||||
glVertex3fv(&v3[0]);
|
||||
glVertex3fv(&v4[0]);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
|
||||
gl_RenderState.SetFixedColormap(CM_DEFAULT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderModel(this, Colormap.colormap);
|
||||
gl_RenderModel(this);
|
||||
}
|
||||
|
||||
if (pass==GLPASS_TRANSLUCENT)
|
||||
|
|
@ -343,22 +294,9 @@ void GLSprite::Draw(int pass)
|
|||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
// [BB] Restore the alpha test after drawing a smooth particle.
|
||||
if (hw_styleflags == STYLEHW_NoAlphaTest)
|
||||
{
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold);
|
||||
}
|
||||
}
|
||||
|
||||
// End of gl_sprite_brightfog hack: restore FadeColor to normalcy
|
||||
if (backupfade != Colormap.FadeColor.d)
|
||||
Colormap.FadeColor = backupfade;
|
||||
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
gl_RenderState.SetDynLight(0,0,0);
|
||||
}
|
||||
|
|
@ -377,13 +315,9 @@ inline void GLSprite::PutSprite(bool translucent)
|
|||
{
|
||||
list = GLDL_TRANSLUCENT;
|
||||
}
|
||||
else if ((!gl_isBlack (Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE))
|
||||
{
|
||||
list = GLDL_FOGMASKED;
|
||||
}
|
||||
else
|
||||
{
|
||||
list = GLDL_MASKED;
|
||||
list = GLDL_MODELS;
|
||||
}
|
||||
gl_drawinfo->drawlists[list].AddSprite(this);
|
||||
}
|
||||
|
|
@ -425,13 +359,6 @@ void GLSprite::SplitSprite(sector_t * frontsector, bool translucent)
|
|||
copySprite.Colormap.LightColor.b=(255+v+v)/3;
|
||||
}
|
||||
|
||||
if (!gl_isWhite(ThingColor))
|
||||
{
|
||||
copySprite.Colormap.LightColor.r=(copySprite.Colormap.LightColor.r*ThingColor.r)>>8;
|
||||
copySprite.Colormap.LightColor.g=(copySprite.Colormap.LightColor.g*ThingColor.g)>>8;
|
||||
copySprite.Colormap.LightColor.b=(copySprite.Colormap.LightColor.b*ThingColor.b)>>8;
|
||||
}
|
||||
|
||||
z1=copySprite.z2=maplightbottom;
|
||||
vt=copySprite.vb=copySprite.vt+
|
||||
(maplightbottom-copySprite.z1)*(copySprite.vb-copySprite.vt)/(z2-copySprite.z1);
|
||||
|
|
@ -471,13 +398,6 @@ void GLSprite::SetSpriteColor(sector_t *sector, fixed_t center_y)
|
|||
Colormap.LightColor.g=
|
||||
Colormap.LightColor.b=(255+v+v)/3;
|
||||
}
|
||||
|
||||
if (!gl_isWhite(ThingColor))
|
||||
{
|
||||
Colormap.LightColor.r=(Colormap.LightColor.r*ThingColor.r)>>8;
|
||||
Colormap.LightColor.g=(Colormap.LightColor.g*ThingColor.g)>>8;
|
||||
Colormap.LightColor.b=(Colormap.LightColor.b*ThingColor.b)>>8;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -535,8 +455,9 @@ void GLSprite::PerformSpriteClipAdjustment(AActor *thing, fixed_t thingx, fixed_
|
|||
if (top == -1000000.0f)
|
||||
top = FIXED2FLOAT(thing->Sector->ceilingplane.ZatPoint(thingx, thingy));
|
||||
|
||||
float diffb = z2 - btm;
|
||||
float difft = z1 - top;
|
||||
// +/-1 to account for the one pixel empty frame around the sprite.
|
||||
float diffb = (z2+1) - btm;
|
||||
float difft = (z1-1) - top;
|
||||
if (diffb >= 0 /*|| !gl_sprite_clip_to_floor*/) diffb = 0;
|
||||
// Adjust sprites clipping into ceiling and adjust clipping adjustment for tall graphics
|
||||
if (smarterclip)
|
||||
|
|
@ -678,12 +599,13 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
bool mirror;
|
||||
FTextureID patch = gl_GetSpriteFrame(spritenum, thing->frame, -1, ang - thing->angle, &mirror);
|
||||
if (!patch.isValid()) return;
|
||||
gltexture = FMaterial::ValidateTexture(patch, false);
|
||||
int type = thing->renderflags & RF_SPRITETYPEMASK;
|
||||
gltexture = FMaterial::ValidateTexture(patch, (type == RF_FACESPRITE), false);
|
||||
if (!gltexture) return;
|
||||
|
||||
vt = gltexture->GetSpriteVT();
|
||||
vb = gltexture->GetSpriteVB();
|
||||
gltexture->GetRect(&r, GLUSE_SPRITE);
|
||||
gltexture->GetSpriteRect(&r);
|
||||
if (mirror)
|
||||
{
|
||||
r.left = -r.width - r.left; // mirror the sprite's x-offset
|
||||
|
|
@ -704,7 +626,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
z1 = z - r.top;
|
||||
z2 = z1 - r.height;
|
||||
|
||||
float spriteheight = FIXED2FLOAT(spritescaleY) * gltexture->GetScaledHeightFloat(GLUSE_SPRITE);
|
||||
float spriteheight = FIXED2FLOAT(spritescaleY) * r.height;
|
||||
|
||||
// Tests show that this doesn't look good for many decorations and corpses
|
||||
if (spriteheight > 0 && gl_spriteclip > 0 && (thing->renderflags & RF_SPRITETYPEMASK) == RF_FACESPRITE)
|
||||
|
|
@ -754,7 +676,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
// allow disabling of the fullbright flag by a brightmap definition
|
||||
// (e.g. to do the gun flashes of Doom's zombies correctly.
|
||||
fullbright = (thing->flags5 & MF5_BRIGHT) ||
|
||||
((thing->renderflags & RF_FULLBRIGHT) && (!gl_BrightmapsActive() || !gltexture || !gltexture->tex->gl_info.bBrightmapDisablesFullbright));
|
||||
((thing->renderflags & RF_FULLBRIGHT) && (!gltexture || !gltexture->tex->gl_info.bBrightmapDisablesFullbright));
|
||||
|
||||
lightlevel=fullbright? 255 :
|
||||
gl_ClampLight(rendersector->GetTexture(sector_t::ceiling) == skyflatnum ?
|
||||
|
|
@ -763,6 +685,10 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
|
||||
lightlevel = (byte)gl_CheckSpriteGlow(rendersector, lightlevel, thingx, thingy, thingz);
|
||||
|
||||
ThingColor = (thing->RenderStyle.Flags & STYLEF_ColorIsFixed) ? thing->fillcolor : 0xffffff;
|
||||
ThingColor.a = 255;
|
||||
RenderStyle = thing->RenderStyle;
|
||||
|
||||
// colormap stuff is a little more complicated here...
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
|
|
@ -771,14 +697,14 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
|| (gl_enhanced_nv_stealth == 3)) // Any fixed colormap
|
||||
enhancedvision=true;
|
||||
|
||||
Colormap.GetFixedColormap();
|
||||
Colormap.Clear();
|
||||
|
||||
if (gl_fixedcolormap==CM_LITE)
|
||||
{
|
||||
if (gl_enhanced_nightvision &&
|
||||
(thing->IsKindOf(RUNTIME_CLASS(AInventory)) || thing->flags3&MF3_ISMONSTER || thing->flags&MF_MISSILE || thing->flags&MF_CORPSE))
|
||||
{
|
||||
Colormap.colormap = CM_FIRSTSPECIALCOLORMAP + INVERSECOLORMAP;
|
||||
RenderStyle.Flags |= STYLEF_InvertSource;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -804,18 +730,13 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
}
|
||||
else if (glset.nocoloredspritelighting)
|
||||
{
|
||||
int v = (Colormap.LightColor.r /* * 77 */ + Colormap.LightColor.g /**143 */ + Colormap.LightColor.b /**35*/)/3;//255;
|
||||
Colormap.LightColor.r=
|
||||
Colormap.LightColor.g=
|
||||
Colormap.LightColor.b=(255+v+v)/3;
|
||||
Colormap.Decolorize();
|
||||
}
|
||||
}
|
||||
|
||||
translation=thing->Translation;
|
||||
|
||||
ThingColor=0xffffff;
|
||||
RenderStyle = thing->RenderStyle;
|
||||
OverrideShader = 0;
|
||||
OverrideShader = -1;
|
||||
trans = FIXED2FLOAT(thing->alpha);
|
||||
hw_styleflags = STYLEHW_Normal;
|
||||
|
||||
|
|
@ -824,7 +745,7 @@ void GLSprite::Process(AActor* thing,sector_t * sector)
|
|||
RenderStyle.CheckFuzz();
|
||||
if (RenderStyle.BlendOp == STYLEOP_Fuzz)
|
||||
{
|
||||
if (gl.shadermodel >= 4 && gl_fuzztype != 0)
|
||||
if (gl_fuzztype != 0)
|
||||
{
|
||||
// Todo: implement shader selection here
|
||||
RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
|
|
@ -951,7 +872,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
Colormap.GetFixedColormap();
|
||||
Colormap.Clear();
|
||||
}
|
||||
else if (!particle->bright)
|
||||
{
|
||||
|
|
@ -984,8 +905,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
OverrideShader = 0;
|
||||
|
||||
ThingColor = particle->color;
|
||||
gl_ModifyColor(ThingColor.r, ThingColor.g, ThingColor.b, Colormap.colormap);
|
||||
ThingColor.a=0;
|
||||
ThingColor.a = 255;
|
||||
|
||||
modelframe=NULL;
|
||||
gltexture=NULL;
|
||||
|
|
@ -1005,7 +925,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
|
||||
if (lump != NULL)
|
||||
{
|
||||
gltexture=FMaterial::ValidateTexture(lump);
|
||||
gltexture = FMaterial::ValidateTexture(lump, true);
|
||||
translation = 0;
|
||||
|
||||
ul = gltexture->GetUL();
|
||||
|
|
@ -1013,7 +933,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
vt = gltexture->GetVT();
|
||||
vb = gltexture->GetVB();
|
||||
FloatRect r;
|
||||
gltexture->GetRect(&r, GLUSE_PATCH);
|
||||
gltexture->GetSpriteRect(&r);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,245 +59,68 @@
|
|||
|
||||
//==========================================================================
|
||||
//
|
||||
// Gets the light for a sprite - takes dynamic lights into account
|
||||
// Sets a single light value from all dynamic lights affecting the specified location
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_GetSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec, int desaturation, float * out, line_t *line, int side)
|
||||
void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec)
|
||||
{
|
||||
ADynamicLight *light;
|
||||
float frac, lr, lg, lb;
|
||||
float radius;
|
||||
bool changed = false;
|
||||
float out[3] = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
out[0]=out[1]=out[2]=0;
|
||||
|
||||
for(int j=0;j<2;j++)
|
||||
// Go through both light lists
|
||||
FLightNode * node = subsec->lighthead;
|
||||
while (node)
|
||||
{
|
||||
// Go through both light lists
|
||||
FLightNode * node = subsec->lighthead[j];
|
||||
while (node)
|
||||
light=node->lightsource;
|
||||
if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer())
|
||||
{
|
||||
light=node->lightsource;
|
||||
if (!light->owned || light->target == NULL || light->target->IsVisibleToPlayer())
|
||||
if (!(light->flags2&MF2_DORMANT) &&
|
||||
(!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self))
|
||||
{
|
||||
if (!(light->flags2&MF2_DORMANT) &&
|
||||
(!(light->flags4&MF4_DONTLIGHTSELF) || light->target != self))
|
||||
float dist = FVector3(FIXED2FLOAT(x - light->x), FIXED2FLOAT(y - light->y), FIXED2FLOAT(z - light->z)).Length();
|
||||
radius = light->GetRadius() * gl_lights_size;
|
||||
|
||||
if (dist < radius)
|
||||
{
|
||||
float dist = FVector3(FIXED2FLOAT(x - light->x), FIXED2FLOAT(y - light->y), FIXED2FLOAT(z - light->z)).Length();
|
||||
radius = light->GetRadius() * gl_lights_size;
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (dist < radius)
|
||||
if (frac > 0)
|
||||
{
|
||||
frac = 1.0f - (dist / radius);
|
||||
|
||||
if (frac > 0)
|
||||
lr = light->GetRed() / 255.0f * gl_lights_intensity;
|
||||
lg = light->GetGreen() / 255.0f * gl_lights_intensity;
|
||||
lb = light->GetBlue() / 255.0f * gl_lights_intensity;
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
if (line != NULL)
|
||||
{
|
||||
if (P_PointOnLineSide(light->x, light->y, line) != side)
|
||||
{
|
||||
node = node->nextLight;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
lr = light->GetRed() / 255.0f * gl_lights_intensity;
|
||||
lg = light->GetGreen() / 255.0f * gl_lights_intensity;
|
||||
lb = light->GetBlue() / 255.0f * gl_lights_intensity;
|
||||
if (light->IsSubtractive())
|
||||
{
|
||||
float bright = FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
changed = true;
|
||||
float bright = FVector3(lr, lg, lb).Length();
|
||||
FVector3 lightColor(lr, lg, lb);
|
||||
lr = (bright - lr) * -1;
|
||||
lg = (bright - lg) * -1;
|
||||
lb = (bright - lb) * -1;
|
||||
}
|
||||
|
||||
out[0] += lr * frac;
|
||||
out[1] += lg * frac;
|
||||
out[2] += lb * frac;
|
||||
}
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
|
||||
// Desaturate dynamic lighting if applicable
|
||||
if (desaturation>0 && desaturation<=CM_DESAT31)
|
||||
{
|
||||
float gray=(out[0]*77 + out[1]*143 + out[2]*37)/257;
|
||||
|
||||
out[0]= (out[0]*(31-desaturation)+ gray*desaturation)/31;
|
||||
out[1]= (out[1]*(31-desaturation)+ gray*desaturation)/31;
|
||||
out[2]= (out[2]*(31-desaturation)+ gray*desaturation)/31;
|
||||
}
|
||||
return changed;
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets the light for a sprite - takes dynamic lights into account
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static int gl_SetSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec,
|
||||
int lightlevel, int rellight, FColormap * cm, float alpha,
|
||||
PalEntry ThingColor, bool weapon)
|
||||
void gl_SetDynSpriteLight(AActor *thing, particle_t *particle)
|
||||
{
|
||||
float r,g,b;
|
||||
float result[4]; // Korshun.
|
||||
|
||||
gl_GetLightColor(lightlevel, rellight, cm, &r, &g, &b, weapon);
|
||||
bool res = gl_GetSpriteLight(self, x, y, z, subsec, cm? cm->colormap : 0, result);
|
||||
if (!res || glset.lightmode == 8)
|
||||
if (thing != NULL)
|
||||
{
|
||||
r *= ThingColor.r/255.f;
|
||||
g *= ThingColor.g/255.f;
|
||||
b *= ThingColor.b/255.f;
|
||||
glColor4f(r, g, b, alpha);
|
||||
if (glset.lightmode == 8)
|
||||
{
|
||||
glVertexAttrib1f(VATTR_LIGHTLEVEL, gl_CalcLightLevel(lightlevel, rellight, weapon) / 255.0f); // Korshun.
|
||||
gl_RenderState.SetDynLight(result[0], result[1], result[2]);
|
||||
}
|
||||
return lightlevel;
|
||||
gl_SetDynSpriteLight(thing, thing->x, thing->y, thing->z + (thing->height >> 1), thing->subsector);
|
||||
}
|
||||
else
|
||||
else if (particle != NULL)
|
||||
{
|
||||
// Note: Due to subtractive lights the values can easily become negative so we have to clamp both
|
||||
// at the low and top end of the range!
|
||||
r = clamp<float>(result[0]+r, 0, 1.0f);
|
||||
g = clamp<float>(result[1]+g, 0, 1.0f);
|
||||
b = clamp<float>(result[2]+b, 0, 1.0f);
|
||||
|
||||
float dlightlevel = r*77 + g*143 + b*35;
|
||||
|
||||
r *= ThingColor.r/255.f;
|
||||
g *= ThingColor.g/255.f;
|
||||
b *= ThingColor.b/255.f;
|
||||
|
||||
glColor4f(r, g, b, alpha);
|
||||
|
||||
if (dlightlevel == 0) return 0;
|
||||
|
||||
if (glset.lightmode&2 && dlightlevel<192.f)
|
||||
{
|
||||
return xs_CRoundToInt(192.f - (192.f - dlightlevel) / 1.95f);
|
||||
}
|
||||
else
|
||||
{
|
||||
return xs_CRoundToInt(dlightlevel);
|
||||
}
|
||||
gl_SetDynSpriteLight(NULL, particle->x, particle->y, particle->z, particle->subsector);
|
||||
}
|
||||
}
|
||||
|
||||
int gl_SetSpriteLight(AActor * thing, int lightlevel, int rellight, FColormap * cm,
|
||||
float alpha, PalEntry ThingColor, bool weapon)
|
||||
{
|
||||
subsector_t * subsec = thing->subsector;
|
||||
return gl_SetSpriteLight(thing, thing->x, thing->y, thing->z+(thing->height>>1), subsec,
|
||||
lightlevel, rellight, cm, alpha, ThingColor, weapon);
|
||||
}
|
||||
|
||||
int gl_SetSpriteLight(particle_t * thing, int lightlevel, int rellight, FColormap *cm, float alpha, PalEntry ThingColor)
|
||||
{
|
||||
return gl_SetSpriteLight(NULL, thing->x, thing->y, thing->z, thing->subsector, lightlevel, rellight,
|
||||
cm, alpha, ThingColor, false);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Modifies the color values depending on the render style
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_GetSpriteLighting(FRenderStyle style, AActor *thing, FColormap *cm, PalEntry &ThingColor)
|
||||
{
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
cm->colormap = CM_SHADE;
|
||||
}
|
||||
if (style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
if (style.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
ThingColor = PalEntry(thing->fillcolor).InverseColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
ThingColor = thing->fillcolor;
|
||||
}
|
||||
}
|
||||
|
||||
// This doesn't work like in the software renderer.
|
||||
if (style.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
int gray = (cm->LightColor.r*77 + cm->LightColor.r*143 + cm->LightColor.r*36)>>8;
|
||||
cm->LightColor.r = cm->LightColor.g = cm->LightColor.b = gray;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets render state to draw the given render style
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int gl_SetSpriteLighting(FRenderStyle style, AActor *thing, int lightlevel, int rellight, FColormap *cm,
|
||||
PalEntry ThingColor, float alpha, bool fullbright, bool weapon)
|
||||
{
|
||||
FColormap internal_cm;
|
||||
|
||||
if (style.Flags & STYLEF_RedIsAlpha)
|
||||
{
|
||||
cm->colormap = CM_SHADE;
|
||||
}
|
||||
if (style.Flags & STYLEF_ColorIsFixed)
|
||||
{
|
||||
if (style.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
ThingColor = PalEntry(thing->fillcolor).InverseColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
ThingColor = thing->fillcolor;
|
||||
}
|
||||
gl_ModifyColor(ThingColor.r, ThingColor.g, ThingColor.b, cm->colormap);
|
||||
}
|
||||
|
||||
// This doesn't work like in the software renderer.
|
||||
if (style.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
internal_cm = *cm;
|
||||
cm = &internal_cm;
|
||||
|
||||
int gray = (internal_cm.LightColor.r*77 + internal_cm.LightColor.r*143 + internal_cm.LightColor.r*36)>>8;
|
||||
cm->LightColor.r = cm->LightColor.g = cm->LightColor.b = gray;
|
||||
}
|
||||
|
||||
if (style.BlendOp == STYLEOP_Shadow)
|
||||
{
|
||||
glColor4f(0.2f * ThingColor.r / 255.f, 0.2f * ThingColor.g / 255.f,
|
||||
0.2f * ThingColor.b / 255.f, (alpha = 0.33f));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gl_light_sprites && gl_lights && GLRenderer->mLightCount && !fullbright)
|
||||
{
|
||||
lightlevel = gl_SetSpriteLight(thing, lightlevel, rellight, cm, alpha, ThingColor, weapon);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_SetColor(lightlevel, rellight, cm, alpha, ThingColor, weapon);
|
||||
}
|
||||
}
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,alpha*gl_mask_sprite_threshold);
|
||||
return lightlevel;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
|
|
@ -53,7 +54,6 @@
|
|||
#include "gl/utility/gl_templates.h"
|
||||
|
||||
EXTERN_CVAR(Bool, gl_seamless)
|
||||
extern int vertexcount;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
@ -61,7 +61,7 @@ extern int vertexcount;
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SplitUpperEdge(texcoord * tcs)
|
||||
void GLWall::SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
{
|
||||
if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return;
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ void GLWall::SplitUpperEdge(texcoord * tcs)
|
|||
float facc = (zceil[1] - zceil[0]) / polyw;
|
||||
float facf = (zfloor[1] - zfloor[0]) / polyw;
|
||||
|
||||
for (int i=0; i < sidedef->numsegs - 1; i++)
|
||||
for (int i = 0; i < sidedef->numsegs - 1; i++)
|
||||
{
|
||||
seg_t *cseg = sidedef->segs[i];
|
||||
float sidefrac = cseg->sidefrac;
|
||||
|
|
@ -82,10 +82,13 @@ void GLWall::SplitUpperEdge(texcoord * tcs)
|
|||
|
||||
float fracfac = sidefrac - glseg.fracleft;
|
||||
|
||||
glTexCoord2f(tcs[1].u + facu * fracfac, tcs[1].v + facv * fracfac);
|
||||
glVertex3f(cseg->v2->fx, ztop[0] + fact * fracfac, cseg->v2->fy);
|
||||
ptr->x = cseg->v2->fx;
|
||||
ptr->y = cseg->v2->fy;
|
||||
ptr->z = ztop[0] + fact * fracfac;
|
||||
ptr->u = tcs[1].u + facu * fracfac;
|
||||
ptr->v = tcs[1].v + facv * fracfac;
|
||||
ptr++;
|
||||
}
|
||||
vertexcount += sidedef->numsegs-1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -94,7 +97,7 @@ void GLWall::SplitUpperEdge(texcoord * tcs)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SplitLowerEdge(texcoord * tcs)
|
||||
void GLWall::SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
{
|
||||
if (seg == NULL || seg->sidedef == NULL || (seg->sidedef->Flags & WALLF_POLYOBJ) || seg->sidedef->numsegs == 1) return;
|
||||
|
||||
|
|
@ -106,7 +109,7 @@ void GLWall::SplitLowerEdge(texcoord * tcs)
|
|||
float facc = (zceil[1] - zceil[0]) / polyw;
|
||||
float facf = (zfloor[1] - zfloor[0]) / polyw;
|
||||
|
||||
for (int i = sidedef->numsegs-2; i >= 0; i--)
|
||||
for (int i = sidedef->numsegs - 2; i >= 0; i--)
|
||||
{
|
||||
seg_t *cseg = sidedef->segs[i];
|
||||
float sidefrac = cseg->sidefrac;
|
||||
|
|
@ -115,10 +118,13 @@ void GLWall::SplitLowerEdge(texcoord * tcs)
|
|||
|
||||
float fracfac = sidefrac - glseg.fracleft;
|
||||
|
||||
glTexCoord2f(tcs[0].u + facu * fracfac, tcs[0].v + facv * fracfac);
|
||||
glVertex3f(cseg->v2->fx, zbottom[0] + facb * fracfac, cseg->v2->fy);
|
||||
ptr->x = cseg->v2->fx;
|
||||
ptr->y = cseg->v2->fy;
|
||||
ptr->z = zbottom[0] + facb * fracfac;
|
||||
ptr->u = tcs[0].u + facu * fracfac;
|
||||
ptr->v = tcs[0].v + facv * fracfac;
|
||||
ptr++;
|
||||
}
|
||||
vertexcount += sidedef->numsegs-1;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -127,29 +133,31 @@ void GLWall::SplitLowerEdge(texcoord * tcs)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SplitLeftEdge(texcoord * tcs)
|
||||
void GLWall::SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
{
|
||||
if (vertexes[0]==NULL) return;
|
||||
if (vertexes[0] == NULL) return;
|
||||
|
||||
vertex_t * vi=vertexes[0];
|
||||
vertex_t * vi = vertexes[0];
|
||||
|
||||
if (vi->numheights)
|
||||
{
|
||||
int i=0;
|
||||
int i = 0;
|
||||
|
||||
float polyh1=ztop[0] - zbottom[0];
|
||||
float factv1=polyh1? (tcs[1].v - tcs[0].v) / polyh1:0;
|
||||
float factu1=polyh1? (tcs[1].u - tcs[0].u) / polyh1:0;
|
||||
float polyh1 = ztop[0] - zbottom[0];
|
||||
float factv1 = polyh1 ? (tcs[1].v - tcs[0].v) / polyh1 : 0;
|
||||
float factu1 = polyh1 ? (tcs[1].u - tcs[0].u) / polyh1 : 0;
|
||||
|
||||
while (i<vi->numheights && vi->heightlist[i] <= zbottom[0] ) i++;
|
||||
while (i<vi->numheights && vi->heightlist[i] <= zbottom[0]) i++;
|
||||
while (i<vi->numheights && vi->heightlist[i] < ztop[0])
|
||||
{
|
||||
glTexCoord2f(factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u,
|
||||
factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v);
|
||||
glVertex3f(glseg.x1, vi->heightlist[i], glseg.y1);
|
||||
ptr->x = glseg.x1;
|
||||
ptr->y = glseg.y1;
|
||||
ptr->z = vi->heightlist[i];
|
||||
ptr->u = factu1*(vi->heightlist[i] - ztop[0]) + tcs[1].u;
|
||||
ptr->v = factv1*(vi->heightlist[i] - ztop[0]) + tcs[1].v;
|
||||
ptr++;
|
||||
i++;
|
||||
}
|
||||
vertexcount+=i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -159,29 +167,31 @@ void GLWall::SplitLeftEdge(texcoord * tcs)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::SplitRightEdge(texcoord * tcs)
|
||||
void GLWall::SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr)
|
||||
{
|
||||
if (vertexes[1]==NULL) return;
|
||||
if (vertexes[1] == NULL) return;
|
||||
|
||||
vertex_t * vi=vertexes[1];
|
||||
vertex_t * vi = vertexes[1];
|
||||
|
||||
if (vi->numheights)
|
||||
{
|
||||
int i=vi->numheights-1;
|
||||
int i = vi->numheights - 1;
|
||||
|
||||
float polyh2 = ztop[1] - zbottom[1];
|
||||
float factv2 = polyh2? (tcs[2].v - tcs[3].v) / polyh2:0;
|
||||
float factu2 = polyh2? (tcs[2].u - tcs[3].u) / polyh2:0;
|
||||
float factv2 = polyh2 ? (tcs[2].v - tcs[3].v) / polyh2 : 0;
|
||||
float factu2 = polyh2 ? (tcs[2].u - tcs[3].u) / polyh2 : 0;
|
||||
|
||||
while (i>0 && vi->heightlist[i] >= ztop[1]) i--;
|
||||
while (i>0 && vi->heightlist[i] > zbottom[1])
|
||||
{
|
||||
glTexCoord2f(factu2 * (vi->heightlist[i] - ztop[1]) + tcs[2].u,
|
||||
factv2 * (vi->heightlist[i] - ztop[1]) + tcs[2].v);
|
||||
glVertex3f(glseg.x2, vi->heightlist[i], glseg.y2);
|
||||
ptr->x = glseg.x2;
|
||||
ptr->y = glseg.y2;
|
||||
ptr->z = vi->heightlist[i];
|
||||
ptr->u = factu2*(vi->heightlist[i] - ztop[1]) + tcs[2].u;
|
||||
ptr->v = factv2*(vi->heightlist[i] - ztop[1]) + tcs[2].v;
|
||||
ptr++;
|
||||
i--;
|
||||
}
|
||||
vertexcount+=i;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ struct GLDrawList;
|
|||
struct GLSkyInfo;
|
||||
struct FTexCoordInfo;
|
||||
struct FPortal;
|
||||
struct FFlatVertex;
|
||||
|
||||
|
||||
enum WallTypes
|
||||
|
|
@ -38,7 +39,6 @@ enum WallTypes
|
|||
RENDERWALL_MIRROR,
|
||||
RENDERWALL_MIRRORSURFACE,
|
||||
RENDERWALL_M2SNF,
|
||||
RENDERWALL_M2SFOG,
|
||||
RENDERWALL_COLOR,
|
||||
RENDERWALL_FFBLOCK,
|
||||
RENDERWALL_COLORLAYER,
|
||||
|
|
@ -96,13 +96,22 @@ public:
|
|||
//GLWF_CLAMPX=1, use GLT_* for these!
|
||||
//GLWF_CLAMPY=2,
|
||||
GLWF_SKYHACK=4,
|
||||
GLWF_FOGGY=8,
|
||||
GLWF_GLOW=16, // illuminated by glowing flats
|
||||
GLWF_NOSHADER=32, // cannot be drawn with shaders.
|
||||
GLWF_NOSPLITUPPER=64,
|
||||
GLWF_NOSPLITLOWER=128,
|
||||
GLWF_GLOW=8, // illuminated by glowing flats
|
||||
GLWF_NOSPLITUPPER=16,
|
||||
GLWF_NOSPLITLOWER=32,
|
||||
GLWF_NOSPLIT=64,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
RWF_BLANK = 0,
|
||||
RWF_TEXTURED = 1, // actually not being used anymore because with buffers it's even less efficient not writing the texture coordinates - but leave it here
|
||||
RWF_GLOW = 2,
|
||||
RWF_NOSPLIT = 4,
|
||||
RWF_NORENDER = 8,
|
||||
};
|
||||
|
||||
|
||||
friend struct GLDrawList;
|
||||
friend class GLPortal;
|
||||
|
||||
|
|
@ -126,7 +135,7 @@ public:
|
|||
float topglowcolor[4];
|
||||
float bottomglowcolor[4];
|
||||
|
||||
int firstdynlight, lastdynlight;
|
||||
int dynlightindex;
|
||||
int firstwall, numwalls; // splitting info.
|
||||
|
||||
union
|
||||
|
|
@ -158,7 +167,7 @@ private:
|
|||
|
||||
void SetupLights();
|
||||
bool PrepareLight(texcoord * tcs, ADynamicLight * light);
|
||||
void RenderWall(int textured, float * color2, ADynamicLight * light=NULL);
|
||||
void RenderWall(int textured, unsigned int *store = NULL);
|
||||
|
||||
void FloodPlane(int pass);
|
||||
|
||||
|
|
@ -210,10 +219,10 @@ private:
|
|||
void RenderMirrorSurface();
|
||||
void RenderTranslucentWall();
|
||||
|
||||
void SplitLeftEdge(texcoord * tcs);
|
||||
void SplitRightEdge(texcoord * tcs);
|
||||
void SplitUpperEdge(texcoord * tcs);
|
||||
void SplitLowerEdge(texcoord * tcs);
|
||||
void SplitLeftEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitRightEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitUpperEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
void SplitLowerEdge(texcoord * tcs, FFlatVertex *&ptr);
|
||||
|
||||
public:
|
||||
|
||||
|
|
@ -270,16 +279,17 @@ public:
|
|||
|
||||
int dynlightindex;
|
||||
|
||||
bool SetupSubsectorLights(bool lightsapplied, subsector_t * sub);
|
||||
void SetupSubsectorLights(int pass, subsector_t * sub, int *dli = NULL);
|
||||
void DrawSubsector(subsector_t * sub);
|
||||
void DrawSubsectorLights(subsector_t * sub, int pass);
|
||||
void DrawSubsectors(int pass, bool istrans);
|
||||
void DrawSubsectors(int pass, bool processlights, bool istrans);
|
||||
void ProcessLights(bool istrans);
|
||||
|
||||
void PutFlat(bool fog = false);
|
||||
void Process(sector_t * model, int whichplane, bool notexture);
|
||||
void SetFrom3DFloor(F3DFloor *rover, bool top, bool underside);
|
||||
void ProcessSector(sector_t * frontsector);
|
||||
void Draw(int pass);
|
||||
void Draw(int pass, bool trans);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -346,20 +356,7 @@ inline float Dist2(float x1,float y1,float x2,float y2)
|
|||
|
||||
// Light + color
|
||||
|
||||
bool gl_GetSpriteLight(AActor *Self, fixed_t x, fixed_t y, fixed_t z, subsector_t * subsec, int desaturation, float * out, line_t *line = NULL, int side = 0);
|
||||
int gl_SetSpriteLight(AActor * thing, int lightlevel, int rellight, FColormap * cm, float alpha, PalEntry ThingColor = 0xffffff, bool weapon=false);
|
||||
|
||||
void gl_GetSpriteLight(AActor * thing, int lightlevel, int rellight, FColormap * cm,
|
||||
float *red, float *green, float *blue,
|
||||
PalEntry ThingColor, bool weapon);
|
||||
|
||||
int gl_SetSpriteLighting(FRenderStyle style, AActor *thing, int lightlevel, int rellight, FColormap *cm,
|
||||
PalEntry ThingColor, float alpha, bool fullbright, bool weapon);
|
||||
|
||||
int gl_SetSpriteLight(particle_t * thing, int lightlevel, int rellight, FColormap *cm, float alpha, PalEntry ThingColor = 0xffffff);
|
||||
void gl_GetLightForThing(AActor * thing, float upper, float lower, float & r, float & g, float & b);
|
||||
|
||||
|
||||
|
||||
void gl_SetDynSpriteLight(AActor *self, fixed_t x, fixed_t y, fixed_t z, subsector_t *subsec);
|
||||
void gl_SetDynSpriteLight(AActor *actor, particle_t *particle);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -53,7 +53,6 @@
|
|||
#include "gl/data/gl_data.h"
|
||||
#include "gl/dynlights/gl_dynlight.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
|
|
@ -71,7 +70,7 @@
|
|||
void GLWall::CheckGlowing()
|
||||
{
|
||||
bottomglowcolor[3] = topglowcolor[3] = 0;
|
||||
if (!gl_isFullbright(Colormap.LightColor, lightlevel) && gl_GlowActive())
|
||||
if (!gl_isFullbright(Colormap.LightColor, lightlevel))
|
||||
{
|
||||
FTexture *tex = TexMan[topflat];
|
||||
if (tex != NULL && tex->isGlowing())
|
||||
|
|
@ -115,9 +114,8 @@ void GLWall::PutWall(bool translucent)
|
|||
4, //RENDERWALL_SECTORSTACK, // special
|
||||
4, //RENDERWALL_PLANEMIRROR, // special
|
||||
4, //RENDERWALL_MIRROR, // special
|
||||
1, //RENDERWALL_MIRRORSURFACE, // needs special handling
|
||||
2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog
|
||||
2, //RENDERWALL_M2SFOG, // depends on render and texture settings, no fog
|
||||
1, //RENDERWALL_MIRRORSURFACE, // only created here from RENDERWALL_MIRROR
|
||||
2, //RENDERWALL_M2SNF, // depends on render and texture settings, no fog, used on mid texture lines with a fog boundary.
|
||||
3, //RENDERWALL_COLOR, // translucent
|
||||
2, //RENDERWALL_FFBLOCK // depends on render and texture settings
|
||||
4, //RENDERWALL_COLORLAYER // color layer needs special handling
|
||||
|
|
@ -133,7 +131,7 @@ void GLWall::PutWall(bool translucent)
|
|||
// light planes don't get drawn with fullbright rendering
|
||||
if (!gltexture && passflag[type]!=4) return;
|
||||
|
||||
Colormap.GetFixedColormap();
|
||||
Colormap.Clear();
|
||||
}
|
||||
|
||||
CheckGlowing();
|
||||
|
|
@ -146,46 +144,18 @@ void GLWall::PutWall(bool translucent)
|
|||
}
|
||||
else if (passflag[type]!=4) // non-translucent walls
|
||||
{
|
||||
static DrawListType list_indices[2][2][2]={
|
||||
{ { GLDL_PLAIN, GLDL_FOG }, { GLDL_MASKED, GLDL_FOGMASKED } },
|
||||
{ { GLDL_LIGHT, GLDL_LIGHTFOG }, { GLDL_LIGHTMASKED, GLDL_LIGHTFOGMASKED } }
|
||||
};
|
||||
|
||||
bool masked;
|
||||
bool light = gl_forcemultipass;
|
||||
|
||||
if (!gl_fixedcolormap)
|
||||
masked = passflag[type]==1? false : (gltexture && gltexture->isMasked());
|
||||
|
||||
if ((flags&GLWF_SKYHACK && type == RENDERWALL_M2S))
|
||||
{
|
||||
if (gl_lights && !gl_dynlight_shader)
|
||||
{
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
light = false;
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
light = seg->sidedef->lighthead[0] != NULL;
|
||||
}
|
||||
else if (sub)
|
||||
{
|
||||
// for polyobjects we cannot use the side's light list.
|
||||
// We must use the subsector's.
|
||||
light = sub->lighthead[0] != NULL;
|
||||
}
|
||||
}
|
||||
list = GLDL_MASKEDWALLSOFS;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
flags&=~GLWF_FOGGY;
|
||||
}
|
||||
|
||||
masked = passflag[type]==1? false : (light && type!=RENDERWALL_FFBLOCK) || (gltexture && gltexture->isMasked());
|
||||
|
||||
list = list_indices[light][masked][!!(flags&GLWF_FOGGY)];
|
||||
if (list == GLDL_LIGHT)
|
||||
{
|
||||
if (gltexture->tex->gl_info.Brightmap && gl_BrightmapsActive()) list = GLDL_LIGHTBRIGHT;
|
||||
if (flags & GLWF_GLOW) list = GLDL_LIGHTBRIGHT;
|
||||
list = masked ? GLDL_MASKEDWALLS : GLDL_PLAINWALLS;
|
||||
}
|
||||
gl_drawinfo->drawlists[list].AddWall(this);
|
||||
|
||||
|
|
@ -193,7 +163,7 @@ void GLWall::PutWall(bool translucent)
|
|||
else switch (type)
|
||||
{
|
||||
case RENDERWALL_COLORLAYER:
|
||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENT].AddWall(this);
|
||||
gl_drawinfo->drawlists[GLDL_TRANSLUCENTBORDER].AddWall(this);
|
||||
break;
|
||||
|
||||
// portals don't go into the draw list.
|
||||
|
|
@ -520,7 +490,7 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
|
|||
hi.colormap.LightColor = (light->extra_colormap)->Color;
|
||||
}
|
||||
|
||||
if (gl_fixedcolormap) hi.colormap.GetFixedColormap();
|
||||
if (gl_fixedcolormap) hi.colormap.Clear();
|
||||
horizon = &hi;
|
||||
PutWall(0);
|
||||
}
|
||||
|
|
@ -549,8 +519,8 @@ bool GLWall::DoHorizon(seg_t * seg,sector_t * fs, vertex_t * v1,vertex_t * v2)
|
|||
hi.colormap.LightColor = (light->extra_colormap)->Color;
|
||||
}
|
||||
|
||||
if (gl_fixedcolormap) hi.colormap.GetFixedColormap();
|
||||
horizon=&hi;
|
||||
if (gl_fixedcolormap) hi.colormap.Clear();
|
||||
horizon = &hi;
|
||||
PutWall(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -808,12 +778,12 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
if ( (seg->linedef->flags & ML_DONTPEGBOTTOM) >0)
|
||||
{
|
||||
texturebottom = MAX(realfront->GetPlaneTexZ(sector_t::floor),realback->GetPlaneTexZ(sector_t::floor))+rowoffset;
|
||||
texturetop=texturebottom+(gltexture->TextureHeight(GLUSE_TEXTURE)<<FRACBITS);
|
||||
texturetop=texturebottom+(gltexture->TextureHeight()<<FRACBITS);
|
||||
}
|
||||
else
|
||||
{
|
||||
texturetop = MIN(realfront->GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling))+rowoffset;
|
||||
texturebottom=texturetop-(gltexture->TextureHeight(GLUSE_TEXTURE)<<FRACBITS);
|
||||
texturebottom=texturetop-(gltexture->TextureHeight()<<FRACBITS);
|
||||
}
|
||||
}
|
||||
else texturetop=texturebottom=0;
|
||||
|
|
@ -940,8 +910,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
fixed_t textureoffset = tci.TextureOffset(t_ofs);
|
||||
int righttex=(textureoffset>>FRACBITS)+seg->sidedef->TexelLength;
|
||||
|
||||
if ((textureoffset==0 && righttex<=gltexture->TextureWidth(GLUSE_TEXTURE)) ||
|
||||
(textureoffset>=0 && righttex==gltexture->TextureWidth(GLUSE_TEXTURE)))
|
||||
if ((textureoffset==0 && righttex<=gltexture->TextureWidth()) ||
|
||||
(textureoffset>=0 && righttex==gltexture->TextureWidth()))
|
||||
{
|
||||
flags|=GLT_CLAMPX;
|
||||
}
|
||||
|
|
@ -1009,6 +979,7 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
//
|
||||
FloatRect *splitrect;
|
||||
int v = gltexture->GetAreas(&splitrect);
|
||||
if (seg->frontsector == seg->backsector) flags |= GLWF_NOSPLIT; // we don't need to do vertex splits if a line has both sides in the same sector
|
||||
if (v>0 && !drawfogboundary && !(seg->linedef->flags&ML_WRAP_MIDTEX))
|
||||
{
|
||||
// split the poly!
|
||||
|
|
@ -1118,19 +1089,19 @@ void GLWall::BuildFFBlock(seg_t * seg, F3DFloor * rover,
|
|||
|
||||
if (rover->flags&FF_UPPERTEXTURE)
|
||||
{
|
||||
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), true);
|
||||
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true);
|
||||
if (!gltexture) return;
|
||||
gltexture->GetTexCoordInfo(&tci, seg->sidedef->GetTextureXScale(side_t::top), seg->sidedef->GetTextureYScale(side_t::top));
|
||||
}
|
||||
else if (rover->flags&FF_LOWERTEXTURE)
|
||||
{
|
||||
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true);
|
||||
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true);
|
||||
if (!gltexture) return;
|
||||
gltexture->GetTexCoordInfo(&tci, seg->sidedef->GetTextureXScale(side_t::bottom), seg->sidedef->GetTextureYScale(side_t::bottom));
|
||||
}
|
||||
else
|
||||
{
|
||||
gltexture = FMaterial::ValidateTexture(mastersd->GetTexture(side_t::mid), true);
|
||||
gltexture = FMaterial::ValidateTexture(mastersd->GetTexture(side_t::mid), false, true);
|
||||
if (!gltexture) return;
|
||||
gltexture->GetTexCoordInfo(&tci, mastersd->GetTextureXScale(side_t::mid), mastersd->GetTextureYScale(side_t::mid));
|
||||
}
|
||||
|
|
@ -1432,7 +1403,7 @@ void GLWall::DoFFloorBlocks(seg_t * seg,sector_t * frontsector,sector_t * backse
|
|||
//==========================================================================
|
||||
void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||
{
|
||||
vertex_t * v1, * v2;
|
||||
vertex_t * v1, *v2;
|
||||
fixed_t fch1;
|
||||
fixed_t ffh1;
|
||||
fixed_t fch2;
|
||||
|
|
@ -1446,7 +1417,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
int a = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// note: we always have a valid sidedef and linedef reference when getting here.
|
||||
|
||||
this->seg = seg;
|
||||
|
|
@ -1461,24 +1432,24 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
{
|
||||
// Need these for aligning the textures
|
||||
realfront = §ors[frontsector->sectornum];
|
||||
realback = backsector? §ors[backsector->sectornum] : NULL;
|
||||
realback = backsector ? §ors[backsector->sectornum] : NULL;
|
||||
}
|
||||
|
||||
if (seg->sidedef == seg->linedef->sidedef[0])
|
||||
{
|
||||
v1=seg->linedef->v1;
|
||||
v2=seg->linedef->v2;
|
||||
v1 = seg->linedef->v1;
|
||||
v2 = seg->linedef->v2;
|
||||
}
|
||||
else
|
||||
{
|
||||
v1=seg->linedef->v2;
|
||||
v2=seg->linedef->v1;
|
||||
v1 = seg->linedef->v2;
|
||||
v2 = seg->linedef->v1;
|
||||
}
|
||||
|
||||
if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
glseg.fracleft=0;
|
||||
glseg.fracright=1;
|
||||
glseg.fracleft = 0;
|
||||
glseg.fracright = 1;
|
||||
if (gl_seamless)
|
||||
{
|
||||
if (v1->dirty) gl_RecalcVertexHeights(v1);
|
||||
|
|
@ -1487,40 +1458,42 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
}
|
||||
else // polyobjects must be rendered per seg.
|
||||
{
|
||||
if (abs(v1->x-v2->x) > abs(v1->y-v2->y))
|
||||
if (abs(v1->x - v2->x) > abs(v1->y - v2->y))
|
||||
{
|
||||
glseg.fracleft = float(seg->v1->x - v1->x)/float(v2->x-v1->x);
|
||||
glseg.fracright = float(seg->v2->x - v1->x)/float(v2->x-v1->x);
|
||||
glseg.fracleft = float(seg->v1->x - v1->x) / float(v2->x - v1->x);
|
||||
glseg.fracright = float(seg->v2->x - v1->x) / float(v2->x - v1->x);
|
||||
}
|
||||
else
|
||||
{
|
||||
glseg.fracleft = float(seg->v1->y - v1->y)/float(v2->y-v1->y);
|
||||
glseg.fracright = float(seg->v2->y - v1->y)/float(v2->y-v1->y);
|
||||
glseg.fracleft = float(seg->v1->y - v1->y) / float(v2->y - v1->y);
|
||||
glseg.fracright = float(seg->v2->y - v1->y) / float(v2->y - v1->y);
|
||||
}
|
||||
v1=seg->v1;
|
||||
v2=seg->v2;
|
||||
v1 = seg->v1;
|
||||
v2 = seg->v2;
|
||||
}
|
||||
|
||||
|
||||
vertexes[0]=v1;
|
||||
vertexes[1]=v2;
|
||||
vertexes[0] = v1;
|
||||
vertexes[1] = v2;
|
||||
|
||||
glseg.x1= FIXED2FLOAT(v1->x);
|
||||
glseg.y1= FIXED2FLOAT(v1->y);
|
||||
glseg.x2= FIXED2FLOAT(v2->x);
|
||||
glseg.y2= FIXED2FLOAT(v2->y);
|
||||
Colormap=frontsector->ColorMap;
|
||||
flags = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE)? GLWF_FOGGY : 0;
|
||||
glseg.x1 = FIXED2FLOAT(v1->x);
|
||||
glseg.y1 = FIXED2FLOAT(v1->y);
|
||||
glseg.x2 = FIXED2FLOAT(v2->x);
|
||||
glseg.y2 = FIXED2FLOAT(v2->y);
|
||||
Colormap = frontsector->ColorMap;
|
||||
flags = 0;
|
||||
dynlightindex = UINT_MAX;
|
||||
|
||||
int rel = 0;
|
||||
int orglightlevel = gl_ClampLight(frontsector->lightlevel);
|
||||
lightlevel = gl_ClampLight(seg->sidedef->GetLightLevel(!!(flags&GLWF_FOGGY), orglightlevel, false, &rel));
|
||||
bool foggy = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE); // fog disables fake contrast
|
||||
lightlevel = gl_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, false, &rel));
|
||||
if (orglightlevel >= 253) // with the software renderer fake contrast won't be visible above this.
|
||||
{
|
||||
rellight = 0;
|
||||
rellight = 0;
|
||||
}
|
||||
else if (lightlevel - rel > 256) // the brighter part of fake contrast will be clamped so also clamp the darker part by the same amount for better looks
|
||||
{
|
||||
{
|
||||
rellight = 256 - lightlevel + rel;
|
||||
}
|
||||
else
|
||||
|
|
@ -1528,35 +1501,35 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
rellight = rel;
|
||||
}
|
||||
|
||||
alpha=1.0f;
|
||||
RenderStyle=STYLE_Normal;
|
||||
gltexture=NULL;
|
||||
alpha = 1.0f;
|
||||
RenderStyle = STYLE_Normal;
|
||||
gltexture = NULL;
|
||||
|
||||
topflat=frontsector->GetTexture(sector_t::ceiling); // for glowing textures. These must be saved because
|
||||
bottomflat=frontsector->GetTexture(sector_t::floor); // the sector passed here might be a temporary copy.
|
||||
topflat = frontsector->GetTexture(sector_t::ceiling); // for glowing textures. These must be saved because
|
||||
bottomflat = frontsector->GetTexture(sector_t::floor); // the sector passed here might be a temporary copy.
|
||||
topplane = frontsector->ceilingplane;
|
||||
bottomplane = frontsector->floorplane;
|
||||
|
||||
// Save a little time (up to 0.3 ms per frame ;) )
|
||||
if (frontsector->floorplane.a | frontsector->floorplane.b)
|
||||
{
|
||||
ffh1=frontsector->floorplane.ZatPoint(v1);
|
||||
ffh2=frontsector->floorplane.ZatPoint(v2);
|
||||
zfloor[0]=FIXED2FLOAT(ffh1);
|
||||
zfloor[1]=FIXED2FLOAT(ffh2);
|
||||
ffh1 = frontsector->floorplane.ZatPoint(v1);
|
||||
ffh2 = frontsector->floorplane.ZatPoint(v2);
|
||||
zfloor[0] = FIXED2FLOAT(ffh1);
|
||||
zfloor[1] = FIXED2FLOAT(ffh2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffh1 = ffh2 = -frontsector->floorplane.d;
|
||||
ffh1 = ffh2 = -frontsector->floorplane.d;
|
||||
zfloor[0] = zfloor[1] = FIXED2FLOAT(ffh2);
|
||||
}
|
||||
|
||||
if (frontsector->ceilingplane.a | frontsector->ceilingplane.b)
|
||||
{
|
||||
fch1=frontsector->ceilingplane.ZatPoint(v1);
|
||||
fch2=frontsector->ceilingplane.ZatPoint(v2);
|
||||
zceil[0]= FIXED2FLOAT(fch1);
|
||||
zceil[1]= FIXED2FLOAT(fch2);
|
||||
fch1 = frontsector->ceilingplane.ZatPoint(v1);
|
||||
fch2 = frontsector->ceilingplane.ZatPoint(v2);
|
||||
zceil[0] = FIXED2FLOAT(fch1);
|
||||
zceil[1] = FIXED2FLOAT(fch2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1565,27 +1538,27 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
}
|
||||
|
||||
|
||||
if (seg->linedef->special==Line_Horizon)
|
||||
if (seg->linedef->special == Line_Horizon)
|
||||
{
|
||||
SkyNormal(frontsector,v1,v2);
|
||||
DoHorizon(seg,frontsector, v1,v2);
|
||||
SkyNormal(frontsector, v1, v2);
|
||||
DoHorizon(seg, frontsector, v1, v2);
|
||||
return;
|
||||
}
|
||||
|
||||
//return;
|
||||
// [GZ] 3D middle textures are necessarily two-sided, even if they lack the explicit two-sided flag
|
||||
if (!backsector || !(seg->linedef->flags&(ML_TWOSIDED|ML_3DMIDTEX))) // one sided
|
||||
if (!backsector || !(seg->linedef->flags&(ML_TWOSIDED | ML_3DMIDTEX))) // one sided
|
||||
{
|
||||
// sector's sky
|
||||
SkyNormal(frontsector,v1,v2);
|
||||
|
||||
SkyNormal(frontsector, v1, v2);
|
||||
|
||||
// normal texture
|
||||
gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), true);
|
||||
if (gltexture)
|
||||
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::mid), false, true);
|
||||
if (gltexture)
|
||||
{
|
||||
DoTexture(RENDERWALL_M1S,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0,
|
||||
realfront->GetPlaneTexZ(sector_t::ceiling),realfront->GetPlaneTexZ(sector_t::floor), // must come from the original!
|
||||
fch1,fch2,ffh1,ffh2,0);
|
||||
DoTexture(RENDERWALL_M1S, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
|
||||
realfront->GetPlaneTexZ(sector_t::ceiling), realfront->GetPlaneTexZ(sector_t::floor), // must come from the original!
|
||||
fch1, fch2, ffh1, ffh2, 0);
|
||||
}
|
||||
}
|
||||
else // two sided
|
||||
|
|
@ -1598,8 +1571,8 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
|
||||
if (backsector->floorplane.a | backsector->floorplane.b)
|
||||
{
|
||||
bfh1=backsector->floorplane.ZatPoint(v1);
|
||||
bfh2=backsector->floorplane.ZatPoint(v2);
|
||||
bfh1 = backsector->floorplane.ZatPoint(v1);
|
||||
bfh2 = backsector->floorplane.ZatPoint(v2);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1608,51 +1581,51 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
|
||||
if (backsector->ceilingplane.a | backsector->ceilingplane.b)
|
||||
{
|
||||
bch1=backsector->ceilingplane.ZatPoint(v1);
|
||||
bch2=backsector->ceilingplane.ZatPoint(v2);
|
||||
bch1 = backsector->ceilingplane.ZatPoint(v1);
|
||||
bch2 = backsector->ceilingplane.ZatPoint(v2);
|
||||
}
|
||||
else
|
||||
{
|
||||
bch1 = bch2 = backsector->ceilingplane.d;
|
||||
}
|
||||
|
||||
SkyTop(seg,frontsector,backsector,v1,v2);
|
||||
SkyBottom(seg,frontsector,backsector,v1,v2);
|
||||
|
||||
SkyTop(seg, frontsector, backsector, v1, v2);
|
||||
SkyBottom(seg, frontsector, backsector, v1, v2);
|
||||
|
||||
// upper texture
|
||||
if (frontsector->GetTexture(sector_t::ceiling)!=skyflatnum || backsector->GetTexture(sector_t::ceiling)!=skyflatnum)
|
||||
if (frontsector->GetTexture(sector_t::ceiling) != skyflatnum || backsector->GetTexture(sector_t::ceiling) != skyflatnum)
|
||||
{
|
||||
fixed_t bch1a=bch1, bch2a=bch2;
|
||||
if (frontsector->GetTexture(sector_t::floor)!=skyflatnum || backsector->GetTexture(sector_t::floor)!=skyflatnum)
|
||||
fixed_t bch1a = bch1, bch2a = bch2;
|
||||
if (frontsector->GetTexture(sector_t::floor) != skyflatnum || backsector->GetTexture(sector_t::floor) != skyflatnum)
|
||||
{
|
||||
// the back sector's floor obstructs part of this wall
|
||||
if (ffh1>bch1 && ffh2>bch2)
|
||||
if (ffh1 > bch1 && ffh2 > bch2)
|
||||
{
|
||||
bch2a=ffh2;
|
||||
bch1a=ffh1;
|
||||
bch2a = ffh2;
|
||||
bch1a = ffh1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bch1a<fch1 || bch2a<fch2)
|
||||
if (bch1a < fch1 || bch2a < fch2)
|
||||
{
|
||||
gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), true);
|
||||
if (gltexture)
|
||||
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::top), false, true);
|
||||
if (gltexture)
|
||||
{
|
||||
DoTexture(RENDERWALL_TOP,seg,(seg->linedef->flags & (ML_DONTPEGTOP))==0,
|
||||
realfront->GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling),
|
||||
fch1,fch2,bch1a,bch2a,0);
|
||||
DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0,
|
||||
realfront->GetPlaneTexZ(sector_t::ceiling), realback->GetPlaneTexZ(sector_t::ceiling),
|
||||
fch1, fch2, bch1a, bch2a, 0);
|
||||
}
|
||||
else if ((frontsector->ceilingplane.a | frontsector->ceilingplane.b |
|
||||
backsector->ceilingplane.a | backsector->ceilingplane.b) &&
|
||||
frontsector->GetTexture(sector_t::ceiling)!=skyflatnum &&
|
||||
backsector->GetTexture(sector_t::ceiling)!=skyflatnum)
|
||||
else if ((frontsector->ceilingplane.a | frontsector->ceilingplane.b |
|
||||
backsector->ceilingplane.a | backsector->ceilingplane.b) &&
|
||||
frontsector->GetTexture(sector_t::ceiling) != skyflatnum &&
|
||||
backsector->GetTexture(sector_t::ceiling) != skyflatnum)
|
||||
{
|
||||
gltexture=FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), true);
|
||||
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::ceiling), false, true);
|
||||
if (gltexture)
|
||||
{
|
||||
DoTexture(RENDERWALL_TOP,seg,(seg->linedef->flags & (ML_DONTPEGTOP))==0,
|
||||
realfront->GetPlaneTexZ(sector_t::ceiling),realback->GetPlaneTexZ(sector_t::ceiling),
|
||||
fch1,fch2,bch1a,bch2a,0);
|
||||
DoTexture(RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0,
|
||||
realfront->GetPlaneTexZ(sector_t::ceiling), realback->GetPlaneTexZ(sector_t::ceiling),
|
||||
fch1, fch2, bch1a, bch2a, 0);
|
||||
}
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
|
|
@ -1676,58 +1649,58 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
{
|
||||
tex = tex->GetRawTexture();
|
||||
}
|
||||
gltexture=FMaterial::ValidateTexture(tex);
|
||||
gltexture = FMaterial::ValidateTexture(tex, false);
|
||||
}
|
||||
else gltexture = NULL;
|
||||
|
||||
if (gltexture || drawfogboundary)
|
||||
{
|
||||
DoMidTexture(seg, drawfogboundary, frontsector, backsector, realfront, realback,
|
||||
DoMidTexture(seg, drawfogboundary, frontsector, backsector, realfront, realback,
|
||||
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||
}
|
||||
|
||||
if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
||||
if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
|
||||
{
|
||||
DoFFloorBlocks(seg,frontsector,backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||
DoFFloorBlocks(seg, frontsector, backsector, fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2);
|
||||
}
|
||||
|
||||
|
||||
/* bottom texture */
|
||||
// the back sector's ceiling obstructs part of this wall (specially important for sky sectors)
|
||||
if (fch1<bfh1 && fch2<bfh2)
|
||||
{
|
||||
bfh1=fch1;
|
||||
bfh2=fch2;
|
||||
bfh1 = fch1;
|
||||
bfh2 = fch2;
|
||||
}
|
||||
|
||||
if (bfh1>ffh1 || bfh2>ffh2)
|
||||
{
|
||||
gltexture=FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), true);
|
||||
if (gltexture)
|
||||
gltexture = FMaterial::ValidateTexture(seg->sidedef->GetTexture(side_t::bottom), false, true);
|
||||
if (gltexture)
|
||||
{
|
||||
DoTexture(RENDERWALL_BOTTOM,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0,
|
||||
realback->GetPlaneTexZ(sector_t::floor),realfront->GetPlaneTexZ(sector_t::floor),
|
||||
bfh1,bfh2,ffh1,ffh2,
|
||||
frontsector->GetTexture(sector_t::ceiling)==skyflatnum && backsector->GetTexture(sector_t::ceiling)==skyflatnum ?
|
||||
realfront->GetPlaneTexZ(sector_t::floor)-realback->GetPlaneTexZ(sector_t::ceiling) :
|
||||
realfront->GetPlaneTexZ(sector_t::floor)-realfront->GetPlaneTexZ(sector_t::ceiling));
|
||||
DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
|
||||
realback->GetPlaneTexZ(sector_t::floor), realfront->GetPlaneTexZ(sector_t::floor),
|
||||
bfh1, bfh2, ffh1, ffh2,
|
||||
frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum ?
|
||||
realfront->GetPlaneTexZ(sector_t::floor) - realback->GetPlaneTexZ(sector_t::ceiling) :
|
||||
realfront->GetPlaneTexZ(sector_t::floor) - realfront->GetPlaneTexZ(sector_t::ceiling));
|
||||
}
|
||||
else if ((frontsector->floorplane.a | frontsector->floorplane.b |
|
||||
backsector->floorplane.a | backsector->floorplane.b) &&
|
||||
frontsector->GetTexture(sector_t::floor)!=skyflatnum &&
|
||||
backsector->GetTexture(sector_t::floor)!=skyflatnum)
|
||||
else if ((frontsector->floorplane.a | frontsector->floorplane.b |
|
||||
backsector->floorplane.a | backsector->floorplane.b) &&
|
||||
frontsector->GetTexture(sector_t::floor) != skyflatnum &&
|
||||
backsector->GetTexture(sector_t::floor) != skyflatnum)
|
||||
{
|
||||
// render it anyway with the sector's floor texture. With a background sky
|
||||
// there are ugly holes otherwise and slopes are simply not precise enough
|
||||
// to mach in any case.
|
||||
gltexture=FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), true);
|
||||
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), false, true);
|
||||
if (gltexture)
|
||||
{
|
||||
DoTexture(RENDERWALL_BOTTOM,seg,(seg->linedef->flags & ML_DONTPEGBOTTOM)>0,
|
||||
realback->GetPlaneTexZ(sector_t::floor),realfront->GetPlaneTexZ(sector_t::floor),
|
||||
bfh1,bfh2,ffh1,ffh2, realfront->GetPlaneTexZ(sector_t::floor)-realfront->GetPlaneTexZ(sector_t::ceiling));
|
||||
DoTexture(RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
|
||||
realback->GetPlaneTexZ(sector_t::floor), realfront->GetPlaneTexZ(sector_t::floor),
|
||||
bfh1, bfh2, ffh1, ffh2, realfront->GetPlaneTexZ(sector_t::floor) - realfront->GetPlaneTexZ(sector_t::ceiling));
|
||||
}
|
||||
}
|
||||
else if (backsector->GetTexture(sector_t::floor)!=skyflatnum &&
|
||||
else if (backsector->GetTexture(sector_t::floor) != skyflatnum &&
|
||||
!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
// skip processing if the back is a malformed subsector
|
||||
|
|
@ -1747,19 +1720,19 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
//==========================================================================
|
||||
void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
||||
{
|
||||
if (frontsector->GetTexture(sector_t::floor)==skyflatnum) return;
|
||||
if (frontsector->GetTexture(sector_t::floor) == skyflatnum) return;
|
||||
|
||||
fixed_t ffh = frontsector->GetPlaneTexZ(sector_t::floor);
|
||||
fixed_t bfh = backsector->GetPlaneTexZ(sector_t::floor);
|
||||
if (bfh>ffh)
|
||||
fixed_t ffh = frontsector->GetPlaneTexZ(sector_t::floor);
|
||||
fixed_t bfh = backsector->GetPlaneTexZ(sector_t::floor);
|
||||
if (bfh > ffh)
|
||||
{
|
||||
this->seg = seg;
|
||||
this->sub = NULL;
|
||||
|
||||
vertex_t * v1=seg->v1;
|
||||
vertex_t * v2=seg->v2;
|
||||
vertexes[0]=v1;
|
||||
vertexes[1]=v2;
|
||||
vertex_t * v1 = seg->v1;
|
||||
vertex_t * v2 = seg->v2;
|
||||
vertexes[0] = v1;
|
||||
vertexes[1] = v2;
|
||||
|
||||
glseg.x1 = FIXED2FLOAT(v1->x);
|
||||
glseg.y1 = FIXED2FLOAT(v1->y);
|
||||
|
|
@ -1768,7 +1741,7 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
|
|||
glseg.fracleft = 0;
|
||||
glseg.fracright = 1;
|
||||
|
||||
flags = (!gl_isBlack(Colormap.FadeColor) || level.flags&LEVEL_HASFADETABLE)? GLWF_FOGGY : 0;
|
||||
flags = 0;
|
||||
|
||||
// can't do fake contrast without a sidedef
|
||||
lightlevel = gl_ClampLight(frontsector->lightlevel);
|
||||
|
|
@ -1782,15 +1755,16 @@ void GLWall::ProcessLowerMiniseg(seg_t *seg, sector_t * frontsector, sector_t *
|
|||
bottomflat = frontsector->GetTexture(sector_t::floor);
|
||||
topplane = frontsector->ceilingplane;
|
||||
bottomplane = frontsector->floorplane;
|
||||
dynlightindex = UINT_MAX;
|
||||
|
||||
zfloor[0] = zfloor[1] = FIXED2FLOAT(ffh);
|
||||
|
||||
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), true);
|
||||
gltexture = FMaterial::ValidateTexture(frontsector->GetTexture(sector_t::floor), false, true);
|
||||
|
||||
if (gltexture)
|
||||
if (gltexture)
|
||||
{
|
||||
FTexCoordInfo tci;
|
||||
type=RENDERWALL_BOTTOM;
|
||||
type = RENDERWALL_BOTTOM;
|
||||
gltexture->GetTexCoordInfo(&tci, FRACUNIT, FRACUNIT);
|
||||
SetWallCoordinates(seg, &tci, FIXED2FLOAT(bfh), bfh, bfh, ffh, ffh, 0);
|
||||
PutWall(false);
|
||||
|
|
|
|||
|
|
@ -48,9 +48,12 @@
|
|||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/dynlights/gl_dynlight.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/scene/gl_portal.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
|
|
@ -60,57 +63,6 @@
|
|||
|
||||
EXTERN_CVAR(Bool, gl_seamless)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Sets up the texture coordinates for one light to be rendered
|
||||
//
|
||||
//==========================================================================
|
||||
bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light)
|
||||
{
|
||||
float vtx[]={glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2};
|
||||
Plane p;
|
||||
Vector nearPt, up, right;
|
||||
float scale;
|
||||
|
||||
p.Init(vtx,4);
|
||||
|
||||
if (!p.ValidNormal())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gl_SetupLight(p, light, nearPt, up, right, scale, Colormap.colormap, true, !!(flags&GLWF_FOGGY)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tcs != NULL)
|
||||
{
|
||||
Vector t1;
|
||||
int outcnt[4]={0,0,0,0};
|
||||
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
t1.Set(&vtx[i*3]);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
|
||||
// quick check whether the light touches this polygon
|
||||
if (tcs[i].u<0) outcnt[0]++;
|
||||
if (tcs[i].u>1) outcnt[1]++;
|
||||
if (tcs[i].v<0) outcnt[2]++;
|
||||
if (tcs[i].v>1) outcnt[3]++;
|
||||
|
||||
}
|
||||
// The light doesn't touch this polygon
|
||||
if (outcnt[0]==4 || outcnt[1]==4 || outcnt[2]==4 || outcnt[3]==4) return false;
|
||||
}
|
||||
|
||||
draw_dlight++;
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Collect lights for shader
|
||||
|
|
@ -118,8 +70,19 @@ bool GLWall::PrepareLight(texcoord * tcs, ADynamicLight * light)
|
|||
//==========================================================================
|
||||
FDynLightData lightdata;
|
||||
|
||||
|
||||
void GLWall::SetupLights()
|
||||
{
|
||||
// check for wall types which cannot have dynamic lights on them (portal types never get here so they don't need to be checked.)
|
||||
switch (type)
|
||||
{
|
||||
case RENDERWALL_FOGBOUNDARY:
|
||||
case RENDERWALL_MIRRORSURFACE:
|
||||
case RENDERWALL_COLOR:
|
||||
case RENDERWALL_COLORLAYER:
|
||||
return;
|
||||
}
|
||||
|
||||
float vtx[]={glseg.x1,zbottom[0],glseg.y1, glseg.x1,ztop[0],glseg.y1, glseg.x2,ztop[1],glseg.y2, glseg.x2,zbottom[1],glseg.y2};
|
||||
Plane p;
|
||||
|
||||
|
|
@ -130,89 +93,80 @@ void GLWall::SetupLights()
|
|||
{
|
||||
return;
|
||||
}
|
||||
for(int i=0;i<2;i++)
|
||||
FLightNode *node;
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
FLightNode *node;
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
node = NULL;
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
node = seg->sidedef->lighthead[i];
|
||||
}
|
||||
else if (sub)
|
||||
{
|
||||
// Polobject segs cannot be checked per sidedef so use the subsector instead.
|
||||
node = sub->lighthead[i];
|
||||
}
|
||||
else node = NULL;
|
||||
node = NULL;
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
node = seg->sidedef->lighthead;
|
||||
}
|
||||
else if (sub)
|
||||
{
|
||||
// Polobject segs cannot be checked per sidedef so use the subsector instead.
|
||||
node = sub->lighthead;
|
||||
}
|
||||
else node = NULL;
|
||||
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
while (node)
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
while (node)
|
||||
{
|
||||
if (!(node->lightsource->flags2&MF2_DORMANT))
|
||||
{
|
||||
if (!(node->lightsource->flags2&MF2_DORMANT))
|
||||
iter_dlight++;
|
||||
|
||||
Vector fn, pos;
|
||||
|
||||
float x = FIXED2FLOAT(node->lightsource->x);
|
||||
float y = FIXED2FLOAT(node->lightsource->y);
|
||||
float z = FIXED2FLOAT(node->lightsource->z);
|
||||
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||
float radius = (node->lightsource->GetRadius() * gl_lights_size);
|
||||
float scale = 1.0f / ((2.f * radius) - dist);
|
||||
|
||||
if (radius > 0.f && dist < radius)
|
||||
{
|
||||
iter_dlight++;
|
||||
Vector nearPt, up, right;
|
||||
|
||||
Vector fn, pos;
|
||||
pos.Set(x,z,y);
|
||||
fn=p.Normal();
|
||||
fn.GetRightUp(right, up);
|
||||
|
||||
float x = FIXED2FLOAT(node->lightsource->x);
|
||||
float y = FIXED2FLOAT(node->lightsource->y);
|
||||
float z = FIXED2FLOAT(node->lightsource->z);
|
||||
float dist = fabsf(p.DistToPoint(x, z, y));
|
||||
float radius = (node->lightsource->GetRadius() * gl_lights_size);
|
||||
float scale = 1.0f / ((2.f * radius) - dist);
|
||||
Vector tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
|
||||
if (radius > 0.f && dist < radius)
|
||||
Vector t1;
|
||||
int outcnt[4]={0,0,0,0};
|
||||
texcoord tcs[4];
|
||||
|
||||
// do a quick check whether the light touches this polygon
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
Vector nearPt, up, right;
|
||||
t1.Set(&vtx[i*3]);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
|
||||
pos.Set(x,z,y);
|
||||
fn=p.Normal();
|
||||
fn.GetRightUp(right, up);
|
||||
if (tcs[i].u<0) outcnt[0]++;
|
||||
if (tcs[i].u>1) outcnt[1]++;
|
||||
if (tcs[i].v<0) outcnt[2]++;
|
||||
if (tcs[i].v>1) outcnt[3]++;
|
||||
|
||||
Vector tmpVec = fn * dist;
|
||||
nearPt = pos + tmpVec;
|
||||
|
||||
Vector t1;
|
||||
int outcnt[4]={0,0,0,0};
|
||||
texcoord tcs[4];
|
||||
|
||||
// do a quick check whether the light touches this polygon
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
t1.Set(&vtx[i*3]);
|
||||
Vector nearToVert = t1 - nearPt;
|
||||
tcs[i].u = (nearToVert.Dot(right) * scale) + 0.5f;
|
||||
tcs[i].v = (nearToVert.Dot(up) * scale) + 0.5f;
|
||||
|
||||
if (tcs[i].u<0) outcnt[0]++;
|
||||
if (tcs[i].u>1) outcnt[1]++;
|
||||
if (tcs[i].v<0) outcnt[2]++;
|
||||
if (tcs[i].v>1) outcnt[3]++;
|
||||
|
||||
}
|
||||
if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4)
|
||||
{
|
||||
gl_GetLight(p, node->lightsource, Colormap.colormap, true, false, lightdata);
|
||||
}
|
||||
}
|
||||
if (outcnt[0]!=4 && outcnt[1]!=4 && outcnt[2]!=4 && outcnt[3]!=4)
|
||||
{
|
||||
gl_GetLight(p, node->lightsource, true, false, lightdata);
|
||||
}
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
int numlights[3];
|
||||
|
||||
lightdata.Combine(numlights, gl.MaxLights());
|
||||
if (numlights[2] > 0)
|
||||
{
|
||||
draw_dlight+=numlights[2]/2;
|
||||
gl_RenderState.EnableLight(true);
|
||||
gl_RenderState.SetLights(numlights, &lightdata.arrays[0][0]);
|
||||
}
|
||||
dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// General purpose wall rendering function
|
||||
|
|
@ -220,67 +174,54 @@ void GLWall::SetupLights()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void GLWall::RenderWall(int textured, float * color2, ADynamicLight * light)
|
||||
void GLWall::RenderWall(int textured, unsigned int *store)
|
||||
{
|
||||
texcoord tcs[4];
|
||||
bool split = (gl_seamless && !(textured&4) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ));
|
||||
static texcoord tcs[4]; // making this variable static saves us a relatively costly stack integrity check.
|
||||
bool split = (gl_seamless && !(textured&RWF_NOSPLIT) && seg->sidedef != NULL && !(seg->sidedef->Flags & WALLF_POLYOBJ) && !(flags & GLWF_NOSPLIT));
|
||||
|
||||
if (!light)
|
||||
tcs[0]=lolft;
|
||||
tcs[1]=uplft;
|
||||
tcs[2]=uprgt;
|
||||
tcs[3]=lorgt;
|
||||
if ((flags&GLWF_GLOW) && (textured & RWF_GLOW))
|
||||
{
|
||||
tcs[0]=lolft;
|
||||
tcs[1]=uplft;
|
||||
tcs[2]=uprgt;
|
||||
tcs[3]=lorgt;
|
||||
if (!!(flags&GLWF_GLOW) && (textured & 2))
|
||||
{
|
||||
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
|
||||
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!PrepareLight(tcs, light)) return;
|
||||
gl_RenderState.SetGlowPlanes(topplane, bottomplane);
|
||||
gl_RenderState.SetGlowParams(topglowcolor, bottomglowcolor);
|
||||
}
|
||||
|
||||
|
||||
gl_RenderState.Apply();
|
||||
if (!(textured & RWF_NORENDER))
|
||||
{
|
||||
gl_RenderState.Apply();
|
||||
gl_RenderState.ApplyLightIndex(dynlightindex);
|
||||
}
|
||||
|
||||
// the rest of the code is identical for textured rendering and lights
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
unsigned int count, offset;
|
||||
|
||||
glBegin(GL_TRIANGLE_FAN);
|
||||
|
||||
// lower left corner
|
||||
if (textured&1) glTexCoord2f(tcs[0].u,tcs[0].v);
|
||||
glVertex3f(glseg.x1,zbottom[0],glseg.y1);
|
||||
|
||||
if (split && glseg.fracleft==0) SplitLeftEdge(tcs);
|
||||
|
||||
// upper left corner
|
||||
if (textured&1) glTexCoord2f(tcs[1].u,tcs[1].v);
|
||||
glVertex3f(glseg.x1,ztop[0],glseg.y1);
|
||||
|
||||
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs);
|
||||
|
||||
// color for right side
|
||||
if (color2) glColor4fv(color2);
|
||||
|
||||
// upper right corner
|
||||
if (textured&1) glTexCoord2f(tcs[2].u,tcs[2].v);
|
||||
glVertex3f(glseg.x2,ztop[1],glseg.y2);
|
||||
|
||||
if (split && glseg.fracright==1) SplitRightEdge(tcs);
|
||||
|
||||
// lower right corner
|
||||
if (textured&1) glTexCoord2f(tcs[3].u,tcs[3].v);
|
||||
glVertex3f(glseg.x2,zbottom[1],glseg.y2);
|
||||
|
||||
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs);
|
||||
|
||||
glEnd();
|
||||
|
||||
vertexcount+=4;
|
||||
|
||||
ptr->Set(glseg.x1, zbottom[0], glseg.y1, tcs[0].u, tcs[0].v);
|
||||
ptr++;
|
||||
if (split && glseg.fracleft == 0) SplitLeftEdge(tcs, ptr);
|
||||
ptr->Set(glseg.x1, ztop[0], glseg.y1, tcs[1].u, tcs[1].v);
|
||||
ptr++;
|
||||
if (split && !(flags & GLWF_NOSPLITUPPER)) SplitUpperEdge(tcs, ptr);
|
||||
ptr->Set(glseg.x2, ztop[1], glseg.y2, tcs[2].u, tcs[2].v);
|
||||
ptr++;
|
||||
if (split && glseg.fracright == 1) SplitRightEdge(tcs, ptr);
|
||||
ptr->Set(glseg.x2, zbottom[1], glseg.y2, tcs[3].u, tcs[3].v);
|
||||
ptr++;
|
||||
if (split && !(flags & GLWF_NOSPLITLOWER)) SplitLowerEdge(tcs, ptr);
|
||||
count = GLRenderer->mVBO->GetCount(ptr, &offset);
|
||||
if (!(textured & RWF_NORENDER))
|
||||
{
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_FAN, offset, count);
|
||||
vertexcount += count;
|
||||
}
|
||||
if (store != NULL)
|
||||
{
|
||||
store[0] = offset;
|
||||
store[1] = count;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -293,52 +234,12 @@ void GLWall::RenderFogBoundary()
|
|||
{
|
||||
if (gl_fogmode && gl_fixedcolormap == 0)
|
||||
{
|
||||
// with shaders this can be done properly
|
||||
if (gl.shadermodel == 4 || (gl.shadermodel == 3 && gl_fog_shader))
|
||||
{
|
||||
int rel = rellight + getExtraLight();
|
||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
RenderWall(0, NULL);
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// otherwise some approximation is needed. This won't look as good
|
||||
// as the shader version but it's an acceptable compromise.
|
||||
float fogdensity=gl_GetFogDensity(lightlevel, Colormap.FadeColor);
|
||||
|
||||
float xcamera=FIXED2FLOAT(viewx);
|
||||
float ycamera=FIXED2FLOAT(viewy);
|
||||
|
||||
float dist1=Dist2(xcamera,ycamera, glseg.x1,glseg.y1);
|
||||
float dist2=Dist2(xcamera,ycamera, glseg.x2,glseg.y2);
|
||||
|
||||
|
||||
// these values were determined by trial and error and are scale dependent!
|
||||
float fogd1=(0.95f-exp(-fogdensity*dist1/62500.f)) * 1.05f;
|
||||
float fogd2=(0.95f-exp(-fogdensity*dist2/62500.f)) * 1.05f;
|
||||
|
||||
gl_ModifyColor(Colormap.FadeColor.r, Colormap.FadeColor.g, Colormap.FadeColor.b, Colormap.colormap);
|
||||
float fc[4]={Colormap.FadeColor.r/255.0f,Colormap.FadeColor.g/255.0f,Colormap.FadeColor.b/255.0f,fogd2};
|
||||
|
||||
gl_RenderState.EnableTexture(false);
|
||||
gl_RenderState.EnableFog(false);
|
||||
gl_RenderState.AlphaFunc(GL_GREATER,0);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glColor4f(fc[0],fc[1],fc[2], fogd1);
|
||||
if (glset.lightmode == 8) glVertexAttrib1f(VATTR_LIGHTLEVEL, 1.0); // Korshun.
|
||||
|
||||
flags &= ~GLWF_GLOW;
|
||||
RenderWall(4,fc);
|
||||
|
||||
glDepthFunc(GL_LESS);
|
||||
gl_RenderState.EnableFog(true);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,0.5f);
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
int rel = rellight + getExtraLight();
|
||||
gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
gl_RenderState.SetEffect(EFF_FOGBOUNDARY);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
RenderWall(RWF_BLANK);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -355,29 +256,35 @@ void GLWall::RenderMirrorSurface()
|
|||
// For the sphere map effect we need a normal of the mirror surface,
|
||||
Vector v(glseg.y2-glseg.y1, 0 ,-glseg.x2+glseg.x1);
|
||||
v.Normalize();
|
||||
glNormal3fv(&v[0]);
|
||||
|
||||
// we use texture coordinates and texture matrix to pass the normal stuff to the shader so that the default vertex buffer format can be used as is.
|
||||
lolft.u = lorgt.u = uplft.u = uprgt.u = v.X();
|
||||
lolft.v = lorgt.v = uplft.v = uprgt.v = v.Z();
|
||||
|
||||
gl_RenderState.EnableTextureMatrix(true);
|
||||
gl_RenderState.mTextureMatrix.computeNormalMatrix(gl_RenderState.mViewMatrix);
|
||||
|
||||
// Use sphere mapping for this
|
||||
gl_RenderState.SetEffect(EFF_SPHEREMAP);
|
||||
|
||||
gl_SetColor(lightlevel, 0, &Colormap ,0.1f);
|
||||
gl_SetColor(lightlevel, 0, Colormap ,0.1f);
|
||||
gl_SetFog(lightlevel, 0, &Colormap, true);
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
gl_RenderState.AlphaFunc(GL_GREATER,0);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
gl_SetFog(lightlevel, getExtraLight(), &Colormap, true);
|
||||
|
||||
FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture);
|
||||
pat->BindPatch(Colormap.colormap, 0);
|
||||
FMaterial * pat=FMaterial::ValidateTexture(GLRenderer->mirrortexture, false);
|
||||
gl_RenderState.SetMaterial(pat, CLAMP_NONE, 0, -1, false);
|
||||
|
||||
flags &= ~GLWF_GLOW;
|
||||
//flags |= GLWF_NOSHADER;
|
||||
RenderWall(0,NULL);
|
||||
RenderWall(RWF_BLANK);
|
||||
|
||||
gl_RenderState.EnableTextureMatrix(false);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
|
||||
// Restore the defaults for the translucent pass
|
||||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,0.5f*gl_mask_sprite_threshold);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_sprite_threshold);
|
||||
glDepthFunc(GL_LESS);
|
||||
|
||||
// This is drawn in the translucent pass which is done after the decal pass
|
||||
|
|
@ -411,16 +318,15 @@ void GLWall::RenderTranslucentWall()
|
|||
// and until that changes I won't fix this code for the new blending modes!
|
||||
bool isadditive = RenderStyle == STYLE_Add;
|
||||
|
||||
if (!transparent) gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_threshold*fabs(alpha));
|
||||
else gl_RenderState.EnableAlphaTest(false);
|
||||
if (!transparent) gl_RenderState.AlphaFunc(GL_GEQUAL, gl_mask_threshold);
|
||||
else gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA,GL_ONE);
|
||||
|
||||
int extra;
|
||||
if (gltexture)
|
||||
{
|
||||
if (flags&GLWF_FOGGY) gl_RenderState.EnableBrightmap(false);
|
||||
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
|
||||
gltexture->Bind(Colormap.colormap, flags, 0);
|
||||
gl_RenderState.SetMaterial(gltexture, flags & 3, 0, -1, false);
|
||||
extra = getExtraLight();
|
||||
}
|
||||
else
|
||||
|
|
@ -429,21 +335,19 @@ void GLWall::RenderTranslucentWall()
|
|||
extra = 0;
|
||||
}
|
||||
|
||||
gl_SetColor(lightlevel, extra, &Colormap, fabsf(alpha));
|
||||
gl_SetColor(lightlevel, extra, Colormap, fabsf(alpha));
|
||||
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, extra, &Colormap, isadditive);
|
||||
else gl_SetFog(255, 0, NULL, false);
|
||||
|
||||
RenderWall(5,NULL);
|
||||
RenderWall(RWF_TEXTURED|RWF_NOSPLIT);
|
||||
|
||||
// restore default settings
|
||||
if (isadditive) gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
if (transparent) gl_RenderState.EnableAlphaTest(true);
|
||||
|
||||
if (!gltexture)
|
||||
{
|
||||
gl_RenderState.EnableTexture(true);
|
||||
}
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_RenderState.EnableGlow(false);
|
||||
}
|
||||
|
||||
|
|
@ -454,7 +358,6 @@ void GLWall::RenderTranslucentWall()
|
|||
//==========================================================================
|
||||
void GLWall::Draw(int pass)
|
||||
{
|
||||
FLightNode * node;
|
||||
int rel;
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
|
@ -465,102 +368,31 @@ void GLWall::Draw(int pass)
|
|||
#endif
|
||||
|
||||
|
||||
// This allows mid textures to be drawn on lines that might overlap a sky wall
|
||||
if ((flags&GLWF_SKYHACK && type==RENDERWALL_M2S) || type == RENDERWALL_COLORLAYER)
|
||||
if (type == RENDERWALL_COLORLAYER && pass != GLPASS_LIGHTSONLY)
|
||||
{
|
||||
if (pass != GLPASS_DECALS)
|
||||
{
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
}
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-1.0f, -128.0f);
|
||||
}
|
||||
|
||||
switch (pass)
|
||||
{
|
||||
case GLPASS_ALL: // Single-pass rendering
|
||||
case GLPASS_LIGHTSONLY:
|
||||
SetupLights();
|
||||
break;
|
||||
|
||||
case GLPASS_ALL:
|
||||
SetupLights();
|
||||
// fall through
|
||||
case GLPASS_PLAIN: // Single-pass rendering
|
||||
case GLPASS_PLAIN:
|
||||
rel = rellight + getExtraLight();
|
||||
gl_SetColor(lightlevel, rel, &Colormap,1.0f);
|
||||
gl_SetColor(lightlevel, rel, Colormap,1.0f);
|
||||
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
else gl_SetFog(255, 0, NULL, false);
|
||||
|
||||
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
|
||||
gltexture->Bind(Colormap.colormap, flags, 0);
|
||||
RenderWall(3, NULL);
|
||||
gl_RenderState.SetMaterial(gltexture, flags & 3, false, -1, false);
|
||||
RenderWall(RWF_TEXTURED|RWF_GLOW);
|
||||
gl_RenderState.EnableGlow(false);
|
||||
gl_RenderState.EnableLight(false);
|
||||
break;
|
||||
|
||||
case GLPASS_BASE: // Base pass for non-masked polygons (all opaque geometry)
|
||||
case GLPASS_BASE_MASKED: // Base pass for masked polygons (2sided mid-textures and transparent 3D floors)
|
||||
rel = rellight + getExtraLight();
|
||||
gl_SetColor(lightlevel, rel, &Colormap,1.0f);
|
||||
if (!(flags&GLWF_FOGGY))
|
||||
{
|
||||
if (type!=RENDERWALL_M2SNF) gl_SetFog(lightlevel, rel, &Colormap, false);
|
||||
else gl_SetFog(255, 0, NULL, false);
|
||||
}
|
||||
gl_RenderState.EnableGlow(!!(flags & GLWF_GLOW));
|
||||
// fall through
|
||||
|
||||
if (pass != GLPASS_BASE)
|
||||
{
|
||||
gltexture->Bind(Colormap.colormap, flags, 0);
|
||||
}
|
||||
RenderWall(pass == GLPASS_BASE? 2:3, NULL);
|
||||
gl_RenderState.EnableGlow(false);
|
||||
gl_RenderState.EnableLight(false);
|
||||
break;
|
||||
|
||||
case GLPASS_TEXTURE: // modulated texture
|
||||
gltexture->Bind(Colormap.colormap, flags, 0);
|
||||
RenderWall(1, NULL);
|
||||
break;
|
||||
|
||||
case GLPASS_LIGHT:
|
||||
case GLPASS_LIGHT_ADDITIVE:
|
||||
// black fog is diminishing light and should affect lights less than the rest!
|
||||
if (!(flags&GLWF_FOGGY)) gl_SetFog((255+lightlevel)>>1, 0, NULL, false);
|
||||
else gl_SetFog(lightlevel, 0, &Colormap, true);
|
||||
|
||||
if (seg->sidedef == NULL)
|
||||
{
|
||||
node = NULL;
|
||||
}
|
||||
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
|
||||
{
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
node = seg->sidedef->lighthead[pass==GLPASS_LIGHT_ADDITIVE];
|
||||
}
|
||||
else if (sub)
|
||||
{
|
||||
// To avoid constant rechecking for polyobjects use the subsector's lightlist instead
|
||||
node = sub->lighthead[pass==GLPASS_LIGHT_ADDITIVE];
|
||||
}
|
||||
else node = NULL;
|
||||
while (node)
|
||||
{
|
||||
if (!(node->lightsource->flags2&MF2_DORMANT))
|
||||
{
|
||||
iter_dlight++;
|
||||
RenderWall(1, NULL, node->lightsource);
|
||||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
break;
|
||||
|
||||
case GLPASS_DECALS:
|
||||
case GLPASS_DECALS_NOFOG:
|
||||
if (seg->sidedef && seg->sidedef->AttachedDecals)
|
||||
{
|
||||
if (pass==GLPASS_DECALS)
|
||||
{
|
||||
gl_SetFog(lightlevel, rellight + getExtraLight(), &Colormap, false);
|
||||
}
|
||||
DoDrawDecals();
|
||||
}
|
||||
break;
|
||||
|
||||
case GLPASS_TRANSLUCENT:
|
||||
|
|
@ -580,12 +412,9 @@ void GLWall::Draw(int pass)
|
|||
}
|
||||
}
|
||||
|
||||
if ((flags&GLWF_SKYHACK && type==RENDERWALL_M2S) || type == RENDERWALL_COLORLAYER)
|
||||
if (type == RENDERWALL_COLORLAYER && pass != GLPASS_LIGHTSONLY)
|
||||
{
|
||||
if (pass!=GLPASS_DECALS)
|
||||
{
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(0, 0);
|
||||
}
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(0, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@
|
|||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
#include "gl/dynlights/gl_glow.h"
|
||||
#include "gl/scene/gl_drawinfo.h"
|
||||
#include "gl/models/gl_models.h"
|
||||
|
|
@ -69,7 +70,7 @@ EXTERN_CVAR(Int, gl_fuzztype)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, int cm_index, bool hudModelStep, int OverrideShader)
|
||||
void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed_t sy, bool hudModelStep, int OverrideShader, bool alphatexture)
|
||||
{
|
||||
float fU1,fV1;
|
||||
float fU2,fV2;
|
||||
|
|
@ -83,7 +84,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
|
|||
// [BB] In the HUD model step we just render the model and break out.
|
||||
if ( hudModelStep )
|
||||
{
|
||||
gl_RenderHUDModel( psp, sx, sy, cm_index );
|
||||
gl_RenderHUDModel( psp, sx, sy);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -92,10 +93,10 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
|
|||
FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, &mirror);
|
||||
if (!lump.isValid()) return;
|
||||
|
||||
FMaterial * tex = FMaterial::ValidateTexture(lump, false);
|
||||
FMaterial * tex = FMaterial::ValidateTexture(lump, true, false);
|
||||
if (!tex) return;
|
||||
|
||||
tex->BindPatch(cm_index, 0, OverrideShader);
|
||||
gl_RenderState.SetMaterial(tex, CLAMP_XY_NOMIP, 0, OverrideShader, alphatexture);
|
||||
|
||||
int vw = viewwidth;
|
||||
int vh = viewheight;
|
||||
|
|
@ -103,18 +104,18 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
|
|||
// calculate edges of the shape
|
||||
scalex = xratio[WidescreenRatio] * vw / 320;
|
||||
|
||||
tx = sx - ((160 + tex->GetScaledLeftOffset(GLUSE_PATCH))<<FRACBITS);
|
||||
tx = sx - ((160 + tex->GetScaledLeftOffset())<<FRACBITS);
|
||||
x1 = (FixedMul(tx, scalex)>>FRACBITS) + (vw>>1);
|
||||
if (x1 > vw) return; // off the right side
|
||||
x1+=viewwindowx;
|
||||
|
||||
tx += tex->TextureWidth(GLUSE_PATCH) << FRACBITS;
|
||||
tx += tex->TextureWidth() << FRACBITS;
|
||||
x2 = (FixedMul(tx, scalex)>>FRACBITS) + (vw>>1);
|
||||
if (x2 < 0) return; // off the left side
|
||||
x2+=viewwindowx;
|
||||
|
||||
// killough 12/98: fix psprite positioning problem
|
||||
texturemid = (100<<FRACBITS) - (sy-(tex->GetScaledTopOffset(GLUSE_PATCH)<<FRACBITS));
|
||||
texturemid = (100<<FRACBITS) - (sy-(tex->GetScaledTopOffset()<<FRACBITS));
|
||||
|
||||
AWeapon * wi=player->ReadyWeapon;
|
||||
if (wi && wi->YAdjust)
|
||||
|
|
@ -131,7 +132,7 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
|
|||
|
||||
scale = ((SCREENHEIGHT*vw)/SCREENWIDTH) / 200.0f;
|
||||
y1 = viewwindowy + (vh >> 1) - (int)(((float)texturemid / (float)FRACUNIT) * scale);
|
||||
y2 = y1 + (int)((float)tex->TextureHeight(GLUSE_PATCH) * scale) + 1;
|
||||
y2 = y1 + (int)((float)tex->TextureHeight() * scale) + 1;
|
||||
|
||||
if (!mirror)
|
||||
{
|
||||
|
|
@ -148,21 +149,22 @@ void FGLRenderer::DrawPSprite (player_t * player,pspdef_t *psp,fixed_t sx, fixed
|
|||
fV2=tex->GetVB();
|
||||
}
|
||||
|
||||
if (tex->GetTransparent() || OverrideShader != 0)
|
||||
if (tex->GetTransparent() || OverrideShader != -1)
|
||||
{
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
}
|
||||
gl_RenderState.Apply();
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(fU1, fV1); glVertex2f(x1,y1);
|
||||
glTexCoord2f(fU1, fV2); glVertex2f(x1,y2);
|
||||
glTexCoord2f(fU2, fV1); glVertex2f(x2,y1);
|
||||
glTexCoord2f(fU2, fV2); glVertex2f(x2,y2);
|
||||
glEnd();
|
||||
if (tex->GetTransparent() || OverrideShader != 0)
|
||||
{
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
}
|
||||
FFlatVertex *ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(x1, y1, 0, fU1, fV1);
|
||||
ptr++;
|
||||
ptr->Set(x1, y2, 0, fU1, fV2);
|
||||
ptr++;
|
||||
ptr->Set(x2, y1, 0, fU2, fV1);
|
||||
ptr++;
|
||||
ptr->Set(x2, y2, 0, fU2, fV2);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -192,36 +194,32 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
(players[consoleplayer].cheats & CF_CHASECAM))
|
||||
return;
|
||||
|
||||
/*
|
||||
if(!player || playermo->renderflags&RF_INVISIBLE || !r_drawplayersprites ||
|
||||
mViewActor!=playermo || playermo->RenderStyle.BlendOp == STYLEOP_None) return;
|
||||
*/
|
||||
|
||||
P_BobWeapon (player, &player->psprites[ps_weapon], &ofsx, &ofsy);
|
||||
|
||||
// check for fullbright
|
||||
if (player->fixedcolormap==NOFIXEDCOLORMAP)
|
||||
{
|
||||
for (i=0, psp=player->psprites; i<=ps_flash; i++,psp++)
|
||||
for (i = 0, psp = player->psprites; i <= ps_flash; i++, psp++)
|
||||
{
|
||||
if (psp->state != NULL)
|
||||
{
|
||||
bool disablefullbright = false;
|
||||
FTextureID lump = gl_GetSpriteFrame(psp->sprite, psp->frame, 0, 0, NULL);
|
||||
if (lump.isValid() && gl_BrightmapsActive())
|
||||
if (lump.isValid())
|
||||
{
|
||||
FMaterial * tex=FMaterial::ValidateTexture(lump, false);
|
||||
FMaterial * tex=FMaterial::ValidateTexture(lump, false, false);
|
||||
if (tex)
|
||||
disablefullbright = tex->tex->gl_info.bBrightmapDisablesFullbright;
|
||||
}
|
||||
statebright[i] = !!psp->state->GetFullbright() && !disablefullbright;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_fixedcolormap)
|
||||
{
|
||||
lightlevel=255;
|
||||
cm.GetFixedColormap();
|
||||
cm.Clear();
|
||||
statebright[0] = statebright[1] = true;
|
||||
fakesec = viewsector;
|
||||
}
|
||||
|
|
@ -286,7 +284,9 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
statebright[0] = statebright[1] = true;
|
||||
}
|
||||
|
||||
PalEntry ThingColor = playermo->fillcolor;
|
||||
PalEntry ThingColor = (playermo->RenderStyle.Flags & STYLEF_ColorIsFixed) ? playermo->fillcolor : 0xffffff;
|
||||
ThingColor.a = 255;
|
||||
|
||||
visstyle_t vis;
|
||||
|
||||
vis.RenderStyle=playermo->RenderStyle;
|
||||
|
|
@ -297,23 +297,23 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
playermo->Inventory->AlterWeaponSprite(&vis);
|
||||
if (vis.colormap >= SpecialColormaps[0].Colormap &&
|
||||
vis.colormap < SpecialColormaps[SpecialColormaps.Size()].Colormap &&
|
||||
cm.colormap == CM_DEFAULT)
|
||||
gl_fixedcolormap == CM_DEFAULT)
|
||||
{
|
||||
ptrdiff_t specialmap = (vis.colormap - SpecialColormaps[0].Colormap) / sizeof(FSpecialColormap);
|
||||
cm.colormap = int(CM_FIRSTSPECIALCOLORMAP + specialmap);
|
||||
// this only happens for Strife's inverted weapon sprite
|
||||
vis.RenderStyle.Flags |= STYLEF_InvertSource;
|
||||
}
|
||||
}
|
||||
|
||||
// Set the render parameters
|
||||
|
||||
int OverrideShader = 0;
|
||||
int OverrideShader = -1;
|
||||
float trans = 0.f;
|
||||
if (vis.RenderStyle.BlendOp >= STYLEOP_Fuzz && vis.RenderStyle.BlendOp <= STYLEOP_FuzzOrRevSub)
|
||||
{
|
||||
vis.RenderStyle.CheckFuzz();
|
||||
if (vis.RenderStyle.BlendOp == STYLEOP_Fuzz)
|
||||
{
|
||||
if (gl.shadermodel >= 4 && gl_fuzztype != 0)
|
||||
if (gl_fuzztype != 0)
|
||||
{
|
||||
// Todo: implement shader selection here
|
||||
vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
|
|
@ -345,6 +345,7 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
|
||||
// now draw the different layers of the weapon
|
||||
gl_RenderState.EnableBrightmap(true);
|
||||
gl_RenderState.SetObjectColor(ThingColor);
|
||||
if (statebright[0] || statebright[1])
|
||||
{
|
||||
// brighten the weapon to reduce the difference between
|
||||
|
|
@ -365,7 +366,6 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
if (statebright[i])
|
||||
{
|
||||
if (fakesec == viewsector || in_area != area_below)
|
||||
// under water areas keep most of their color for fullbright objects
|
||||
{
|
||||
cmc.LightColor.r=
|
||||
cmc.LightColor.g=
|
||||
|
|
@ -373,17 +373,27 @@ void FGLRenderer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
}
|
||||
else
|
||||
{
|
||||
cmc.LightColor.r = (3*cmc.LightColor.r + 0xff)/4;
|
||||
// under water areas keep most of their color for fullbright objects
|
||||
cmc.LightColor.r = (3 * cmc.LightColor.r + 0xff) / 4;
|
||||
cmc.LightColor.g = (3*cmc.LightColor.g + 0xff)/4;
|
||||
cmc.LightColor.b = (3*cmc.LightColor.b + 0xff)/4;
|
||||
}
|
||||
}
|
||||
// set the lighting parameters (only calls glColor and glAlphaFunc)
|
||||
gl_SetSpriteLighting(vis.RenderStyle, playermo, statebright[i]? 255 : lightlevel,
|
||||
0, &cmc, 0xffffff, trans, statebright[i], true);
|
||||
DrawPSprite (player,psp,psp->sx+ofsx, psp->sy+ofsy, cm.colormap, hudModelStep, OverrideShader);
|
||||
// set the lighting parameters
|
||||
if (vis.RenderStyle.BlendOp == STYLEOP_Shadow)
|
||||
{
|
||||
gl_RenderState.SetColor(0.2f, 0.2f, 0.2f, 0.33f, cmc.desaturation);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl_SetDynSpriteLight(playermo, NULL);
|
||||
gl_SetColor(statebright[i] ? 255 : lightlevel, 0, cmc, trans, true);
|
||||
}
|
||||
DrawPSprite(player, psp, psp->sx + ofsx, psp->sy + ofsy, hudModelStep, OverrideShader, !!(vis.RenderStyle.Flags & STYLEF_RedIsAlpha));
|
||||
}
|
||||
}
|
||||
gl_RenderState.SetObjectColor(0xffffffff);
|
||||
gl_RenderState.SetDynLight(0, 0, 0);
|
||||
gl_RenderState.EnableBrightmap(false);
|
||||
glset.lightmode = oldlightmode;
|
||||
}
|
||||
|
|
@ -408,10 +418,10 @@ void FGLRenderer::DrawTargeterSprites()
|
|||
gl_RenderState.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL,gl_mask_sprite_threshold);
|
||||
gl_RenderState.BlendEquation(GL_FUNC_ADD);
|
||||
glColor3f(1.0f,1.0f,1.0f);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
// The Targeter's sprites are always drawn normally.
|
||||
for (i=ps_targetcenter, psp = &player->psprites[ps_targetcenter]; i<NUMPSPRITES; i++,psp++)
|
||||
if (psp->state) DrawPSprite (player,psp,psp->sx, psp->sy, CM_DEFAULT, false, 0);
|
||||
if (psp->state) DrawPSprite (player,psp,psp->sx, psp->sy, false, 0, false);
|
||||
}
|
||||
|
|
@ -51,22 +51,13 @@
|
|||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/data/gl_matrix.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
|
||||
// these will only have an effect on SM3 cards.
|
||||
// For SM4 they are always on and for SM2 always off
|
||||
CVAR(Bool, gl_warp_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
CVAR(Bool, gl_fog_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
CVAR(Bool, gl_colormap_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
CVAR(Bool, gl_brightmap_shader, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
CVAR(Bool, gl_glow_shader, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
|
||||
|
||||
extern long gl_frameMS;
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
@ -79,123 +70,174 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
static char buffer[10000];
|
||||
FString error;
|
||||
|
||||
if (gl.shadermodel > 0)
|
||||
int i_lump = Wads.CheckNumForFullName("shaders/glsl/shaderdefs.i");
|
||||
if (i_lump == -1) I_Error("Unable to load 'shaders/glsl/shaderdefs.i'");
|
||||
FMemLump i_data = Wads.ReadLump(i_lump);
|
||||
|
||||
int vp_lump = Wads.CheckNumForFullName(vert_prog_lump);
|
||||
if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump);
|
||||
FMemLump vp_data = Wads.ReadLump(vp_lump);
|
||||
|
||||
int fp_lump = Wads.CheckNumForFullName(frag_prog_lump);
|
||||
if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump);
|
||||
FMemLump fp_data = Wads.ReadLump(fp_lump);
|
||||
|
||||
|
||||
|
||||
//
|
||||
// The following code uses GetChars on the strings to get rid of terminating 0 characters. Do not remove or the code may break!
|
||||
//
|
||||
unsigned int lightbuffertype = GLRenderer->mLights->GetBufferType();
|
||||
unsigned int lightbuffersize = GLRenderer->mLights->GetBlockSize();
|
||||
|
||||
FString vp_comb;
|
||||
|
||||
if (lightbuffertype == GL_UNIFORM_BUFFER)
|
||||
{
|
||||
int vp_lump = Wads.CheckNumForFullName(vert_prog_lump);
|
||||
if (vp_lump == -1) I_Error("Unable to load '%s'", vert_prog_lump);
|
||||
FMemLump vp_data = Wads.ReadLump(vp_lump);
|
||||
|
||||
int fp_lump = Wads.CheckNumForFullName(frag_prog_lump);
|
||||
if (fp_lump == -1) I_Error("Unable to load '%s'", frag_prog_lump);
|
||||
FMemLump fp_data = Wads.ReadLump(fp_lump);
|
||||
|
||||
|
||||
FString vp_comb;
|
||||
FString fp_comb;
|
||||
vp_comb = defines;
|
||||
if (gl.shadermodel < 4)
|
||||
{
|
||||
vp_comb << "#define NO_SM4\n";
|
||||
}
|
||||
|
||||
fp_comb = vp_comb;
|
||||
// This uses GetChars on the strings to get rid of terminating 0 characters.
|
||||
vp_comb << vp_data.GetString().GetChars() << "\n";
|
||||
fp_comb << fp_data.GetString().GetChars() << "\n";
|
||||
|
||||
if (proc_prog_lump != NULL)
|
||||
{
|
||||
if (*proc_prog_lump != '#')
|
||||
{
|
||||
int pp_lump = Wads.CheckNumForFullName(proc_prog_lump);
|
||||
if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump);
|
||||
FMemLump pp_data = Wads.ReadLump(pp_lump);
|
||||
|
||||
fp_comb << pp_data.GetString().GetChars();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proc_prog_lump is not a lump name but the source itself (from generated shaders)
|
||||
fp_comb << proc_prog_lump+1;
|
||||
}
|
||||
}
|
||||
|
||||
hVertProg = glCreateShader(GL_VERTEX_SHADER);
|
||||
hFragProg = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
|
||||
int vp_size = (int)vp_comb.Len();
|
||||
int fp_size = (int)fp_comb.Len();
|
||||
|
||||
const char *vp_ptr = vp_comb.GetChars();
|
||||
const char *fp_ptr = fp_comb.GetChars();
|
||||
|
||||
glShaderSource(hVertProg, 1, &vp_ptr, &vp_size);
|
||||
glShaderSource(hFragProg, 1, &fp_ptr, &fp_size);
|
||||
|
||||
glCompileShader(hVertProg);
|
||||
glCompileShader(hFragProg);
|
||||
|
||||
hShader = glCreateProgram();
|
||||
|
||||
glAttachShader(hShader, hVertProg);
|
||||
glAttachShader(hShader, hFragProg);
|
||||
|
||||
glBindAttribLocation(hShader, VATTR_FOGPARAMS, "fogparams");
|
||||
glBindAttribLocation(hShader, VATTR_LIGHTLEVEL, "lightlevel_in"); // Korshun.
|
||||
|
||||
glLinkProgram(hShader);
|
||||
|
||||
glGetShaderInfoLog(hVertProg, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Vertex shader:\n" << buffer << "\n";
|
||||
}
|
||||
glGetShaderInfoLog(hFragProg, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Fragment shader:\n" << buffer << "\n";
|
||||
}
|
||||
|
||||
glGetProgramInfoLog(hShader, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Linking:\n" << buffer << "\n";
|
||||
}
|
||||
int linked;
|
||||
glGetProgramiv(hShader, GL_LINK_STATUS, &linked);
|
||||
if (linked == 0)
|
||||
{
|
||||
// only print message if there's an error.
|
||||
Printf("Init Shader '%s':\n%s\n", name, error.GetChars());
|
||||
}
|
||||
timer_index = glGetUniformLocation(hShader, "timer");
|
||||
desaturation_index = glGetUniformLocation(hShader, "desaturation_factor");
|
||||
fogenabled_index = glGetUniformLocation(hShader, "fogenabled");
|
||||
texturemode_index = glGetUniformLocation(hShader, "texturemode");
|
||||
camerapos_index = glGetUniformLocation(hShader, "camerapos");
|
||||
lightparms_index = glGetUniformLocation(hShader, "lightparms");
|
||||
colormapstart_index = glGetUniformLocation(hShader, "colormapstart");
|
||||
colormaprange_index = glGetUniformLocation(hShader, "colormaprange");
|
||||
lightrange_index = glGetUniformLocation(hShader, "lightrange");
|
||||
fogcolor_index = glGetUniformLocation(hShader, "fogcolor");
|
||||
lights_index = glGetUniformLocation(hShader, "lights");
|
||||
dlightcolor_index = glGetUniformLocation(hShader, "dlightcolor");
|
||||
|
||||
glowbottomcolor_index = glGetUniformLocation(hShader, "bottomglowcolor");
|
||||
glowtopcolor_index = glGetUniformLocation(hShader, "topglowcolor");
|
||||
glowbottomplane_index = glGetUniformLocation(hShader, "glowbottomplane");
|
||||
glowtopplane_index = glGetUniformLocation(hShader, "glowtopplane");
|
||||
|
||||
glUseProgram(hShader);
|
||||
|
||||
int texture_index = glGetUniformLocation(hShader, "texture2");
|
||||
if (texture_index > 0) glUniform1i(texture_index, 1);
|
||||
|
||||
glUseProgram(0);
|
||||
return !!linked;
|
||||
vp_comb.Format("#version 130\n#extension GL_ARB_uniform_buffer_object : require\n#define NUM_UBO_LIGHTS %d\n", lightbuffersize);
|
||||
}
|
||||
return false;
|
||||
else
|
||||
{
|
||||
vp_comb = "#version 400 core\n#extension GL_ARB_shader_storage_buffer_object : require\n#define SHADER_STORAGE_LIGHTS\n";
|
||||
}
|
||||
|
||||
vp_comb << defines << i_data.GetString().GetChars();
|
||||
FString fp_comb = vp_comb;
|
||||
|
||||
vp_comb << vp_data.GetString().GetChars() << "\n";
|
||||
fp_comb << fp_data.GetString().GetChars() << "\n";
|
||||
|
||||
if (proc_prog_lump != NULL)
|
||||
{
|
||||
if (*proc_prog_lump != '#')
|
||||
{
|
||||
int pp_lump = Wads.CheckNumForFullName(proc_prog_lump);
|
||||
if (pp_lump == -1) I_Error("Unable to load '%s'", proc_prog_lump);
|
||||
FMemLump pp_data = Wads.ReadLump(pp_lump);
|
||||
|
||||
if (pp_data.GetString().IndexOf("ProcessTexel") < 0)
|
||||
{
|
||||
// this looks like an old custom hardware shader.
|
||||
// We need to replace the ProcessTexel call to make it work.
|
||||
|
||||
fp_comb.Substitute("vec4 frag = ProcessTexel();", "vec4 frag = Process(vec4(1.0));");
|
||||
}
|
||||
fp_comb << pp_data.GetString().GetChars();
|
||||
fp_comb.Substitute("gl_TexCoord[0]", "vTexCoord"); // fix old custom shaders.
|
||||
|
||||
if (pp_data.GetString().IndexOf("ProcessLight") < 0)
|
||||
{
|
||||
int pl_lump = Wads.CheckNumForFullName("shaders/glsl/func_defaultlight.fp");
|
||||
if (pl_lump == -1) I_Error("Unable to load '%s'", "shaders/glsl/func_defaultlight.fp");
|
||||
FMemLump pl_data = Wads.ReadLump(pl_lump);
|
||||
fp_comb << "\n" << pl_data.GetString().GetChars();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Proc_prog_lump is not a lump name but the source itself (from generated shaders)
|
||||
fp_comb << proc_prog_lump + 1;
|
||||
}
|
||||
}
|
||||
|
||||
hVertProg = glCreateShader(GL_VERTEX_SHADER);
|
||||
hFragProg = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
|
||||
int vp_size = (int)vp_comb.Len();
|
||||
int fp_size = (int)fp_comb.Len();
|
||||
|
||||
const char *vp_ptr = vp_comb.GetChars();
|
||||
const char *fp_ptr = fp_comb.GetChars();
|
||||
|
||||
glShaderSource(hVertProg, 1, &vp_ptr, &vp_size);
|
||||
glShaderSource(hFragProg, 1, &fp_ptr, &fp_size);
|
||||
|
||||
glCompileShader(hVertProg);
|
||||
glCompileShader(hFragProg);
|
||||
|
||||
hShader = glCreateProgram();
|
||||
|
||||
glAttachShader(hShader, hVertProg);
|
||||
glAttachShader(hShader, hFragProg);
|
||||
|
||||
glBindAttribLocation(hShader, VATTR_VERTEX, "aPosition");
|
||||
glBindAttribLocation(hShader, VATTR_TEXCOORD, "aTexCoord");
|
||||
glBindAttribLocation(hShader, VATTR_COLOR, "aColor");
|
||||
glBindAttribLocation(hShader, VATTR_VERTEX2, "aVertex2");
|
||||
|
||||
glLinkProgram(hShader);
|
||||
|
||||
glGetShaderInfoLog(hVertProg, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Vertex shader:\n" << buffer << "\n";
|
||||
}
|
||||
glGetShaderInfoLog(hFragProg, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Fragment shader:\n" << buffer << "\n";
|
||||
}
|
||||
|
||||
glGetProgramInfoLog(hShader, 10000, NULL, buffer);
|
||||
if (*buffer)
|
||||
{
|
||||
error << "Linking:\n" << buffer << "\n";
|
||||
}
|
||||
int linked;
|
||||
glGetProgramiv(hShader, GL_LINK_STATUS, &linked);
|
||||
if (linked == 0)
|
||||
{
|
||||
// only print message if there's an error.
|
||||
I_Error("Init Shader '%s':\n%s\n", name, error.GetChars());
|
||||
}
|
||||
|
||||
|
||||
muDesaturation.Init(hShader, "uDesaturationFactor");
|
||||
muFogEnabled.Init(hShader, "uFogEnabled");
|
||||
muTextureMode.Init(hShader, "uTextureMode");
|
||||
muCameraPos.Init(hShader, "uCameraPos");
|
||||
muLightParms.Init(hShader, "uLightAttr");
|
||||
muColormapStart.Init(hShader, "uFixedColormapStart");
|
||||
muColormapRange.Init(hShader, "uFixedColormapRange");
|
||||
muLightIndex.Init(hShader, "uLightIndex");
|
||||
muFogColor.Init(hShader, "uFogColor");
|
||||
muDynLightColor.Init(hShader, "uDynLightColor");
|
||||
muObjectColor.Init(hShader, "uObjectColor");
|
||||
muGlowBottomColor.Init(hShader, "uGlowBottomColor");
|
||||
muGlowTopColor.Init(hShader, "uGlowTopColor");
|
||||
muGlowBottomPlane.Init(hShader, "uGlowBottomPlane");
|
||||
muGlowTopPlane.Init(hShader, "uGlowTopPlane");
|
||||
muFixedColormap.Init(hShader, "uFixedColormap");
|
||||
muInterpolationFactor.Init(hShader, "uInterpolationFactor");
|
||||
muClipHeightTop.Init(hShader, "uClipHeightTop");
|
||||
muClipHeightBottom.Init(hShader, "uClipHeightBottom");
|
||||
muAlphaThreshold.Init(hShader, "uAlphaThreshold");
|
||||
muTimer.Init(hShader, "timer");
|
||||
|
||||
lights_index = glGetUniformLocation(hShader, "lights");
|
||||
fakevb_index = glGetUniformLocation(hShader, "fakeVB");
|
||||
projectionmatrix_index = glGetUniformLocation(hShader, "ProjectionMatrix");
|
||||
viewmatrix_index = glGetUniformLocation(hShader, "ViewMatrix");
|
||||
modelmatrix_index = glGetUniformLocation(hShader, "ModelMatrix");
|
||||
texturematrix_index = glGetUniformLocation(hShader, "TextureMatrix");
|
||||
|
||||
int tempindex = glGetUniformBlockIndex(hShader, "LightBufferUBO");
|
||||
if (tempindex != -1) glUniformBlockBinding(hShader, tempindex, LIGHTBUF_BINDINGPOINT);
|
||||
|
||||
glUseProgram(hShader);
|
||||
|
||||
// set up other texture units (if needed by the shader)
|
||||
for (int i = 2; i<16; i++)
|
||||
{
|
||||
char stringbuf[20];
|
||||
mysnprintf(stringbuf, 20, "texture%d", i);
|
||||
tempindex = glGetUniformLocation(hShader, stringbuf);
|
||||
if (tempindex > 0) glUniform1i(tempindex, i - 1);
|
||||
}
|
||||
|
||||
glUseProgram(0);
|
||||
return !!linked;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -218,160 +260,41 @@ FShader::~FShader()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool FShader::Bind(float Speed)
|
||||
bool FShader::Bind()
|
||||
{
|
||||
GLRenderer->mShaderManager->SetActiveShader(this);
|
||||
if (timer_index >=0 && Speed > 0.f) glUniform1f(timer_index, gl_frameMS*Speed/1000.f);
|
||||
return true;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
// Since all shaders are REQUIRED, any error here needs to be fatal
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FShaderContainer::FShaderContainer(const char *ShaderName, const char *ShaderPath)
|
||||
FShader *FShaderManager::Compile (const char *ShaderName, const char *ShaderPath, bool usediscard)
|
||||
{
|
||||
const char * shaderdefines[] = {
|
||||
"#define NO_GLOW\n#define NO_DESATURATE\n",
|
||||
"#define NO_DESATURATE\n",
|
||||
"#define NO_GLOW\n",
|
||||
"\n",
|
||||
"#define NO_GLOW\n#define NO_DESATURATE\n#define DYNLIGHT\n",
|
||||
"#define NO_DESATURATE\n#define DYNLIGHT\n",
|
||||
"#define NO_GLOW\n#define DYNLIGHT\n",
|
||||
"\n#define DYNLIGHT\n",
|
||||
"#define NO_GLOW\n#define NO_DESATURATE\n#define SOFTLIGHT\n",
|
||||
"#define NO_DESATURATE\n#define SOFTLIGHT\n",
|
||||
"#define NO_GLOW\n#define SOFTLIGHT\n",
|
||||
"\n#define SOFTLIGHT\n",
|
||||
"#define NO_GLOW\n#define NO_DESATURATE\n#define DYNLIGHT\n#define SOFTLIGHT\n",
|
||||
"#define NO_DESATURATE\n#define DYNLIGHT\n#define SOFTLIGHT\n",
|
||||
"#define NO_GLOW\n#define DYNLIGHT\n#define SOFTLIGHT\n",
|
||||
"\n#define DYNLIGHT\n#define SOFTLIGHT\n"
|
||||
};
|
||||
|
||||
const char * shaderdesc[] = {
|
||||
"::default",
|
||||
"::glow",
|
||||
"::desaturate",
|
||||
"::glow+desaturate",
|
||||
"::default+dynlight",
|
||||
"::glow+dynlight",
|
||||
"::desaturate+dynlight",
|
||||
"::glow+desaturate+dynlight",
|
||||
"::softlight",
|
||||
"::glow+softlight",
|
||||
"::desaturate+softlight",
|
||||
"::glow+desaturate+softlight",
|
||||
"::default+dynlight+softlight",
|
||||
"::glow+dynlight+softlight",
|
||||
"::desaturate+dynlight+softlight",
|
||||
"::glow+desaturate+dynlight+softlight",
|
||||
};
|
||||
|
||||
FString name;
|
||||
|
||||
name << ShaderName << "::colormap";
|
||||
FString defines;
|
||||
// this can't be in the shader code due to ATI strangeness.
|
||||
if (gl.MaxLights() == 128) defines += "#define MAXLIGHTS128\n";
|
||||
if (!usediscard) defines += "#define NO_ALPHATEST\n";
|
||||
|
||||
FShader *shader = NULL;
|
||||
try
|
||||
{
|
||||
shader_cm = new FShader;
|
||||
if (!shader_cm->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main_colormap.fp", ShaderPath, "#define NO_FOG\n#define NO_GLOW\n"))
|
||||
shader = new FShader(ShaderName);
|
||||
if (!shader->Load(ShaderName, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, defines.GetChars()))
|
||||
{
|
||||
delete shader_cm;
|
||||
shader_cm = NULL;
|
||||
I_FatalError("Unable to load shader %s\n", ShaderName);
|
||||
}
|
||||
}
|
||||
catch(CRecoverableError &err)
|
||||
{
|
||||
shader_cm = NULL;
|
||||
I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage());
|
||||
}
|
||||
|
||||
name << ShaderName << "::foglayer";
|
||||
|
||||
try
|
||||
{
|
||||
shader_fl = new FShader;
|
||||
if (!shader_fl->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main_foglayer.fp", ShaderPath, "#define NO_GLOW\n"))
|
||||
{
|
||||
delete shader_fl;
|
||||
shader_fl = NULL;
|
||||
}
|
||||
}
|
||||
catch (CRecoverableError &err)
|
||||
{
|
||||
shader_fl = NULL;
|
||||
I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage());
|
||||
}
|
||||
|
||||
if (gl.shadermodel > 2)
|
||||
{
|
||||
for(int i = 0;i < NUM_SHADERS; i++)
|
||||
{
|
||||
FString name;
|
||||
|
||||
name << ShaderName << shaderdesc[i];
|
||||
|
||||
try
|
||||
{
|
||||
FString str;
|
||||
if ((i&4) != 0)
|
||||
{
|
||||
if (gl.maxuniforms < 1024 || gl.shadermodel != 4)
|
||||
{
|
||||
shader[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
// this can't be in the shader code due to ATI strangeness.
|
||||
str = "#version 120\n#extension GL_EXT_gpu_shader4 : enable\n";
|
||||
if (gl.MaxLights() == 128) str += "#define MAXLIGHTS128\n";
|
||||
}
|
||||
if ((i&8) == 0)
|
||||
{
|
||||
if (gl.shadermodel != 4)
|
||||
{
|
||||
shader[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
str += shaderdefines[i];
|
||||
shader[i] = new FShader;
|
||||
if (!shader[i]->Load(name, "shaders/glsl/main.vp", "shaders/glsl/main.fp", ShaderPath, str.GetChars()))
|
||||
{
|
||||
delete shader[i];
|
||||
shader[i] = NULL;
|
||||
}
|
||||
}
|
||||
catch(CRecoverableError &err)
|
||||
{
|
||||
shader[i] = NULL;
|
||||
I_Error("Unable to load shader %s:\n%s\n", name.GetChars(), err.GetMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
else memset(shader, 0, sizeof(shader));
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
FShaderContainer::~FShaderContainer()
|
||||
{
|
||||
if (shader_cm != NULL) delete shader_cm;
|
||||
if (shader_fl != NULL) delete shader_fl;
|
||||
for (int i = 0; i < NUM_SHADERS; i++)
|
||||
{
|
||||
if (shader[i] != NULL)
|
||||
{
|
||||
delete shader[i];
|
||||
shader[i] = NULL;
|
||||
}
|
||||
if (shader != NULL) delete shader;
|
||||
shader = NULL;
|
||||
I_FatalError("Unable to load shader %s:\n%s\n", ShaderName, err.GetMessage());
|
||||
}
|
||||
return shader;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -380,49 +303,11 @@ FShaderContainer::~FShaderContainer()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FShader *FShaderContainer::Bind(int cm, bool glowing, float Speed, bool lights)
|
||||
void FShader::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
|
||||
{
|
||||
FShader *sh=NULL;
|
||||
|
||||
if (cm == CM_FOGLAYER)
|
||||
{
|
||||
if (shader_fl)
|
||||
{
|
||||
shader_fl->Bind(Speed);
|
||||
}
|
||||
return shader_fl;
|
||||
}
|
||||
else if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_MAXCOLORMAP)
|
||||
{
|
||||
// these are never used with any kind of lighting or fog
|
||||
sh = shader_cm;
|
||||
// [BB] If there was a problem when loading the shader, sh is NULL here.
|
||||
if( sh )
|
||||
{
|
||||
FSpecialColormap *map = &SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP];
|
||||
sh->Bind(Speed);
|
||||
float m[3]= {map->ColorizeEnd[0] - map->ColorizeStart[0],
|
||||
map->ColorizeEnd[1] - map->ColorizeStart[1], map->ColorizeEnd[2] - map->ColorizeStart[2]};
|
||||
|
||||
glUniform3fv(sh->colormapstart_index, 1, map->ColorizeStart);
|
||||
glUniform3fv(sh->colormaprange_index, 1, m);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool desat = cm>=CM_DESAT1 && cm<=CM_DESAT31;
|
||||
sh = shader[glowing + 2*desat + 4*lights + (glset.lightmode & 8)];
|
||||
// [BB] If there was a problem when loading the shader, sh is NULL here.
|
||||
if( sh )
|
||||
{
|
||||
sh->Bind(Speed);
|
||||
if (desat)
|
||||
{
|
||||
glUniform1f(sh->desaturation_index, 1.f-float(cm-CM_DESAT0)/(CM_DESAT31-CM_DESAT0));
|
||||
}
|
||||
}
|
||||
}
|
||||
return sh;
|
||||
Bind();
|
||||
glUniformMatrix4fv(projectionmatrix_index, 1, false, proj->get());
|
||||
glUniformMatrix4fv(viewmatrix_index, 1, false, view->get());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -469,8 +354,10 @@ struct FEffectShader
|
|||
|
||||
static const FEffectShader effectshaders[]=
|
||||
{
|
||||
{"fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "#define NO_GLOW\n"},
|
||||
{"spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define NO_GLOW\n#define NO_DESATURATE\n#define SPHEREMAP\n#define SPHEREMAP_0\n"}
|
||||
{ "fogboundary", "shaders/glsl/main.vp", "shaders/glsl/fogboundary.fp", NULL, "#define NO_ALPHATEST\n" },
|
||||
{ "spheremap", "shaders/glsl/main.vp", "shaders/glsl/main.fp", "shaders/glsl/func_normal.fp", "#define SPHEREMAP\n#define NO_ALPHATEST\n" },
|
||||
{ "burn", "shaders/glsl/main.vp", "shaders/glsl/burn.fp", NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" },
|
||||
{ "stencil", "shaders/glsl/main.vp", "shaders/glsl/stencil.fp", NULL, "#define SIMPLE\n#define NO_ALPHATEST\n" },
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -502,55 +389,46 @@ FShaderManager::~FShaderManager()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderManager::Recompile()
|
||||
{
|
||||
Clean();
|
||||
CompileShaders();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FShaderManager::CompileShaders()
|
||||
{
|
||||
mActiveShader = mEffectShaders[0] = mEffectShaders[1] = NULL;
|
||||
if (gl.shadermodel > 0)
|
||||
mActiveShader = NULL;
|
||||
|
||||
mTextureEffects.Clear();
|
||||
mTextureEffectsNAT.Clear();
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
|
||||
{
|
||||
FShaderContainer * shc = new FShaderContainer(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc);
|
||||
mTextureEffects.Push(shc);
|
||||
if (gl.shadermodel <= 2) return; // SM2 will only initialize the default shader
|
||||
}
|
||||
mEffectShaders[i] = NULL;
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < usershaders.Size(); i++)
|
||||
for(int i=0;defaultshaders[i].ShaderName != NULL;i++)
|
||||
{
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, true);
|
||||
mTextureEffects.Push(shc);
|
||||
if (i <= 3)
|
||||
{
|
||||
FString name = ExtractFileBase(usershaders[i]);
|
||||
FName sfn = name;
|
||||
|
||||
if (gl.shadermodel > 2)
|
||||
{
|
||||
FShaderContainer * shc = new FShaderContainer(sfn, usershaders[i]);
|
||||
mTextureEffects.Push(shc);
|
||||
}
|
||||
FShader *shc = Compile(defaultshaders[i].ShaderName, defaultshaders[i].gettexelfunc, false);
|
||||
mTextureEffectsNAT.Push(shc);
|
||||
}
|
||||
}
|
||||
|
||||
if (gl.shadermodel > 2)
|
||||
for(unsigned i = 0; i < usershaders.Size(); i++)
|
||||
{
|
||||
FString name = ExtractFileBase(usershaders[i]);
|
||||
FName sfn = name;
|
||||
|
||||
FShader *shc = Compile(sfn, usershaders[i], true);
|
||||
mTextureEffects.Push(shc);
|
||||
}
|
||||
|
||||
for(int i=0;i<MAX_EFFECTS;i++)
|
||||
{
|
||||
FShader *eff = new FShader(effectshaders[i].ShaderName);
|
||||
if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1,
|
||||
effectshaders[i].fp2, effectshaders[i].defines))
|
||||
{
|
||||
for(int i=0;i<NUM_EFFECTS;i++)
|
||||
{
|
||||
FShader *eff = new FShader();
|
||||
if (!eff->Load(effectshaders[i].ShaderName, effectshaders[i].vp, effectshaders[i].fp1,
|
||||
effectshaders[i].fp2, effectshaders[i].defines))
|
||||
{
|
||||
delete eff;
|
||||
}
|
||||
else mEffectShaders[i] = eff;
|
||||
}
|
||||
delete eff;
|
||||
}
|
||||
else mEffectShaders[i] = eff;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -562,17 +440,24 @@ void FShaderManager::CompileShaders()
|
|||
|
||||
void FShaderManager::Clean()
|
||||
{
|
||||
SetActiveShader(NULL);
|
||||
for(unsigned int i=0;i<mTextureEffects.Size();i++)
|
||||
glUseProgram(0);
|
||||
mActiveShader = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < mTextureEffectsNAT.Size(); i++)
|
||||
{
|
||||
if (mTextureEffectsNAT[i] != NULL) delete mTextureEffectsNAT[i];
|
||||
}
|
||||
for (unsigned int i = 0; i < mTextureEffects.Size(); i++)
|
||||
{
|
||||
if (mTextureEffects[i] != NULL) delete mTextureEffects[i];
|
||||
}
|
||||
for(int i=0;i<NUM_EFFECTS;i++)
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
if (mEffectShaders[i] != NULL) delete mEffectShaders[i];
|
||||
mEffectShaders[i] = NULL;
|
||||
}
|
||||
mTextureEffects.Clear();
|
||||
mTextureEffectsNAT.Clear();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -587,7 +472,7 @@ int FShaderManager::Find(const char * shn)
|
|||
|
||||
for(unsigned int i=0;i<mTextureEffects.Size();i++)
|
||||
{
|
||||
if (mTextureEffects[i]->Name == sfn)
|
||||
if (mTextureEffects[i]->mName == sfn)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
|
|
@ -603,14 +488,14 @@ int FShaderManager::Find(const char * shn)
|
|||
|
||||
void FShaderManager::SetActiveShader(FShader *sh)
|
||||
{
|
||||
// shadermodel needs to be tested here because without it UseProgram will be NULL.
|
||||
if (gl.shadermodel > 0 && mActiveShader != sh)
|
||||
if (mActiveShader != sh)
|
||||
{
|
||||
glUseProgram(sh == NULL? 0 : sh->GetHandle());
|
||||
glUseProgram(sh!= NULL? sh->GetHandle() : 0);
|
||||
mActiveShader = sh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -619,15 +504,45 @@ void FShaderManager::SetActiveShader(FShader *sh)
|
|||
|
||||
FShader *FShaderManager::BindEffect(int effect)
|
||||
{
|
||||
if (effect > 0 && effect <= NUM_EFFECTS && mEffectShaders[effect-1] != NULL)
|
||||
if (effect >= 0 && effect < MAX_EFFECTS && mEffectShaders[effect] != NULL)
|
||||
{
|
||||
mEffectShaders[effect-1]->Bind(0);
|
||||
return mEffectShaders[effect-1];
|
||||
mEffectShaders[effect]->Bind();
|
||||
return mEffectShaders[effect];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
EXTERN_CVAR(Int, gl_fuzztype)
|
||||
|
||||
void FShaderManager::ApplyMatrices(VSMatrix *proj, VSMatrix *view)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view);
|
||||
mTextureEffectsNAT[i]->ApplyMatrices(proj, view);
|
||||
}
|
||||
mTextureEffects[4]->ApplyMatrices(proj, view);
|
||||
if (gl_fuzztype != 0)
|
||||
{
|
||||
mTextureEffects[4+gl_fuzztype]->ApplyMatrices(proj, view);
|
||||
}
|
||||
for (unsigned i = 12; i < mTextureEffects.Size(); i++)
|
||||
{
|
||||
mTextureEffects[i]->ApplyMatrices(proj, view);
|
||||
}
|
||||
for (int i = 0; i < MAX_EFFECTS; i++)
|
||||
{
|
||||
mEffectShaders[i]->ApplyMatrices(proj, view);
|
||||
}
|
||||
if (mActiveShader != NULL) mActiveShader->Bind();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
|||
|
|
@ -7,76 +7,222 @@
|
|||
|
||||
extern bool gl_shaderactive;
|
||||
|
||||
const int VATTR_FOGPARAMS = 14;
|
||||
const int VATTR_LIGHTLEVEL = 13; // Korshun.
|
||||
enum
|
||||
{
|
||||
VATTR_VERTEX = 0,
|
||||
VATTR_TEXCOORD = 1,
|
||||
VATTR_COLOR = 2,
|
||||
VATTR_VERTEX2 = 3
|
||||
};
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FUniform1i
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
}
|
||||
|
||||
void Set(int newvalue)
|
||||
{
|
||||
glUniform1i(mIndex, newvalue);
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform1i
|
||||
{
|
||||
int mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(int newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform1i(mIndex, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform4i
|
||||
{
|
||||
int mBuffer[4];
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
memset(mBuffer, 0, sizeof(mBuffer));
|
||||
}
|
||||
|
||||
void Set(const int *newvalue)
|
||||
{
|
||||
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
|
||||
{
|
||||
memcpy(mBuffer, newvalue, sizeof(mBuffer));
|
||||
glUniform4iv(mIndex, 1, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform1f
|
||||
{
|
||||
float mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(float newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform1f(mIndex, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniform4f
|
||||
{
|
||||
float mBuffer[4];
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
memset(mBuffer, 0, sizeof(mBuffer));
|
||||
}
|
||||
|
||||
void Set(const float *newvalue)
|
||||
{
|
||||
if (memcmp(newvalue, mBuffer, sizeof(mBuffer)))
|
||||
{
|
||||
memcpy(mBuffer, newvalue, sizeof(mBuffer));
|
||||
glUniform4fv(mIndex, 1, newvalue);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class FUniform4f
|
||||
{
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
}
|
||||
|
||||
void Set(const float *newvalue)
|
||||
{
|
||||
glUniform4fv(mIndex, 1, newvalue);
|
||||
}
|
||||
|
||||
void Set(float a, float b, float c, float d)
|
||||
{
|
||||
glUniform4f(mIndex, a, b, c, d);
|
||||
}
|
||||
};
|
||||
|
||||
class FBufferedUniformPE
|
||||
{
|
||||
PalEntry mBuffer;
|
||||
int mIndex;
|
||||
|
||||
public:
|
||||
void Init(GLuint hShader, const GLchar *name)
|
||||
{
|
||||
mIndex = glGetUniformLocation(hShader, name);
|
||||
mBuffer = 0;
|
||||
}
|
||||
|
||||
void Set(PalEntry newvalue)
|
||||
{
|
||||
if (newvalue != mBuffer)
|
||||
{
|
||||
mBuffer = newvalue;
|
||||
glUniform4f(mIndex, newvalue.r/255.f, newvalue.g/255.f, newvalue.b/255.f, newvalue.a/255.f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FShader
|
||||
{
|
||||
friend class FShaderContainer;
|
||||
friend class FShaderManager;
|
||||
friend class FRenderState;
|
||||
|
||||
unsigned int hShader;
|
||||
unsigned int hVertProg;
|
||||
unsigned int hFragProg;
|
||||
FName mName;
|
||||
|
||||
int timer_index;
|
||||
int desaturation_index;
|
||||
int fogenabled_index;
|
||||
int texturemode_index;
|
||||
int camerapos_index;
|
||||
int lightparms_index;
|
||||
int colormapstart_index;
|
||||
int colormaprange_index;
|
||||
int lightrange_index;
|
||||
int fogcolor_index;
|
||||
FBufferedUniform1f muDesaturation;
|
||||
FBufferedUniform1i muFogEnabled;
|
||||
FBufferedUniform1i muTextureMode;
|
||||
FBufferedUniform4f muCameraPos;
|
||||
FBufferedUniform4f muLightParms;
|
||||
FUniform1i muFixedColormap;
|
||||
FUniform4f muColormapStart;
|
||||
FUniform4f muColormapRange;
|
||||
FBufferedUniform1i muLightIndex;
|
||||
FBufferedUniformPE muFogColor;
|
||||
FBufferedUniform4f muDynLightColor;
|
||||
FBufferedUniformPE muObjectColor;
|
||||
FUniform4f muGlowBottomColor;
|
||||
FUniform4f muGlowTopColor;
|
||||
FUniform4f muGlowBottomPlane;
|
||||
FUniform4f muGlowTopPlane;
|
||||
FBufferedUniform1f muInterpolationFactor;
|
||||
FBufferedUniform1f muClipHeightTop;
|
||||
FBufferedUniform1f muClipHeightBottom;
|
||||
FBufferedUniform1f muAlphaThreshold;
|
||||
FBufferedUniform1f muTimer;
|
||||
|
||||
int lights_index;
|
||||
int dlightcolor_index;
|
||||
int glowbottomcolor_index;
|
||||
int glowtopcolor_index;
|
||||
int glowbottomplane_index;
|
||||
int glowtopplane_index;
|
||||
|
||||
int projectionmatrix_index;
|
||||
int viewmatrix_index;
|
||||
int modelmatrix_index;
|
||||
int texturematrix_index;
|
||||
public:
|
||||
int fakevb_index;
|
||||
private:
|
||||
int currentglowstate;
|
||||
int currentfogenabled;
|
||||
int currenttexturemode;
|
||||
float currentlightfactor;
|
||||
float currentlightdist;
|
||||
|
||||
PalEntry currentfogcolor;
|
||||
float currentfogdensity;
|
||||
|
||||
FStateVec3 currentcamerapos;
|
||||
int currentfixedcolormap;
|
||||
bool currentTextureMatrixState;
|
||||
bool currentModelMatrixState;
|
||||
|
||||
public:
|
||||
FShader()
|
||||
FShader(const char *name)
|
||||
: mName(name)
|
||||
{
|
||||
hShader = hVertProg = hFragProg = 0;
|
||||
currentglowstate = currentfogenabled = currenttexturemode = 0;
|
||||
currentlightfactor = currentlightdist = 0.0f;
|
||||
currentfogdensity = -1;
|
||||
currentfogcolor = 0;
|
||||
|
||||
timer_index = -1;
|
||||
desaturation_index = -1;
|
||||
fogenabled_index = -1;
|
||||
texturemode_index = -1;
|
||||
camerapos_index = -1;
|
||||
lightparms_index = -1;
|
||||
colormapstart_index = -1;
|
||||
colormaprange_index = -1;
|
||||
lightrange_index = -1;
|
||||
fogcolor_index = -1;
|
||||
lights_index = -1;
|
||||
dlightcolor_index = -1;
|
||||
glowtopplane_index = -1;
|
||||
glowbottomplane_index = -1;
|
||||
glowtopcolor_index = -1;
|
||||
glowbottomcolor_index = -1;
|
||||
currentglowstate = 0;
|
||||
currentfixedcolormap = 0;
|
||||
currentTextureMatrixState = true; // by setting the matrix state to 'true' it is guaranteed to be set the first time the render state gets applied.
|
||||
currentModelMatrixState = true;
|
||||
}
|
||||
|
||||
~FShader();
|
||||
|
|
@ -87,34 +233,11 @@ public:
|
|||
void SetGlowParams(float *topcolors, float topheight, float *bottomcolors, float bottomheight);
|
||||
void SetLightRange(int start, int end, int forceadd);
|
||||
|
||||
bool Bind(float Speed);
|
||||
bool Bind();
|
||||
unsigned int GetHandle() const { return hShader; }
|
||||
|
||||
};
|
||||
void ApplyMatrices(VSMatrix *proj, VSMatrix *view);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This class contains the shaders for the different lighting modes
|
||||
// that are required (e.g. special colormaps etc.)
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
class FShaderContainer
|
||||
{
|
||||
friend class FShaderManager;
|
||||
|
||||
FName Name;
|
||||
|
||||
enum { NUM_SHADERS = 16 };
|
||||
|
||||
FShader *shader[NUM_SHADERS];
|
||||
FShader *shader_cm; // the shader for fullscreen colormaps
|
||||
FShader *shader_fl; // the shader for the fog layer
|
||||
|
||||
public:
|
||||
FShaderContainer(const char *ShaderName, const char *ShaderPath);
|
||||
~FShaderContainer();
|
||||
FShader *Bind(int cm, bool glowing, float Speed, bool lights);
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -125,14 +248,10 @@ public:
|
|||
//==========================================================================
|
||||
class FShaderManager
|
||||
{
|
||||
enum
|
||||
{
|
||||
NUM_EFFECTS = 2
|
||||
};
|
||||
|
||||
TArray<FShaderContainer*> mTextureEffects;
|
||||
TArray<FShader*> mTextureEffects;
|
||||
TArray<FShader*> mTextureEffectsNAT;
|
||||
FShader *mActiveShader;
|
||||
FShader *mEffectShaders[NUM_EFFECTS];
|
||||
FShader *mEffectShaders[MAX_EFFECTS];
|
||||
|
||||
void Clean();
|
||||
void CompileShaders();
|
||||
|
|
@ -140,25 +259,37 @@ class FShaderManager
|
|||
public:
|
||||
FShaderManager();
|
||||
~FShaderManager();
|
||||
FShader *Compile(const char *ShaderName, const char *ShaderPath, bool usediscard);
|
||||
int Find(const char *mame);
|
||||
FShader *BindEffect(int effect);
|
||||
void SetActiveShader(FShader *sh);
|
||||
void ApplyMatrices(VSMatrix *proj, VSMatrix *view);
|
||||
FShader *GetActiveShader() const
|
||||
{
|
||||
return mActiveShader;
|
||||
}
|
||||
|
||||
FShaderContainer *Get(unsigned int eff)
|
||||
FShader *Get(unsigned int eff, bool alphateston)
|
||||
{
|
||||
// indices 0-2 match the warping modes, 3 is brightmap, 4 no texture, the following are custom
|
||||
if (!alphateston && eff <= 3)
|
||||
{
|
||||
return mTextureEffectsNAT[eff]; // Non-alphatest shaders are only created for default, warp1+2 and brightmap. The rest won't get used anyway
|
||||
}
|
||||
if (eff < mTextureEffects.Size())
|
||||
{
|
||||
return mTextureEffects[eff];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Recompile();
|
||||
};
|
||||
|
||||
#define FIRST_USER_SHADER 12
|
||||
|
||||
enum
|
||||
{
|
||||
LIGHTBUF_BINDINGPOINT = 1
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -10,12 +10,6 @@
|
|||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
EXTERN_CVAR(Bool, gl_warp_shader)
|
||||
EXTERN_CVAR(Bool, gl_fog_shader)
|
||||
EXTERN_CVAR(Bool, gl_colormap_shader)
|
||||
EXTERN_CVAR(Bool, gl_brightmap_shader)
|
||||
EXTERN_CVAR(Bool, gl_glow_shader)
|
||||
|
||||
EXTERN_CVAR(Bool,gl_enhanced_nightvision)
|
||||
EXTERN_CVAR(Int, screenblocks);
|
||||
EXTERN_CVAR(Bool, gl_texture)
|
||||
|
|
@ -27,8 +21,6 @@ EXTERN_CVAR(Bool, gl_usefb)
|
|||
|
||||
EXTERN_CVAR(Int, gl_weaponlight)
|
||||
|
||||
EXTERN_CVAR(Bool, gl_forcemultipass)
|
||||
|
||||
EXTERN_CVAR (Bool, gl_lights);
|
||||
EXTERN_CVAR (Bool, gl_attachedlights);
|
||||
EXTERN_CVAR (Bool, gl_lights_checkside);
|
||||
|
|
@ -44,15 +36,9 @@ EXTERN_CVAR(Bool,gl_mirror_envmap)
|
|||
|
||||
EXTERN_CVAR(Bool,gl_mirrors)
|
||||
EXTERN_CVAR(Bool,gl_mirror_envmap)
|
||||
EXTERN_CVAR(Bool, gl_render_segs)
|
||||
EXTERN_CVAR(Bool, gl_seamless)
|
||||
EXTERN_CVAR(Bool, gl_dynlight_shader)
|
||||
|
||||
EXTERN_CVAR(Float, gl_mask_threshold)
|
||||
EXTERN_CVAR(Float, gl_mask_sprite_threshold)
|
||||
|
||||
EXTERN_CVAR(Int, gl_usevbo)
|
||||
|
||||
|
||||
|
||||
#endif // _GL_INTERN_H
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@
|
|||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/textures/gl_hwtexture.h"
|
||||
|
|
@ -73,9 +74,9 @@ CVAR(Bool, gl_aalines, false, CVAR_ARCHIVE)
|
|||
|
||||
FGLRenderer *GLRenderer;
|
||||
|
||||
void gl_SetupMenu();
|
||||
void gl_LoadExtensions();
|
||||
void gl_PrintStartupLog();
|
||||
void gl_SetupMenu();
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
@ -120,11 +121,12 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
|
||||
if (first)
|
||||
{
|
||||
glewInit();
|
||||
ogl_LoadFunctions();
|
||||
}
|
||||
|
||||
gl_LoadExtensions();
|
||||
Super::InitializeState();
|
||||
|
||||
if (first)
|
||||
{
|
||||
first=false;
|
||||
|
|
@ -137,31 +139,17 @@ void OpenGLFrameBuffer::InitializeState()
|
|||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
glClearDepth(1.0f);
|
||||
glDepthFunc(GL_LESS);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glEnable(GL_DITHER);
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_POLYGON_OFFSET_FILL);
|
||||
glEnable(GL_POLYGON_OFFSET_LINE);
|
||||
glEnable(GL_BLEND);
|
||||
glEnable(GL_DEPTH_CLAMP_NV);
|
||||
glEnable(GL_DEPTH_CLAMP);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glAlphaFunc(GL_GEQUAL,0.5f);
|
||||
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
|
||||
glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
|
||||
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
|
||||
// This was to work around a bug in some older driver. Probably doesn't make sense anymore.
|
||||
glEnable(GL_FOG);
|
||||
glDisable(GL_FOG);
|
||||
|
||||
glHint(GL_FOG_HINT, GL_FASTEST);
|
||||
glFogi(GL_FOG_MODE, GL_EXP);
|
||||
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
|
@ -386,18 +374,10 @@ FNativePalette *OpenGLFrameBuffer::CreatePalette(FRemapTable *remap)
|
|||
//==========================================================================
|
||||
bool OpenGLFrameBuffer::Begin2D(bool)
|
||||
{
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glOrtho(
|
||||
(GLdouble) 0,
|
||||
(GLdouble) GetWidth(),
|
||||
(GLdouble) GetHeight(),
|
||||
(GLdouble) 0,
|
||||
(GLdouble) -1.0,
|
||||
(GLdouble) 1.0
|
||||
);
|
||||
gl_RenderState.mViewMatrix.loadIdentity();
|
||||
gl_RenderState.mProjectionMatrix.ortho(0, GetWidth(), GetHeight(), 0, -1.0f, 1.0f);
|
||||
gl_RenderState.ApplyMatrices();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
// Korshun: ENABLE AUTOMAP ANTIALIASING!!!
|
||||
|
|
@ -556,4 +536,5 @@ void OpenGLFrameBuffer::GameRestart()
|
|||
ScreenshotBuffer = NULL;
|
||||
LastCamera = NULL;
|
||||
gl_GenerateGlobalBrightmapFromColormap();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,6 @@ RenderContext gl;
|
|||
|
||||
int occlusion_type=0;
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -61,24 +60,15 @@ int occlusion_type=0;
|
|||
|
||||
static void CollectExtensions()
|
||||
{
|
||||
const char *supported = NULL;
|
||||
char *extensions, *extension;
|
||||
const char *extension;
|
||||
|
||||
supported = (char *)glGetString(GL_EXTENSIONS);
|
||||
int max = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &max);
|
||||
|
||||
if (supported)
|
||||
for(int i = 0; i < max; i++)
|
||||
{
|
||||
extensions = new char[strlen(supported) + 1];
|
||||
strcpy(extensions, supported);
|
||||
|
||||
extension = strtok(extensions, " ");
|
||||
while(extension)
|
||||
{
|
||||
m_Extensions.Push(FString(extension));
|
||||
extension = strtok(NULL, " ");
|
||||
}
|
||||
|
||||
delete [] extensions;
|
||||
extension = (const char*)glGetStringi(GL_EXTENSIONS, i);
|
||||
m_Extensions.Push(FString(extension));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -122,61 +112,41 @@ void gl_LoadExtensions()
|
|||
InitContext();
|
||||
CollectExtensions();
|
||||
|
||||
const char *version = (const char*)glGetString(GL_VERSION);
|
||||
const char *version = Args->CheckValue("-glversion");
|
||||
if (version == NULL) version = (const char*)glGetString(GL_VERSION);
|
||||
else Printf("Emulating OpenGL v %s\n", version);
|
||||
|
||||
// Don't even start if it's lower than 1.3
|
||||
if (strcmp(version, "2.0") < 0)
|
||||
// Don't even start if it's lower than 3.0
|
||||
if (strcmp(version, "3.0") < 0)
|
||||
{
|
||||
I_FatalError("Unsupported OpenGL version.\nAt least GL 2.0 is required to run " GAMENAME ".\n");
|
||||
I_FatalError("Unsupported OpenGL version.\nAt least OpenGL 3.0 is required to run " GAMENAME ".\n");
|
||||
}
|
||||
|
||||
// This loads any function pointers and flags that require a vaild render context to
|
||||
// initialize properly
|
||||
// add 0.01 to account for roundoff errors making the number a tad smaller than the actual version
|
||||
gl.version = strtod(version, NULL) + 0.01f;
|
||||
gl.glslversion = strtod((char*)glGetString(GL_SHADING_LANGUAGE_VERSION), NULL) + 0.01f;
|
||||
|
||||
gl.shadermodel = 0; // assume no shader support
|
||||
gl.vendorstring=(char*)glGetString(GL_VENDOR);
|
||||
gl.vendorstring = (char*)glGetString(GL_VENDOR);
|
||||
|
||||
if (CheckExtension("GL_ARB_texture_compression")) gl.flags|=RFL_TEXTURE_COMPRESSION;
|
||||
if (CheckExtension("GL_EXT_texture_compression_s3tc")) gl.flags|=RFL_TEXTURE_COMPRESSION_S3TC;
|
||||
if (strstr(gl.vendorstring, "NVIDIA")) gl.flags|=RFL_NVIDIA;
|
||||
else if (strstr(gl.vendorstring, "ATI Technologies")) gl.flags|=RFL_ATI;
|
||||
|
||||
if (strcmp(version, "2.0") >= 0) gl.flags|=RFL_GL_20;
|
||||
if (strcmp(version, "2.1") >= 0) gl.flags|=RFL_GL_21;
|
||||
if (strcmp(version, "3.0") >= 0) gl.flags|=RFL_GL_30;
|
||||
|
||||
if (!Args->CheckParm("-gl3"))
|
||||
{
|
||||
// don't use GL 4.x features when running in GL 3 emulation mode.
|
||||
if (CheckExtension("GL_ARB_shader_storage_buffer_object")) gl.flags |= RFL_SHADER_STORAGE_BUFFER;
|
||||
if (CheckExtension("GL_ARB_buffer_storage")) gl.flags |= RFL_BUFFER_STORAGE;
|
||||
}
|
||||
|
||||
int v;
|
||||
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v);
|
||||
gl.maxuniforms = v;
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v);
|
||||
gl.maxuniformblock = v;
|
||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v);
|
||||
gl.uniformblockalignment = v;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gl.max_texturesize);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
if (gl.flags & RFL_GL_20)
|
||||
{
|
||||
// Rules:
|
||||
// SM4 will always use shaders. No option to switch them off is needed here.
|
||||
// SM3 has shaders optional but they are off by default (they will have a performance impact
|
||||
// SM2 only uses shaders for colormaps on camera textures and has no option to use them in general.
|
||||
// On SM2 cards the shaders will be too slow and show visual bugs (at least on GF 6800.)
|
||||
if (strcmp((const char*)glGetString(GL_SHADING_LANGUAGE_VERSION), "1.3") >= 0) gl.shadermodel = 4;
|
||||
else if (CheckExtension("GL_NV_GPU_shader4")) gl.shadermodel = 4; // for pre-3.0 drivers that support GF8xxx.
|
||||
else if (CheckExtension("GL_EXT_GPU_shader4")) gl.shadermodel = 4; // for pre-3.0 drivers that support GF8xxx.
|
||||
else if (CheckExtension("GL_NV_vertex_program3")) gl.shadermodel = 3;
|
||||
else if (!strstr(gl.vendorstring, "NVIDIA")) gl.shadermodel = 3;
|
||||
else gl.shadermodel = 2; // Only for older NVidia cards which had notoriously bad shader support.
|
||||
|
||||
// Command line overrides for testing and problem cases.
|
||||
if (Args->CheckParm("-sm2") && gl.shadermodel > 2) gl.shadermodel = 2;
|
||||
else if (Args->CheckParm("-sm3") && gl.shadermodel > 3) gl.shadermodel = 3;
|
||||
}
|
||||
|
||||
if (CheckExtension("GL_ARB_map_buffer_range"))
|
||||
{
|
||||
gl.flags|=RFL_MAP_BUFFER_RANGE;
|
||||
}
|
||||
|
||||
if (gl.flags & RFL_GL_30)
|
||||
{
|
||||
gl.flags|=RFL_FRAMEBUFFER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -187,99 +157,39 @@ void gl_LoadExtensions()
|
|||
|
||||
void gl_PrintStartupLog()
|
||||
{
|
||||
int v;
|
||||
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &v);
|
||||
|
||||
Printf ("GL_VENDOR: %s\n", glGetString(GL_VENDOR));
|
||||
Printf ("GL_RENDERER: %s\n", glGetString(GL_RENDERER));
|
||||
Printf ("GL_VERSION: %s\n", glGetString(GL_VERSION));
|
||||
Printf ("GL_VERSION: %s (%s profile)\n", glGetString(GL_VERSION), (v & GL_CONTEXT_CORE_PROFILE_BIT)? "Core" : "Compatibility");
|
||||
Printf ("GL_SHADING_LANGUAGE_VERSION: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
Printf ("GL_EXTENSIONS: %s\n", glGetString(GL_EXTENSIONS));
|
||||
int v;
|
||||
Printf ("GL_EXTENSIONS:");
|
||||
for (unsigned i = 0; i < m_Extensions.Size(); i++)
|
||||
{
|
||||
Printf(" %s", m_Extensions[i].GetChars());
|
||||
}
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &v);
|
||||
Printf("Max. texture size: %d\n", v);
|
||||
Printf("\nMax. texture size: %d\n", v);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &v);
|
||||
Printf ("Max. texture units: %d\n", v);
|
||||
glGetIntegerv(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, &v);
|
||||
Printf ("Max. fragment uniforms: %d\n", v);
|
||||
if (gl.shadermodel == 4) gl.maxuniforms = v;
|
||||
glGetIntegerv(GL_MAX_VERTEX_UNIFORM_COMPONENTS, &v);
|
||||
Printf ("Max. vertex uniforms: %d\n", v);
|
||||
glGetIntegerv(GL_MAX_UNIFORM_BLOCK_SIZE, &v);
|
||||
Printf ("Max. uniform block size: %d\n", v);
|
||||
glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &v);
|
||||
Printf ("Uniform block alignment: %d\n", v);
|
||||
|
||||
glGetIntegerv(GL_MAX_VARYING_FLOATS, &v);
|
||||
Printf ("Max. varying: %d\n", v);
|
||||
glGetIntegerv(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, &v);
|
||||
Printf ("Max. combined uniforms: %d\n", v);
|
||||
glGetIntegerv(GL_MAX_COMBINED_UNIFORM_BLOCKS, &v);
|
||||
Printf ("Max. combined uniform blocks: %d\n", v);
|
||||
glGetIntegerv(GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS, &v);
|
||||
Printf("Max. combined shader storage blocks: %d\n", v);
|
||||
glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &v);
|
||||
Printf("Max. vertex shader storage blocks: %d\n", v);
|
||||
|
||||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_SetTextureMode(int type)
|
||||
{
|
||||
static float white[] = {1.f,1.f,1.f,1.f};
|
||||
|
||||
if (type == TM_MASK)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
|
||||
}
|
||||
else if (type == TM_OPAQUE)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
}
|
||||
else if (type == TM_INVERT)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_SRC_ALPHA);
|
||||
}
|
||||
else if (type == TM_INVERTOPAQUE)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE0);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PRIMARY_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
}
|
||||
else // if (type == TM_MODULATE)
|
||||
{
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
}
|
||||
}
|
||||
|
||||
//} // extern "C"
|
||||
|
|
|
|||
|
|
@ -6,40 +6,30 @@
|
|||
enum RenderFlags
|
||||
{
|
||||
// [BB] Added texture compression flags.
|
||||
RFL_TEXTURE_COMPRESSION=8,
|
||||
RFL_TEXTURE_COMPRESSION_S3TC=16,
|
||||
RFL_TEXTURE_COMPRESSION=1,
|
||||
RFL_TEXTURE_COMPRESSION_S3TC=2,
|
||||
|
||||
RFL_MAP_BUFFER_RANGE = 64,
|
||||
RFL_FRAMEBUFFER = 128,
|
||||
RFL_TEXTUREBUFFER = 256,
|
||||
RFL_NVIDIA = 512,
|
||||
RFL_ATI = 1024,
|
||||
|
||||
|
||||
RFL_GL_20 = 0x10000000,
|
||||
RFL_GL_21 = 0x20000000,
|
||||
RFL_GL_30 = 0x40000000,
|
||||
RFL_SHADER_STORAGE_BUFFER = 4,
|
||||
RFL_BUFFER_STORAGE = 8
|
||||
};
|
||||
|
||||
enum TexMode
|
||||
{
|
||||
TMF_MASKBIT = 1,
|
||||
TMF_OPAQUEBIT = 2,
|
||||
TMF_INVERTBIT = 4,
|
||||
|
||||
TM_MODULATE = 0,
|
||||
TM_MASK = TMF_MASKBIT,
|
||||
TM_OPAQUE = TMF_OPAQUEBIT,
|
||||
TM_INVERT = TMF_INVERTBIT,
|
||||
//TM_INVERTMASK = TMF_MASKBIT | TMF_INVERTBIT
|
||||
TM_INVERTOPAQUE = TMF_INVERTBIT | TMF_OPAQUEBIT,
|
||||
TM_MODULATE = 0, // (r, g, b, a)
|
||||
TM_MASK, // (1, 1, 1, a)
|
||||
TM_OPAQUE, // (r, g, b, 1)
|
||||
TM_INVERSE, // (1-r, 1-g, 1-b, a)
|
||||
TM_REDTOALPHA, // (1, 1, 1, r)
|
||||
};
|
||||
|
||||
struct RenderContext
|
||||
{
|
||||
unsigned int flags;
|
||||
unsigned int shadermodel;
|
||||
unsigned int maxuniforms;
|
||||
unsigned int maxuniformblock;
|
||||
unsigned int uniformblockalignment;
|
||||
float version;
|
||||
float glslversion;
|
||||
int max_texturesize;
|
||||
char * vendorstring;
|
||||
|
||||
|
|
|
|||
1346
src/gl/system/gl_load.c
Normal file
1346
src/gl/system/gl_load.c
Normal file
File diff suppressed because it is too large
Load diff
1793
src/gl/system/gl_load.h
Normal file
1793
src/gl/system/gl_load.h
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -57,64 +57,4 @@ CUSTOM_CVAR (Float, vid_contrast, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
// when they are actually valid.
|
||||
void gl_SetupMenu()
|
||||
{
|
||||
if (gl.shadermodel < 4)
|
||||
{
|
||||
// Radial fog and Doom lighting are not available in SM < 4 cards
|
||||
// The way they are implemented does not work well on older hardware.
|
||||
|
||||
FOptionValues **opt = OptionValues.CheckKey("LightingModes");
|
||||
if (opt != NULL)
|
||||
{
|
||||
for(int i = (*opt)->mValues.Size()-1; i>=0; i--)
|
||||
{
|
||||
// Delete 'Doom' lighting mode
|
||||
if ((*opt)->mValues[i].Value == 2.0 || (*opt)->mValues[i].Value == 8.0)
|
||||
{
|
||||
(*opt)->mValues.Delete(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
opt = OptionValues.CheckKey("FogMode");
|
||||
if (opt != NULL)
|
||||
{
|
||||
for(int i = (*opt)->mValues.Size()-1; i>=0; i--)
|
||||
{
|
||||
// Delete 'Radial' fog mode
|
||||
if ((*opt)->mValues[i].Value == 2.0)
|
||||
{
|
||||
(*opt)->mValues.Delete(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disable features that don't work without shaders.
|
||||
if (gl_lightmode == 2 || gl_lightmode == 8) gl_lightmode = 3;
|
||||
if (gl_fogmode == 2) gl_fogmode = 1;
|
||||
if (gl_dynlight_shader) gl_dynlight_shader = false;
|
||||
}
|
||||
|
||||
if (gl.shadermodel != 3)
|
||||
{
|
||||
// The shader menu will only be visible on SM3.
|
||||
// SM2 won't use shaders unless unavoidable (and then it's automatic) and SM4 will always use shaders.
|
||||
// Find the OpenGLOptions menu and remove the item named GLShaderOptions.
|
||||
|
||||
FMenuDescriptor **desc = MenuDescriptors.CheckKey("OpenGLOptions");
|
||||
if (desc != NULL && (*desc)->mType == MDESC_OptionsMenu)
|
||||
{
|
||||
FOptionMenuDescriptor *opt = (FOptionMenuDescriptor *)*desc;
|
||||
|
||||
FName shader = "GLShaderOptions";
|
||||
for(unsigned i=0;i<opt->mItems.Size();i++)
|
||||
{
|
||||
FName nm = opt->mItems[i]->GetAction(NULL);
|
||||
if (nm == shader)
|
||||
{
|
||||
delete opt->mItems[i];
|
||||
opt->mItems.Delete(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,16 +67,10 @@
|
|||
#include <fcntl.h>
|
||||
|
||||
//GL headers
|
||||
#include <GL/glew.h>
|
||||
#include "gl_load.h"
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#elif defined(__unix__)
|
||||
//#include <GL/glxew.h>
|
||||
#else // !__APPLE__ && !__unix__
|
||||
#define DWORD WINDOWS_DWORD // I don't want to depend on this throughout the GL code!
|
||||
#include <GL/wglew.h>
|
||||
#undef DWORD
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
|||
|
|
@ -1,247 +0,0 @@
|
|||
#if 0 //ndef __GL_THREADS_H
|
||||
#define __GL_THREADS_H
|
||||
|
||||
#ifdef WIN32
|
||||
#include <process.h>
|
||||
#endif
|
||||
|
||||
#include "critsec.h"
|
||||
|
||||
// system specific Base classes - should be externalized to a separate header later.
|
||||
#ifdef WIN32
|
||||
class FEvent
|
||||
{
|
||||
HANDLE mEvent;
|
||||
|
||||
public:
|
||||
|
||||
FEvent(bool manual = true, bool initial = false)
|
||||
{
|
||||
mEvent = CreateEvent(NULL, manual, initial, NULL);
|
||||
}
|
||||
|
||||
~FEvent()
|
||||
{
|
||||
CloseHandle(mEvent);
|
||||
}
|
||||
|
||||
void Set()
|
||||
{
|
||||
SetEvent(mEvent);
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
ResetEvent(mEvent);
|
||||
}
|
||||
};
|
||||
|
||||
class FThread
|
||||
{
|
||||
protected:
|
||||
uintptr_t hThread;
|
||||
bool mTerminateRequest;
|
||||
public:
|
||||
|
||||
FThread(int stacksize)
|
||||
{
|
||||
hThread = _beginthreadex(NULL, stacksize, StaticRun, this, 0, NULL);
|
||||
}
|
||||
|
||||
virtual ~FThread()
|
||||
{
|
||||
CloseHandle((HANDLE)hThread);
|
||||
}
|
||||
|
||||
void SignalTerminate()
|
||||
{
|
||||
mTerminateRequest = true;
|
||||
}
|
||||
|
||||
virtual void Run() = 0;
|
||||
|
||||
private:
|
||||
static unsigned __stdcall StaticRun(void *param)
|
||||
{
|
||||
FThread *thread = (FThread*)param;
|
||||
thread->Run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#else
|
||||
class FEvent
|
||||
{
|
||||
public:
|
||||
|
||||
FEvent(bool manual = true, bool initial = false)
|
||||
{
|
||||
}
|
||||
|
||||
~FEvent()
|
||||
{
|
||||
}
|
||||
|
||||
void Set()
|
||||
{
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class FThread
|
||||
{
|
||||
protected:
|
||||
bool mTerminateRequest;
|
||||
public:
|
||||
|
||||
FThread(int stacksize)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~FThread()
|
||||
{
|
||||
}
|
||||
|
||||
void SignalTerminate()
|
||||
{
|
||||
mTerminateRequest = true;
|
||||
}
|
||||
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
CS_ValidateTexture,
|
||||
CS_Hacks,
|
||||
CS_Drawlist,
|
||||
CS_Portals,
|
||||
|
||||
MAX_GL_CRITICAL_SECTIONS
|
||||
};
|
||||
|
||||
class FJob
|
||||
{
|
||||
friend class FJobQueue;
|
||||
FJob *pNext;
|
||||
FJob *pPrev;
|
||||
|
||||
public:
|
||||
FJob() { pNext = pPrev = NULL; }
|
||||
virtual ~FJob();
|
||||
virtual void Run() = 0;
|
||||
};
|
||||
|
||||
class FJobQueue
|
||||
{
|
||||
FCriticalSection mCritSec; // for limiting access
|
||||
FEvent mEvent; // signals that the queue is emoty or not
|
||||
FJob *pFirst;
|
||||
FJob *pLast;
|
||||
|
||||
public:
|
||||
FJobQueue();
|
||||
~FJobQueue();
|
||||
|
||||
void AddJob(FJob *job);
|
||||
FJob *GetJob();
|
||||
};
|
||||
|
||||
class FJobThread : public FThread
|
||||
{
|
||||
FJobQueue *mQueue;
|
||||
|
||||
public:
|
||||
FJobThread(FJobQueue *queue);
|
||||
~FJobThread();
|
||||
void Run();
|
||||
};
|
||||
|
||||
class FGLJobProcessWall : public FJob
|
||||
{
|
||||
seg_t *mSeg;
|
||||
subsector_t *mSub;
|
||||
int mFrontsector, mBacksector;
|
||||
public:
|
||||
FGLJobProcessWall(seg_t *seg, subsector_t *sub, int frontsector, int backsector)
|
||||
{
|
||||
mSeg = seg;
|
||||
mSub = sub;
|
||||
mFrontsector = frontsector;
|
||||
mBacksector = backsector;
|
||||
}
|
||||
|
||||
void Run();
|
||||
};
|
||||
|
||||
class FGLJobProcessSprites : public FJob
|
||||
{
|
||||
sector_t *mSector;
|
||||
public:
|
||||
FGLJobProcessSprites(sector_t *sector);
|
||||
void Run();
|
||||
};
|
||||
|
||||
class FGLJobProcessParticles : public FJob
|
||||
{
|
||||
subsector_t *mSubsector;
|
||||
public:
|
||||
FGLJobProcessParticles(subsector_t *subsector);
|
||||
void Run();
|
||||
};
|
||||
|
||||
class FGLJobProcessFlats : public FJob
|
||||
{
|
||||
subsector_t *mSubsector;
|
||||
public:
|
||||
FGLJobProcessFlats(subsector_t *subsector);
|
||||
void Run();
|
||||
};
|
||||
|
||||
|
||||
class FGLThreadManager
|
||||
{
|
||||
#if 0
|
||||
FCriticalSection mCritSecs[MAX_GL_CRITICAL_SECTIONS];
|
||||
FJobQueue mJobs;
|
||||
FJobThread *mThreads[2];
|
||||
|
||||
public:
|
||||
FGLThreadManager() {}
|
||||
~FGLThreadManager() {}
|
||||
|
||||
void StartJobs();
|
||||
|
||||
void PauseJobs();
|
||||
|
||||
void EnterCS(int index)
|
||||
{
|
||||
mCritSecs[index].Enter();
|
||||
}
|
||||
|
||||
void LeaveCS(int index)
|
||||
{
|
||||
mCritSecs[index].Leave();
|
||||
}
|
||||
|
||||
void AddJob(FJob *job)
|
||||
{
|
||||
mJobs.AddJob(job);
|
||||
}
|
||||
|
||||
FJob *GetJob()
|
||||
{
|
||||
return mJobs.GetJob();
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -53,9 +53,12 @@
|
|||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
#include "gl/data/gl_vertexbuffer.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
struct POINT {
|
||||
|
|
@ -144,13 +147,13 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
|||
return false;
|
||||
}
|
||||
|
||||
wipestartscreen = new FHardwareTexture(Width, Height, false, false, false, true);
|
||||
wipestartscreen->CreateTexture(NULL, Width, Height, false, 0, CM_DEFAULT);
|
||||
wipestartscreen = new FHardwareTexture(Width, Height, true);
|
||||
wipestartscreen->CreateTexture(NULL, Width, Height, 0, false, 0);
|
||||
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER);
|
||||
GLRenderer->mSamplerManager->Bind(1, CLAMP_NONE);
|
||||
glFinish();
|
||||
wipestartscreen->Bind(0, CM_DEFAULT);
|
||||
wipestartscreen->Bind(0, false, false);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
|
|
@ -167,10 +170,11 @@ bool OpenGLFrameBuffer::WipeStartScreen(int type)
|
|||
|
||||
void OpenGLFrameBuffer::WipeEndScreen()
|
||||
{
|
||||
wipeendscreen = new FHardwareTexture(Width, Height, false, false, false, true);
|
||||
wipeendscreen->CreateTexture(NULL, Width, Height, false, 0, CM_DEFAULT);
|
||||
glFlush();
|
||||
wipeendscreen->Bind(0, CM_DEFAULT);
|
||||
wipeendscreen = new FHardwareTexture(Width, Height, true);
|
||||
wipeendscreen->CreateTexture(NULL, Width, Height, 0, false, 0);
|
||||
GLRenderer->mSamplerManager->Bind(0, CLAMP_NOFILTER);
|
||||
glFinish();
|
||||
wipeendscreen->Bind(0, false, false);
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, Width, Height);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
|
@ -237,6 +241,7 @@ void OpenGLFrameBuffer::WipeCleanup()
|
|||
delete wipeendscreen;
|
||||
wipeendscreen = NULL;
|
||||
}
|
||||
FMaterial::ClearLastTexture();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -278,34 +283,29 @@ bool OpenGLFrameBuffer::Wiper_Crossfade::Run(int ticks, OpenGLFrameBuffer *fb)
|
|||
float vb = fb->GetHeight() / FHardwareTexture::GetTexDimension(fb->GetHeight());
|
||||
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
fb->wipestartscreen->Bind(0, CM_DEFAULT);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(0, vb);
|
||||
glVertex2i(0, 0);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(0, fb->Height);
|
||||
glTexCoord2f(ur, vb);
|
||||
glVertex2i(fb->Width, 0);
|
||||
glTexCoord2f(ur, 0);
|
||||
glVertex2i(fb->Width, fb->Height);
|
||||
glEnd();
|
||||
fb->wipestartscreen->Bind(0, 0, false);
|
||||
|
||||
fb->wipeendscreen->Bind(0, CM_DEFAULT);
|
||||
glColor4f(1.f, 1.f, 1.f, clamp(Clock/32.f, 0.f, 1.f));
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(0, vb);
|
||||
glVertex2i(0, 0);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(0, fb->Height);
|
||||
glTexCoord2f(ur, vb);
|
||||
glVertex2i(fb->Width, 0);
|
||||
glTexCoord2f(ur, 0);
|
||||
glVertex2i(fb->Width, fb->Height);
|
||||
glEnd();
|
||||
gl_RenderState.EnableAlphaTest(true);
|
||||
FFlatVertex *ptr;
|
||||
unsigned int offset, count;
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(0, 0, 0, 0, vb);
|
||||
ptr++;
|
||||
ptr->Set(0, fb->Height, 0, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(fb->Width, 0, 0, ur, vb);
|
||||
ptr++;
|
||||
ptr->Set(fb->Width, fb->Height, 0, ur, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);
|
||||
|
||||
fb->wipeendscreen->Bind(0, 0, false);
|
||||
gl_RenderState.SetColorAlpha(0xffffff, clamp(Clock/32.f, 0.f, 1.f));
|
||||
gl_RenderState.Apply();
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.5f);
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
|
||||
return Clock >= 32;
|
||||
|
|
@ -346,24 +346,25 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
|
|||
|
||||
// Draw the new screen on the bottom.
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
fb->wipeendscreen->Bind(0, CM_DEFAULT);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(0, vb);
|
||||
glVertex2i(0, 0);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(0, fb->Height);
|
||||
glTexCoord2f(ur, vb);
|
||||
glVertex2i(fb->Width, 0);
|
||||
glTexCoord2f(ur, 0);
|
||||
glVertex2i(fb->Width, fb->Height);
|
||||
glEnd();
|
||||
fb->wipeendscreen->Bind(0, 0, false);
|
||||
FFlatVertex *ptr;
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(0, 0, 0, 0, vb);
|
||||
ptr++;
|
||||
ptr->Set(0, fb->Height, 0, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(fb->Width, 0, 0, ur, vb);
|
||||
ptr++;
|
||||
ptr->Set(fb->Width, fb->Height, 0, ur, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
|
||||
int i, dy;
|
||||
bool done = false;
|
||||
|
||||
fb->wipestartscreen->Bind(0, CM_DEFAULT);
|
||||
fb->wipestartscreen->Bind(0, 0, false);
|
||||
// Copy the old screen in vertical strips on top of the new one.
|
||||
while (ticks--)
|
||||
{
|
||||
|
|
@ -382,7 +383,9 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
|
|||
done = false;
|
||||
}
|
||||
if (ticks == 0)
|
||||
{ // Only draw for the final tick.
|
||||
{
|
||||
// Only draw for the final tick.
|
||||
// No need for optimization. Wipes won't ever be drawn with anything else.
|
||||
RECT rect;
|
||||
POINT dpt;
|
||||
|
||||
|
|
@ -398,17 +401,17 @@ bool OpenGLFrameBuffer::Wiper_Melt::Run(int ticks, OpenGLFrameBuffer *fb)
|
|||
float th = (float)FHardwareTexture::GetTexDimension(fb->Height);
|
||||
rect.bottom = fb->Height - rect.bottom;
|
||||
rect.top = fb->Height - rect.top;
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(rect.left / tw, rect.top / th);
|
||||
glVertex2i(rect.left, rect.bottom);
|
||||
glTexCoord2f(rect.left / tw, rect.bottom / th);
|
||||
glVertex2i(rect.left, rect.top);
|
||||
glTexCoord2f(rect.right / tw, rect.top / th);
|
||||
glVertex2i(rect.right, rect.bottom);
|
||||
glTexCoord2f(rect.right / tw, rect.bottom / th);
|
||||
glVertex2i(rect.right, rect.top);
|
||||
glEnd();
|
||||
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(rect.left, rect.bottom, 0, rect.left / tw, rect.top / th);
|
||||
ptr++;
|
||||
ptr->Set(rect.left, rect.top, 0, rect.left / tw, rect.bottom / th);
|
||||
ptr++;
|
||||
ptr->Set(rect.right, rect.bottom, 0, rect.right / tw, rect.top / th);
|
||||
ptr++;
|
||||
ptr->Set(rect.right, rect.top, 0, rect.right / tw, rect.bottom / th);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -468,7 +471,7 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
|
|||
}
|
||||
|
||||
if (BurnTexture != NULL) delete BurnTexture;
|
||||
BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, false, false, false, true);
|
||||
BurnTexture = new FHardwareTexture(WIDTH, HEIGHT, true);
|
||||
|
||||
// Update the burn texture with the new burn data
|
||||
BYTE rgb_buffer[WIDTH*HEIGHT*4];
|
||||
|
|
@ -490,68 +493,35 @@ bool OpenGLFrameBuffer::Wiper_Burn::Run(int ticks, OpenGLFrameBuffer *fb)
|
|||
|
||||
// Put the initial screen back to the buffer.
|
||||
gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
gl_RenderState.EnableAlphaTest(false);
|
||||
gl_RenderState.AlphaFunc(GL_GEQUAL, 0.f);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
fb->wipestartscreen->Bind(0, CM_DEFAULT);
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glTexCoord2f(0, vb);
|
||||
glVertex2i(0, 0);
|
||||
glTexCoord2f(0, 0);
|
||||
glVertex2i(0, fb->Height);
|
||||
glTexCoord2f(ur, vb);
|
||||
glVertex2i(fb->Width, 0);
|
||||
glTexCoord2f(ur, 0);
|
||||
glVertex2i(fb->Width, fb->Height);
|
||||
glEnd();
|
||||
fb->wipestartscreen->Bind(0, 0, false);
|
||||
FFlatVertex *ptr;
|
||||
unsigned int offset, count;
|
||||
ptr = GLRenderer->mVBO->GetBuffer();
|
||||
ptr->Set(0, 0, 0, 0, vb);
|
||||
ptr++;
|
||||
ptr->Set(0, fb->Height, 0, 0, 0);
|
||||
ptr++;
|
||||
ptr->Set(fb->Width, 0, 0, ur, vb);
|
||||
ptr++;
|
||||
ptr->Set(fb->Width, fb->Height, 0, ur, 0);
|
||||
ptr++;
|
||||
GLRenderer->mVBO->RenderCurrent(ptr, GL_TRIANGLE_STRIP, &offset, &count);
|
||||
|
||||
gl_RenderState.SetTextureMode(TM_MODULATE);
|
||||
gl_RenderState.Apply(true);
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
// mask out the alpha channel of the wipeendscreen.
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE1);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
gl_RenderState.SetEffect(EFF_BURN);
|
||||
gl_RenderState.ResetColor();
|
||||
gl_RenderState.Apply();
|
||||
|
||||
// Burn the new screen on top of it.
|
||||
glColor4f(1.f, 1.f, 1.f, 1.f);
|
||||
fb->wipeendscreen->Bind(1, CM_DEFAULT);
|
||||
//BurnTexture->Bind(0, CM_DEFAULT);
|
||||
fb->wipeendscreen->Bind(0, 0, false);
|
||||
|
||||
BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, false, 0, CM_DEFAULT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
BurnTexture->CreateTexture(rgb_buffer, WIDTH, HEIGHT, 1, true, 0);
|
||||
|
||||
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
glMultiTexCoord2f(GL_TEXTURE0, 0, 0);
|
||||
glMultiTexCoord2f(GL_TEXTURE1, 0, vb);
|
||||
glVertex2i(0, 0);
|
||||
glMultiTexCoord2f(GL_TEXTURE0, 0, 1);
|
||||
glMultiTexCoord2f(GL_TEXTURE1, 0, 0);
|
||||
glVertex2i(0, fb->Height);
|
||||
glMultiTexCoord2f(GL_TEXTURE0, 1, 0);
|
||||
glMultiTexCoord2f(GL_TEXTURE1, ur, vb);
|
||||
glVertex2i(fb->Width, 0);
|
||||
glMultiTexCoord2f(GL_TEXTURE0, 1, 1);
|
||||
glMultiTexCoord2f(GL_TEXTURE1, ur, 0);
|
||||
glVertex2i(fb->Width, fb->Height);
|
||||
glEnd();
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
GLRenderer->mVBO->RenderArray(GL_TRIANGLE_STRIP, offset, count);
|
||||
gl_RenderState.SetEffect(EFF_NONE);
|
||||
|
||||
// The fire may not always stabilize, so the wipe is forced to end
|
||||
// after an arbitrary maximum time.
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@
|
|||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
#include "gl/textures/gl_bitmap.h"
|
||||
#include "gl/system/gl_interface.h"
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
@ -50,74 +51,25 @@
|
|||
//
|
||||
//===========================================================================
|
||||
template<class T>
|
||||
void iCopyColors(unsigned char * pout, const unsigned char * pin, int cm, int count, int step)
|
||||
void iCopyColors(unsigned char * pout, const unsigned char * pin, int count, int step)
|
||||
{
|
||||
int i;
|
||||
int fac;
|
||||
|
||||
if (cm == CM_DEFAULT)
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
for(i=0;i<count;i++)
|
||||
if (T::A(pin) != 0)
|
||||
{
|
||||
if (T::A(pin) != 0)
|
||||
{
|
||||
pout[0]=T::R(pin);
|
||||
pout[1]=T::G(pin);
|
||||
pout[2]=T::B(pin);
|
||||
pout[3]=T::A(pin);
|
||||
}
|
||||
pout+=4;
|
||||
pin+=step;
|
||||
}
|
||||
}
|
||||
else if (cm == CM_SHADE)
|
||||
{
|
||||
// Alpha shade uses the red channel for true color pics
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
if (T::A(pin) != 0)
|
||||
{
|
||||
pout[0] = pout[1] = pout[2] = 255;
|
||||
pout[3] = T::R(pin);
|
||||
}
|
||||
pout+=4;
|
||||
pin+=step;
|
||||
}
|
||||
}
|
||||
else if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_FIRSTSPECIALCOLORMAP + int(SpecialColormaps.Size()))
|
||||
{
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
if (T::A(pin) != 0)
|
||||
{
|
||||
PalEntry pe = SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP].GrayscaleToColor[T::Gray(pin)];
|
||||
pout[0] = pe.r;
|
||||
pout[1] = pe.g;
|
||||
pout[2] = pe.b;
|
||||
pout[3] = T::A(pin);
|
||||
}
|
||||
pout+=4;
|
||||
pin+=step;
|
||||
}
|
||||
}
|
||||
else if (cm<=CM_DESAT31)
|
||||
{
|
||||
// Desaturated light settings.
|
||||
fac=cm-CM_DESAT0;
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
if (T::A(pin) != 0)
|
||||
{
|
||||
gl_Desaturate(T::Gray(pin), T::R(pin), T::G(pin), T::B(pin), pout[0], pout[1], pout[2], fac);
|
||||
pout[3] = T::A(pin);
|
||||
}
|
||||
pout+=4;
|
||||
pin+=step;
|
||||
pout[0]=T::R(pin);
|
||||
pout[1]=T::G(pin);
|
||||
pout[2]=T::B(pin);
|
||||
pout[3]=T::A(pin);
|
||||
}
|
||||
pout+=4;
|
||||
pin+=step;
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, int cm, int count, int step);
|
||||
typedef void (*CopyFunc)(unsigned char * pout, const unsigned char * pin, int count, int step);
|
||||
|
||||
static CopyFunc copyfuncs[]={
|
||||
iCopyColors<cRGB>,
|
||||
|
|
@ -147,57 +99,11 @@ void FGLBitmap::CopyPixelDataRGB(int originx, int originy,
|
|||
BYTE *buffer = GetPixels() + 4*originx + Pitch*originy;
|
||||
for (int y=0;y<srcheight;y++)
|
||||
{
|
||||
copyfuncs[ct](&buffer[y*Pitch], &patch[y*step_y], cm, srcwidth, step_x);
|
||||
copyfuncs[ct](&buffer[y*Pitch], &patch[y*step_y], srcwidth, step_x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Creates one of the special palette translations for the given palette
|
||||
//
|
||||
//===========================================================================
|
||||
void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count)
|
||||
{
|
||||
int i;
|
||||
int fac;
|
||||
|
||||
if (cm == CM_DEFAULT)
|
||||
{
|
||||
if (pin != pout)
|
||||
memcpy(pout, pin, count * sizeof(PalEntry));
|
||||
}
|
||||
else if (cm >= CM_FIRSTSPECIALCOLORMAP && cm < CM_FIRSTSPECIALCOLORMAP + int(SpecialColormaps.Size()))
|
||||
{
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
int gray = (pin[i].r*77 + pin[i].g*143 + pin[i].b*37) >> 8;
|
||||
// This can be done in place so we cannot copy the color directly.
|
||||
PalEntry pe = SpecialColormaps[cm - CM_FIRSTSPECIALCOLORMAP].GrayscaleToColor[gray];
|
||||
pout[i].r = pe.r;
|
||||
pout[i].g = pe.g;
|
||||
pout[i].b = pe.b;
|
||||
pout[i].a = pin[i].a;
|
||||
}
|
||||
}
|
||||
else if (cm<=CM_DESAT31)
|
||||
{
|
||||
// Desaturated light settings.
|
||||
fac=cm-CM_DESAT0;
|
||||
for(i=0;i<count;i++)
|
||||
{
|
||||
int gray=(pin[i].r*77 + pin[i].g*143 + pin[i].b*36)>>8;
|
||||
gl_Desaturate(gray, pin[i].r, pin[i].g, pin[i].b, pout[i].r, pout[i].g, pout[i].b, fac);
|
||||
pout[i].a = pin[i].a;
|
||||
}
|
||||
}
|
||||
else if (pin!=pout)
|
||||
{
|
||||
memcpy(pout, pin, count * sizeof(PalEntry));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Paletted to True Color texture copy function
|
||||
|
|
@ -214,48 +120,21 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
|
|||
{
|
||||
BYTE *buffer = GetPixels() + 4*originx + Pitch*originy;
|
||||
|
||||
// CM_SHADE is an alpha map with 0==transparent and 1==opaque
|
||||
if (cm == CM_SHADE)
|
||||
if (translation > 0)
|
||||
{
|
||||
for(int i=0;i<256;i++)
|
||||
PalEntry *ptrans = GLTranslationPalette::GetPalette(translation);
|
||||
if (ptrans)
|
||||
{
|
||||
if (palette[i].a != 0)
|
||||
penew[i]=PalEntry(i, 255,255,255);
|
||||
else
|
||||
penew[i]=PalEntry(0,255,255,255); // If the palette contains transparent colors keep them.
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
penew[i] = (ptrans[i] & 0xffffff) | (palette[i] & 0xff000000);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// apply any translation.
|
||||
// The ice and blood color translations are done directly
|
||||
// because that yields better results.
|
||||
switch(translation)
|
||||
{
|
||||
default:
|
||||
{
|
||||
PalEntry *ptrans = GLTranslationPalette::GetPalette(translation);
|
||||
if (ptrans)
|
||||
{
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
penew[i] = (ptrans[i]&0xffffff) | (palette[i]&0xff000000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
case 0:
|
||||
memcpy(penew, palette, 256*sizeof(PalEntry));
|
||||
break;
|
||||
}
|
||||
if (cm!=0)
|
||||
{
|
||||
// Apply color modifications like invulnerability, desaturation and Boom colormaps
|
||||
ModifyPalette(penew, penew, cm, 256);
|
||||
}
|
||||
memcpy(penew, palette, 256*sizeof(PalEntry));
|
||||
}
|
||||
// Now penew contains the actual palette that is to be used for creating the image.
|
||||
|
||||
// convert the image according to the translated palette.
|
||||
for (y=0;y<srcheight;y++)
|
||||
|
|
@ -271,15 +150,6 @@ void FGLBitmap::CopyPixelData(int originx, int originy, const BYTE * patch, int
|
|||
buffer[pos+2] = penew[v].b;
|
||||
buffer[pos+3] = penew[v].a;
|
||||
}
|
||||
/*
|
||||
else if (penew[v].a!=255)
|
||||
{
|
||||
buffer[pos ] = (buffer[pos ] * penew[v].a + penew[v].r * (1-penew[v].a)) / 255;
|
||||
buffer[pos+1] = (buffer[pos+1] * penew[v].a + penew[v].g * (1-penew[v].a)) / 255;
|
||||
buffer[pos+2] = (buffer[pos+2] * penew[v].a + penew[v].b * (1-penew[v].a)) / 255;
|
||||
buffer[pos+3] = clamp<int>(buffer[pos+3] + (( 255-buffer[pos+3]) * (255-penew[v].a))/255, 0, 255);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,22 +5,23 @@
|
|||
#include "gl/textures/gl_material.h"
|
||||
|
||||
|
||||
void ModifyPalette(PalEntry * pout, PalEntry * pin, int cm, int count);
|
||||
|
||||
class FGLBitmap : public FBitmap
|
||||
{
|
||||
int cm;
|
||||
int translation;
|
||||
public:
|
||||
|
||||
FGLBitmap() { cm = CM_DEFAULT; translation = 0; }
|
||||
FGLBitmap()
|
||||
{
|
||||
translation = 0;
|
||||
}
|
||||
FGLBitmap(BYTE *buffer, int pitch, int width, int height)
|
||||
: FBitmap(buffer, pitch, width, height)
|
||||
{ cm = CM_DEFAULT; translation = 0; }
|
||||
|
||||
void SetTranslationInfo(int _cm, int _trans=-1337)
|
||||
{
|
||||
if (_cm != -1) cm = _cm;
|
||||
translation = 0;
|
||||
}
|
||||
|
||||
void SetTranslationInfo(int _trans)
|
||||
{
|
||||
if (_trans != -1337) translation = _trans;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@
|
|||
#include "gl/textures/gl_texture.h"
|
||||
#include "c_cvars.h"
|
||||
#include "gl/hqnx/hqx.h"
|
||||
#ifdef _MSC_VER
|
||||
#include "gl/hqnx_asm/hqnx_asm.h"
|
||||
#endif
|
||||
|
||||
CUSTOM_CVAR(Int, gl_texture_hqresize, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
{
|
||||
|
|
@ -179,6 +182,38 @@ static unsigned char *scaleNxHelper( void (*scaleNxFunction) ( uint32* , uint32*
|
|||
return newBuffer;
|
||||
}
|
||||
|
||||
// [BB] hqnx scaling is only supported with the MS compiler.
|
||||
#ifdef _MSC_VER
|
||||
static unsigned char *hqNxAsmHelper( void (*hqNxFunction) ( int*, unsigned char*, int, int, int ),
|
||||
const int N,
|
||||
unsigned char *inputBuffer,
|
||||
const int inWidth,
|
||||
const int inHeight,
|
||||
int &outWidth,
|
||||
int &outHeight )
|
||||
{
|
||||
outWidth = N * inWidth;
|
||||
outHeight = N *inHeight;
|
||||
|
||||
static int initdone = false;
|
||||
|
||||
if (!initdone)
|
||||
{
|
||||
HQnX_asm::InitLUTs();
|
||||
initdone = true;
|
||||
}
|
||||
|
||||
HQnX_asm::CImage cImageIn;
|
||||
cImageIn.SetImage(inputBuffer, inWidth, inHeight, 32);
|
||||
cImageIn.Convert32To17();
|
||||
|
||||
unsigned char * newBuffer = new unsigned char[outWidth*outHeight*4];
|
||||
hqNxFunction( reinterpret_cast<int*>(cImageIn.m_pBitmap), newBuffer, cImageIn.m_Xres, cImageIn.m_Yres, outWidth*4 );
|
||||
delete[] inputBuffer;
|
||||
return newBuffer;
|
||||
}
|
||||
#endif
|
||||
|
||||
static unsigned char *hqNxHelper( void (*hqNxFunction) ( unsigned*, unsigned*, int, int ),
|
||||
const int N,
|
||||
unsigned char *inputBuffer,
|
||||
|
|
@ -203,6 +238,7 @@ static unsigned char *hqNxHelper( void (*hqNxFunction) ( unsigned*, unsigned*, i
|
|||
return newBuffer;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// [BB] Upsamples the texture in inputBuffer, frees inputBuffer and returns
|
||||
|
|
@ -224,10 +260,6 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u
|
|||
if ( inputTexture->bHasCanvas )
|
||||
return inputBuffer;
|
||||
|
||||
// [BB] Don't upsample non-shader handled warped textures. Needs too much memory and time
|
||||
if (gl.shadermodel == 2 || (gl.shadermodel == 3 && inputTexture->bWarped))
|
||||
return inputBuffer;
|
||||
|
||||
switch (inputTexture->UseType)
|
||||
{
|
||||
case FTexture::TEX_Sprite:
|
||||
|
|
@ -249,11 +281,11 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u
|
|||
outWidth = inWidth;
|
||||
outHeight = inHeight;
|
||||
int type = gl_texture_hqresize;
|
||||
#if 0
|
||||
// hqNx does not preserve the alpha channel so fall back to ScaleNx for such textures
|
||||
if (hasAlpha && type > 3)
|
||||
#ifdef _MSC_VER
|
||||
// ASM-hqNx does not preserve the alpha channel so fall back to C-version for such textures
|
||||
if (!hasAlpha && type > 3 && type <= 6)
|
||||
{
|
||||
type -= 3;
|
||||
type += 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -271,6 +303,14 @@ unsigned char *gl_CreateUpsampledTextureBuffer ( const FTexture *inputTexture, u
|
|||
return hqNxHelper( &hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
case 6:
|
||||
return hqNxHelper( &hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
#ifdef _MSC_VER
|
||||
case 7:
|
||||
return hqNxAsmHelper( &HQnX_asm::hq2x_32, 2, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
case 8:
|
||||
return hqNxAsmHelper( &HQnX_asm::hq3x_32, 3, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
case 9:
|
||||
return hqNxAsmHelper( &HQnX_asm::hq4x_32, 4, inputBuffer, inWidth, inHeight, outWidth, outHeight );
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return inputBuffer;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
** containers for the various translations a texture can have.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2004-2005 Christoph Oelckers
|
||||
** Copyright 2004-2014 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
|
@ -54,7 +54,6 @@
|
|||
|
||||
extern TexFilter_s TexFilter[];
|
||||
extern int TexFormat[];
|
||||
EXTERN_CVAR(Bool, gl_clamp_per_texture)
|
||||
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -174,6 +173,7 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un
|
|||
}
|
||||
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Loads the texture image into the hardware
|
||||
|
|
@ -183,18 +183,22 @@ void FHardwareTexture::Resize(int width, int height, unsigned char *src_data, un
|
|||
// strange crashes deep inside the GL driver when I didn't do it!
|
||||
//
|
||||
//===========================================================================
|
||||
void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit)
|
||||
|
||||
unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation)
|
||||
{
|
||||
int rh,rw;
|
||||
int texformat=TexFormat[gl_texture_format];
|
||||
bool deletebuffer=false;
|
||||
bool use_mipmapping = TexFilter[gl_texture_filter].mipmapping;
|
||||
|
||||
if (alphatexture) texformat=GL_ALPHA8;
|
||||
else if (forcenocompression) texformat = GL_RGBA8;
|
||||
if (glTexID==0) glGenTextures(1,&glTexID);
|
||||
glBindTexture(GL_TEXTURE_2D, glTexID);
|
||||
lastbound[texunit]=glTexID;
|
||||
if (forcenocompression)
|
||||
{
|
||||
texformat = GL_RGBA8;
|
||||
}
|
||||
TranslatedTexture * glTex=GetTexID(translation);
|
||||
if (glTex->glTexID==0) glGenTextures(1,&glTex->glTexID);
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit);
|
||||
glBindTexture(GL_TEXTURE_2D, glTex->glTexID);
|
||||
lastbound[texunit] = glTex->glTexID;
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
|
|
@ -204,8 +208,7 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
|
|||
rh = GetTexDimension (h);
|
||||
|
||||
// The texture must at least be initialized if no data is present.
|
||||
mipmap=false;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, false);
|
||||
glTex->mipmapped = false;
|
||||
buffer=(unsigned char *)calloc(4,rw * (rh+1));
|
||||
deletebuffer=true;
|
||||
//texheight=-h;
|
||||
|
|
@ -215,8 +218,6 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
|
|||
rw = GetTexDimension (w);
|
||||
rh = GetTexDimension (h);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, (mipmap && use_mipmapping && !forcenofiltering));
|
||||
|
||||
if (rw < w || rh < h)
|
||||
{
|
||||
// The texture is larger than what the hardware can handle so scale it down.
|
||||
|
|
@ -233,35 +234,14 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
|
|||
|
||||
if (deletebuffer) free(buffer);
|
||||
|
||||
// When using separate samplers the stuff below is not needed.
|
||||
// if (gl.flags & RFL_SAMPLER_OBJECTS) return;
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapparam==GL_CLAMP? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapparam==GL_CLAMP? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
clampmode = wrapparam==GL_CLAMP? GLT_CLAMPX|GLT_CLAMPY : 0;
|
||||
|
||||
if (forcenofiltering)
|
||||
if (mipmap && TexFilter[gl_texture_filter].mipmapping)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mipmap && use_mipmapping)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter);
|
||||
if (gl_texture_filter_anisotropic)
|
||||
{
|
||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter);
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
glTex->mipmapped = true;
|
||||
}
|
||||
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0);
|
||||
return glTex->glTexID;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -270,19 +250,16 @@ void FHardwareTexture::LoadImage(unsigned char * buffer,int w, int h, unsigned i
|
|||
// Creates a texture
|
||||
//
|
||||
//===========================================================================
|
||||
FHardwareTexture::FHardwareTexture(int _width, int _height, bool _mipmap, bool wrap, bool nofilter, bool nocompression)
|
||||
FHardwareTexture::FHardwareTexture(int _width, int _height, bool nocompression)
|
||||
{
|
||||
forcenocompression = nocompression;
|
||||
mipmap=_mipmap;
|
||||
texwidth=_width;
|
||||
texheight=_height;
|
||||
|
||||
int cm_arraysize = CM_FIRSTSPECIALCOLORMAP + SpecialColormaps.Size();
|
||||
glTexID = new unsigned[cm_arraysize];
|
||||
memset(glTexID,0,sizeof(unsigned int)*cm_arraysize);
|
||||
clampmode=0;
|
||||
glDefTex.glTexID = 0;
|
||||
glDefTex.translation = 0;
|
||||
glDefTex.mipmapped = false;
|
||||
glDepthID = 0;
|
||||
forcenofiltering = nofilter;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -291,18 +268,20 @@ FHardwareTexture::FHardwareTexture(int _width, int _height, bool _mipmap, bool w
|
|||
// Deletes a texture id and unbinds it from the texture units
|
||||
//
|
||||
//===========================================================================
|
||||
void FHardwareTexture::DeleteTexture(unsigned int texid)
|
||||
void FHardwareTexture::TranslatedTexture::Delete()
|
||||
{
|
||||
if (texid != 0)
|
||||
if (glTexID != 0)
|
||||
{
|
||||
for(int i = 0; i < MAX_TEXTURES; i++)
|
||||
{
|
||||
if (lastbound[i] == texid)
|
||||
if (lastbound[i] == glTexID)
|
||||
{
|
||||
lastbound[i] = 0;
|
||||
}
|
||||
}
|
||||
glDeleteTextures(1, &texid);
|
||||
glDeleteTextures(1, &glTexID);
|
||||
glTexID = 0;
|
||||
mipmapped = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -317,27 +296,13 @@ void FHardwareTexture::Clean(bool all)
|
|||
|
||||
if (all)
|
||||
{
|
||||
for (int i=0;i<cm_arraysize;i++)
|
||||
{
|
||||
DeleteTexture(glTexID[i]);
|
||||
}
|
||||
//glDeleteTextures(cm_arraysize,glTexID);
|
||||
memset(glTexID,0,sizeof(unsigned int)*cm_arraysize);
|
||||
glDefTex.Delete();
|
||||
}
|
||||
else
|
||||
for(unsigned int i=0;i<glTex_Translated.Size();i++)
|
||||
{
|
||||
for (int i=1;i<cm_arraysize;i++)
|
||||
{
|
||||
DeleteTexture(glTexID[i]);
|
||||
}
|
||||
//glDeleteTextures(cm_arraysize-1,glTexID+1);
|
||||
memset(glTexID+1,0,sizeof(unsigned int)*(cm_arraysize-1));
|
||||
glTex_Translated[i].Delete();
|
||||
}
|
||||
for(unsigned int i=0;i<glTexID_Translated.Size();i++)
|
||||
{
|
||||
DeleteTexture(glTexID_Translated[i].glTexID);
|
||||
}
|
||||
glTexID_Translated.Clear();
|
||||
glTex_Translated.Clear();
|
||||
if (glDepthID != 0) glDeleteRenderbuffers(1, &glDepthID);
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +314,6 @@ void FHardwareTexture::Clean(bool all)
|
|||
FHardwareTexture::~FHardwareTexture()
|
||||
{
|
||||
Clean(true);
|
||||
delete [] glTexID;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -359,31 +323,28 @@ FHardwareTexture::~FHardwareTexture()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
unsigned * FHardwareTexture::GetTexID(int cm, int translation)
|
||||
FHardwareTexture::TranslatedTexture *FHardwareTexture::GetTexID(int translation)
|
||||
{
|
||||
if (cm < 0 || cm >= CM_MAXCOLORMAP) cm=CM_DEFAULT;
|
||||
|
||||
if (translation==0)
|
||||
if (translation == 0)
|
||||
{
|
||||
return &glTexID[cm];
|
||||
return &glDefTex;
|
||||
}
|
||||
|
||||
// normally there aren't more than very few different
|
||||
// translations here so this isn't performance critical.
|
||||
for(unsigned int i=0;i<glTexID_Translated.Size();i++)
|
||||
for (unsigned int i = 0; i < glTex_Translated.Size(); i++)
|
||||
{
|
||||
if (glTexID_Translated[i].cm == cm &&
|
||||
glTexID_Translated[i].translation == translation)
|
||||
if (glTex_Translated[i].translation == translation)
|
||||
{
|
||||
return &glTexID_Translated[i].glTexID;
|
||||
return &glTex_Translated[i];
|
||||
}
|
||||
}
|
||||
|
||||
int add = glTexID_Translated.Reserve(1);
|
||||
glTexID_Translated[add].cm=cm;
|
||||
glTexID_Translated[add].translation=translation;
|
||||
glTexID_Translated[add].glTexID=0;
|
||||
return &glTexID_Translated[add].glTexID;
|
||||
int add = glTex_Translated.Reserve(1);
|
||||
glTex_Translated[add].translation = translation;
|
||||
glTex_Translated[add].glTexID = 0;
|
||||
glTex_Translated[add].mipmapped = false;
|
||||
return &glTex_Translated[add];
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -391,18 +352,24 @@ unsigned * FHardwareTexture::GetTexID(int cm, int translation)
|
|||
// Binds this patch
|
||||
//
|
||||
//===========================================================================
|
||||
unsigned int FHardwareTexture::Bind(int texunit, int cm,int translation)
|
||||
unsigned int FHardwareTexture::Bind(int texunit, int translation, bool needmipmap)
|
||||
{
|
||||
unsigned int * pTexID=GetTexID(cm, translation);
|
||||
TranslatedTexture *pTex = GetTexID(translation);
|
||||
|
||||
if (*pTexID!=0)
|
||||
if (pTex->glTexID != 0)
|
||||
{
|
||||
if (lastbound[texunit]==*pTexID) return *pTexID;
|
||||
lastbound[texunit]=*pTexID;
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit);
|
||||
glBindTexture(GL_TEXTURE_2D, *pTexID);
|
||||
if (lastbound[texunit] == pTex->glTexID) return pTex->glTexID;
|
||||
lastbound[texunit] = pTex->glTexID;
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0 + texunit);
|
||||
glBindTexture(GL_TEXTURE_2D, pTex->glTexID);
|
||||
// Check if we need mipmaps on a texture that was creted without them.
|
||||
if (needmipmap && !pTex->mipmapped && TexFilter[gl_texture_filter].mipmapping)
|
||||
{
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
pTex->mipmapped = true;
|
||||
}
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0);
|
||||
return *pTexID;
|
||||
return pTex->glTexID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -425,6 +392,7 @@ void FHardwareTexture::UnbindAll()
|
|||
{
|
||||
Unbind(texunit);
|
||||
}
|
||||
FMaterial::ClearLastTexture();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -435,19 +403,15 @@ void FHardwareTexture::UnbindAll()
|
|||
|
||||
int FHardwareTexture::GetDepthBuffer()
|
||||
{
|
||||
if (gl.flags & RFL_FRAMEBUFFER)
|
||||
if (glDepthID == 0)
|
||||
{
|
||||
if (glDepthID == 0)
|
||||
{
|
||||
glGenRenderbuffers(1, &glDepthID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, glDepthID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
|
||||
GetTexDimension(texwidth), GetTexDimension(texheight));
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
return glDepthID;
|
||||
glGenRenderbuffers(1, &glDepthID);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, glDepthID);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8,
|
||||
GetTexDimension(texwidth), GetTexDimension(texheight));
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, 0);
|
||||
}
|
||||
return 0;
|
||||
return glDepthID;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -459,30 +423,7 @@ int FHardwareTexture::GetDepthBuffer()
|
|||
|
||||
void FHardwareTexture::BindToFrameBuffer()
|
||||
{
|
||||
if (gl.flags & RFL_FRAMEBUFFER)
|
||||
{
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glTexID[0], 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer());
|
||||
}
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, glDefTex.glTexID, 0);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, GetDepthBuffer());
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// (re-)creates the texture
|
||||
//
|
||||
//===========================================================================
|
||||
unsigned int FHardwareTexture::CreateTexture(unsigned char * buffer, int w, int h, bool wrap, int texunit,
|
||||
int cm, int translation)
|
||||
{
|
||||
if (cm < 0 || cm >= CM_MAXCOLORMAP) cm=CM_DEFAULT;
|
||||
|
||||
unsigned int * pTexID=GetTexID(cm, translation);
|
||||
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0+texunit);
|
||||
LoadImage(buffer, w, h, *pTexID, wrap? GL_REPEAT:GL_CLAMP, cm==CM_SHADE, texunit);
|
||||
if (texunit != 0) glActiveTexture(GL_TEXTURE0);
|
||||
return *pTexID;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,10 @@
|
|||
#ifndef __GLTEXTURE_H
|
||||
#define __GLTEXTURE_H
|
||||
|
||||
#ifdef LoadImage
|
||||
#undef LoadImage
|
||||
#endif
|
||||
|
||||
#define SHADED_TEXTURE -1
|
||||
#define DIRECT_PALETTE -2
|
||||
|
||||
|
|
@ -10,6 +14,12 @@
|
|||
class FCanvasTexture;
|
||||
class AActor;
|
||||
|
||||
// For error catching while changing parameters.
|
||||
enum EInvalid
|
||||
{
|
||||
Invalid = 0
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
GLT_CLAMPX=1,
|
||||
|
|
@ -18,23 +28,26 @@ enum
|
|||
|
||||
class FHardwareTexture
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAX_TEXTURES = 16
|
||||
};
|
||||
|
||||
private:
|
||||
struct TranslatedTexture
|
||||
{
|
||||
unsigned int glTexID;
|
||||
int translation;
|
||||
int cm;
|
||||
bool mipmapped;
|
||||
|
||||
void Delete();
|
||||
};
|
||||
|
||||
public:
|
||||
|
||||
static unsigned int lastbound[MAX_TEXTURES];
|
||||
static int lastactivetexture;
|
||||
static bool supportsNonPower2;
|
||||
static int max_texturesize;
|
||||
|
||||
static int GetTexDimension(int value);
|
||||
|
|
@ -42,25 +55,19 @@ public:
|
|||
private:
|
||||
|
||||
short texwidth, texheight;
|
||||
//float scalexfac, scaleyfac;
|
||||
bool mipmap;
|
||||
BYTE clampmode;
|
||||
bool forcenofiltering;
|
||||
bool forcenocompression;
|
||||
|
||||
unsigned int * glTexID;
|
||||
TArray<TranslatedTexture> glTexID_Translated;
|
||||
TranslatedTexture glDefTex;
|
||||
TArray<TranslatedTexture> glTex_Translated;
|
||||
unsigned int glDepthID; // only used by camera textures
|
||||
|
||||
void LoadImage(unsigned char * buffer,int w, int h, unsigned int & glTexID,int wrapparam, bool alphatexture, int texunit);
|
||||
unsigned * GetTexID(int cm, int translation);
|
||||
TranslatedTexture * GetTexID(int translation);
|
||||
|
||||
int GetDepthBuffer();
|
||||
void DeleteTexture(unsigned int texid);
|
||||
void Resize(int width, int height, unsigned char *src_data, unsigned char *dst_data);
|
||||
|
||||
public:
|
||||
FHardwareTexture(int w, int h, bool mip, bool wrap, bool nofilter, bool nocompress);
|
||||
FHardwareTexture(int w, int h, bool nocompress);
|
||||
~FHardwareTexture();
|
||||
|
||||
static void Unbind(int texunit);
|
||||
|
|
@ -68,9 +75,8 @@ public:
|
|||
|
||||
void BindToFrameBuffer();
|
||||
|
||||
unsigned int Bind(int texunit, int cm, int translation=0);
|
||||
unsigned int CreateTexture(unsigned char * buffer, int w, int h,bool wrap, int texunit, int cm, int translation=0);
|
||||
void Resize(int _width, int _height) ;
|
||||
unsigned int Bind(int texunit, int translation, bool needmipmap);
|
||||
unsigned int CreateTexture(unsigned char * buffer, int w, int h, int texunit, bool mipmap, int translation);
|
||||
|
||||
void Clean(bool all);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -53,11 +53,13 @@
|
|||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/data/gl_data.h"
|
||||
#include "gl/textures/gl_texture.h"
|
||||
#include "gl/textures/gl_translate.h"
|
||||
#include "gl/textures/gl_bitmap.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
|
||||
EXTERN_CVAR(Bool, gl_render_precise)
|
||||
|
|
@ -78,18 +80,16 @@ EXTERN_CVAR(Bool, gl_texture_usehires)
|
|||
//===========================================================================
|
||||
FGLTexture::FGLTexture(FTexture * tx, bool expandpatches)
|
||||
{
|
||||
assert(tx->gl_info.SystemTexture == NULL);
|
||||
assert(tx->gl_info.SystemTexture[expandpatches] == NULL);
|
||||
tex = tx;
|
||||
|
||||
glpatch=NULL;
|
||||
for(int i=0;i<5;i++) gltexture[i]=NULL;
|
||||
HiresLump=-1;
|
||||
mHwTexture = NULL;
|
||||
HiresLump = -1;
|
||||
hirestexture = NULL;
|
||||
currentwarp = 0;
|
||||
bHasColorkey = false;
|
||||
bIsTransparent = -1;
|
||||
bExpand = expandpatches;
|
||||
tex->gl_info.SystemTexture = this;
|
||||
tex->gl_info.SystemTexture[expandpatches] = this;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -109,7 +109,7 @@ FGLTexture::~FGLTexture()
|
|||
// Checks for the presence of a hires texture replacement and loads it
|
||||
//
|
||||
//==========================================================================
|
||||
unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height, int cm)
|
||||
unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *height)
|
||||
{
|
||||
if (HiresLump==-1)
|
||||
{
|
||||
|
|
@ -131,8 +131,6 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig
|
|||
memset(buffer, 0, w * (h+1) * 4);
|
||||
|
||||
FGLBitmap bmp(buffer, w*4, w, h);
|
||||
bmp.SetTranslationInfo(cm);
|
||||
|
||||
|
||||
int trans = hirestexture->CopyTrueColorPixels(&bmp, 0, 0);
|
||||
hirestexture->CheckTrans(buffer, w*h, trans);
|
||||
|
|
@ -163,107 +161,17 @@ unsigned char *FGLTexture::LoadHiresTexture(FTexture *tex, int *width, int *heig
|
|||
|
||||
void FGLTexture::Clean(bool all)
|
||||
{
|
||||
for(int i=0;i<5;i++)
|
||||
if (mHwTexture)
|
||||
{
|
||||
if (gltexture[i])
|
||||
{
|
||||
if (!all) gltexture[i]->Clean(false);
|
||||
else
|
||||
{
|
||||
delete gltexture[i];
|
||||
gltexture[i]=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (glpatch)
|
||||
{
|
||||
if (!all) glpatch->Clean(false);
|
||||
if (!all) mHwTexture->Clean(false);
|
||||
else
|
||||
{
|
||||
delete glpatch;
|
||||
glpatch=NULL;
|
||||
delete mHwTexture;
|
||||
mHwTexture = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// FGLTex::WarpBuffer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
BYTE *FGLTexture::WarpBuffer(BYTE *buffer, int Width, int Height, int warp)
|
||||
{
|
||||
if (Width > 256 || Height > 256) return buffer;
|
||||
|
||||
DWORD *in = (DWORD*)buffer;
|
||||
DWORD *out = (DWORD*)new BYTE[4*Width*Height];
|
||||
float Speed = static_cast<FWarpTexture*>(tex)->GetSpeed();
|
||||
|
||||
static_cast<FWarpTexture*>(tex)->GenTime = r_FrameTime;
|
||||
|
||||
static DWORD linebuffer[256]; // anything larger will bring down performance so it is excluded above.
|
||||
DWORD timebase = DWORD(r_FrameTime*Speed*23/28);
|
||||
int xsize = Width;
|
||||
int ysize = Height;
|
||||
int xmask = xsize - 1;
|
||||
int ymask = ysize - 1;
|
||||
int ds_xbits;
|
||||
int i,x;
|
||||
|
||||
if (warp == 1)
|
||||
{
|
||||
for(ds_xbits=-1,i=Width; i; i>>=1, ds_xbits++);
|
||||
|
||||
for (x = xsize-1; x >= 0; x--)
|
||||
{
|
||||
int yt, yf = (finesine[(timebase+(x+17)*128)&FINEMASK]>>13) & ymask;
|
||||
const DWORD *source = in + x;
|
||||
DWORD *dest = out + x;
|
||||
for (yt = ysize; yt; yt--, yf = (yf+1)&ymask, dest += xsize)
|
||||
{
|
||||
*dest = *(source+(yf<<ds_xbits));
|
||||
}
|
||||
}
|
||||
timebase = DWORD(r_FrameTime*Speed*32/28);
|
||||
int y;
|
||||
for (y = ysize-1; y >= 0; y--)
|
||||
{
|
||||
int xt, xf = (finesine[(timebase+y*128)&FINEMASK]>>13) & xmask;
|
||||
DWORD *source = out + (y<<ds_xbits);
|
||||
DWORD *dest = linebuffer;
|
||||
for (xt = xsize; xt; xt--, xf = (xf+1)&xmask)
|
||||
{
|
||||
*dest++ = *(source+xf);
|
||||
}
|
||||
memcpy (out+y*xsize, linebuffer, xsize*sizeof(DWORD));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int ybits;
|
||||
for(ybits=-1,i=ysize; i; i>>=1, ybits++);
|
||||
|
||||
DWORD timebase = (r_FrameTime * Speed * 40 / 28);
|
||||
for (x = xsize-1; x >= 0; x--)
|
||||
{
|
||||
for (int y = ysize-1; y >= 0; y--)
|
||||
{
|
||||
int xt = (x + 128
|
||||
+ ((finesine[(y*128 + timebase*5 + 900) & 8191]*2)>>FRACBITS)
|
||||
+ ((finesine[(x*256 + timebase*4 + 300) & 8191]*2)>>FRACBITS)) & xmask;
|
||||
int yt = (y + 128
|
||||
+ ((finesine[(y*128 + timebase*3 + 700) & 8191]*2)>>FRACBITS)
|
||||
+ ((finesine[(x*256 + timebase*4 + 1200) & 8191]*2)>>FRACBITS)) & ymask;
|
||||
const DWORD *source = in + (xt << ybits) + yt;
|
||||
DWORD *dest = out + (x << ybits) + y;
|
||||
*dest = *source;
|
||||
}
|
||||
}
|
||||
}
|
||||
delete [] buffer;
|
||||
return (BYTE*)out;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
@ -271,7 +179,7 @@ BYTE *FGLTexture::WarpBuffer(BYTE *buffer, int Width, int Height, int warp)
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp)
|
||||
unsigned char * FGLTexture::CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck)
|
||||
{
|
||||
unsigned char * buffer;
|
||||
int W, H;
|
||||
|
|
@ -281,22 +189,22 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in
|
|||
// by hires textures
|
||||
if (gl_texture_usehires && hirescheck != NULL)
|
||||
{
|
||||
buffer = LoadHiresTexture (hirescheck, &w, &h, cm);
|
||||
buffer = LoadHiresTexture (hirescheck, &w, &h);
|
||||
if (buffer)
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
W = w = tex->GetWidth() + expand*2;
|
||||
H = h = tex->GetHeight() + expand*2;
|
||||
W = w = tex->GetWidth() + bExpand*2;
|
||||
H = h = tex->GetHeight() + bExpand*2;
|
||||
|
||||
|
||||
buffer=new unsigned char[W*(H+1)*4];
|
||||
memset(buffer, 0, W * (H+1) * 4);
|
||||
|
||||
FGLBitmap bmp(buffer, W*4, W, H);
|
||||
bmp.SetTranslationInfo(cm, translation);
|
||||
bmp.SetTranslationInfo(translation);
|
||||
|
||||
if (tex->bComplex)
|
||||
{
|
||||
|
|
@ -307,7 +215,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in
|
|||
if (imgCreate.Create(W, H))
|
||||
{
|
||||
memset(imgCreate.GetPixels(), 0, W * H * 4);
|
||||
int trans = tex->CopyTrueColorPixels(&imgCreate, expand, expand);
|
||||
int trans = tex->CopyTrueColorPixels(&imgCreate, bExpand, bExpand);
|
||||
bmp.CopyPixelDataRGB(0, 0, imgCreate.GetPixels(), W, H, 4, W * 4, 0, CF_BGRA);
|
||||
tex->CheckTrans(buffer, W*H, trans);
|
||||
bIsTransparent = tex->gl_info.mIsTransparent;
|
||||
|
|
@ -315,7 +223,7 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in
|
|||
}
|
||||
else if (translation<=0)
|
||||
{
|
||||
int trans = tex->CopyTrueColorPixels(&bmp, expand, expand);
|
||||
int trans = tex->CopyTrueColorPixels(&bmp, bExpand, bExpand);
|
||||
tex->CheckTrans(buffer, W*H, trans);
|
||||
bIsTransparent = tex->gl_info.mIsTransparent;
|
||||
}
|
||||
|
|
@ -324,25 +232,13 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in
|
|||
// When using translations everything must be mapped to the base palette.
|
||||
// Since FTexture's method is doing exactly that by calling GetPixels let's use that here
|
||||
// to do all the dirty work for us. ;)
|
||||
tex->FTexture::CopyTrueColorPixels(&bmp, expand, expand);
|
||||
tex->FTexture::CopyTrueColorPixels(&bmp, bExpand, bExpand);
|
||||
bIsTransparent = 0;
|
||||
}
|
||||
|
||||
if (warp != 0)
|
||||
{
|
||||
buffer = WarpBuffer(buffer, W, H, warp);
|
||||
}
|
||||
// [BB] The hqnx upsampling (not the scaleN one) destroys partial transparency, don't upsamle textures using it.
|
||||
// Also don't upsample warped textures.
|
||||
else //if (bIsTransparent != 1)
|
||||
{
|
||||
// [BB] Potentially upsample the buffer.
|
||||
buffer = gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, bIsTransparent || cm == CM_SHADE );
|
||||
}
|
||||
currentwarp = warp;
|
||||
currentwarptime = gl_frameMS;
|
||||
|
||||
return buffer;
|
||||
// [BB] Potentially upsample the buffer.
|
||||
return gl_CreateUpsampledTextureBuffer ( tex, buffer, W, H, w, h, !!bIsTransparent);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -352,83 +248,44 @@ unsigned char * FGLTexture::CreateTexBuffer(int cm, int translation, int & w, in
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
FHardwareTexture *FGLTexture::CreateTexture(int clampmode)
|
||||
FHardwareTexture *FGLTexture::CreateHwTexture()
|
||||
{
|
||||
if (tex->UseType==FTexture::TEX_Null) return NULL; // Cannot register a NULL texture
|
||||
if (!gltexture[clampmode])
|
||||
if (mHwTexture == NULL)
|
||||
{
|
||||
gltexture[clampmode] = new FHardwareTexture(tex->GetWidth(), tex->GetHeight(), true, true, false, tex->gl_info.bNoCompress);
|
||||
mHwTexture = new FHardwareTexture(tex->GetWidth() + bExpand*2, tex->GetHeight() + bExpand*2, tex->gl_info.bNoCompress);
|
||||
}
|
||||
return gltexture[clampmode];
|
||||
return mHwTexture;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Create Hardware texture for patch use
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
bool FGLTexture::CreatePatch()
|
||||
{
|
||||
if (tex->UseType==FTexture::TEX_Null) return false; // Cannot register a NULL texture
|
||||
if (!glpatch)
|
||||
{
|
||||
glpatch=new FHardwareTexture(tex->GetWidth() + bExpand, tex->GetHeight() + bExpand, false, false, tex->gl_info.bNoFilter, tex->gl_info.bNoCompress);
|
||||
}
|
||||
if (glpatch) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Binds a texture to the renderer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int translation, FTexture *hirescheck, int warp)
|
||||
const FHardwareTexture *FGLTexture::Bind(int texunit, int clampmode, int translation, FTexture *hirescheck)
|
||||
{
|
||||
int usebright = false;
|
||||
|
||||
if (translation <= 0) translation = -translation;
|
||||
else translation = GLTranslationPalette::GetInternalTranslation(translation);
|
||||
|
||||
FHardwareTexture *hwtex;
|
||||
|
||||
if (gltexture[4] != NULL && clampmode < 4 && gltexture[clampmode] == NULL)
|
||||
{
|
||||
hwtex = gltexture[clampmode] = gltexture[4];
|
||||
gltexture[4] = NULL;
|
||||
bool needmipmap = (clampmode <= CLAMP_XY);
|
||||
|
||||
if (hwtex->Bind(texunit, cm, translation))
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (clampmode & GLT_CLAMPX)? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (clampmode & GLT_CLAMPY)? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hwtex = CreateTexture(clampmode);
|
||||
}
|
||||
FHardwareTexture *hwtex = CreateHwTexture();
|
||||
|
||||
if (hwtex)
|
||||
{
|
||||
if ((warp != 0 || currentwarp != warp) && currentwarptime != gl_frameMS)
|
||||
{
|
||||
// must recreate the texture
|
||||
Clean(true);
|
||||
hwtex = CreateTexture(clampmode);
|
||||
}
|
||||
|
||||
// Texture has become invalid - this is only for special textures, not the regular warping, which is handled above
|
||||
else if ((warp == 0 && !tex->bHasCanvas && !tex->bWarped) && tex->CheckModified())
|
||||
// Texture has become invalid
|
||||
if ((!tex->bHasCanvas && !tex->bWarped) && tex->CheckModified())
|
||||
{
|
||||
Clean(true);
|
||||
hwtex = CreateTexture(clampmode);
|
||||
hwtex = CreateHwTexture();
|
||||
}
|
||||
|
||||
// Bind it to the system.
|
||||
if (!hwtex->Bind(texunit, cm, translation))
|
||||
if (!hwtex->Bind(texunit, translation, needmipmap))
|
||||
{
|
||||
|
||||
int w=0, h=0;
|
||||
|
|
@ -438,80 +295,25 @@ const FHardwareTexture *FGLTexture::Bind(int texunit, int cm, int clampmode, int
|
|||
|
||||
if (!tex->bHasCanvas)
|
||||
{
|
||||
buffer = CreateTexBuffer(cm, translation, w, h, false, hirescheck, warp);
|
||||
buffer = CreateTexBuffer(translation, w, h, hirescheck);
|
||||
tex->ProcessData(buffer, w, h, false);
|
||||
}
|
||||
if (!hwtex->CreateTexture(buffer, w, h, true, texunit, cm, translation))
|
||||
if (!hwtex->CreateTexture(buffer, w, h, texunit, needmipmap, translation))
|
||||
{
|
||||
// could not create texture
|
||||
delete[] buffer;
|
||||
return NULL;
|
||||
}
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, (clampmode & GLT_CLAMPX)? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, (clampmode & GLT_CLAMPY)? GL_CLAMP_TO_EDGE : GL_REPEAT);
|
||||
delete[] buffer;
|
||||
}
|
||||
|
||||
if (tex->bHasCanvas) static_cast<FCanvasTexture*>(tex)->NeedUpdate();
|
||||
GLRenderer->mSamplerManager->Bind(texunit, clampmode);
|
||||
return hwtex;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Binds a sprite to the renderer
|
||||
//
|
||||
//===========================================================================
|
||||
const FHardwareTexture * FGLTexture::BindPatch(int texunit, int cm, int translation, int warp)
|
||||
{
|
||||
bool usebright = false;
|
||||
int transparm = translation;
|
||||
|
||||
if (translation <= 0) translation = -translation;
|
||||
else translation = GLTranslationPalette::GetInternalTranslation(translation);
|
||||
|
||||
if (CreatePatch())
|
||||
{
|
||||
if (warp != 0 || currentwarp != warp)
|
||||
{
|
||||
// must recreate the texture
|
||||
Clean(true);
|
||||
CreatePatch();
|
||||
}
|
||||
|
||||
// Texture has become invalid - this is only for special textures, not the regular warping, which is handled above
|
||||
else if ((warp == 0 && !tex->bHasCanvas && !tex->bWarped) && tex->CheckModified())
|
||||
{
|
||||
Clean(true);
|
||||
CreatePatch();
|
||||
}
|
||||
|
||||
|
||||
// Bind it to the system.
|
||||
if (!glpatch->Bind(texunit, cm, translation))
|
||||
{
|
||||
int w, h;
|
||||
|
||||
// Create this texture
|
||||
unsigned char * buffer = CreateTexBuffer(cm, translation, w, h, bExpand, NULL, warp);
|
||||
tex->ProcessData(buffer, w, h, true);
|
||||
if (!glpatch->CreateTexture(buffer, w, h, false, texunit, cm, translation))
|
||||
{
|
||||
// could not create texture
|
||||
delete[] buffer;
|
||||
return NULL;
|
||||
}
|
||||
delete[] buffer;
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
return glpatch;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -579,7 +381,7 @@ FGLTexture * FMaterial::ValidateSysTexture(FTexture * tex, bool expand)
|
|||
{
|
||||
if (tex && tex->UseType!=FTexture::TEX_Null)
|
||||
{
|
||||
FGLTexture *gltex = tex->gl_info.SystemTexture;
|
||||
FGLTexture *gltex = tex->gl_info.SystemTexture[expand];
|
||||
if (gltex == NULL)
|
||||
{
|
||||
gltex = new FGLTexture(tex, expand);
|
||||
|
|
@ -597,16 +399,10 @@ FGLTexture * FMaterial::ValidateSysTexture(FTexture * tex, bool expand)
|
|||
TArray<FMaterial *> FMaterial::mMaterials;
|
||||
int FMaterial::mMaxBound;
|
||||
|
||||
FMaterial::FMaterial(FTexture * tx, bool forceexpand)
|
||||
FMaterial::FMaterial(FTexture * tx, bool expanded)
|
||||
{
|
||||
assert(tx->gl_info.Material == NULL);
|
||||
|
||||
bool expanded = tx->UseType == FTexture::TEX_Sprite ||
|
||||
tx->UseType == FTexture::TEX_SkinSprite ||
|
||||
tx->UseType == FTexture::TEX_Decal ||
|
||||
forceexpand;
|
||||
|
||||
mShaderIndex = 0;
|
||||
tex = tx;
|
||||
|
||||
// TODO: apply custom shader object here
|
||||
/* if (tx->CustomShaderDefinition)
|
||||
|
|
@ -624,7 +420,7 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand)
|
|||
{
|
||||
expanded = false;
|
||||
}
|
||||
else if (gl.shadermodel > 2)
|
||||
else
|
||||
{
|
||||
if (tx->gl_info.shaderindex >= FIRST_USER_SHADER)
|
||||
{
|
||||
|
|
@ -643,83 +439,61 @@ FMaterial::FMaterial(FTexture * tx, bool forceexpand)
|
|||
}
|
||||
}
|
||||
}
|
||||
assert(tx->gl_info.Material[expanded] == NULL);
|
||||
mBaseLayer = ValidateSysTexture(tx, true);
|
||||
|
||||
|
||||
for (int i=GLUSE_PATCH; i<=GLUSE_TEXTURE; i++)
|
||||
{
|
||||
Width[i] = tx->GetWidth();
|
||||
Height[i] = tx->GetHeight();
|
||||
LeftOffset[i] = tx->LeftOffset;
|
||||
TopOffset[i] = tx->TopOffset;
|
||||
RenderWidth[i] = tx->GetScaledWidth();
|
||||
RenderHeight[i] = tx->GetScaledHeight();
|
||||
}
|
||||
Width[GLUSE_SPRITE] = Width[GLUSE_PATCH];
|
||||
Height[GLUSE_SPRITE] = Height[GLUSE_PATCH];
|
||||
LeftOffset[GLUSE_SPRITE] = LeftOffset[GLUSE_PATCH];
|
||||
TopOffset[GLUSE_SPRITE] = TopOffset[GLUSE_PATCH];
|
||||
SpriteU[0] = SpriteV[0] = 0;
|
||||
spriteright = SpriteU[1] = Width[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Width[GLUSE_PATCH]);
|
||||
spritebottom = SpriteV[1] = Height[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Height[GLUSE_PATCH]);
|
||||
mWidth = tx->GetWidth();
|
||||
mHeight = tx->GetHeight();
|
||||
mLeftOffset = tx->LeftOffset;
|
||||
mTopOffset = tx->TopOffset;
|
||||
mRenderWidth = tx->GetScaledWidth();
|
||||
mRenderHeight = tx->GetScaledHeight();
|
||||
mSpriteU[0] = mSpriteV[0] = 0.f;
|
||||
mSpriteU[1] = mSpriteV[1] = 1.f;
|
||||
|
||||
mTextureLayers.ShrinkToFit();
|
||||
mMaxBound = -1;
|
||||
mMaterials.Push(this);
|
||||
tx->gl_info.Material = this;
|
||||
if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0;
|
||||
tex = tx;
|
||||
FTexture *basetex = tx->GetRedirect(false);
|
||||
mBaseLayer = ValidateSysTexture(basetex, expanded);
|
||||
|
||||
tx->gl_info.mExpanded = expanded;
|
||||
FTexture *basetex = tx->GetRedirect(gl.shadermodel < 4);
|
||||
if (!expanded && !basetex->gl_info.mExpanded && basetex->UseType != FTexture::TEX_Sprite)
|
||||
{
|
||||
// check if the texture is just a simple redirect to a patch
|
||||
// If so we should use the patch for texture creation to
|
||||
// avoid eventual redundancies.
|
||||
// This may only be done if both textures use the same expansion mode
|
||||
// Redirects to sprites are not permitted because sprites get expanded, however, this won't have been set
|
||||
// if the sprite hadn't been used yet.
|
||||
mBaseLayer = ValidateSysTexture(basetex, false);
|
||||
}
|
||||
else if (!expanded)
|
||||
{
|
||||
// if we got a non-expanded texture that redirects to an expanded one
|
||||
mBaseLayer = ValidateSysTexture(tx, false);
|
||||
}
|
||||
else
|
||||
// mSpriteRect is for positioning the sprite in the scene.
|
||||
mSpriteRect.left = -mLeftOffset / FIXED2FLOAT(tx->xScale);
|
||||
mSpriteRect.top = -mTopOffset / FIXED2FLOAT(tx->yScale);
|
||||
mSpriteRect.width = mWidth / FIXED2FLOAT(tx->xScale);
|
||||
mSpriteRect.height = mHeight / FIXED2FLOAT(tx->yScale);
|
||||
|
||||
if (expanded)
|
||||
{
|
||||
// a little adjustment to make sprites look better with texture filtering:
|
||||
// create a 1 pixel wide empty frame around them.
|
||||
RenderWidth[GLUSE_PATCH]+=2;
|
||||
RenderHeight[GLUSE_PATCH]+=2;
|
||||
Width[GLUSE_PATCH]+=2;
|
||||
Height[GLUSE_PATCH]+=2;
|
||||
LeftOffset[GLUSE_PATCH]+=1;
|
||||
TopOffset[GLUSE_PATCH]+=1;
|
||||
Width[GLUSE_SPRITE] += 2;
|
||||
Height[GLUSE_SPRITE] += 2;
|
||||
LeftOffset[GLUSE_SPRITE] += 1;
|
||||
TopOffset[GLUSE_SPRITE] += 1;
|
||||
spriteright = SpriteU[1] = Width[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Width[GLUSE_PATCH]);
|
||||
spritebottom = SpriteV[1] = Height[GLUSE_PATCH] / (float)FHardwareTexture::GetTexDimension(Height[GLUSE_PATCH]);
|
||||
|
||||
mBaseLayer = ValidateSysTexture(tx, true);
|
||||
mWidth+=2;
|
||||
mHeight+=2;
|
||||
mLeftOffset+=1;
|
||||
mTopOffset+=1;
|
||||
mRenderWidth = mRenderWidth * mWidth / (mWidth-2);
|
||||
mRenderHeight = mRenderHeight * mHeight / (mHeight-2);
|
||||
|
||||
int trim[4];
|
||||
|
||||
if (TrimBorders(trim))
|
||||
{
|
||||
Width[GLUSE_SPRITE] = trim[2] + 2;
|
||||
Height[GLUSE_SPRITE] = trim[3] + 2;
|
||||
LeftOffset[GLUSE_SPRITE] -= trim[0];
|
||||
TopOffset[GLUSE_SPRITE] -= trim[1];
|
||||
mSpriteRect.left = -(mLeftOffset - trim[0]) / FIXED2FLOAT(tx->xScale);
|
||||
mSpriteRect.top = -(mTopOffset - trim[1]) / FIXED2FLOAT(tx->yScale);
|
||||
mSpriteRect.width = (trim[2] + 2) / FIXED2FLOAT(tx->xScale);
|
||||
mSpriteRect.height = (trim[3] + 2) / FIXED2FLOAT(tx->yScale);
|
||||
|
||||
SpriteU[0] = SpriteU[1] * (trim[0] / (float)Width[GLUSE_PATCH]);
|
||||
SpriteV[0] = SpriteV[1] * (trim[1] / (float)Height[GLUSE_PATCH]);
|
||||
SpriteU[1] *= (trim[0]+trim[2]+2) / (float)Width[GLUSE_PATCH];
|
||||
SpriteV[1] *= (trim[1]+trim[3]+2) / (float)Height[GLUSE_PATCH];
|
||||
mSpriteU[0] = trim[0] / (float)mWidth;
|
||||
mSpriteV[0] = trim[1] / (float)mHeight;
|
||||
mSpriteU[1] *= (trim[0]+trim[2]+2) / (float)mWidth;
|
||||
mSpriteV[1] *= (trim[1]+trim[3]+2) / (float)mHeight;
|
||||
}
|
||||
}
|
||||
|
||||
mTextureLayers.ShrinkToFit();
|
||||
mMaxBound = -1;
|
||||
mMaterials.Push(this);
|
||||
tx->gl_info.Material[expanded] = this;
|
||||
if (tx->bHasCanvas) tx->gl_info.mIsTransparent = 0;
|
||||
mExpanded = expanded;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -755,13 +529,13 @@ bool FMaterial::TrimBorders(int *rect)
|
|||
int w;
|
||||
int h;
|
||||
|
||||
unsigned char *buffer = CreateTexBuffer(CM_DEFAULT, 0, w, h);
|
||||
unsigned char *buffer = CreateTexBuffer(0, w, h);
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (w != Width[GLUSE_TEXTURE] || h != Height[GLUSE_TEXTURE])
|
||||
if (w != mWidth || h != mHeight)
|
||||
{
|
||||
// external Hires replacements cannot be trimmed.
|
||||
delete [] buffer;
|
||||
|
|
@ -834,21 +608,28 @@ outl:
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader)
|
||||
static FMaterial *last;
|
||||
static int lastclamp;
|
||||
static int lasttrans;
|
||||
|
||||
|
||||
void FMaterial::Bind(int clampmode, int translation)
|
||||
{
|
||||
// avoid rebinding the same texture multiple times.
|
||||
if (this == last && lastclamp == clampmode && translation == lasttrans) return;
|
||||
last = this;
|
||||
lastclamp = clampmode;
|
||||
lasttrans = translation;
|
||||
|
||||
int usebright = false;
|
||||
int shaderindex = overrideshader > 0? overrideshader : mShaderIndex;
|
||||
int maxbound = 0;
|
||||
bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT;
|
||||
bool allowhires = tex->xScale == FRACUNIT && tex->yScale == FRACUNIT && clampmode <= CLAMP_XY && !mExpanded;
|
||||
|
||||
int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed);
|
||||
if (tex->bHasCanvas) clampmode = CLAMP_CAMTEX;
|
||||
else if (tex->bWarped && clampmode <= CLAMP_XY) clampmode = CLAMP_NONE;
|
||||
|
||||
if (tex->bHasCanvas || tex->bWarped) clampmode = 0;
|
||||
else if (clampmode != -1) clampmode &= 3;
|
||||
else clampmode = 4;
|
||||
|
||||
const FHardwareTexture *gltexture = mBaseLayer->Bind(0, cm, clampmode, translation, allowhires? tex:NULL, softwarewarp);
|
||||
if (gltexture != NULL && shaderindex > 0 && overrideshader == 0)
|
||||
const FHardwareTexture *gltexture = mBaseLayer->Bind(0, clampmode, translation, allowhires? tex:NULL);
|
||||
if (gltexture != NULL)
|
||||
{
|
||||
for(unsigned i=0;i<mTextureLayers.Size();i++)
|
||||
{
|
||||
|
|
@ -857,13 +638,13 @@ void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader)
|
|||
{
|
||||
FTextureID id = mTextureLayers[i].texture->id;
|
||||
layer = TexMan(id);
|
||||
ValidateSysTexture(layer, false);
|
||||
ValidateSysTexture(layer, mExpanded);
|
||||
}
|
||||
else
|
||||
{
|
||||
layer = mTextureLayers[i].texture;
|
||||
}
|
||||
layer->gl_info.SystemTexture->Bind(i+1, CM_DEFAULT, clampmode, 0, NULL, false);
|
||||
layer->gl_info.SystemTexture[mExpanded]->Bind(i+1, clampmode, 0, NULL);
|
||||
maxbound = i+1;
|
||||
}
|
||||
}
|
||||
|
|
@ -876,36 +657,6 @@ void FMaterial::Bind(int cm, int clampmode, int translation, int overrideshader)
|
|||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// Binds a texture to the renderer
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FMaterial::BindPatch(int cm, int translation, int overrideshader)
|
||||
{
|
||||
int usebright = false;
|
||||
int shaderindex = overrideshader > 0? overrideshader : mShaderIndex;
|
||||
int maxbound = 0;
|
||||
|
||||
int softwarewarp = gl_RenderState.SetupShader(tex->bHasCanvas, shaderindex, cm, tex->gl_info.shaderspeed);
|
||||
|
||||
const FHardwareTexture *glpatch = mBaseLayer->BindPatch(0, cm, translation, softwarewarp);
|
||||
// The only multitexture effect usable on sprites is the brightmap.
|
||||
if (glpatch != NULL && shaderindex == 3)
|
||||
{
|
||||
mTextureLayers[0].texture->gl_info.SystemTexture->BindPatch(1, CM_DEFAULT, 0, 0);
|
||||
maxbound = 1;
|
||||
}
|
||||
// unbind everything from the last texture that's still active
|
||||
for(int i=maxbound+1; i<=mMaxBound;i++)
|
||||
{
|
||||
FHardwareTexture::Unbind(i);
|
||||
mMaxBound = maxbound;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
//
|
||||
|
|
@ -913,31 +664,12 @@ void FMaterial::BindPatch(int cm, int translation, int overrideshader)
|
|||
//===========================================================================
|
||||
void FMaterial::Precache()
|
||||
{
|
||||
if (tex->UseType==FTexture::TEX_Sprite)
|
||||
{
|
||||
BindPatch(CM_DEFAULT, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int cached = 0;
|
||||
for(int i=0;i<4;i++)
|
||||
{
|
||||
if (mBaseLayer->gltexture[i] != 0)
|
||||
{
|
||||
Bind (CM_DEFAULT, i, 0);
|
||||
cached++;
|
||||
}
|
||||
if (cached == 0) Bind(CM_DEFAULT, -1, 0);
|
||||
}
|
||||
}
|
||||
Bind(0, 0);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// This function is needed here to temporarily manipulate the texture
|
||||
// for per-wall scaling so that the coordinate functions return proper
|
||||
// results. Doing this here is much easier than having the calling code
|
||||
// make these calculations.
|
||||
// Retrieve texture coordinate info for per-wall scaling
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
|
|
@ -945,14 +677,14 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const
|
|||
{
|
||||
if (x == FRACUNIT)
|
||||
{
|
||||
tci->mRenderWidth = RenderWidth[GLUSE_TEXTURE];
|
||||
tci->mRenderWidth = mRenderWidth;
|
||||
tci->mScaleX = tex->xScale;
|
||||
tci->mTempScaleX = FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t scale_x = FixedMul(x, tex->xScale);
|
||||
int foo = (Width[GLUSE_TEXTURE] << 17) / scale_x;
|
||||
int foo = (mWidth << 17) / scale_x;
|
||||
tci->mRenderWidth = (foo >> 1) + (foo & 1);
|
||||
tci->mScaleX = scale_x;
|
||||
tci->mTempScaleX = x;
|
||||
|
|
@ -960,14 +692,14 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const
|
|||
|
||||
if (y == FRACUNIT)
|
||||
{
|
||||
tci->mRenderHeight = RenderHeight[GLUSE_TEXTURE];
|
||||
tci->mRenderHeight = mRenderHeight;
|
||||
tci->mScaleY = tex->yScale;
|
||||
tci->mTempScaleY = FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t scale_y = FixedMul(y, tex->yScale);
|
||||
int foo = (Height[GLUSE_TEXTURE] << 17) / scale_y;
|
||||
int foo = (mHeight << 17) / scale_y;
|
||||
tci->mRenderHeight = (foo >> 1) + (foo & 1);
|
||||
tci->mScaleY = scale_y;
|
||||
tci->mTempScaleY = y;
|
||||
|
|
@ -978,7 +710,7 @@ void FMaterial::GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const
|
|||
tci->mRenderHeight = -tci->mRenderHeight;
|
||||
}
|
||||
tci->mWorldPanning = tex->bWorldPanning;
|
||||
tci->mWidth = Width[GLUSE_TEXTURE];
|
||||
tci->mWidth = mWidth;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -1009,30 +741,16 @@ int FMaterial::GetAreas(FloatRect **pAreas) const
|
|||
|
||||
void FMaterial::BindToFrameBuffer()
|
||||
{
|
||||
if (mBaseLayer->gltexture[0] == NULL)
|
||||
if (mBaseLayer->mHwTexture == NULL)
|
||||
{
|
||||
// must create the hardware texture first
|
||||
mBaseLayer->Bind(0, CM_DEFAULT, 0, 0, NULL, 0);
|
||||
mBaseLayer->Bind(0, 0, 0, NULL);
|
||||
FHardwareTexture::Unbind(0);
|
||||
ClearLastTexture();
|
||||
}
|
||||
mBaseLayer->gltexture[0]->BindToFrameBuffer();
|
||||
mBaseLayer->mHwTexture->BindToFrameBuffer();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// GetRect
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
void FMaterial::GetRect(FloatRect * r, ETexUse i) const
|
||||
{
|
||||
r->left = -GetScaledLeftOffsetFloat(i);
|
||||
r->top = -GetScaledTopOffsetFloat(i);
|
||||
r->width = GetScaledWidthFloat(i);
|
||||
r->height = GetScaledHeightFloat(i);
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Gets a texture from the texture manager and checks its validity for
|
||||
|
|
@ -1040,23 +758,23 @@ void FMaterial::GetRect(FloatRect * r, ETexUse i) const
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
FMaterial * FMaterial::ValidateTexture(FTexture * tex)
|
||||
FMaterial * FMaterial::ValidateTexture(FTexture * tex, bool expand)
|
||||
{
|
||||
if (tex && tex->UseType!=FTexture::TEX_Null)
|
||||
{
|
||||
FMaterial *gltex = tex->gl_info.Material;
|
||||
FMaterial *gltex = tex->gl_info.Material[expand];
|
||||
if (gltex == NULL)
|
||||
{
|
||||
gltex = new FMaterial(tex, false);
|
||||
gltex = new FMaterial(tex, expand);
|
||||
}
|
||||
return gltex;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FMaterial * FMaterial::ValidateTexture(FTextureID no, bool translate)
|
||||
FMaterial * FMaterial::ValidateTexture(FTextureID no, bool expand, bool translate)
|
||||
{
|
||||
return ValidateTexture(translate? TexMan(no) : TexMan[no]);
|
||||
return ValidateTexture(translate? TexMan(no) : TexMan[no], expand);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1076,47 +794,15 @@ void FMaterial::FlushAll()
|
|||
// so this will catch everything.
|
||||
for(int i=TexMan.NumTextures()-1;i>=0;i--)
|
||||
{
|
||||
FGLTexture *gltex = TexMan.ByIndex(i)->gl_info.SystemTexture;
|
||||
if (gltex != NULL) gltex->Clean(true);
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Prints some texture info
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
int FGLTexture::Dump(int i)
|
||||
{
|
||||
int cnt = 0;
|
||||
int lump = tex->GetSourceLump();
|
||||
Printf(PRINT_LOG, "Texture '%s' (Index %d, Lump %d, Name '%s'):\n", tex->Name.GetChars(), i, lump, Wads.GetLumpFullName(lump));
|
||||
if (hirestexture) Printf(PRINT_LOG, "\tHirestexture\n");
|
||||
if (glpatch) Printf(PRINT_LOG, "\tPatch\n"),cnt++;
|
||||
if (gltexture[0]) Printf(PRINT_LOG, "\tTexture (x:no, y:no )\n"),cnt++;
|
||||
if (gltexture[1]) Printf(PRINT_LOG, "\tTexture (x:yes, y:no )\n"),cnt++;
|
||||
if (gltexture[2]) Printf(PRINT_LOG, "\tTexture (x:no, y:yes)\n"),cnt++;
|
||||
if (gltexture[3]) Printf(PRINT_LOG, "\tTexture (x:yes, y:yes)\n"),cnt++;
|
||||
if (gltexture[4]) Printf(PRINT_LOG, "\tTexture precache\n"),cnt++;
|
||||
return cnt;
|
||||
}
|
||||
|
||||
CCMD(textureinfo)
|
||||
{
|
||||
int cnth = 0, cntt = 0, pix = 0;
|
||||
for(int i=0; i<TexMan.NumTextures(); i++)
|
||||
{
|
||||
FTexture *tex = TexMan.ByIndex(i);
|
||||
FGLTexture *systex = tex->gl_info.SystemTexture;
|
||||
if (systex != NULL)
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
int cnt = systex->Dump(i);
|
||||
cnth+=cnt;
|
||||
cntt++;
|
||||
pix += cnt * tex->GetWidth() * tex->GetHeight();
|
||||
FGLTexture *gltex = TexMan.ByIndex(i)->gl_info.SystemTexture[j];
|
||||
if (gltex != NULL) gltex->Clean(true);
|
||||
}
|
||||
}
|
||||
Printf(PRINT_LOG, "%d system textures, %d hardware textures, %d pixels\n", cntt, cnth, pix);
|
||||
}
|
||||
|
||||
void FMaterial::ClearLastTexture()
|
||||
{
|
||||
last = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,17 @@ EXTERN_CVAR(Bool, gl_precache)
|
|||
struct FRemapTable;
|
||||
class FTextureShader;
|
||||
|
||||
enum
|
||||
{
|
||||
CLAMP_NONE = 0,
|
||||
CLAMP_X = 1,
|
||||
CLAMP_Y = 2,
|
||||
CLAMP_XY = 3,
|
||||
CLAMP_XY_NOMIP = 4,
|
||||
CLAMP_NOFILTER = 5,
|
||||
CLAMP_CAMTEX = 6,
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct FTexCoordInfo
|
||||
|
|
@ -40,15 +51,8 @@ struct FTexCoordInfo
|
|||
//===========================================================================
|
||||
class FMaterial;
|
||||
|
||||
enum ETexUse
|
||||
{
|
||||
GLUSE_PATCH,
|
||||
GLUSE_TEXTURE,
|
||||
GLUSE_SPRITE,
|
||||
};
|
||||
|
||||
|
||||
class FGLTexture //: protected WorldTextureInfo, protected PatchTextureInfo
|
||||
class FGLTexture
|
||||
{
|
||||
friend class FMaterial;
|
||||
public:
|
||||
|
|
@ -58,31 +62,22 @@ public:
|
|||
int HiresLump;
|
||||
|
||||
private:
|
||||
FHardwareTexture *gltexture[5];
|
||||
FHardwareTexture *glpatch;
|
||||
|
||||
int currentwarp;
|
||||
int currentwarptime;
|
||||
FHardwareTexture *mHwTexture;
|
||||
|
||||
bool bHasColorkey; // only for hires
|
||||
bool bExpand;
|
||||
float AlphaThreshold;
|
||||
|
||||
unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height, int cm);
|
||||
BYTE *WarpBuffer(BYTE *buffer, int Width, int Height, int warp);
|
||||
unsigned char * LoadHiresTexture(FTexture *hirescheck, int *width, int *height);
|
||||
|
||||
FHardwareTexture *CreateTexture(int clampmode);
|
||||
//bool CreateTexture();
|
||||
bool CreatePatch();
|
||||
|
||||
const FHardwareTexture *Bind(int texunit, int cm, int clamp, int translation, FTexture *hirescheck, int warp);
|
||||
const FHardwareTexture *BindPatch(int texunit, int cm, int translation, int warp);
|
||||
FHardwareTexture *CreateHwTexture();
|
||||
|
||||
const FHardwareTexture *Bind(int texunit, int clamp, int translation, FTexture *hirescheck);
|
||||
|
||||
public:
|
||||
FGLTexture(FTexture * tx, bool expandpatches);
|
||||
~FGLTexture();
|
||||
|
||||
unsigned char * CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand, FTexture *hirescheck, int warp);
|
||||
unsigned char * CreateTexBuffer(int translation, int & w, int & h, FTexture *hirescheck);
|
||||
|
||||
void Clean(bool all);
|
||||
int Dump(int i);
|
||||
|
|
@ -97,6 +92,8 @@ public:
|
|||
|
||||
class FMaterial
|
||||
{
|
||||
friend class FRenderState;
|
||||
|
||||
struct FTextureLayer
|
||||
{
|
||||
FTexture *texture;
|
||||
|
|
@ -110,17 +107,17 @@ class FMaterial
|
|||
TArray<FTextureLayer> mTextureLayers;
|
||||
int mShaderIndex;
|
||||
|
||||
short LeftOffset[3];
|
||||
short TopOffset[3];
|
||||
short Width[3];
|
||||
short Height[3];
|
||||
short RenderWidth[2];
|
||||
short RenderHeight[2];
|
||||
short mLeftOffset;
|
||||
short mTopOffset;
|
||||
short mWidth;
|
||||
short mHeight;
|
||||
short mRenderWidth;
|
||||
short mRenderHeight;
|
||||
bool mExpanded;
|
||||
|
||||
float SpriteU[2], SpriteV[2];
|
||||
float spriteright, spritebottom;
|
||||
float mSpriteU[2], mSpriteV[2];
|
||||
FloatRect mSpriteRect;
|
||||
|
||||
void SetupShader(int shaderindex, int &cm);
|
||||
FGLTexture * ValidateSysTexture(FTexture * tex, bool expand);
|
||||
bool TrimBorders(int *rect);
|
||||
|
||||
|
|
@ -135,12 +132,16 @@ public:
|
|||
return !!mBaseLayer->tex->bMasked;
|
||||
}
|
||||
|
||||
void Bind(int cm, int clamp = 0, int translation = 0, int overrideshader = 0);
|
||||
void BindPatch(int cm, int translation = 0, int overrideshader = 0);
|
||||
|
||||
unsigned char * CreateTexBuffer(int cm, int translation, int & w, int & h, bool expand = false, bool allowhires=true) const
|
||||
int GetLayers() const
|
||||
{
|
||||
return mBaseLayer->CreateTexBuffer(cm, translation, w, h, expand, allowhires? tex:NULL, 0);
|
||||
return mTextureLayers.Size() + 1;
|
||||
}
|
||||
|
||||
void Bind(int clamp, int translation);
|
||||
|
||||
unsigned char * CreateTexBuffer(int translation, int & w, int & h, bool allowhires=true) const
|
||||
{
|
||||
return mBaseLayer->CreateTexBuffer(translation, w, h, allowhires? tex : NULL);
|
||||
}
|
||||
|
||||
void Clean(bool f)
|
||||
|
|
@ -151,78 +152,82 @@ public:
|
|||
void BindToFrameBuffer();
|
||||
// Patch drawing utilities
|
||||
|
||||
void GetRect(FloatRect *r, ETexUse i) const;
|
||||
void GetSpriteRect(FloatRect * r) const
|
||||
{
|
||||
*r = mSpriteRect;
|
||||
}
|
||||
|
||||
void GetTexCoordInfo(FTexCoordInfo *tci, fixed_t x, fixed_t y) const;
|
||||
|
||||
// This is scaled size in integer units as needed by walls and flats
|
||||
int TextureHeight(ETexUse i) const { return RenderHeight[i]; }
|
||||
int TextureWidth(ETexUse i) const { return RenderWidth[i]; }
|
||||
int TextureHeight() const { return mRenderHeight; }
|
||||
int TextureWidth() const { return mRenderWidth; }
|
||||
|
||||
int GetAreas(FloatRect **pAreas) const;
|
||||
|
||||
int GetWidth(ETexUse i) const
|
||||
int GetWidth() const
|
||||
{
|
||||
return Width[i];
|
||||
return mWidth;
|
||||
}
|
||||
|
||||
int GetHeight(ETexUse i) const
|
||||
int GetHeight() const
|
||||
{
|
||||
return Height[i];
|
||||
return mHeight;
|
||||
}
|
||||
|
||||
int GetLeftOffset(ETexUse i) const
|
||||
int GetLeftOffset() const
|
||||
{
|
||||
return LeftOffset[i];
|
||||
return mLeftOffset;
|
||||
}
|
||||
|
||||
int GetTopOffset(ETexUse i) const
|
||||
int GetTopOffset() const
|
||||
{
|
||||
return TopOffset[i];
|
||||
return mTopOffset;
|
||||
}
|
||||
|
||||
int GetScaledLeftOffset(ETexUse i) const
|
||||
int GetScaledLeftOffset() const
|
||||
{
|
||||
return DivScale16(LeftOffset[i], tex->xScale);
|
||||
return DivScale16(mLeftOffset, tex->xScale);
|
||||
}
|
||||
|
||||
int GetScaledTopOffset(ETexUse i) const
|
||||
int GetScaledTopOffset() const
|
||||
{
|
||||
return DivScale16(TopOffset[i], tex->yScale);
|
||||
return DivScale16(mTopOffset, tex->yScale);
|
||||
}
|
||||
|
||||
float GetScaledLeftOffsetFloat(ETexUse i) const
|
||||
float GetScaledLeftOffsetFloat() const
|
||||
{
|
||||
return LeftOffset[i] / FIXED2FLOAT(tex->xScale);
|
||||
return mLeftOffset / FIXED2FLOAT(tex->xScale);
|
||||
}
|
||||
|
||||
float GetScaledTopOffsetFloat(ETexUse i) const
|
||||
float GetScaledTopOffsetFloat() const
|
||||
{
|
||||
return TopOffset[i] / FIXED2FLOAT(tex->yScale);
|
||||
return mTopOffset/ FIXED2FLOAT(tex->yScale);
|
||||
}
|
||||
|
||||
// This is scaled size in floating point as needed by sprites
|
||||
float GetScaledWidthFloat(ETexUse i) const
|
||||
float GetScaledWidthFloat() const
|
||||
{
|
||||
return Width[i] / FIXED2FLOAT(tex->xScale);
|
||||
return mWidth / FIXED2FLOAT(tex->xScale);
|
||||
}
|
||||
|
||||
float GetScaledHeightFloat(ETexUse i) const
|
||||
float GetScaledHeightFloat() const
|
||||
{
|
||||
return Height[i] / FIXED2FLOAT(tex->yScale);
|
||||
return mHeight / FIXED2FLOAT(tex->yScale);
|
||||
}
|
||||
|
||||
// Get right/bottom UV coordinates for patch drawing
|
||||
float GetUL() const { return 0; }
|
||||
float GetVT() const { return 0; }
|
||||
float GetUR() const { return spriteright; }
|
||||
float GetVB() const { return spritebottom; }
|
||||
float GetU(float upix) const { return upix/(float)Width[GLUSE_PATCH] * spriteright; }
|
||||
float GetV(float vpix) const { return vpix/(float)Height[GLUSE_PATCH] * spritebottom; }
|
||||
float GetUR() const { return 1; }
|
||||
float GetVB() const { return 1; }
|
||||
float GetU(float upix) const { return upix/(float)mWidth; }
|
||||
float GetV(float vpix) const { return vpix/(float)mHeight; }
|
||||
|
||||
float GetSpriteUL() const { return SpriteU[0]; }
|
||||
float GetSpriteVT() const { return SpriteV[0]; }
|
||||
float GetSpriteUR() const { return SpriteU[1]; }
|
||||
float GetSpriteVB() const { return SpriteV[1]; }
|
||||
float GetSpriteUL() const { return mSpriteU[0]; }
|
||||
float GetSpriteVT() const { return mSpriteV[0]; }
|
||||
float GetSpriteUR() const { return mSpriteU[1]; }
|
||||
float GetSpriteVB() const { return mSpriteV[1]; }
|
||||
|
||||
|
||||
|
||||
|
|
@ -233,7 +238,7 @@ public:
|
|||
if (!mBaseLayer->tex->bHasCanvas)
|
||||
{
|
||||
int w, h;
|
||||
unsigned char *buffer = CreateTexBuffer(CM_DEFAULT, 0, w, h);
|
||||
unsigned char *buffer = CreateTexBuffer(0, w, h);
|
||||
delete [] buffer;
|
||||
}
|
||||
else
|
||||
|
|
@ -246,8 +251,9 @@ public:
|
|||
|
||||
static void DeleteAll();
|
||||
static void FlushAll();
|
||||
static FMaterial *ValidateTexture(FTexture * tex);
|
||||
static FMaterial *ValidateTexture(FTextureID no, bool trans);
|
||||
static FMaterial *ValidateTexture(FTexture * tex, bool expand);
|
||||
static FMaterial *ValidateTexture(FTextureID no, bool expand, bool trans);
|
||||
static void ClearLastTexture();
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
112
src/gl/textures/gl_samplers.cpp
Normal file
112
src/gl/textures/gl_samplers.cpp
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
** gl_samplers.cpp
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2014 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
** 4. When not used as part of GZDoom or a GZDoom derivative, this code will be
|
||||
** covered by the terms of the GNU Lesser General Public License as published
|
||||
** by the Free Software Foundation; either version 2.1 of the License, or (at
|
||||
** your option) any later version.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "templates.h"
|
||||
#include "c_cvars.h"
|
||||
#include "c_dispatch.h"
|
||||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl_samplers.h"
|
||||
|
||||
extern TexFilter_s TexFilter[];
|
||||
|
||||
|
||||
FSamplerManager::FSamplerManager()
|
||||
{
|
||||
glGenSamplers(6, mSamplers);
|
||||
SetTextureFilterMode();
|
||||
glSamplerParameteri(mSamplers[5], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glSamplerParameteri(mSamplers[5], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glSamplerParameterf(mSamplers[5], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
|
||||
glSamplerParameterf(mSamplers[4], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
|
||||
glSamplerParameterf(mSamplers[6], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f);
|
||||
|
||||
glSamplerParameteri(mSamplers[1], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(mSamplers[2], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(mSamplers[3], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glSamplerParameteri(mSamplers[4], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
}
|
||||
|
||||
FSamplerManager::~FSamplerManager()
|
||||
{
|
||||
UnbindAll();
|
||||
glDeleteSamplers(6, mSamplers);
|
||||
}
|
||||
|
||||
void FSamplerManager::UnbindAll()
|
||||
{
|
||||
for (int i = 0; i < FHardwareTexture::MAX_TEXTURES; i++)
|
||||
{
|
||||
mLastBound[i] = 0;
|
||||
glBindSampler(i, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void FSamplerManager::Bind(int texunit, int num)
|
||||
{
|
||||
unsigned int samp = mSamplers[num];
|
||||
//if (samp != mLastBound[texunit])
|
||||
{
|
||||
glBindSampler(texunit, samp);
|
||||
mLastBound[texunit] = samp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FSamplerManager::SetTextureFilterMode()
|
||||
{
|
||||
UnbindAll();
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
glSamplerParameteri(mSamplers[i], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].minfilter);
|
||||
glSamplerParameteri(mSamplers[i], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter);
|
||||
glSamplerParameterf(mSamplers[i], GL_TEXTURE_MAX_ANISOTROPY_EXT, gl_texture_filter_anisotropic);
|
||||
}
|
||||
glSamplerParameteri(mSamplers[4], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter);
|
||||
glSamplerParameteri(mSamplers[4], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter);
|
||||
glSamplerParameteri(mSamplers[6], GL_TEXTURE_MIN_FILTER, TexFilter[gl_texture_filter].magfilter);
|
||||
glSamplerParameteri(mSamplers[6], GL_TEXTURE_MAG_FILTER, TexFilter[gl_texture_filter].magfilter);
|
||||
}
|
||||
|
||||
|
||||
28
src/gl/textures/gl_samplers.h
Normal file
28
src/gl/textures/gl_samplers.h
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef __GL_SAMPLERS_H
|
||||
#define __GL_SAMPLERS_H
|
||||
|
||||
#include "gl_hwtexture.h"
|
||||
|
||||
class FSamplerManager
|
||||
{
|
||||
// We need 6 different samplers: 4 for the different clamping modes,
|
||||
// one for 2D-textures and one for voxel textures
|
||||
unsigned int mSamplers[6];
|
||||
unsigned int mLastBound[FHardwareTexture::MAX_TEXTURES];
|
||||
|
||||
void UnbindAll();
|
||||
|
||||
public:
|
||||
|
||||
FSamplerManager();
|
||||
~FSamplerManager();
|
||||
|
||||
void Bind(int texunit, int num);
|
||||
void SetTextureFilterMode();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -132,9 +132,15 @@ void FSkyBox::Unload ()
|
|||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void FSkyBox::PrecacheGL()
|
||||
void FSkyBox::PrecacheGL(int cache)
|
||||
{
|
||||
//for(int i=0;i<6;i++) if (faces[i]) faces[i]->PrecacheGL();
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (faces[i])
|
||||
{
|
||||
faces[i]->PrecacheGL(cache);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public:
|
|||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
|
||||
bool UseBasePalette();
|
||||
void Unload ();
|
||||
void PrecacheGL();
|
||||
void PrecacheGL(int cache);
|
||||
|
||||
void SetSize()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@
|
|||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/textures/gl_texture.h"
|
||||
#include "gl/textures/gl_material.h"
|
||||
#include "gl/textures/gl_samplers.h"
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
|
@ -60,7 +61,7 @@
|
|||
//==========================================================================
|
||||
CUSTOM_CVAR(Float,gl_texture_filter_anisotropic,8.0f,CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
{
|
||||
if (GLRenderer != NULL) GLRenderer->FlushTextures();
|
||||
if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode();
|
||||
}
|
||||
|
||||
CCMD(gl_flush)
|
||||
|
|
@ -71,7 +72,7 @@ CCMD(gl_flush)
|
|||
CUSTOM_CVAR(Int, gl_texture_filter, 4, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
{
|
||||
if (self < 0 || self > 5) self=4;
|
||||
if (GLRenderer != NULL) GLRenderer->FlushTextures();
|
||||
if (GLRenderer != NULL && GLRenderer->mSamplerManager != NULL) GLRenderer->mSamplerManager->SetTextureFilterMode();
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Int, gl_texture_format, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOINITCALL)
|
||||
|
|
@ -94,7 +95,6 @@ CUSTOM_CVAR(Bool, gl_texture_usehires, true, CVAR_ARCHIVE|CVAR_NOINITCALL)
|
|||
}
|
||||
|
||||
CVAR(Bool, gl_precache, false, CVAR_ARCHIVE)
|
||||
CVAR(Bool, gl_clamp_per_texture, false, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
CVAR(Bool, gl_trimsprites, true, CVAR_ARCHIVE);
|
||||
|
||||
|
|
@ -210,7 +210,7 @@ PalEntry averageColor(const DWORD *data, int size, fixed_t maxout_factor)
|
|||
g = Scale(g, maxout_factor, maxv);
|
||||
b = Scale(b, maxout_factor, maxv);
|
||||
}
|
||||
return PalEntry(r,g,b);
|
||||
return PalEntry(255,r,g,b);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -236,37 +236,34 @@ FTexture::MiscGLInfo::MiscGLInfo() throw()
|
|||
bBrightmapDisablesFullbright = false;
|
||||
bNoFilter = false;
|
||||
bNoCompress = false;
|
||||
mExpanded = false;
|
||||
areas = NULL;
|
||||
areacount = 0;
|
||||
mIsTransparent = -1;
|
||||
shaderspeed = 1.f;
|
||||
shaderindex = 0;
|
||||
precacheTime = 0;
|
||||
|
||||
Material = NULL;
|
||||
SystemTexture = NULL;
|
||||
Material[1] = Material[0] = NULL;
|
||||
SystemTexture[1] = SystemTexture[0] = NULL;
|
||||
Brightmap = NULL;
|
||||
DecalTexture = NULL;
|
||||
}
|
||||
|
||||
FTexture::MiscGLInfo::~MiscGLInfo()
|
||||
{
|
||||
if (Material != NULL) delete Material;
|
||||
Material = NULL;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (Material[i] != NULL) delete Material[i];
|
||||
Material[i] = NULL;
|
||||
|
||||
if (SystemTexture != NULL) delete SystemTexture;
|
||||
SystemTexture = NULL;
|
||||
if (SystemTexture[i] != NULL) delete SystemTexture[i];
|
||||
SystemTexture[i] = NULL;
|
||||
}
|
||||
|
||||
// this is managed by the texture manager so it may not be deleted here.
|
||||
//if (Brightmap != NULL) delete Brightmap;
|
||||
// this is just a reference to another texture in the texture manager.
|
||||
Brightmap = NULL;
|
||||
|
||||
if (areas != NULL) delete [] areas;
|
||||
areas = NULL;
|
||||
|
||||
if (DecalTexture != NULL) delete DecalTexture;
|
||||
DecalTexture = NULL;
|
||||
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
|
@ -320,12 +317,21 @@ void FTexture::CreateDefaultBrightmap()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FTexture::PrecacheGL()
|
||||
void FTexture::PrecacheGL(int cache)
|
||||
{
|
||||
if (gl_precache)
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(this);
|
||||
if (gltex) gltex->Precache();
|
||||
if (cache & 2)
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(this, false);
|
||||
if (gltex) gltex->Precache();
|
||||
}
|
||||
if (cache & 4)
|
||||
{
|
||||
FMaterial * gltex = FMaterial::ValidateTexture(this, true);
|
||||
if (gltex) gltex->Precache();
|
||||
}
|
||||
gl_info.precacheTime = TexMan.precacheTime;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -337,7 +343,12 @@ void FTexture::PrecacheGL()
|
|||
|
||||
void FTexture::UncacheGL()
|
||||
{
|
||||
if (gl_info.Material) gl_info.Material->Clean(true);
|
||||
if (gl_info.precacheTime != TexMan.precacheTime)
|
||||
{
|
||||
if (gl_info.Material[0]) gl_info.Material[0]->Clean(true);
|
||||
if (gl_info.Material[1]) gl_info.Material[1]->Clean(true);
|
||||
gl_info.precacheTime = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -641,49 +652,6 @@ int FBrightmapTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotat
|
|||
}
|
||||
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A cloned texture. This is needed by the decal code which needs to assign
|
||||
// a different texture type to some of its graphics.
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
FCloneTexture::FCloneTexture (FTexture *source, int usetype)
|
||||
{
|
||||
Name = "";
|
||||
SourcePic = source;
|
||||
CopySize(source);
|
||||
bNoDecals = source->bNoDecals;
|
||||
Rotations = source->Rotations;
|
||||
UseType = usetype;
|
||||
gl_info.bBrightmap = false;
|
||||
id.SetInvalid();
|
||||
SourceLump = -1;
|
||||
}
|
||||
|
||||
FCloneTexture::~FCloneTexture ()
|
||||
{
|
||||
}
|
||||
|
||||
const BYTE *FCloneTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const BYTE *FCloneTexture::GetPixels ()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FCloneTexture::Unload ()
|
||||
{
|
||||
}
|
||||
|
||||
int FCloneTexture::CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf)
|
||||
{
|
||||
return SourcePic->CopyTrueColorPixels(bmp, x, y, rotate, inf);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Parses a brightmap definition
|
||||
|
|
@ -830,3 +798,42 @@ void gl_ParseDetailTexture(FScanner &sc)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Prints some texture info
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD(textureinfo)
|
||||
{
|
||||
int cntt = 0;
|
||||
for (int i = 0; i < TexMan.NumTextures(); i++)
|
||||
{
|
||||
FTexture *tex = TexMan.ByIndex(i);
|
||||
if (tex->gl_info.SystemTexture[0] || tex->gl_info.SystemTexture[1] || tex->gl_info.Material[0] || tex->gl_info.Material[1])
|
||||
{
|
||||
int lump = tex->GetSourceLump();
|
||||
Printf(PRINT_LOG, "Texture '%s' (Index %d, Lump %d, Name '%s'):\n", tex->Name.GetChars(), i, lump, Wads.GetLumpFullName(lump));
|
||||
if (tex->gl_info.Material[0])
|
||||
{
|
||||
Printf(PRINT_LOG, "in use (normal)\n");
|
||||
}
|
||||
else if (tex->gl_info.SystemTexture[0])
|
||||
{
|
||||
Printf(PRINT_LOG, "referenced (normal)\n");
|
||||
}
|
||||
if (tex->gl_info.Material[1])
|
||||
{
|
||||
Printf(PRINT_LOG, "in use (expanded)\n");
|
||||
}
|
||||
else if (tex->gl_info.SystemTexture[1])
|
||||
{
|
||||
Printf(PRINT_LOG, "referenced (normal)\n");
|
||||
}
|
||||
cntt++;
|
||||
}
|
||||
}
|
||||
Printf(PRINT_LOG, "%d system textures\n", cntt);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,23 +56,6 @@ protected:
|
|||
//Span **Spans;
|
||||
};
|
||||
|
||||
class FCloneTexture : public FTexture
|
||||
{
|
||||
public:
|
||||
FCloneTexture (FTexture *source, int usetype);
|
||||
~FCloneTexture ();
|
||||
|
||||
const BYTE *GetColumn (unsigned int column, const Span **spans_out);
|
||||
const BYTE *GetPixels ();
|
||||
void Unload ();
|
||||
|
||||
int CopyTrueColorPixels(FBitmap *bmp, int x, int y, int rotate, FCopyInfo *inf);
|
||||
bool UseBasePalette() { return false; }
|
||||
|
||||
protected:
|
||||
FTexture *SourcePic;
|
||||
};
|
||||
|
||||
|
||||
void gl_GenerateGlobalBrightmapFromColormap();
|
||||
PalEntry averageColor(const DWORD *data, int size, fixed_t maxout);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ glcycle_t All, Finish, PortalAll, Bsp;
|
|||
glcycle_t ProcessAll;
|
||||
glcycle_t RenderAll;
|
||||
glcycle_t Dirty;
|
||||
glcycle_t drawcalls;
|
||||
int vertexcount, flatvertices, flatprimitives;
|
||||
|
||||
int rendered_lines,rendered_flats,rendered_sprites,render_vertexsplit,render_texsplit,rendered_decals, rendered_portals;
|
||||
|
|
@ -96,6 +97,7 @@ void ResetProfilingData()
|
|||
SetupFlat.Reset();
|
||||
RenderSprite.Reset();
|
||||
SetupSprite.Reset();
|
||||
drawcalls.Reset();
|
||||
|
||||
flatvertices=flatprimitives=vertexcount=0;
|
||||
render_texsplit=render_vertexsplit=rendered_lines=rendered_flats=rendered_sprites=rendered_decals=rendered_portals = 0;
|
||||
|
|
@ -116,10 +118,10 @@ static void AppendRenderTimes(FString &str)
|
|||
str.AppendFormat("W: Render=%2.3f, Split = %2.3f, Setup=%2.3f, Clip=%2.3f\n"
|
||||
"F: Render=%2.3f, Setup=%2.3f\n"
|
||||
"S: Render=%2.3f, Setup=%2.3f\n"
|
||||
"All=%2.3f, Render=%2.3f, Setup=%2.3f, BSP = %2.3f, Portal=%2.3f, Finish=%2.3f\n",
|
||||
"All=%2.3f, Render=%2.3f, Setup=%2.3f, BSP = %2.3f, Portal=%2.3f, Drawcalls=%2.3f, Finish=%2.3f\n",
|
||||
RenderWall.TimeMS(), SplitWall.TimeMS(), setupwall, clipwall, RenderFlat.TimeMS(), SetupFlat.TimeMS(),
|
||||
RenderSprite.TimeMS(), SetupSprite.TimeMS(), All.TimeMS() + Finish.TimeMS(), RenderAll.TimeMS(),
|
||||
ProcessAll.TimeMS(), bsp, PortalAll.TimeMS(), Finish.TimeMS());
|
||||
ProcessAll.TimeMS(), bsp, PortalAll.TimeMS(), drawcalls.TimeMS(), Finish.TimeMS());
|
||||
}
|
||||
|
||||
static void AppendRenderStats(FString &out)
|
||||
|
|
@ -219,4 +221,13 @@ CCMD(bench)
|
|||
switchfps = false;
|
||||
}
|
||||
C_HideConsole ();
|
||||
}
|
||||
}
|
||||
|
||||
bool gl_benching = false;
|
||||
|
||||
void checkBenchActive()
|
||||
{
|
||||
FStat *stat = FStat::FindStat("rendertimes");
|
||||
gl_benching = ((stat != NULL && stat->isActive()) || printstats);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,13 @@
|
|||
#include "x86.h"
|
||||
#include "m_fixed.h"
|
||||
|
||||
extern bool gl_benching;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
extern double gl_SecondsPerCycle;
|
||||
extern double gl_MillisecPerCycle;
|
||||
|
||||
|
||||
__forceinline long long GetClockCycle ()
|
||||
{
|
||||
#if _M_X64
|
||||
|
|
@ -75,13 +76,13 @@ public:
|
|||
// Not using QueryPerformanceCounter directly, so we don't need
|
||||
// to pull in the Windows headers for every single file that
|
||||
// wants to do some profiling.
|
||||
long long time = GetClockCycle();
|
||||
long long time = (gl_benching? GetClockCycle() : 0);
|
||||
Counter -= time;
|
||||
}
|
||||
|
||||
__forceinline void Unclock()
|
||||
{
|
||||
long long time = GetClockCycle();
|
||||
long long time = (gl_benching? GetClockCycle() : 0);
|
||||
Counter += time;
|
||||
}
|
||||
|
||||
|
|
@ -108,6 +109,7 @@ extern glcycle_t All, Finish, PortalAll, Bsp;
|
|||
extern glcycle_t ProcessAll;
|
||||
extern glcycle_t RenderAll;
|
||||
extern glcycle_t Dirty;
|
||||
extern glcycle_t drawcalls;
|
||||
|
||||
extern int iter_dlightf, iter_dlight, draw_dlight, draw_dlightf;
|
||||
extern int rendered_lines,rendered_flats,rendered_sprites,rendered_decals,render_vertexsplit,render_texsplit;
|
||||
|
|
@ -117,6 +119,7 @@ extern int vertexcount, flatvertices, flatprimitives;
|
|||
|
||||
void ResetProfilingData();
|
||||
void CheckBench();
|
||||
void checkBenchActive();
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -824,6 +824,15 @@ void R_InitTranslationTables ()
|
|||
remap->Remap[i] = IcePaletteRemap[v];
|
||||
remap->Palette[i] = PalEntry(255, IcePalette[v][0], IcePalette[v][1], IcePalette[v][2]);
|
||||
}
|
||||
|
||||
// The alphatexture translation. Since alphatextures use the red channel this is just a standard grayscale mapping.
|
||||
PushIdentityTable(TRANSLATION_Standard);
|
||||
remap = translationtables[TRANSLATION_Standard][8];
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
remap->Remap[i] = i;
|
||||
remap->Palette[i] = PalEntry(255, i, i, i);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@
|
|||
#include "r_data/voxels.h"
|
||||
#include "textures/textures.h"
|
||||
|
||||
void gl_InitModels();
|
||||
|
||||
// variables used to look up
|
||||
// and range check thing_t sprites patches
|
||||
TArray<spritedef_t> sprites;
|
||||
|
|
@ -986,6 +988,8 @@ void R_InitSprites ()
|
|||
|
||||
// [RH] Sort the skins, but leave base as skin 0
|
||||
//qsort (&skins[PlayerClasses.Size ()], numskins-PlayerClasses.Size (), sizeof(FPlayerSkin), skinsorter);
|
||||
|
||||
gl_InitModels();
|
||||
}
|
||||
|
||||
void R_DeinitSpriteData()
|
||||
|
|
|
|||
|
|
@ -786,6 +786,7 @@ struct sector_t
|
|||
int subsectorcount; // list of subsectors
|
||||
subsector_t ** subsectors;
|
||||
FPortal * portals[2]; // floor and ceiling portals
|
||||
FLightNode * lighthead;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
@ -962,7 +963,7 @@ struct side_t
|
|||
vertex_t *V2() const;
|
||||
|
||||
//For GL
|
||||
FLightNode * lighthead[2]; // all blended lights that may affect this wall
|
||||
FLightNode * lighthead; // all blended lights that may affect this wall
|
||||
|
||||
seg_t **segs; // all segs belonging to this sidedef in ascending order. Used for precise rendering
|
||||
int numsegs;
|
||||
|
|
@ -1082,7 +1083,7 @@ struct subsector_t
|
|||
|
||||
void BuildPolyBSP();
|
||||
// subsector related GL data
|
||||
FLightNode * lighthead[2]; // Light nodes (blended and additive)
|
||||
FLightNode * lighthead; // Light nodes (blended and additive)
|
||||
int validcount;
|
||||
short mapsection;
|
||||
char hacked; // 1: is part of a render hack
|
||||
|
|
|
|||
|
|
@ -267,6 +267,10 @@ public:
|
|||
virtual FString GetStats () = 0;
|
||||
|
||||
void ToggleStat ();
|
||||
bool isActive() const
|
||||
{
|
||||
return m_Active;
|
||||
}
|
||||
|
||||
static void PrintStat ();
|
||||
static FStat *FindStat (const char *name);
|
||||
|
|
|
|||
|
|
@ -1239,6 +1239,8 @@ void FTextureManager::PrecacheLevel (void)
|
|||
if (demoplayback)
|
||||
return;
|
||||
|
||||
precacheTime = I_MSTime();
|
||||
|
||||
hitlist = new BYTE[cnt];
|
||||
memset (hitlist, 0, cnt);
|
||||
|
||||
|
|
|
|||
|
|
@ -329,10 +329,9 @@ public:
|
|||
|
||||
struct MiscGLInfo
|
||||
{
|
||||
FMaterial *Material;
|
||||
FGLTexture *SystemTexture;
|
||||
FMaterial *Material[2];
|
||||
FGLTexture *SystemTexture[2];
|
||||
FTexture *Brightmap;
|
||||
FTexture *DecalTexture; // This is needed for decals of UseType TEX_MiscPatch-
|
||||
PalEntry GlowColor;
|
||||
PalEntry FloorSkyColor;
|
||||
PalEntry CeilingSkyColor;
|
||||
|
|
@ -340,6 +339,7 @@ public:
|
|||
FloatRect *areas;
|
||||
int areacount;
|
||||
int shaderindex;
|
||||
unsigned int precacheTime;
|
||||
float shaderspeed;
|
||||
int mIsTransparent:2;
|
||||
bool bGlowing:1; // Texture glows
|
||||
|
|
@ -351,14 +351,13 @@ public:
|
|||
bool bBrightmapDisablesFullbright:1; // This disables fullbright display
|
||||
bool bNoFilter:1;
|
||||
bool bNoCompress:1;
|
||||
bool mExpanded:1;
|
||||
|
||||
MiscGLInfo() throw ();
|
||||
~MiscGLInfo();
|
||||
};
|
||||
MiscGLInfo gl_info;
|
||||
|
||||
virtual void PrecacheGL();
|
||||
virtual void PrecacheGL(int cache);
|
||||
virtual void UncacheGL();
|
||||
void GetGlowColor(float *data);
|
||||
PalEntry GetSkyCapColor(bool bottom);
|
||||
|
|
@ -479,6 +478,8 @@ public:
|
|||
FSwitchDef *FindSwitch (FTextureID texture);
|
||||
FDoorAnimation *FindAnimatedDoor (FTextureID picnum);
|
||||
|
||||
unsigned int precacheTime;
|
||||
|
||||
private:
|
||||
|
||||
// texture counting
|
||||
|
|
|
|||
|
|
@ -1245,7 +1245,7 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist)
|
|||
FTextureID pic = frame->Texture[k];
|
||||
if (pic.isValid())
|
||||
{
|
||||
hitlist[pic.GetIndex()] = 1;
|
||||
hitlist[pic.GetIndex()] = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1264,7 +1264,7 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist)
|
|||
{
|
||||
hitlist[sides[i].GetTexture(side_t::top).GetIndex()] =
|
||||
hitlist[sides[i].GetTexture(side_t::mid).GetIndex()] =
|
||||
hitlist[sides[i].GetTexture(side_t::bottom).GetIndex()] |= 1;
|
||||
hitlist[sides[i].GetTexture(side_t::bottom).GetIndex()] |= 3;
|
||||
}
|
||||
|
||||
// Sky texture is always present.
|
||||
|
|
@ -1276,11 +1276,11 @@ void DFrameBuffer::GetHitlist(BYTE *hitlist)
|
|||
|
||||
if (sky1texture.isValid())
|
||||
{
|
||||
hitlist[sky1texture.GetIndex()] |= 1;
|
||||
hitlist[sky1texture.GetIndex()] |= 3;
|
||||
}
|
||||
if (sky2texture.isValid())
|
||||
{
|
||||
hitlist[sky2texture.GetIndex()] |= 1;
|
||||
hitlist[sky2texture.GetIndex()] |= 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,12 +41,12 @@ const char *GetVersionString();
|
|||
|
||||
/** Lots of different version numbers **/
|
||||
|
||||
#define VERSIONSTR "1.9pre"
|
||||
#define VERSIONSTR "2.1pre"
|
||||
|
||||
// The version as seen in the Windows resource
|
||||
#define RC_FILEVERSION 1,8,9999,0
|
||||
#define RC_PRODUCTVERSION 1,8,9999,0
|
||||
#define RC_PRODUCTVERSION2 "1.9pre"
|
||||
#define RC_FILEVERSION 2,0,9999,0
|
||||
#define RC_PRODUCTVERSION 2,0,9999,0
|
||||
#define RC_PRODUCTVERSION2 "2.1pre"
|
||||
|
||||
// Version identifier for network games.
|
||||
// Bump it every time you do a release unless you're certain you
|
||||
|
|
|
|||
840
src/win32/wglext.h
Normal file
840
src/win32/wglext.h
Normal file
|
|
@ -0,0 +1,840 @@
|
|||
#ifndef __wglext_h_
|
||||
#define __wglext_h_ 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Copyright (c) 2013-2014 The Khronos Group Inc.
|
||||
**
|
||||
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||
** copy of this software and/or associated documentation files (the
|
||||
** "Materials"), to deal in the Materials without restriction, including
|
||||
** without limitation the rights to use, copy, modify, merge, publish,
|
||||
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||
** permit persons to whom the Materials are furnished to do so, subject to
|
||||
** the following conditions:
|
||||
**
|
||||
** The above copyright notice and this permission notice shall be included
|
||||
** in all copies or substantial portions of the Materials.
|
||||
**
|
||||
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||
*/
|
||||
/*
|
||||
** This header is generated from the Khronos OpenGL / OpenGL ES XML
|
||||
** API Registry. The current version of the Registry, generator scripts
|
||||
** used to make the header, and the header can be found at
|
||||
** http://www.opengl.org/registry/
|
||||
**
|
||||
** Khronos $Revision: 27684 $ on $Date: 2014-08-11 01:21:35 -0700 (Mon, 11 Aug 2014) $
|
||||
*/
|
||||
|
||||
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#define WGL_WGLEXT_VERSION 20140810
|
||||
|
||||
/* Generated C header for:
|
||||
* API: wgl
|
||||
* Versions considered: .*
|
||||
* Versions emitted: _nomatch_^
|
||||
* Default extensions included: wgl
|
||||
* Additional extensions included: _nomatch_^
|
||||
* Extensions removed: _nomatch_^
|
||||
*/
|
||||
|
||||
#ifndef WGL_ARB_buffer_region
|
||||
#define WGL_ARB_buffer_region 1
|
||||
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
|
||||
#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002
|
||||
#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004
|
||||
#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008
|
||||
typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType);
|
||||
typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion);
|
||||
typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height);
|
||||
typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
HANDLE WINAPI wglCreateBufferRegionARB (HDC hDC, int iLayerPlane, UINT uType);
|
||||
VOID WINAPI wglDeleteBufferRegionARB (HANDLE hRegion);
|
||||
BOOL WINAPI wglSaveBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height);
|
||||
BOOL WINAPI wglRestoreBufferRegionARB (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc);
|
||||
#endif
|
||||
#endif /* WGL_ARB_buffer_region */
|
||||
|
||||
#ifndef WGL_ARB_context_flush_control
|
||||
#define WGL_ARB_context_flush_control 1
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_ARB 0x2097
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB 0
|
||||
#define WGL_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB 0x2098
|
||||
#endif /* WGL_ARB_context_flush_control */
|
||||
|
||||
#ifndef WGL_ARB_create_context
|
||||
#define WGL_ARB_create_context 1
|
||||
#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
|
||||
#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
|
||||
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
|
||||
#define WGL_CONTEXT_FLAGS_ARB 0x2094
|
||||
#define ERROR_INVALID_VERSION_ARB 0x2095
|
||||
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
HGLRC WINAPI wglCreateContextAttribsARB (HDC hDC, HGLRC hShareContext, const int *attribList);
|
||||
#endif
|
||||
#endif /* WGL_ARB_create_context */
|
||||
|
||||
#ifndef WGL_ARB_create_context_profile
|
||||
#define WGL_ARB_create_context_profile 1
|
||||
#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||
#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
|
||||
#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
|
||||
#define ERROR_INVALID_PROFILE_ARB 0x2096
|
||||
#endif /* WGL_ARB_create_context_profile */
|
||||
|
||||
#ifndef WGL_ARB_create_context_robustness
|
||||
#define WGL_ARB_create_context_robustness 1
|
||||
#define WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB 0x00000004
|
||||
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
|
||||
#define WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB 0x8256
|
||||
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
|
||||
#endif /* WGL_ARB_create_context_robustness */
|
||||
|
||||
#ifndef WGL_ARB_extensions_string
|
||||
#define WGL_ARB_extensions_string 1
|
||||
typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
const char *WINAPI wglGetExtensionsStringARB (HDC hdc);
|
||||
#endif
|
||||
#endif /* WGL_ARB_extensions_string */
|
||||
|
||||
#ifndef WGL_ARB_framebuffer_sRGB
|
||||
#define WGL_ARB_framebuffer_sRGB 1
|
||||
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20A9
|
||||
#endif /* WGL_ARB_framebuffer_sRGB */
|
||||
|
||||
#ifndef WGL_ARB_make_current_read
|
||||
#define WGL_ARB_make_current_read 1
|
||||
#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043
|
||||
#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054
|
||||
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
|
||||
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglMakeContextCurrentARB (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
|
||||
HDC WINAPI wglGetCurrentReadDCARB (void);
|
||||
#endif
|
||||
#endif /* WGL_ARB_make_current_read */
|
||||
|
||||
#ifndef WGL_ARB_multisample
|
||||
#define WGL_ARB_multisample 1
|
||||
#define WGL_SAMPLE_BUFFERS_ARB 0x2041
|
||||
#define WGL_SAMPLES_ARB 0x2042
|
||||
#endif /* WGL_ARB_multisample */
|
||||
|
||||
#ifndef WGL_ARB_pbuffer
|
||||
#define WGL_ARB_pbuffer 1
|
||||
DECLARE_HANDLE(HPBUFFERARB);
|
||||
#define WGL_DRAW_TO_PBUFFER_ARB 0x202D
|
||||
#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E
|
||||
#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F
|
||||
#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030
|
||||
#define WGL_PBUFFER_LARGEST_ARB 0x2033
|
||||
#define WGL_PBUFFER_WIDTH_ARB 0x2034
|
||||
#define WGL_PBUFFER_HEIGHT_ARB 0x2035
|
||||
#define WGL_PBUFFER_LOST_ARB 0x2036
|
||||
typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
|
||||
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer);
|
||||
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC);
|
||||
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
HPBUFFERARB WINAPI wglCreatePbufferARB (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
|
||||
HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB hPbuffer);
|
||||
int WINAPI wglReleasePbufferDCARB (HPBUFFERARB hPbuffer, HDC hDC);
|
||||
BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB hPbuffer);
|
||||
BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB hPbuffer, int iAttribute, int *piValue);
|
||||
#endif
|
||||
#endif /* WGL_ARB_pbuffer */
|
||||
|
||||
#ifndef WGL_ARB_pixel_format
|
||||
#define WGL_ARB_pixel_format 1
|
||||
#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000
|
||||
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
|
||||
#define WGL_DRAW_TO_BITMAP_ARB 0x2002
|
||||
#define WGL_ACCELERATION_ARB 0x2003
|
||||
#define WGL_NEED_PALETTE_ARB 0x2004
|
||||
#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005
|
||||
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
|
||||
#define WGL_SWAP_METHOD_ARB 0x2007
|
||||
#define WGL_NUMBER_OVERLAYS_ARB 0x2008
|
||||
#define WGL_NUMBER_UNDERLAYS_ARB 0x2009
|
||||
#define WGL_TRANSPARENT_ARB 0x200A
|
||||
#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037
|
||||
#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038
|
||||
#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039
|
||||
#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A
|
||||
#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B
|
||||
#define WGL_SHARE_DEPTH_ARB 0x200C
|
||||
#define WGL_SHARE_STENCIL_ARB 0x200D
|
||||
#define WGL_SHARE_ACCUM_ARB 0x200E
|
||||
#define WGL_SUPPORT_GDI_ARB 0x200F
|
||||
#define WGL_SUPPORT_OPENGL_ARB 0x2010
|
||||
#define WGL_DOUBLE_BUFFER_ARB 0x2011
|
||||
#define WGL_STEREO_ARB 0x2012
|
||||
#define WGL_PIXEL_TYPE_ARB 0x2013
|
||||
#define WGL_COLOR_BITS_ARB 0x2014
|
||||
#define WGL_RED_BITS_ARB 0x2015
|
||||
#define WGL_RED_SHIFT_ARB 0x2016
|
||||
#define WGL_GREEN_BITS_ARB 0x2017
|
||||
#define WGL_GREEN_SHIFT_ARB 0x2018
|
||||
#define WGL_BLUE_BITS_ARB 0x2019
|
||||
#define WGL_BLUE_SHIFT_ARB 0x201A
|
||||
#define WGL_ALPHA_BITS_ARB 0x201B
|
||||
#define WGL_ALPHA_SHIFT_ARB 0x201C
|
||||
#define WGL_ACCUM_BITS_ARB 0x201D
|
||||
#define WGL_ACCUM_RED_BITS_ARB 0x201E
|
||||
#define WGL_ACCUM_GREEN_BITS_ARB 0x201F
|
||||
#define WGL_ACCUM_BLUE_BITS_ARB 0x2020
|
||||
#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021
|
||||
#define WGL_DEPTH_BITS_ARB 0x2022
|
||||
#define WGL_STENCIL_BITS_ARB 0x2023
|
||||
#define WGL_AUX_BUFFERS_ARB 0x2024
|
||||
#define WGL_NO_ACCELERATION_ARB 0x2025
|
||||
#define WGL_GENERIC_ACCELERATION_ARB 0x2026
|
||||
#define WGL_FULL_ACCELERATION_ARB 0x2027
|
||||
#define WGL_SWAP_EXCHANGE_ARB 0x2028
|
||||
#define WGL_SWAP_COPY_ARB 0x2029
|
||||
#define WGL_SWAP_UNDEFINED_ARB 0x202A
|
||||
#define WGL_TYPE_RGBA_ARB 0x202B
|
||||
#define WGL_TYPE_COLORINDEX_ARB 0x202C
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
|
||||
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglGetPixelFormatAttribivARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);
|
||||
BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues);
|
||||
BOOL WINAPI wglChoosePixelFormatARB (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
|
||||
#endif
|
||||
#endif /* WGL_ARB_pixel_format */
|
||||
|
||||
#ifndef WGL_ARB_pixel_format_float
|
||||
#define WGL_ARB_pixel_format_float 1
|
||||
#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0
|
||||
#endif /* WGL_ARB_pixel_format_float */
|
||||
|
||||
#ifndef WGL_ARB_render_texture
|
||||
#define WGL_ARB_render_texture 1
|
||||
#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070
|
||||
#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071
|
||||
#define WGL_TEXTURE_FORMAT_ARB 0x2072
|
||||
#define WGL_TEXTURE_TARGET_ARB 0x2073
|
||||
#define WGL_MIPMAP_TEXTURE_ARB 0x2074
|
||||
#define WGL_TEXTURE_RGB_ARB 0x2075
|
||||
#define WGL_TEXTURE_RGBA_ARB 0x2076
|
||||
#define WGL_NO_TEXTURE_ARB 0x2077
|
||||
#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078
|
||||
#define WGL_TEXTURE_1D_ARB 0x2079
|
||||
#define WGL_TEXTURE_2D_ARB 0x207A
|
||||
#define WGL_MIPMAP_LEVEL_ARB 0x207B
|
||||
#define WGL_CUBE_MAP_FACE_ARB 0x207C
|
||||
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D
|
||||
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E
|
||||
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F
|
||||
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080
|
||||
#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081
|
||||
#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082
|
||||
#define WGL_FRONT_LEFT_ARB 0x2083
|
||||
#define WGL_FRONT_RIGHT_ARB 0x2084
|
||||
#define WGL_BACK_LEFT_ARB 0x2085
|
||||
#define WGL_BACK_RIGHT_ARB 0x2086
|
||||
#define WGL_AUX0_ARB 0x2087
|
||||
#define WGL_AUX1_ARB 0x2088
|
||||
#define WGL_AUX2_ARB 0x2089
|
||||
#define WGL_AUX3_ARB 0x208A
|
||||
#define WGL_AUX4_ARB 0x208B
|
||||
#define WGL_AUX5_ARB 0x208C
|
||||
#define WGL_AUX6_ARB 0x208D
|
||||
#define WGL_AUX7_ARB 0x208E
|
||||
#define WGL_AUX8_ARB 0x208F
|
||||
#define WGL_AUX9_ARB 0x2090
|
||||
typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglBindTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
|
||||
BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB hPbuffer, int iBuffer);
|
||||
BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB hPbuffer, const int *piAttribList);
|
||||
#endif
|
||||
#endif /* WGL_ARB_render_texture */
|
||||
|
||||
#ifndef WGL_ARB_robustness_application_isolation
|
||||
#define WGL_ARB_robustness_application_isolation 1
|
||||
#define WGL_CONTEXT_RESET_ISOLATION_BIT_ARB 0x00000008
|
||||
#endif /* WGL_ARB_robustness_application_isolation */
|
||||
|
||||
#ifndef WGL_ARB_robustness_share_group_isolation
|
||||
#define WGL_ARB_robustness_share_group_isolation 1
|
||||
#endif /* WGL_ARB_robustness_share_group_isolation */
|
||||
|
||||
#ifndef WGL_3DFX_multisample
|
||||
#define WGL_3DFX_multisample 1
|
||||
#define WGL_SAMPLE_BUFFERS_3DFX 0x2060
|
||||
#define WGL_SAMPLES_3DFX 0x2061
|
||||
#endif /* WGL_3DFX_multisample */
|
||||
|
||||
#ifndef WGL_3DL_stereo_control
|
||||
#define WGL_3DL_stereo_control 1
|
||||
#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055
|
||||
#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056
|
||||
#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057
|
||||
#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058
|
||||
typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglSetStereoEmitterState3DL (HDC hDC, UINT uState);
|
||||
#endif
|
||||
#endif /* WGL_3DL_stereo_control */
|
||||
|
||||
#ifndef WGL_AMD_gpu_association
|
||||
#define WGL_AMD_gpu_association 1
|
||||
#define WGL_GPU_VENDOR_AMD 0x1F00
|
||||
#define WGL_GPU_RENDERER_STRING_AMD 0x1F01
|
||||
#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02
|
||||
#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2
|
||||
#define WGL_GPU_RAM_AMD 0x21A3
|
||||
#define WGL_GPU_CLOCK_AMD 0x21A4
|
||||
#define WGL_GPU_NUM_PIPES_AMD 0x21A5
|
||||
#define WGL_GPU_NUM_SIMD_AMD 0x21A6
|
||||
#define WGL_GPU_NUM_RB_AMD 0x21A7
|
||||
#define WGL_GPU_NUM_SPI_AMD 0x21A8
|
||||
typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids);
|
||||
typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data);
|
||||
typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc);
|
||||
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id);
|
||||
typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList);
|
||||
typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc);
|
||||
typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc);
|
||||
typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void);
|
||||
typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
UINT WINAPI wglGetGPUIDsAMD (UINT maxCount, UINT *ids);
|
||||
INT WINAPI wglGetGPUInfoAMD (UINT id, int property, GLenum dataType, UINT size, void *data);
|
||||
UINT WINAPI wglGetContextGPUIDAMD (HGLRC hglrc);
|
||||
HGLRC WINAPI wglCreateAssociatedContextAMD (UINT id);
|
||||
HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT id, HGLRC hShareContext, const int *attribList);
|
||||
BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC hglrc);
|
||||
BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC hglrc);
|
||||
HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void);
|
||||
VOID WINAPI wglBlitContextFramebufferAMD (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
|
||||
#endif
|
||||
#endif /* WGL_AMD_gpu_association */
|
||||
|
||||
#ifndef WGL_ATI_pixel_format_float
|
||||
#define WGL_ATI_pixel_format_float 1
|
||||
#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0
|
||||
#endif /* WGL_ATI_pixel_format_float */
|
||||
|
||||
#ifndef WGL_EXT_create_context_es2_profile
|
||||
#define WGL_EXT_create_context_es2_profile 1
|
||||
#define WGL_CONTEXT_ES2_PROFILE_BIT_EXT 0x00000004
|
||||
#endif /* WGL_EXT_create_context_es2_profile */
|
||||
|
||||
#ifndef WGL_EXT_create_context_es_profile
|
||||
#define WGL_EXT_create_context_es_profile 1
|
||||
#define WGL_CONTEXT_ES_PROFILE_BIT_EXT 0x00000004
|
||||
#endif /* WGL_EXT_create_context_es_profile */
|
||||
|
||||
#ifndef WGL_EXT_depth_float
|
||||
#define WGL_EXT_depth_float 1
|
||||
#define WGL_DEPTH_FLOAT_EXT 0x2040
|
||||
#endif /* WGL_EXT_depth_float */
|
||||
|
||||
#ifndef WGL_EXT_display_color_table
|
||||
#define WGL_EXT_display_color_table 1
|
||||
typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id);
|
||||
typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length);
|
||||
typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id);
|
||||
typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort id);
|
||||
GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *table, GLuint length);
|
||||
GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort id);
|
||||
VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort id);
|
||||
#endif
|
||||
#endif /* WGL_EXT_display_color_table */
|
||||
|
||||
#ifndef WGL_EXT_extensions_string
|
||||
#define WGL_EXT_extensions_string 1
|
||||
typedef const char *(WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
const char *WINAPI wglGetExtensionsStringEXT (void);
|
||||
#endif
|
||||
#endif /* WGL_EXT_extensions_string */
|
||||
|
||||
#ifndef WGL_EXT_framebuffer_sRGB
|
||||
#define WGL_EXT_framebuffer_sRGB 1
|
||||
#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9
|
||||
#endif /* WGL_EXT_framebuffer_sRGB */
|
||||
|
||||
#ifndef WGL_EXT_make_current_read
|
||||
#define WGL_EXT_make_current_read 1
|
||||
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
|
||||
typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
|
||||
typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglMakeContextCurrentEXT (HDC hDrawDC, HDC hReadDC, HGLRC hglrc);
|
||||
HDC WINAPI wglGetCurrentReadDCEXT (void);
|
||||
#endif
|
||||
#endif /* WGL_EXT_make_current_read */
|
||||
|
||||
#ifndef WGL_EXT_multisample
|
||||
#define WGL_EXT_multisample 1
|
||||
#define WGL_SAMPLE_BUFFERS_EXT 0x2041
|
||||
#define WGL_SAMPLES_EXT 0x2042
|
||||
#endif /* WGL_EXT_multisample */
|
||||
|
||||
#ifndef WGL_EXT_pbuffer
|
||||
#define WGL_EXT_pbuffer 1
|
||||
DECLARE_HANDLE(HPBUFFEREXT);
|
||||
#define WGL_DRAW_TO_PBUFFER_EXT 0x202D
|
||||
#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E
|
||||
#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F
|
||||
#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030
|
||||
#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031
|
||||
#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032
|
||||
#define WGL_PBUFFER_LARGEST_EXT 0x2033
|
||||
#define WGL_PBUFFER_WIDTH_EXT 0x2034
|
||||
#define WGL_PBUFFER_HEIGHT_EXT 0x2035
|
||||
typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
|
||||
typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer);
|
||||
typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC);
|
||||
typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList);
|
||||
HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT hPbuffer);
|
||||
int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT hPbuffer, HDC hDC);
|
||||
BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT hPbuffer);
|
||||
BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue);
|
||||
#endif
|
||||
#endif /* WGL_EXT_pbuffer */
|
||||
|
||||
#ifndef WGL_EXT_pixel_format
|
||||
#define WGL_EXT_pixel_format 1
|
||||
#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000
|
||||
#define WGL_DRAW_TO_WINDOW_EXT 0x2001
|
||||
#define WGL_DRAW_TO_BITMAP_EXT 0x2002
|
||||
#define WGL_ACCELERATION_EXT 0x2003
|
||||
#define WGL_NEED_PALETTE_EXT 0x2004
|
||||
#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005
|
||||
#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006
|
||||
#define WGL_SWAP_METHOD_EXT 0x2007
|
||||
#define WGL_NUMBER_OVERLAYS_EXT 0x2008
|
||||
#define WGL_NUMBER_UNDERLAYS_EXT 0x2009
|
||||
#define WGL_TRANSPARENT_EXT 0x200A
|
||||
#define WGL_TRANSPARENT_VALUE_EXT 0x200B
|
||||
#define WGL_SHARE_DEPTH_EXT 0x200C
|
||||
#define WGL_SHARE_STENCIL_EXT 0x200D
|
||||
#define WGL_SHARE_ACCUM_EXT 0x200E
|
||||
#define WGL_SUPPORT_GDI_EXT 0x200F
|
||||
#define WGL_SUPPORT_OPENGL_EXT 0x2010
|
||||
#define WGL_DOUBLE_BUFFER_EXT 0x2011
|
||||
#define WGL_STEREO_EXT 0x2012
|
||||
#define WGL_PIXEL_TYPE_EXT 0x2013
|
||||
#define WGL_COLOR_BITS_EXT 0x2014
|
||||
#define WGL_RED_BITS_EXT 0x2015
|
||||
#define WGL_RED_SHIFT_EXT 0x2016
|
||||
#define WGL_GREEN_BITS_EXT 0x2017
|
||||
#define WGL_GREEN_SHIFT_EXT 0x2018
|
||||
#define WGL_BLUE_BITS_EXT 0x2019
|
||||
#define WGL_BLUE_SHIFT_EXT 0x201A
|
||||
#define WGL_ALPHA_BITS_EXT 0x201B
|
||||
#define WGL_ALPHA_SHIFT_EXT 0x201C
|
||||
#define WGL_ACCUM_BITS_EXT 0x201D
|
||||
#define WGL_ACCUM_RED_BITS_EXT 0x201E
|
||||
#define WGL_ACCUM_GREEN_BITS_EXT 0x201F
|
||||
#define WGL_ACCUM_BLUE_BITS_EXT 0x2020
|
||||
#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021
|
||||
#define WGL_DEPTH_BITS_EXT 0x2022
|
||||
#define WGL_STENCIL_BITS_EXT 0x2023
|
||||
#define WGL_AUX_BUFFERS_EXT 0x2024
|
||||
#define WGL_NO_ACCELERATION_EXT 0x2025
|
||||
#define WGL_GENERIC_ACCELERATION_EXT 0x2026
|
||||
#define WGL_FULL_ACCELERATION_EXT 0x2027
|
||||
#define WGL_SWAP_EXCHANGE_EXT 0x2028
|
||||
#define WGL_SWAP_COPY_EXT 0x2029
|
||||
#define WGL_SWAP_UNDEFINED_EXT 0x202A
|
||||
#define WGL_TYPE_RGBA_EXT 0x202B
|
||||
#define WGL_TYPE_COLORINDEX_EXT 0x202C
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
|
||||
typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
|
||||
typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues);
|
||||
BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues);
|
||||
BOOL WINAPI wglChoosePixelFormatEXT (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats);
|
||||
#endif
|
||||
#endif /* WGL_EXT_pixel_format */
|
||||
|
||||
#ifndef WGL_EXT_pixel_format_packed_float
|
||||
#define WGL_EXT_pixel_format_packed_float 1
|
||||
#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8
|
||||
#endif /* WGL_EXT_pixel_format_packed_float */
|
||||
|
||||
#ifndef WGL_EXT_swap_control
|
||||
#define WGL_EXT_swap_control 1
|
||||
typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval);
|
||||
typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglSwapIntervalEXT (int interval);
|
||||
int WINAPI wglGetSwapIntervalEXT (void);
|
||||
#endif
|
||||
#endif /* WGL_EXT_swap_control */
|
||||
|
||||
#ifndef WGL_EXT_swap_control_tear
|
||||
#define WGL_EXT_swap_control_tear 1
|
||||
#endif /* WGL_EXT_swap_control_tear */
|
||||
|
||||
#ifndef WGL_I3D_digital_video_control
|
||||
#define WGL_I3D_digital_video_control 1
|
||||
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050
|
||||
#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051
|
||||
#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052
|
||||
#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053
|
||||
typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
|
||||
typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC hDC, int iAttribute, int *piValue);
|
||||
BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC hDC, int iAttribute, const int *piValue);
|
||||
#endif
|
||||
#endif /* WGL_I3D_digital_video_control */
|
||||
|
||||
#ifndef WGL_I3D_gamma
|
||||
#define WGL_I3D_gamma 1
|
||||
#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E
|
||||
#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F
|
||||
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue);
|
||||
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue);
|
||||
typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
|
||||
typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglGetGammaTableParametersI3D (HDC hDC, int iAttribute, int *piValue);
|
||||
BOOL WINAPI wglSetGammaTableParametersI3D (HDC hDC, int iAttribute, const int *piValue);
|
||||
BOOL WINAPI wglGetGammaTableI3D (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue);
|
||||
BOOL WINAPI wglSetGammaTableI3D (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue);
|
||||
#endif
|
||||
#endif /* WGL_I3D_gamma */
|
||||
|
||||
#ifndef WGL_I3D_genlock
|
||||
#define WGL_I3D_genlock 1
|
||||
#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044
|
||||
#define WGL_GENLOCK_SOURCE_EXTERNAL_SYNC_I3D 0x2045
|
||||
#define WGL_GENLOCK_SOURCE_EXTERNAL_FIELD_I3D 0x2046
|
||||
#define WGL_GENLOCK_SOURCE_EXTERNAL_TTL_I3D 0x2047
|
||||
#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048
|
||||
#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049
|
||||
#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A
|
||||
#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B
|
||||
#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C
|
||||
typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC);
|
||||
typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC);
|
||||
typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag);
|
||||
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource);
|
||||
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource);
|
||||
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge);
|
||||
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge);
|
||||
typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate);
|
||||
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate);
|
||||
typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay);
|
||||
typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglEnableGenlockI3D (HDC hDC);
|
||||
BOOL WINAPI wglDisableGenlockI3D (HDC hDC);
|
||||
BOOL WINAPI wglIsEnabledGenlockI3D (HDC hDC, BOOL *pFlag);
|
||||
BOOL WINAPI wglGenlockSourceI3D (HDC hDC, UINT uSource);
|
||||
BOOL WINAPI wglGetGenlockSourceI3D (HDC hDC, UINT *uSource);
|
||||
BOOL WINAPI wglGenlockSourceEdgeI3D (HDC hDC, UINT uEdge);
|
||||
BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC hDC, UINT *uEdge);
|
||||
BOOL WINAPI wglGenlockSampleRateI3D (HDC hDC, UINT uRate);
|
||||
BOOL WINAPI wglGetGenlockSampleRateI3D (HDC hDC, UINT *uRate);
|
||||
BOOL WINAPI wglGenlockSourceDelayI3D (HDC hDC, UINT uDelay);
|
||||
BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC hDC, UINT *uDelay);
|
||||
BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay);
|
||||
#endif
|
||||
#endif /* WGL_I3D_genlock */
|
||||
|
||||
#ifndef WGL_I3D_image_buffer
|
||||
#define WGL_I3D_image_buffer 1
|
||||
#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001
|
||||
#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002
|
||||
typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags);
|
||||
typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress);
|
||||
typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
|
||||
typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
LPVOID WINAPI wglCreateImageBufferI3D (HDC hDC, DWORD dwSize, UINT uFlags);
|
||||
BOOL WINAPI wglDestroyImageBufferI3D (HDC hDC, LPVOID pAddress);
|
||||
BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count);
|
||||
BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC hDC, const LPVOID *pAddress, UINT count);
|
||||
#endif
|
||||
#endif /* WGL_I3D_image_buffer */
|
||||
|
||||
#ifndef WGL_I3D_swap_frame_lock
|
||||
#define WGL_I3D_swap_frame_lock 1
|
||||
typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void);
|
||||
typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void);
|
||||
typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglEnableFrameLockI3D (void);
|
||||
BOOL WINAPI wglDisableFrameLockI3D (void);
|
||||
BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *pFlag);
|
||||
BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *pFlag);
|
||||
#endif
|
||||
#endif /* WGL_I3D_swap_frame_lock */
|
||||
|
||||
#ifndef WGL_I3D_swap_frame_usage
|
||||
#define WGL_I3D_swap_frame_usage 1
|
||||
typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage);
|
||||
typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void);
|
||||
typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglGetFrameUsageI3D (float *pUsage);
|
||||
BOOL WINAPI wglBeginFrameTrackingI3D (void);
|
||||
BOOL WINAPI wglEndFrameTrackingI3D (void);
|
||||
BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage);
|
||||
#endif
|
||||
#endif /* WGL_I3D_swap_frame_usage */
|
||||
|
||||
#ifndef WGL_NV_DX_interop
|
||||
#define WGL_NV_DX_interop 1
|
||||
#define WGL_ACCESS_READ_ONLY_NV 0x00000000
|
||||
#define WGL_ACCESS_READ_WRITE_NV 0x00000001
|
||||
#define WGL_ACCESS_WRITE_DISCARD_NV 0x00000002
|
||||
typedef BOOL (WINAPI * PFNWGLDXSETRESOURCESHAREHANDLENVPROC) (void *dxObject, HANDLE shareHandle);
|
||||
typedef HANDLE (WINAPI * PFNWGLDXOPENDEVICENVPROC) (void *dxDevice);
|
||||
typedef BOOL (WINAPI * PFNWGLDXCLOSEDEVICENVPROC) (HANDLE hDevice);
|
||||
typedef HANDLE (WINAPI * PFNWGLDXREGISTEROBJECTNVPROC) (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
|
||||
typedef BOOL (WINAPI * PFNWGLDXUNREGISTEROBJECTNVPROC) (HANDLE hDevice, HANDLE hObject);
|
||||
typedef BOOL (WINAPI * PFNWGLDXOBJECTACCESSNVPROC) (HANDLE hObject, GLenum access);
|
||||
typedef BOOL (WINAPI * PFNWGLDXLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
|
||||
typedef BOOL (WINAPI * PFNWGLDXUNLOCKOBJECTSNVPROC) (HANDLE hDevice, GLint count, HANDLE *hObjects);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglDXSetResourceShareHandleNV (void *dxObject, HANDLE shareHandle);
|
||||
HANDLE WINAPI wglDXOpenDeviceNV (void *dxDevice);
|
||||
BOOL WINAPI wglDXCloseDeviceNV (HANDLE hDevice);
|
||||
HANDLE WINAPI wglDXRegisterObjectNV (HANDLE hDevice, void *dxObject, GLuint name, GLenum type, GLenum access);
|
||||
BOOL WINAPI wglDXUnregisterObjectNV (HANDLE hDevice, HANDLE hObject);
|
||||
BOOL WINAPI wglDXObjectAccessNV (HANDLE hObject, GLenum access);
|
||||
BOOL WINAPI wglDXLockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
|
||||
BOOL WINAPI wglDXUnlockObjectsNV (HANDLE hDevice, GLint count, HANDLE *hObjects);
|
||||
#endif
|
||||
#endif /* WGL_NV_DX_interop */
|
||||
|
||||
#ifndef WGL_NV_DX_interop2
|
||||
#define WGL_NV_DX_interop2 1
|
||||
#endif /* WGL_NV_DX_interop2 */
|
||||
|
||||
#ifndef WGL_NV_copy_image
|
||||
#define WGL_NV_copy_image 1
|
||||
typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglCopyImageSubDataNV (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth);
|
||||
#endif
|
||||
#endif /* WGL_NV_copy_image */
|
||||
|
||||
#ifndef WGL_NV_delay_before_swap
|
||||
#define WGL_NV_delay_before_swap 1
|
||||
typedef BOOL (WINAPI * PFNWGLDELAYBEFORESWAPNVPROC) (HDC hDC, GLfloat seconds);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglDelayBeforeSwapNV (HDC hDC, GLfloat seconds);
|
||||
#endif
|
||||
#endif /* WGL_NV_delay_before_swap */
|
||||
|
||||
#ifndef WGL_NV_float_buffer
|
||||
#define WGL_NV_float_buffer 1
|
||||
#define WGL_FLOAT_COMPONENTS_NV 0x20B0
|
||||
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1
|
||||
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2
|
||||
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3
|
||||
#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4
|
||||
#define WGL_TEXTURE_FLOAT_R_NV 0x20B5
|
||||
#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6
|
||||
#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7
|
||||
#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8
|
||||
#endif /* WGL_NV_float_buffer */
|
||||
|
||||
#ifndef WGL_NV_gpu_affinity
|
||||
#define WGL_NV_gpu_affinity 1
|
||||
DECLARE_HANDLE(HGPUNV);
|
||||
struct _GPU_DEVICE {
|
||||
DWORD cb;
|
||||
CHAR DeviceName[32];
|
||||
CHAR DeviceString[128];
|
||||
DWORD Flags;
|
||||
RECT rcVirtualScreen;
|
||||
};
|
||||
typedef struct _GPU_DEVICE *PGPU_DEVICE;
|
||||
#define ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0
|
||||
#define ERROR_MISSING_AFFINITY_MASK_NV 0x20D1
|
||||
typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu);
|
||||
typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
|
||||
typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList);
|
||||
typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
|
||||
typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglEnumGpusNV (UINT iGpuIndex, HGPUNV *phGpu);
|
||||
BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice);
|
||||
HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *phGpuList);
|
||||
BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu);
|
||||
BOOL WINAPI wglDeleteDCNV (HDC hdc);
|
||||
#endif
|
||||
#endif /* WGL_NV_gpu_affinity */
|
||||
|
||||
#ifndef WGL_NV_multisample_coverage
|
||||
#define WGL_NV_multisample_coverage 1
|
||||
#define WGL_COVERAGE_SAMPLES_NV 0x2042
|
||||
#define WGL_COLOR_SAMPLES_NV 0x20B9
|
||||
#endif /* WGL_NV_multisample_coverage */
|
||||
|
||||
#ifndef WGL_NV_present_video
|
||||
#define WGL_NV_present_video 1
|
||||
DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV);
|
||||
#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0
|
||||
typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
|
||||
typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
int WINAPI wglEnumerateVideoDevicesNV (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList);
|
||||
BOOL WINAPI wglBindVideoDeviceNV (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList);
|
||||
BOOL WINAPI wglQueryCurrentContextNV (int iAttribute, int *piValue);
|
||||
#endif
|
||||
#endif /* WGL_NV_present_video */
|
||||
|
||||
#ifndef WGL_NV_render_depth_texture
|
||||
#define WGL_NV_render_depth_texture 1
|
||||
#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3
|
||||
#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4
|
||||
#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5
|
||||
#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6
|
||||
#define WGL_DEPTH_COMPONENT_NV 0x20A7
|
||||
#endif /* WGL_NV_render_depth_texture */
|
||||
|
||||
#ifndef WGL_NV_render_texture_rectangle
|
||||
#define WGL_NV_render_texture_rectangle 1
|
||||
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0
|
||||
#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1
|
||||
#define WGL_TEXTURE_RECTANGLE_NV 0x20A2
|
||||
#endif /* WGL_NV_render_texture_rectangle */
|
||||
|
||||
#ifndef WGL_NV_swap_group
|
||||
#define WGL_NV_swap_group 1
|
||||
typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group);
|
||||
typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count);
|
||||
typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglJoinSwapGroupNV (HDC hDC, GLuint group);
|
||||
BOOL WINAPI wglBindSwapBarrierNV (GLuint group, GLuint barrier);
|
||||
BOOL WINAPI wglQuerySwapGroupNV (HDC hDC, GLuint *group, GLuint *barrier);
|
||||
BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers);
|
||||
BOOL WINAPI wglQueryFrameCountNV (HDC hDC, GLuint *count);
|
||||
BOOL WINAPI wglResetFrameCountNV (HDC hDC);
|
||||
#endif
|
||||
#endif /* WGL_NV_swap_group */
|
||||
|
||||
#ifndef WGL_NV_vertex_array_range
|
||||
#define WGL_NV_vertex_array_range 1
|
||||
typedef void *(WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
|
||||
typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
void *WINAPI wglAllocateMemoryNV (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority);
|
||||
void WINAPI wglFreeMemoryNV (void *pointer);
|
||||
#endif
|
||||
#endif /* WGL_NV_vertex_array_range */
|
||||
|
||||
#ifndef WGL_NV_video_capture
|
||||
#define WGL_NV_video_capture 1
|
||||
DECLARE_HANDLE(HVIDEOINPUTDEVICENV);
|
||||
#define WGL_UNIQUE_ID_NV 0x20CE
|
||||
#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF
|
||||
typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
|
||||
typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
|
||||
typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
|
||||
typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
|
||||
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice);
|
||||
UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList);
|
||||
BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
|
||||
BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue);
|
||||
BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC hDc, HVIDEOINPUTDEVICENV hDevice);
|
||||
#endif
|
||||
#endif /* WGL_NV_video_capture */
|
||||
|
||||
#ifndef WGL_NV_video_output
|
||||
#define WGL_NV_video_output 1
|
||||
DECLARE_HANDLE(HPVIDEODEV);
|
||||
#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0
|
||||
#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1
|
||||
#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2
|
||||
#define WGL_VIDEO_OUT_COLOR_NV 0x20C3
|
||||
#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4
|
||||
#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5
|
||||
#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6
|
||||
#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7
|
||||
#define WGL_VIDEO_OUT_FRAME 0x20C8
|
||||
#define WGL_VIDEO_OUT_FIELD_1 0x20C9
|
||||
#define WGL_VIDEO_OUT_FIELD_2 0x20CA
|
||||
#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB
|
||||
#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC
|
||||
typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
|
||||
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice);
|
||||
typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer);
|
||||
typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
|
||||
typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglGetVideoDeviceNV (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice);
|
||||
BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV hVideoDevice);
|
||||
BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer);
|
||||
BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB hPbuffer, int iVideoBuffer);
|
||||
BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock);
|
||||
BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo);
|
||||
#endif
|
||||
#endif /* WGL_NV_video_output */
|
||||
|
||||
#ifndef WGL_OML_sync_control
|
||||
#define WGL_OML_sync_control 1
|
||||
typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
|
||||
typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator);
|
||||
typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
|
||||
typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
|
||||
typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
|
||||
typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
|
||||
#ifdef WGL_WGLEXT_PROTOTYPES
|
||||
BOOL WINAPI wglGetSyncValuesOML (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc);
|
||||
BOOL WINAPI wglGetMscRateOML (HDC hdc, INT32 *numerator, INT32 *denominator);
|
||||
INT64 WINAPI wglSwapBuffersMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder);
|
||||
INT64 WINAPI wglSwapLayerBuffersMscOML (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder);
|
||||
BOOL WINAPI wglWaitForMscOML (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc);
|
||||
BOOL WINAPI wglWaitForSbcOML (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc);
|
||||
#endif
|
||||
#endif /* WGL_OML_sync_control */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,8 +1,15 @@
|
|||
#include "gl/system/gl_system.h"
|
||||
//#include "gl/system/gl_system.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include "wglext.h"
|
||||
|
||||
#define USE_WINDOWS_DWORD
|
||||
#include "win32iface.h"
|
||||
#include "win32gliface.h"
|
||||
//#include "gl/gl_intern.h"
|
||||
#include "x86.h"
|
||||
#include "templates.h"
|
||||
#include "version.h"
|
||||
#include "c_console.h"
|
||||
|
|
@ -12,16 +19,21 @@
|
|||
#include "i_system.h"
|
||||
#include "doomstat.h"
|
||||
#include "v_text.h"
|
||||
#include "m_argv.h"
|
||||
//#include "gl_defs.h"
|
||||
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
#include "gl/system/gl_framebuffer.h"
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/utility/gl_templates.h"
|
||||
|
||||
void gl_CalculateCPUSpeed();
|
||||
extern int NewWidth, NewHeight, NewBits, DisplayBits;
|
||||
|
||||
// these get used before GLEW is initialized so we have to use separate pointers with different names
|
||||
PFNWGLCHOOSEPIXELFORMATARBPROC myWglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC myWglCreateContextAttribsARB;
|
||||
PFNWGLSWAPINTERVALEXTPROC vsyncfunc;
|
||||
|
||||
|
||||
CUSTOM_CVAR(Int, gl_vid_multisample, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL )
|
||||
{
|
||||
Printf("This won't take effect until "GAMENAME" is restarted.\n");
|
||||
|
|
@ -581,8 +593,8 @@ bool Win32GLVideo::SetPixelFormat()
|
|||
hRC = wglCreateContext(hDC);
|
||||
wglMakeCurrent(hDC, hRC);
|
||||
|
||||
wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
wglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
|
||||
myWglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
myWglCreateContextAttribsARB = (PFNWGLCREATECONTEXTATTRIBSARBPROC)wglGetProcAddress("wglCreateContextAttribsARB");
|
||||
// any extra stuff here?
|
||||
|
||||
wglMakeCurrent(NULL, NULL);
|
||||
|
|
@ -599,7 +611,7 @@ bool Win32GLVideo::SetPixelFormat()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample)
|
||||
bool Win32GLVideo::SetupPixelFormat(int multisample)
|
||||
{
|
||||
int colorDepth;
|
||||
HDC deskDC;
|
||||
|
|
@ -612,7 +624,7 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample)
|
|||
colorDepth = GetDeviceCaps(deskDC, BITSPIXEL);
|
||||
ReleaseDC(GetDesktopWindow(), deskDC);
|
||||
|
||||
if (wglChoosePixelFormatARB)
|
||||
if (myWglChoosePixelFormatARB)
|
||||
{
|
||||
attributes[0] = WGL_RED_BITS_ARB; //bits
|
||||
attributes[1] = 8;
|
||||
|
|
@ -635,14 +647,7 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample)
|
|||
attributes[17] = true;
|
||||
|
||||
attributes[18] = WGL_ACCELERATION_ARB; //required to be FULL_ACCELERATION_ARB
|
||||
if (allowsoftware)
|
||||
{
|
||||
attributes[19] = WGL_NO_ACCELERATION_ARB;
|
||||
}
|
||||
else
|
||||
{
|
||||
attributes[19] = WGL_FULL_ACCELERATION_ARB;
|
||||
}
|
||||
attributes[19] = WGL_FULL_ACCELERATION_ARB;
|
||||
|
||||
if (multisample > 0)
|
||||
{
|
||||
|
|
@ -662,7 +667,7 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample)
|
|||
attributes[24] = 0;
|
||||
attributes[25] = 0;
|
||||
|
||||
if (!wglChoosePixelFormatARB(m_hDC, attributes, attribsFloat, 1, &pixelFormat, &numFormats))
|
||||
if (!myWglChoosePixelFormatARB(m_hDC, attributes, attribsFloat, 1, &pixelFormat, &numFormats))
|
||||
{
|
||||
Printf("R_OPENGL: Couldn't choose pixel format. Retrying in compatibility mode\n");
|
||||
goto oldmethod;
|
||||
|
|
@ -702,11 +707,8 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample)
|
|||
|
||||
if (pfd.dwFlags & PFD_GENERIC_FORMAT)
|
||||
{
|
||||
if (!allowsoftware)
|
||||
{
|
||||
Printf("R_OPENGL: OpenGL driver not accelerated! Falling back to software renderer.\n");
|
||||
return false;
|
||||
}
|
||||
Printf("R_OPENGL: OpenGL driver not accelerated! Falling back to software renderer.\n");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -724,43 +726,93 @@ bool Win32GLVideo::SetupPixelFormat(bool allowsoftware, int multisample)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool Win32GLVideo::InitHardware (HWND Window, bool allowsoftware, int multisample)
|
||||
// since we cannot use the extension loader here, before it gets initialized,
|
||||
// we have to define the extended GL stuff we need, ourselves here.
|
||||
// The headers generated by GLLoadGen only work if the loader gets initialized.
|
||||
typedef const GLubyte * (APIENTRY *PFNGLGETSTRINGIPROC)(GLenum, GLuint);
|
||||
#define GL_NUM_EXTENSIONS 0x821D
|
||||
|
||||
bool Win32GLVideo::checkCoreUsability()
|
||||
{
|
||||
// if we explicitly want to disable 4.x features this must fail.
|
||||
if (Args->CheckParm("-gl3")) return false;
|
||||
|
||||
// GL 4.4 implies GL_ARB_buffer_storage
|
||||
if (strcmp((char*)glGetString(GL_VERSION), "4.4") >= 0) return true;
|
||||
|
||||
// at this point the extension loader has not been initialized so we have to retrieve glGetStringi ourselves.
|
||||
PFNGLGETSTRINGIPROC myglGetStringi = (PFNGLGETSTRINGIPROC)wglGetProcAddress("glGetStringi");
|
||||
if (!myglGetStringi) return false; // this should not happen.
|
||||
|
||||
const char *extension;
|
||||
|
||||
int max = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &max);
|
||||
|
||||
// step through all reported extensions and see if we got what we need...
|
||||
for (int i = 0; i < max; i++)
|
||||
{
|
||||
extension = (const char*)myglGetStringi(GL_EXTENSIONS, i);
|
||||
if (!strcmp(extension, "GL_ARB_buffer_storage")) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Win32GLVideo::InitHardware (HWND Window, int multisample)
|
||||
{
|
||||
m_Window=Window;
|
||||
m_hDC = GetDC(Window);
|
||||
|
||||
if (!SetupPixelFormat(allowsoftware, multisample))
|
||||
if (!SetupPixelFormat(multisample))
|
||||
{
|
||||
Printf ("R_OPENGL: Reverting to software mode...\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_hRC = 0;
|
||||
if (wglCreateContextAttribsARB != NULL)
|
||||
for (int prof = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; prof <= WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB; prof++)
|
||||
{
|
||||
int ctxAttribs[] = {
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
|
||||
WGL_CONTEXT_FLAGS_ARB, gl_debug? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
|
||||
0
|
||||
};
|
||||
m_hRC = NULL;
|
||||
if (myWglCreateContextAttribsARB != NULL)
|
||||
{
|
||||
// let's try to get the best version possible. Some drivers only give us the version we request
|
||||
// which breaks all version checks for feature support. The highest used features we use are from version 4.4, and 3.0 is a requirement.
|
||||
static int versions[] = { 45, 44, 43, 42, 41, 40, 33, 32, 31, 30, -1 };
|
||||
|
||||
m_hRC = wglCreateContextAttribsARB(m_hDC, 0, ctxAttribs);
|
||||
}
|
||||
if (m_hRC == 0)
|
||||
{
|
||||
m_hRC = wglCreateContext(m_hDC);
|
||||
}
|
||||
for (int i = 0; versions[i] > 0; i++)
|
||||
{
|
||||
int ctxAttribs[] = {
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, versions[i] / 10,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, versions[i] % 10,
|
||||
WGL_CONTEXT_FLAGS_ARB, gl_debug ? WGL_CONTEXT_DEBUG_BIT_ARB : 0,
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, prof,
|
||||
0
|
||||
};
|
||||
|
||||
if (m_hRC == NULL)
|
||||
{
|
||||
Printf ("R_OPENGL: Couldn't create render context. Reverting to software mode...\n");
|
||||
return false;
|
||||
}
|
||||
m_hRC = myWglCreateContextAttribsARB(m_hDC, 0, ctxAttribs);
|
||||
if (m_hRC != NULL) break;
|
||||
}
|
||||
}
|
||||
|
||||
wglMakeCurrent(m_hDC, m_hRC);
|
||||
return true;
|
||||
if (m_hRC == NULL && prof == WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB)
|
||||
{
|
||||
Printf("R_OPENGL: Couldn't create render context. Reverting to software mode...\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
wglMakeCurrent(m_hDC, m_hRC);
|
||||
|
||||
// we can only use core profile contexts if GL_ARB_buffer_storage is supported or GL version is >= 4.4
|
||||
if (prof == WGL_CONTEXT_CORE_PROFILE_BIT_ARB && !checkCoreUsability())
|
||||
{
|
||||
wglMakeCurrent(0, 0);
|
||||
wglDeleteContext(m_hRC);
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
@ -892,7 +944,7 @@ Win32GLFrameBuffer::Win32GLFrameBuffer(void *hMonitor, int width, int height, in
|
|||
I_RestoreWindowedPos();
|
||||
}
|
||||
|
||||
if (!static_cast<Win32GLVideo *>(Video)->InitHardware(Window, false, localmultisample))
|
||||
if (!static_cast<Win32GLVideo *>(Video)->InitHardware(Window, localmultisample))
|
||||
{
|
||||
vid_renderer = 0;
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef __WIN32GLIFACE_H__
|
||||
#define __WIN32GLIFACE_H__
|
||||
|
||||
#include "gl/system/gl_system.h"
|
||||
#include "hardware.h"
|
||||
#include "win32iface.h"
|
||||
#include "v_video.h"
|
||||
|
|
@ -42,12 +41,10 @@ public:
|
|||
DFrameBuffer *CreateFrameBuffer (int width, int height, bool fs, DFrameBuffer *old);
|
||||
virtual bool SetResolution (int width, int height, int bits);
|
||||
void DumpAdapters();
|
||||
bool InitHardware (HWND Window, bool allowsoftware, int multisample);
|
||||
bool InitHardware (HWND Window, int multisample);
|
||||
void Shutdown();
|
||||
bool SetFullscreen(const char *devicename, int w, int h, int bits, int hz);
|
||||
|
||||
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB; // = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
|
||||
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB;
|
||||
HDC m_hDC;
|
||||
|
||||
protected:
|
||||
|
|
@ -83,12 +80,13 @@ protected:
|
|||
HWND InitDummy();
|
||||
void ShutdownDummy(HWND dummy);
|
||||
bool SetPixelFormat();
|
||||
bool SetupPixelFormat(bool allowsoftware, int multisample);
|
||||
bool SetupPixelFormat(int multisample);
|
||||
|
||||
void GetDisplayDeviceName();
|
||||
void MakeModesList();
|
||||
void AddMode(int x, int y, int bits, int baseHeight, int refreshHz);
|
||||
void FreeModes();
|
||||
bool checkCoreUsability();
|
||||
public:
|
||||
int GetTrueHeight() { return m_trueHeight; }
|
||||
|
||||
|
|
@ -107,7 +105,6 @@ public:
|
|||
Win32GLFrameBuffer(void *hMonitor, int width, int height, int bits, int refreshHz, bool fullscreen);
|
||||
virtual ~Win32GLFrameBuffer();
|
||||
|
||||
PFNWGLSWAPINTERVALEXTPROC vsyncfunc;
|
||||
|
||||
// unused but must be defined
|
||||
virtual void Blank ();
|
||||
|
|
|
|||
Binary file not shown.
|
Before Width: | Height: | Size: 13 KiB |
|
|
@ -14,13 +14,6 @@ OptionValue "EnhancedStealth"
|
|||
3, "Any fixed colormap"
|
||||
}
|
||||
|
||||
OptionValue "VBOModes"
|
||||
{
|
||||
0, "Off"
|
||||
1, "Static"
|
||||
2, "Dynamic"
|
||||
}
|
||||
|
||||
OptionValue "FilterModes"
|
||||
{
|
||||
0, "None"
|
||||
|
|
@ -112,12 +105,6 @@ OptionValue "HqResizeModes"
|
|||
6, "hq4x"
|
||||
}
|
||||
|
||||
OptionValue "HqResizeTargets"
|
||||
{
|
||||
0, "Everything"
|
||||
1, "Sprites/fonts"
|
||||
}
|
||||
|
||||
OptionValue "FogMode"
|
||||
{
|
||||
0, "Off"
|
||||
|
|
@ -152,6 +139,7 @@ OptionMenu "GLTextureGLOptions"
|
|||
Option "Precache GL textures", gl_precache, "YesNo"
|
||||
Option "Camera textures offscreen", gl_usefb, "OnOff"
|
||||
Option "Trim sprite edges", gl_trimsprites, "OnOff"
|
||||
Option "Sort draw lists by texture", gl_sort_textures, "YesNo"
|
||||
}
|
||||
|
||||
OptionMenu "GLLightOptions"
|
||||
|
|
@ -165,7 +153,6 @@ OptionMenu "GLLightOptions"
|
|||
Option "Force additive lighting", gl_lights_additive, "YesNo"
|
||||
Slider "Light intensity", gl_lights_intensity, 0.0, 1.0, 0.1
|
||||
Slider "Light size", gl_lights_size, 0.0, 2.0, 0.1
|
||||
Option "Use shaders for lights", gl_dynlight_shader, "YesNo"
|
||||
}
|
||||
|
||||
OptionMenu "GLPrefOptions"
|
||||
|
|
@ -186,17 +173,6 @@ OptionMenu "GLPrefOptions"
|
|||
Option "Particle style", gl_particles_style, "Particles"
|
||||
Slider "Ambient light level", gl_light_ambient, 1.0, 255.0, 5.0
|
||||
Option "Rendering quality", gl_render_precise, "Precision"
|
||||
Option "Use vertex buffer", gl_usevbo, "VBOModes"
|
||||
}
|
||||
|
||||
OptionMenu "GLShaderOptions"
|
||||
{
|
||||
Title "SHADER OPTIONS"
|
||||
Option "Enable brightness maps", gl_brightmap_shader, "OnOff"
|
||||
Option "Shaders for texture warp", gl_warp_shader, "OnOff"
|
||||
Option "Shaders for fog", gl_fog_shader, "OnOff"
|
||||
Option "Shaders for colormaps", gl_colormap_shader, "OnOff"
|
||||
Option "Shaders for glowing textures", gl_glow_shader, "OnOff"
|
||||
}
|
||||
|
||||
OptionMenu "OpenGLOptions"
|
||||
|
|
@ -204,7 +180,6 @@ OptionMenu "OpenGLOptions"
|
|||
Title "OPENGL OPTIONS"
|
||||
Submenu "Dynamic Light Options", "GLLightOptions"
|
||||
Submenu "Texture Options", "GLTextureGLOptions"
|
||||
Submenu "Shader Options", "GLShaderOptions"
|
||||
Submenu "Preferences", "GLPrefOptions"
|
||||
}
|
||||
|
||||
|
|
|
|||
15
wadsrc/static/shaders/glsl/burn.fp
Normal file
15
wadsrc/static/shaders/glsl/burn.fp
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
uniform sampler2D tex;
|
||||
uniform sampler2D texture2;
|
||||
in vec4 vTexCoord;
|
||||
in vec4 vColor;
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 frag = vColor;
|
||||
|
||||
vec4 t1 = texture2D(tex, vTexCoord.xy);
|
||||
vec4 t2 = texture2D(texture2, vec2(vTexCoord.x, 1.0-vTexCoord.y));
|
||||
|
||||
FragColor = frag * vec4(t1.r, t1.g, t1.b, t2.a);
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
uniform int fogenabled;
|
||||
uniform vec4 fogcolor;
|
||||
uniform vec3 camerapos;
|
||||
varying vec4 pixelpos;
|
||||
varying vec4 fogparm;
|
||||
in vec4 pixelpos;
|
||||
in vec2 glowdist;
|
||||
out vec4 FragColor;
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
@ -18,19 +16,15 @@ void main()
|
|||
//
|
||||
// calculate fog factor
|
||||
//
|
||||
#ifndef NO_SM4
|
||||
if (fogenabled == -1)
|
||||
{
|
||||
fogdist = pixelpos.w;
|
||||
}
|
||||
else
|
||||
{
|
||||
fogdist = max(16.0, distance(pixelpos.xyz, camerapos));
|
||||
}
|
||||
#else
|
||||
if (uFogEnabled == -1)
|
||||
{
|
||||
fogdist = pixelpos.w;
|
||||
#endif
|
||||
fogfactor = exp2 (fogparm.z * fogdist);
|
||||
gl_FragColor = vec4(fogcolor.rgb, 1.0 - fogfactor);
|
||||
}
|
||||
else
|
||||
{
|
||||
fogdist = max(16.0, distance(pixelpos.xyz, uCameraPos.xyz));
|
||||
}
|
||||
fogfactor = exp2 (uFogDensity * fogdist);
|
||||
FragColor = vec4(uFogColor.rgb, 1.0 - fogfactor);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
uniform sampler2D texture2;
|
||||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
vec4 brightpix = desaturate(texture2D(texture2, gl_TexCoord[0].st));
|
||||
vec4 texel = getTexel(gl_TexCoord[0].st);
|
||||
return vec4(texel.rgb * min (color.rgb + brightpix.rgb, 1.0), texel.a*color.a);
|
||||
return getTexel(vTexCoord.st);
|
||||
}
|
||||
|
||||
vec4 ProcessLight(vec4 color)
|
||||
{
|
||||
vec4 brightpix = desaturate(texture2D(texture2, vTexCoord.st));
|
||||
return vec4(min (color.rgb + brightpix.rgb, 1.0), color.a);
|
||||
}
|
||||
|
|
|
|||
5
wadsrc/static/shaders/glsl/func_defaultlight.fp
Normal file
5
wadsrc/static/shaders/glsl/func_defaultlight.fp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
vec4 ProcessLight(vec4 color)
|
||||
{
|
||||
return color;
|
||||
}
|
||||
|
|
@ -1,7 +1,6 @@
|
|||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
vec4 pix = getTexel(gl_TexCoord[0].st);
|
||||
return pix * color;
|
||||
return getTexel(vTexCoord.st);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
return color;
|
||||
return desaturate(uObjectColor);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
uniform float timer;
|
||||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
vec2 texCoord = gl_TexCoord[0].st;
|
||||
vec2 texCoord = vTexCoord.st;
|
||||
|
||||
const float pi = 3.14159265358979323846;
|
||||
vec2 offset = vec2(0,0);
|
||||
|
|
@ -12,6 +12,6 @@ vec4 Process(vec4 color)
|
|||
|
||||
texCoord += offset;
|
||||
|
||||
return getTexel(texCoord) * color;
|
||||
return getTexel(texCoord);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
uniform float timer;
|
||||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
vec2 texCoord = gl_TexCoord[0].st;
|
||||
vec2 texCoord = vTexCoord.st;
|
||||
|
||||
const float pi = 3.14159265358979323846;
|
||||
vec2 offset = vec2(0.0,0.0);
|
||||
|
|
@ -13,6 +13,6 @@ vec4 Process(vec4 color)
|
|||
|
||||
texCoord += offset;
|
||||
|
||||
return getTexel(texCoord) * color;
|
||||
return getTexel(texCoord);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
uniform float timer;
|
||||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
vec2 texCoord = gl_TexCoord[0].st;
|
||||
vec2 texCoord = vTexCoord.st;
|
||||
|
||||
const float pi = 3.14159265358979323846;
|
||||
|
||||
texCoord.x += sin(pi * 2.0 * (texCoord.y + timer * 0.125)) * 0.1;
|
||||
|
||||
return getTexel(texCoord) * color;
|
||||
return getTexel(texCoord);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,16 @@
|
|||
//created by Evil Space Tomato
|
||||
uniform float timer;
|
||||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
vec2 texCoord = gl_TexCoord[0].st;
|
||||
vec2 texCoord = vTexCoord.st;
|
||||
|
||||
vec2 texSplat;
|
||||
const float pi = 3.14159265358979323846;
|
||||
texSplat.x = texCoord.x + mod(sin(pi * 2.0 * (texCoord.y + timer * 2.0)),0.1) * 0.1;
|
||||
texSplat.y = texCoord.y + mod(cos(pi * 2.0 * (texCoord.x + timer * 2.0)),0.1) * 0.1;
|
||||
|
||||
vec4 basicColor = getTexel(texSplat) * color;
|
||||
vec4 basicColor = getTexel(texSplat);
|
||||
|
||||
float texX = sin(texCoord.x * 100.0 + timer*5.0);
|
||||
float texY = cos(texCoord.x * 100.0 + timer*5.0);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
//created by Evil Space Tomato
|
||||
uniform float timer;
|
||||
|
||||
vec4 Process(vec4 color)
|
||||
vec4 ProcessTexel()
|
||||
{
|
||||
vec2 texCoord = gl_TexCoord[0].st;
|
||||
vec4 basicColor = getTexel(texCoord) * color;
|
||||
vec2 texCoord = vTexCoord.st;
|
||||
vec4 basicColor = getTexel(texCoord);
|
||||
|
||||
texCoord.x = float( int(texCoord.x * 128.0) ) / 128.0;
|
||||
texCoord.y = float( int(texCoord.y * 128.0) ) / 128.0;
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue