Browse Source

Merge upstream commits from ioquake/master

Figured out method of referencing GLSL generated C files outside of code directory
  E2K: fixed build by MCST lcc compiler when using USE_CURL=1 option
  Fix duplicate team join center print for bots and g_teamAutoJoin
  Further tweaks to Xcode project
  Fix team orders menu not listing clients with lower clientnums
  Updated to latest recommended build settings, increased deployment target to 10.7
  Several updates to xcode project files for Xcode 11
  Fix for macOS Catalina screen resolution issue
  Fix lightning gun handling for corpses and single player podiums
  Create Funding.yml
  q3rcc: Allow to override build date
  Restore OpenGL 1.1 support (GL_CLAMP)
  Remove erroneous newlines from Com_Error in sdl_glimp.c
  Fix IQM quat normalize fail case
  Fix warnings that IQM blendWeights may not be initialized
  Fix rendering IQM models between model frames
  OpenGL2: Disable r_cubeMapping if not OpenGL 3.0+
  Override video mode list in Team Arena UI
  Add current (custom) resolution to Q3 UI video mode list
  OpenGL2: Fix compiling lightall GLSL on OpenGL 2.1
  Fix PRINT_ERROR print level missing from CL_RefPrintf
  Add r_parallaxMapShadows.
  OpenGL2: r_cubemapping 2 for box cubemap parallax.
  Add .gitignore for misc/msvc12
  Prevent Q_IsColorString from asserting on negative ascii chars
  Make Team Arena prevTeamMember command loop around player list
  Don't use host pkg-config when cross-compiling
  Make s_info command display channels instead of stereo
  Fix SDL audio playback with 16-bit stereo sound
  Disable pulseaudio capture regardless of SDL version
  Allow binds to use hex values for all key codes
  Fix predicting entity origin on rotating mover
  Fix SDL audio playback with surround sound
  Improve finding obelisk entitynum for bot AI
  Fix loading favorites as initial source in server browser
  Calculate bounds for unanimated IQM models
  Fix axis returned by IQM's LerpTag
  OpenGL2: Add GPU vertex skinning for IQM models
  Improve IQM CPU vertex skinning performance
  Improve IQM loading
  Fix IQM root joint backlerp when joint number is more than 0
  OpenGL2: Misc fixes and cleanup
  OpenGL2: Fix world VAO cache drawing when glIndex_t is unsigned short
  Don't check fixed function GL extensions when using shader pipeline
  Load OpenGL ES 2.0 function procs
  Don't load non-core GL functions for OpenGL 3.2 core context
  OpenGL1: Use RE_UploadCinematic() instead of duplicate code
  Don't upload 8 bit grayscale images as 16 bit luminance
  Fix renderer not clearing some GL extension variables at vid_restart
  Remove unused renderer_buffer variable
urt
Mickaël Thomas 1 month ago
parent
commit
5055eefbdc
41 changed files with 2713 additions and 1353 deletions
  1. +14
    -0
      .github/FUNDING.yml
  2. +4
    -6
      code/client/cl_keys.c
  3. +3
    -1
      code/client/cl_main.c
  4. +5
    -10
      code/client/snd_dma.c
  5. +1
    -0
      code/client/snd_local.h
  6. +42
    -24
      code/client/snd_mix.c
  7. +22
    -0
      code/qcommon/q_shared.c
  8. +5
    -1
      code/qcommon/q_shared.h
  9. +41
    -25
      code/renderercommon/qgl.h
  10. +2
    -1
      code/renderercommon/tr_common.h
  11. +3
    -19
      code/renderergl1/tr_backend.c
  12. +3
    -9
      code/renderergl1/tr_image.c
  13. +7
    -6
      code/renderergl1/tr_init.c
  14. +29
    -8
      code/renderergl1/tr_local.h
  15. +815
    -505
      code/renderergl1/tr_model_iqm.c
  16. +1
    -1
      code/renderergl2/glsl/calclevels4x_fp.glsl
  17. +14
    -0
      code/renderergl2/glsl/fogpass_vp.glsl
  18. +14
    -0
      code/renderergl2/glsl/generic_vp.glsl
  19. +78
    -1
      code/renderergl2/glsl/lightall_fp.glsl
  20. +17
    -0
      code/renderergl2/glsl/lightall_vp.glsl
  21. +23
    -4
      code/renderergl2/glsl/shadowfill_vp.glsl
  22. +1
    -1
      code/renderergl2/glsl/ssao_fp.glsl
  23. +1
    -7
      code/renderergl2/tr_backend.c
  24. +2
    -2
      code/renderergl2/tr_cmds.c
  25. +3
    -3
      code/renderergl2/tr_dsa.c
  26. +3
    -23
      code/renderergl2/tr_extensions.c
  27. +0
    -4
      code/renderergl2/tr_flares.c
  28. +129
    -24
      code/renderergl2/tr_glsl.c
  29. +2
    -8
      code/renderergl2/tr_image.c
  30. +28
    -6
      code/renderergl2/tr_init.c
  31. +83
    -18
      code/renderergl2/tr_local.h
  32. +1075
    -511
      code/renderergl2/tr_model_iqm.c
  33. +1
    -1
      code/renderergl2/tr_scene.c
  34. +48
    -4
      code/renderergl2/tr_shade.c
  35. +11
    -3
      code/renderergl2/tr_shadows.c
  36. +1
    -0
      code/renderergl2/tr_surface.c
  37. +24
    -22
      code/renderergl2/tr_vbo.c
  38. +145
    -80
      code/sdl/sdl_glimp.c
  39. +6
    -15
      code/sdl/sdl_snd.c
  40. +2
    -0
      make-macosx-app.sh
  41. +5
    -0
      opengl2-readme.md

+ 14
- 0
.github/FUNDING.yml View File

@@ -0,0 +1,14 @@
# These are supported funding model platforms

patreon: timedoctor
open_collective: # Replace with a single Open Collective username
ko_fi: jackslater
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ['https://www.patreon.com/icculus', 'https://www.patreon.com/SmileTheory', 'https://ko-fi.com/zturtleman']


#please add your links to this if you've been a long-time contributor!

+ 4
- 6
code/client/cl_keys.c View File

@@ -839,6 +839,7 @@ to be configured even if they don't have defined names.
*/
int Key_StringToKeynum( char *str ) {
keyname_t *kn;
int n;
if ( !str || !str[0] ) {
return -1;
@@ -848,12 +849,9 @@ int Key_StringToKeynum( char *str ) {
}

// check for hex code
if ( strlen( str ) == 4 ) {
int n = Com_HexStrToInt( str );

if ( n >= 0 ) {
return n;
}
n = Com_HexStrToInt( str );
if ( n >= 0 && n < MAX_KEYS ) {
return n;
}

// scan for a text match


+ 3
- 1
code/client/cl_main.c View File

@@ -3212,8 +3212,10 @@ static __attribute__ ((format (printf, 2, 3))) void QDECL CL_RefPrintf( int prin
Com_Printf ("%s", msg);
} else if ( print_level == PRINT_WARNING ) {
Com_Printf (S_COLOR_YELLOW "%s", msg); // yellow
} else if ( print_level == PRINT_ERROR ) {
Com_Printf (S_COLOR_RED "%s", msg); // red
} else if ( print_level == PRINT_DEVELOPER ) {
Com_DPrintf (S_COLOR_RED "%s", msg); // red
Com_DPrintf (S_COLOR_RED "%s", msg); // red - developer only
}
}



+ 5
- 10
code/client/snd_dma.c View File

@@ -99,7 +99,7 @@ void S_Base_SoundInfo(void) {
if (!s_soundStarted) {
Com_Printf ("sound system not started\n");
} else {
Com_Printf("%5d stereo\n", dma.channels - 1);
Com_Printf("%5d channels\n", dma.channels);
Com_Printf("%5d samples\n", dma.samples);
Com_Printf("%5d samplebits (%s)\n", dma.samplebits, dma.isfloat ? "float" : "int");
Com_Printf("%5d submission_chunk\n", dma.submission_chunk);
@@ -1243,9 +1243,6 @@ void S_GetSoundtime(void)
int samplepos;
static int buffers;
static int oldsamplepos;
int fullsamples;
fullsamples = dma.samples / dma.channels;

if( CL_VideoRecording( ) )
{
@@ -1269,13 +1266,13 @@ void S_GetSoundtime(void)
if (s_paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits
buffers = 0;
s_paintedtime = fullsamples;
s_paintedtime = dma.fullsamples;
S_Base_StopAllSounds ();
}
}
oldsamplepos = samplepos;

s_soundtime = buffers*fullsamples + samplepos/dma.channels;
s_soundtime = buffers*dma.fullsamples + samplepos/dma.channels;

#if 0
// check to make sure that we haven't overshot
@@ -1296,7 +1293,6 @@ void S_GetSoundtime(void)

void S_Update_(void) {
unsigned endtime;
int samps;
static float lastTime = 0.0f;
float ma, op;
float thisTime, sane;
@@ -1340,9 +1336,8 @@ void S_Update_(void) {
& ~(dma.submission_chunk-1);

// never mix more than the complete buffer
samps = dma.samples >> (dma.channels-1);
if (endtime - s_soundtime > samps)
endtime = s_soundtime + samps;
if (endtime - s_soundtime > dma.fullsamples)
endtime = s_soundtime + dma.fullsamples;





+ 1
- 0
code/client/snd_local.h View File

@@ -66,6 +66,7 @@ typedef struct sfx_s {
typedef struct {
int channels;
int samples; // mono samples in buffer
int fullsamples; // samples with all channels in buffer (samples divided by channels)
int submission_chunk; // don't mix less than this #
int samplebits;
int isfloat;


+ 42
- 24
code/client/snd_mix.c View File

@@ -119,24 +119,24 @@ void S_TransferStereo16 (unsigned long *pbuf, int endtime)
while (ls_paintedtime < endtime)
{
// handle recirculating buffer issues
lpos = ls_paintedtime & ((dma.samples>>1)-1);
lpos = ls_paintedtime % dma.fullsamples;

snd_out = (short *) pbuf + (lpos<<1);
snd_out = (short *) pbuf + (lpos<<1); // lpos * dma.channels

snd_linear_count = (dma.samples>>1) - lpos;
snd_linear_count = dma.fullsamples - lpos;
if (ls_paintedtime + snd_linear_count > endtime)
snd_linear_count = endtime - ls_paintedtime;

snd_linear_count <<= 1;
snd_linear_count <<= 1; // snd_linear_count *= dma.channels

// write a linear blast of samples
S_WriteLinearBlastStereo16 ();

snd_p += snd_linear_count;
ls_paintedtime += (snd_linear_count>>1);
ls_paintedtime += (snd_linear_count>>1); // snd_linear_count / dma.channels

if( CL_VideoRecording( ) )
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 );
CL_WriteAVIAudioFrame( (byte *)snd_out, snd_linear_count << 1 ); // snd_linear_count * (dma.samplebits/8)
}
}

@@ -150,18 +150,16 @@ void S_TransferPaintBuffer(int endtime)
{
int out_idx;
int count;
int out_mask;
int *p;
int step;
int val;
int i;
unsigned long *pbuf;

pbuf = (unsigned long *)dma.buffer;


if ( s_testsound->integer ) {
int i;

// write a fixed sine wave
count = (endtime - s_paintedtime);
for (i=0 ; i<count ; i++)
@@ -177,53 +175,73 @@ void S_TransferPaintBuffer(int endtime)
{ // general case
p = (int *) paintbuffer;
count = (endtime - s_paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = s_paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
out_idx = (s_paintedtime * dma.channels) % dma.samples;
step = 3 - MIN(dma.channels, 2);

if ((dma.isfloat) && (dma.samplebits == 32))
{
float *out = (float *) pbuf;
while (count--)
for (i=0 ; i<count ; i++)
{
val = *p >> 8;
p+= step;
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32767) /* clamp to one less than max to make division max out at -1.0f. */
val = -32767;
out[out_idx] = ((float) val) / 32767.0f;
out_idx = (out_idx + 1) & out_mask;
out_idx = (out_idx + 1) % dma.samples;
}
}
else if (dma.samplebits == 16)
{
short *out = (short *) pbuf;
while (count--)
for (i=0 ; i<count ; i++)
{
val = *p >> 8;
p+= step;
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32768)
val = -32768;
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
out_idx = (out_idx + 1) % dma.samples;
}
}
else if (dma.samplebits == 8)
{
unsigned char *out = (unsigned char *) pbuf;
while (count--)
for (i=0 ; i<count ; i++)
{
val = *p >> 8;
p+= step;
if ((i % dma.channels) >= 2)
{
val = 0;
}
else
{
val = *p >> 8;
p+= step;
}
if (val > 0x7fff)
val = 0x7fff;
else if (val < -32768)
val = -32768;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
out_idx = (out_idx + 1) % dma.samples;
}
}
}


+ 22
- 0
code/qcommon/q_shared.c View File

@@ -23,6 +23,28 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// q_shared.c -- stateless support routines that are included in each code dll
#include "q_shared.h"

// ^[0-9a-zA-Z]
qboolean Q_IsColorString(const char *p) {
if (!p)
return qfalse;

if (p[0] != Q_COLOR_ESCAPE)
return qfalse;

if (p[1] == 0)
return qfalse;

// isalnum expects a signed integer in the range -1 (EOF) to 255, or it might assert on undefined behaviour
// a dereferenced char pointer has the range -128 to 127, so we just need to rangecheck the negative part
if (p[1] < 0)
return qfalse;

if (isalnum(p[1]) == 0)
return qfalse;

return qtrue;
}

float Com_Clamp( float min, float max, float value ) {
if ( value < min ) {
return min;


+ 5
- 1
code/qcommon/q_shared.h View File

@@ -353,6 +353,8 @@ typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t vec5_t[5];

typedef vec_t quat_t[4];

typedef int fixed4_t;
typedef int fixed8_t;
typedef int fixed16_t;
@@ -394,7 +396,7 @@ extern vec4_t colorMdGrey;
extern vec4_t colorDkGrey;

#define Q_COLOR_ESCAPE '^'
#define Q_IsColorString(p) ((p) && *(p) == Q_COLOR_ESCAPE && *((p)+1) && isalnum(*((p)+1))) // ^[0-9a-zA-Z]
qboolean Q_IsColorString(const char *p); // ^[0-9a-zA-Z]

#define COLOR_BLACK '0'
#define COLOR_RED '1'
@@ -569,6 +571,8 @@ typedef struct {

#define Byte4Copy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])

#define QuatCopy(a,b) ((b)[0]=(a)[0],(b)[1]=(a)[1],(b)[2]=(a)[2],(b)[3]=(a)[3])

#define SnapVector(v) {v[0]=((int)(v[0]));v[1]=((int)(v[1]));v[2]=((int)(v[2]));}
// just in case you don't want to use the macros
vec_t _DotProduct( const vec3_t v1, const vec3_t v2 );


+ 41
- 25
code/renderercommon/qgl.h View File

@@ -45,27 +45,22 @@ extern void (APIENTRYP qglUnlockArraysEXT) (void);
// GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
// get missing functions from code/SDL2/include/SDL_opengl.h

// OpenGL 1.0/1.1 and OpenGL ES 1.0
// OpenGL 1.0/1.1, OpenGL ES 1.0, and OpenGL 3.2 core profile
#define QGL_1_1_PROCS \
GLE(void, AlphaFunc, GLenum func, GLclampf ref) \
GLE(void, BindTexture, GLenum target, GLuint texture) \
GLE(void, BlendFunc, GLenum sfactor, GLenum dfactor) \
GLE(void, ClearColor, GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) \
GLE(void, Clear, GLbitfield mask) \
GLE(void, ClearStencil, GLint s) \
GLE(void, Color4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) \
GLE(void, ColorMask, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) \
GLE(void, ColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \
GLE(void, CopyTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) \
GLE(void, CullFace, GLenum mode) \
GLE(void, DeleteTextures, GLsizei n, const GLuint *textures) \
GLE(void, DepthFunc, GLenum func) \
GLE(void, DepthMask, GLboolean flag) \
GLE(void, DisableClientState, GLenum cap) \
GLE(void, Disable, GLenum cap) \
GLE(void, DrawArrays, GLenum mode, GLint first, GLsizei count) \
GLE(void, DrawElements, GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) \
GLE(void, EnableClientState, GLenum cap) \
GLE(void, Enable, GLenum cap) \
GLE(void, Finish, void) \
GLE(void, Flush, void) \
@@ -75,53 +70,67 @@ extern void (APIENTRYP qglUnlockArraysEXT) (void);
GLE(void, GetIntegerv, GLenum pname, GLint *params) \
GLE(const GLubyte *, GetString, GLenum name) \
GLE(void, LineWidth, GLfloat width) \
GLE(void, LoadIdentity, void) \
GLE(void, LoadMatrixf, const GLfloat *m) \
GLE(void, MatrixMode, GLenum mode) \
GLE(void, PolygonOffset, GLfloat factor, GLfloat units) \
GLE(void, PopMatrix, void) \
GLE(void, PushMatrix, void) \
GLE(void, ReadPixels, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) \
GLE(void, Scissor, GLint x, GLint y, GLsizei width, GLsizei height) \
GLE(void, ShadeModel, GLenum mode) \
GLE(void, StencilFunc, GLenum func, GLint ref, GLuint mask) \
GLE(void, StencilMask, GLuint mask) \
GLE(void, StencilOp, GLenum fail, GLenum zfail, GLenum zpass) \
GLE(void, TexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \
GLE(void, TexEnvf, GLenum target, GLenum pname, GLfloat param) \
GLE(void, TexImage2D, GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) \
GLE(void, TexParameterf, GLenum target, GLenum pname, GLfloat param) \
GLE(void, TexParameteri, GLenum target, GLenum pname, GLint param) \
GLE(void, TexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) \
GLE(void, Translatef, GLfloat x, GLfloat y, GLfloat z) \
GLE(void, VertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \
GLE(void, Viewport, GLint x, GLint y, GLsizei width, GLsizei height) \

// OpenGL 1.0/1.1 but not OpenGL ES 1.x
// OpenGL 1.0/1.1 and OpenGL ES 1.x but not OpenGL 3.2 core profile
#define QGL_1_1_FIXED_FUNCTION_PROCS \
GLE(void, AlphaFunc, GLenum func, GLclampf ref) \
GLE(void, Color4f, GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) \
GLE(void, ColorPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \
GLE(void, DisableClientState, GLenum cap) \
GLE(void, EnableClientState, GLenum cap) \
GLE(void, LoadIdentity, void) \
GLE(void, LoadMatrixf, const GLfloat *m) \
GLE(void, MatrixMode, GLenum mode) \
GLE(void, PopMatrix, void) \
GLE(void, PushMatrix, void) \
GLE(void, ShadeModel, GLenum mode) \
GLE(void, TexCoordPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \
GLE(void, TexEnvf, GLenum target, GLenum pname, GLfloat param) \
GLE(void, VertexPointer, GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) \

// OpenGL 1.0/1.1 and 3.2 core profile but not OpenGL ES 1.x
#define QGL_DESKTOP_1_1_PROCS \
GLE(void, ClearDepth, GLclampd depth) \
GLE(void, DepthRange, GLclampd near_val, GLclampd far_val) \
GLE(void, DrawBuffer, GLenum mode) \
GLE(void, PolygonMode, GLenum face, GLenum mode) \

// OpenGL 1.0/1.1 but not OpenGL 3.2 core profile or OpenGL ES 1.x
#define QGL_DESKTOP_1_1_FIXED_FUNCTION_PROCS \
GLE(void, ArrayElement, GLint i) \
GLE(void, Begin, GLenum mode) \
GLE(void, ClearDepth, GLclampd depth) \
GLE(void, ClipPlane, GLenum plane, const GLdouble *equation) \
GLE(void, Color3f, GLfloat red, GLfloat green, GLfloat blue) \
GLE(void, Color4ubv, const GLubyte *v) \
GLE(void, DepthRange, GLclampd near_val, GLclampd far_val) \
GLE(void, DrawBuffer, GLenum mode) \
GLE(void, End, void) \
GLE(void, Frustum, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) \
GLE(void, Ortho, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val) \
GLE(void, PolygonMode, GLenum face, GLenum mode) \
GLE(void, TexCoord2f, GLfloat s, GLfloat t) \
GLE(void, TexCoord2fv, const GLfloat *v) \
GLE(void, Vertex2f, GLfloat x, GLfloat y) \
GLE(void, Vertex3f, GLfloat x, GLfloat y, GLfloat z) \
GLE(void, Vertex3fv, const GLfloat *v) \

// OpenGL ES 1.1 but not desktop OpenGL 1.x
// OpenGL ES 1.1 and OpenGL ES 2.0 but not desktop OpenGL 1.x
#define QGL_ES_1_1_PROCS \
GLE(void, ClearDepthf, GLclampf depth) \
GLE(void, ClipPlanef, GLenum plane, const GLfloat *equation) \
GLE(void, DepthRangef, GLclampf near_val, GLclampf far_val) \

// OpenGL ES 1.1 but not OpenGL ES 2.0 or desktop OpenGL 1.x
#define QGL_ES_1_1_FIXED_FUNCTION_PROCS \
GLE(void, ClipPlanef, GLenum plane, const GLfloat *equation) \
GLE(void, Frustumf, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near_val, GLfloat far_val) \
GLE(void, Orthof, GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat near_val, GLfloat far_val) \

@@ -131,14 +140,17 @@ extern void (APIENTRYP qglUnlockArraysEXT) (void);
GLE(void, CompressedTexImage2D, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data) \
GLE(void, CompressedTexSubImage2D, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data) \

// OpenGL 1.5, was GL_ARB_vertex_buffer_object and GL_ARB_occlusion_query
#define QGL_1_5_PROCS \
// GL_ARB_occlusion_query, built-in to OpenGL 1.5 but not OpenGL ES 2.0
#define QGL_ARB_occlusion_query_PROCS \
GLE(void, GenQueries, GLsizei n, GLuint *ids) \
GLE(void, DeleteQueries, GLsizei n, const GLuint *ids) \
GLE(void, BeginQuery, GLenum target, GLuint id) \
GLE(void, EndQuery, GLenum target) \
GLE(void, GetQueryObjectiv, GLuint id, GLenum pname, GLint *params) \
GLE(void, GetQueryObjectuiv, GLuint id, GLenum pname, GLuint *params) \

// OpenGL 1.5, was GL_ARB_vertex_buffer_object
#define QGL_1_5_PROCS \
GLE(void, BindBuffer, GLenum target, GLuint buffer) \
GLE(void, DeleteBuffers, GLsizei n, const GLuint *buffers) \
GLE(void, GenBuffers, GLsizei n, GLuint *buffers) \
@@ -301,14 +313,18 @@ extern void (APIENTRYP qglUnlockArraysEXT) (void);
GLE(GLvoid, NamedFramebufferTexture2DEXT, GLuint framebuffer, GLenum attachment, GLenum textarget, GLuint texture, GLint level) \
GLE(GLvoid, NamedFramebufferRenderbufferEXT, GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) \

#define GLE(ret, name, ...) typedef ret APIENTRY name##proc(__VA_ARGS__); extern name##proc * qgl##name;
#define GLE(ret, name, ...) typedef ret APIENTRY name##proc(__VA_ARGS__);
QGL_1_1_PROCS;
QGL_1_1_FIXED_FUNCTION_PROCS;
QGL_DESKTOP_1_1_PROCS;
QGL_DESKTOP_1_1_FIXED_FUNCTION_PROCS;
QGL_ES_1_1_PROCS;
QGL_ES_1_1_FIXED_FUNCTION_PROCS;
QGL_1_3_PROCS;
QGL_1_5_PROCS;
QGL_2_0_PROCS;
QGL_3_0_PROCS;
QGL_ARB_occlusion_query_PROCS;
QGL_ARB_framebuffer_object_PROCS;
QGL_ARB_vertex_array_object_PROCS;
QGL_EXT_direct_state_access_PROCS;


+ 2
- 1
code/renderercommon/tr_common.h View File

@@ -80,6 +80,7 @@ extern glconfig_t glConfig; // outside of TR since it shouldn't be cleared duri
extern qboolean textureFilterAnisotropic;
extern int maxAnisotropy;
extern float displayAspect;
extern qboolean haveClampToEdge;

//
// cvars
@@ -155,7 +156,7 @@ IMPLEMENTATION SPECIFIC FUNCTIONS
====================================================================
*/

void GLimp_Init( qboolean );
void GLimp_Init( qboolean fixedFunction );
void GLimp_Shutdown( void );
void GLimp_EndFrame( void );



+ 3
- 19
code/renderergl1/tr_backend.c View File

@@ -759,25 +759,9 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
ri.Error (ERR_DROP, "Draw_StretchRaw: size not a power of 2: %i by %i", cols, rows);
}

RE_UploadCinematic (w, h, cols, rows, data, client, dirty);
GL_Bind( tr.scratchImage[client] );

// if the scratchImage isn't in the format we want, specify it as a new texture
if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
} else {
if (dirty) {
// otherwise, just subimage upload it so that drivers can tell we are going to be changing
// it and don't try and do a texture compression
qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
}
}

if ( r_speeds->integer ) {
end = ri.Milliseconds();
ri.Printf( PRINT_ALL, "qglTexSubImage2D %i, %i: %i msec\n", cols, rows, end - start );
@@ -810,8 +794,8 @@ void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int
qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, haveClampToEdge ? GL_CLAMP_TO_EDGE : GL_CLAMP );
qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, haveClampToEdge ? GL_CLAMP_TO_EDGE : GL_CLAMP );
} else {
if (dirty) {
// otherwise, just subimage upload it so that drivers can tell we are going to be changing


+ 3
- 9
code/renderergl1/tr_image.c View File

@@ -206,7 +206,6 @@ void R_ImageList_f( void ) {
estSize *= 4;
break;
case GL_LUMINANCE8:
case GL_LUMINANCE16:
case GL_LUMINANCE:
format = "L ";
// 1 byte per pixel?
@@ -219,7 +218,6 @@ void R_ImageList_f( void ) {
estSize *= 3;
break;
case GL_LUMINANCE8_ALPHA8:
case GL_LUMINANCE16_ALPHA16:
case GL_LUMINANCE_ALPHA:
format = "LA ";
// 2 bytes per pixel?
@@ -684,10 +682,8 @@ static void Upload32( unsigned *data,
{
if(r_greyscale->integer)
{
if(r_texturebits->integer == 16)
if(r_texturebits->integer == 16 || r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE8;
else if(r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE16;
else
internalFormat = GL_LUMINANCE;
}
@@ -719,10 +715,8 @@ static void Upload32( unsigned *data,
{
if(r_greyscale->integer)
{
if(r_texturebits->integer == 16)
if(r_texturebits->integer == 16 || r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE8_ALPHA8;
else if(r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE16_ALPHA16;
else
internalFormat = GL_LUMINANCE_ALPHA;
}
@@ -872,7 +866,7 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height,
image->width = width;
image->height = height;
if (flags & IMGFLAG_CLAMPTOEDGE)
glWrapClampMode = GL_CLAMP_TO_EDGE;
glWrapClampMode = haveClampToEdge ? GL_CLAMP_TO_EDGE : GL_CLAMP;
else
glWrapClampMode = GL_REPEAT;



+ 7
- 6
code/renderergl1/tr_init.c View File

@@ -27,6 +27,7 @@ glconfig_t glConfig;
qboolean textureFilterAnisotropic = qfalse;
int maxAnisotropy = 0;
float displayAspect = 0.0f;
qboolean haveClampToEdge = qfalse;

glstate_t glState;

@@ -178,8 +179,6 @@ int max_polyverts;
*/
static void InitOpenGL( void )
{
char renderer_buffer[1024];

//
// initialize OS specific portions of the renderer
//
@@ -195,10 +194,7 @@ static void InitOpenGL( void )
{
GLint temp;
GLimp_Init( qfalse );

strcpy( renderer_buffer, glConfig.renderer_string );
Q_strlwr( renderer_buffer );
GLimp_Init( qtrue );

// OpenGL driver constants
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
@@ -1303,6 +1299,11 @@ void RE_Shutdown( qboolean destroyWindow ) {
GLimp_Shutdown();

Com_Memset( &glConfig, 0, sizeof( glConfig ) );
textureFilterAnisotropic = qfalse;
maxAnisotropy = 0;
displayAspect = 0.0f;
haveClampToEdge = qfalse;

Com_Memset( &glState, 0, sizeof( glState ) );
}



+ 29
- 8
code/renderergl1/tr_local.h View File

@@ -32,6 +32,14 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../renderercommon/iqm.h"
#include "../renderercommon/qgl.h"

#define GLE(ret, name, ...) extern name##proc * qgl##name;
QGL_1_1_PROCS;
QGL_1_1_FIXED_FUNCTION_PROCS;
QGL_DESKTOP_1_1_PROCS;
QGL_DESKTOP_1_1_FIXED_FUNCTION_PROCS;
QGL_3_0_PROCS;
#undef GLE

#define GL_INDEX_TYPE GL_UNSIGNED_INT
typedef unsigned int glIndex_t;

@@ -581,6 +589,12 @@ typedef struct {
drawVert_t *verts;
} srfTriangles_t;

typedef struct {
vec3_t translate;
quat_t rotate;
vec3_t scale;
} iqmTransform_t;

// inter-quake-model
typedef struct {
int num_vertexes;
@@ -591,28 +605,34 @@ typedef struct {
int num_poses;
struct srfIQModel_s *surfaces;

int *triangles;

// vertex arrays
float *positions;
float *texcoords;
float *normals;
float *tangents;
byte *blendIndexes;
byte *colors;
int *influences; // [num_vertexes] indexes into influenceBlendVertexes

// unique list of vertex blend indexes/weights for faster CPU vertex skinning
byte *influenceBlendIndexes; // [num_influences]
union {
float *f;
byte *b;
} blendWeights;
byte *colors;
int *triangles;
} influenceBlendWeights; // [num_influences]

// depending upon the exporter, blend indices and weights might be int/float
// as opposed to the recommended byte/byte, for example Noesis exports
// int/float whereas the official IQM tool exports byte/byte
byte blendWeightsType; // IQM_UBYTE or IQM_FLOAT
int blendWeightsType; // IQM_UBYTE or IQM_FLOAT

char *jointNames;
int *jointParents;
float *jointMats;
float *poseMats;
float *bindJoints; // [num_joints * 12]
float *invBindJoints; // [num_joints * 12]
iqmTransform_t *poses; // [num_frames * num_poses]
float *bounds;
char *names;
} iqmData_t;

// inter-quake-model surface
@@ -623,6 +643,7 @@ typedef struct srfIQModel_s {
iqmData_t *data;
int first_vertex, num_vertexes;
int first_triangle, num_triangles;
int first_influence, num_influences;
} srfIQModel_t;




+ 815
- 505
code/renderergl1/tr_model_iqm.c
File diff suppressed because it is too large
View File


+ 1
- 1
code/renderergl2/glsl/calclevels4x_fp.glsl View File

@@ -56,5 +56,5 @@ void main()
current.y *= 0.0625;
#endif

gl_FragColor = vec4(current, 1.0f);
gl_FragColor = vec4(current, 1.0);
}

+ 14
- 0
code/renderergl2/glsl/fogpass_vp.glsl View File

@@ -6,6 +6,9 @@ attribute vec4 attr_TexCoord0;
#if defined(USE_VERTEX_ANIMATION)
attribute vec3 attr_Position2;
attribute vec3 attr_Normal2;
#elif defined(USE_BONE_ANIMATION)
attribute vec4 attr_BoneIndexes;
attribute vec4 attr_BoneWeights;
#endif

uniform vec4 u_FogDistance;
@@ -22,6 +25,8 @@ uniform mat4 u_ModelViewProjectionMatrix;

#if defined(USE_VERTEX_ANIMATION)
uniform float u_VertexLerp;
#elif defined(USE_BONE_ANIMATION)
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
#endif

uniform vec4 u_Color;
@@ -102,6 +107,15 @@ void main()
#if defined(USE_VERTEX_ANIMATION)
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
#elif defined(USE_BONE_ANIMATION)
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));

vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
vec3 normal = normalize(nrmMat * attr_Normal);
#else
vec3 position = attr_Position;
vec3 normal = attr_Normal;


+ 14
- 0
code/renderergl2/glsl/generic_vp.glsl View File

@@ -4,6 +4,9 @@ attribute vec3 attr_Normal;
#if defined(USE_VERTEX_ANIMATION)
attribute vec3 attr_Position2;
attribute vec3 attr_Normal2;
#elif defined(USE_BONE_ANIMATION)
attribute vec4 attr_BoneIndexes;
attribute vec4 attr_BoneWeights;
#endif

attribute vec4 attr_Color;
@@ -54,6 +57,8 @@ uniform float u_PortalRange;

#if defined(USE_VERTEX_ANIMATION)
uniform float u_VertexLerp;
#elif defined(USE_BONE_ANIMATION)
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
#endif

varying vec2 var_DiffuseTex;
@@ -204,6 +209,15 @@ void main()
#if defined(USE_VERTEX_ANIMATION)
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
#elif defined(USE_BONE_ANIMATION)
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));

vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
vec3 normal = normalize(nrmMat * attr_Normal);
#else
vec3 position = attr_Position;
vec3 normal = attr_Normal;


+ 78
- 1
code/renderergl2/glsl/lightall_fp.glsl View File

@@ -143,6 +143,35 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap)

return bestDepth;
}

float LightRay(vec2 dp, vec2 ds, sampler2D normalMap)
{
const int linearSearchSteps = 16;

// current size of search window
float size = 1.0 / float(linearSearchSteps);

// current height from initial texel depth
float height = 0.0;

float startDepth = SampleDepth(normalMap, dp);

// find a collision or escape
for(int i = 0; i < linearSearchSteps - 1; ++i)
{
height += size;

if (startDepth < height)
return 1.0;
float t = SampleDepth(normalMap, dp + ds * height);

if (startDepth > t + height)
return 0.0;
}

return 1.0;
}
#endif

vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness)
@@ -193,6 +222,37 @@ float CalcLightAttenuation(float point, float normDist)
return attenuation;
}

#if defined(USE_BOX_CUBEMAP_PARALLAX)
vec4 hitCube(vec3 ray, vec3 pos, vec3 invSize, float lod, samplerCube tex)
{
// find any hits on cubemap faces facing the camera
vec3 scale = (sign(ray) - pos) / ray;

// find the nearest hit
float minScale = min(min(scale.x, scale.y), scale.z);

// if the nearest hit is behind the camera, ignore
// should not be necessary as long as pos is inside the cube
//if (minScale < 0.0)
//return vec4(0.0);

// calculate the hit position, that's our texture coordinates
vec3 tc = pos + ray * minScale;

// if the texture coordinates are outside the cube, ignore
// necessary since we're not fading out outside the cube
if (any(greaterThan(abs(tc), vec3(1.00001))))
return vec4(0.0);

// fade out when approaching the cubemap edges
//vec3 fade3 = abs(pos);
//float fade = max(max(fade3.x, fade3.y), fade3.z);
//fade = clamp(1.0 - fade, 0.0, 1.0);
//return vec4(textureCubeLod(tex, tc, lod).rgb * fade, fade);
return vec4(textureCubeLod(tex, tc, lod).rgb, 1.0);
}
#endif

void main()
{
@@ -222,7 +282,7 @@ void main()
vec2 texCoords = var_TexCoords.xy;

#if defined(USE_PARALLAXMAP)
vec3 offsetDir = viewDir * tangentToWorld;
vec3 offsetDir = E * tangentToWorld;

offsetDir.xy *= -u_NormalScale.a / offsetDir.z;

@@ -289,6 +349,13 @@ void main()
#endif
#endif

#if defined(USE_PARALLAXMAP) && defined(USE_PARALLAXMAP_SHADOWS)
offsetDir = L * tangentToWorld;
offsetDir.xy *= u_NormalScale.a / offsetDir.z;
lightColor *= LightRay(texCoords, offsetDir.xy, u_NormalMap);
#endif


#if !defined(USE_LIGHT_VECTOR)
ambientColor = lightColor;
float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0);
@@ -374,7 +441,11 @@ void main()
// from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir;

#if defined(USE_BOX_CUBEMAP_PARALLAX)
vec3 cubeLightColor = hitCube(R * u_CubeMapInfo.w, parallax, u_CubeMapInfo.www, ROUGHNESS_MIPS * roughness, u_CubeMap).rgb * u_EnableTextures.w;
#else
vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, ROUGHNESS_MIPS * roughness).rgb * u_EnableTextures.w;
#endif

// normalize cubemap based on last roughness mip (~diffuse)
// multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation
@@ -423,6 +494,12 @@ void main()
// enable when point lights are supported as primary lights
//lightColor *= CalcLightAttenuation(float(u_PrimaryLightDir.w > 0.0), u_PrimaryLightDir.w / sqrLightDist);

#if defined(USE_PARALLAXMAP) && defined(USE_PARALLAXMAP_SHADOWS)
offsetDir = L2 * tangentToWorld;
offsetDir.xy *= u_NormalScale.a / offsetDir.z;
lightColor *= LightRay(texCoords, offsetDir.xy, u_NormalMap);
#endif

gl_FragColor.rgb += lightColor * reflectance * NL2;
#endif



+ 17
- 0
code/renderergl2/glsl/lightall_vp.glsl View File

@@ -12,6 +12,9 @@ attribute vec4 attr_Tangent;
attribute vec3 attr_Position2;
attribute vec3 attr_Normal2;
attribute vec4 attr_Tangent2;
#elif defined(USE_BONE_ANIMATION)
attribute vec4 attr_BoneIndexes;
attribute vec4 attr_BoneWeights;
#endif

#if defined(USE_LIGHT) && !defined(USE_LIGHT_VECTOR)
@@ -48,6 +51,8 @@ uniform mat4 u_ModelMatrix;

#if defined(USE_VERTEX_ANIMATION)
uniform float u_VertexLerp;
#elif defined(USE_BONE_ANIMATION)
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
#endif

#if defined(USE_LIGHT_VECTOR)
@@ -151,6 +156,18 @@ void main()
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 tangent = mix(attr_Tangent.xyz, attr_Tangent2.xyz, u_VertexLerp);
#endif
#elif defined(USE_BONE_ANIMATION)
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));

vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
vec3 normal = normalize(nrmMat * attr_Normal);
#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)
vec3 tangent = normalize(nrmMat * attr_Tangent.xyz);
#endif
#else
vec3 position = attr_Position;
vec3 normal = attr_Normal;


+ 23
- 4
code/renderergl2/glsl/shadowfill_vp.glsl View File

@@ -2,10 +2,13 @@ attribute vec3 attr_Position;
attribute vec3 attr_Normal;
attribute vec4 attr_TexCoord0;

//#if defined(USE_VERTEX_ANIMATION)
#if defined(USE_VERTEX_ANIMATION)
attribute vec3 attr_Position2;
attribute vec3 attr_Normal2;
//#endif
#elif defined(USE_BONE_ANIMATION)
attribute vec4 attr_BoneIndexes;
attribute vec4 attr_BoneWeights;
#endif

//#if defined(USE_DEFORM_VERTEXES)
uniform int u_DeformGen;
@@ -17,9 +20,11 @@ uniform mat4 u_ModelViewProjectionMatrix;

uniform mat4 u_ModelMatrix;

//#if defined(USE_VERTEX_ANIMATION)
#if defined(USE_VERTEX_ANIMATION)
uniform float u_VertexLerp;
//#endif
#elif defined(USE_BONE_ANIMATION)
uniform mat4 u_BoneMatrix[MAX_GLSL_BONES];
#endif

varying vec3 var_Position;

@@ -78,8 +83,22 @@ vec3 DeformPosition(const vec3 pos, const vec3 normal, const vec2 st)

void main()
{
#if defined(USE_VERTEX_ANIMATION)
vec3 position = mix(attr_Position, attr_Position2, u_VertexLerp);
vec3 normal = mix(attr_Normal, attr_Normal2, u_VertexLerp);
#elif defined(USE_BONE_ANIMATION)
mat4 vtxMat = u_BoneMatrix[int(attr_BoneIndexes.x)] * attr_BoneWeights.x;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.y)] * attr_BoneWeights.y;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.z)] * attr_BoneWeights.z;
vtxMat += u_BoneMatrix[int(attr_BoneIndexes.w)] * attr_BoneWeights.w;
mat3 nrmMat = mat3(cross(vtxMat[1].xyz, vtxMat[2].xyz), cross(vtxMat[2].xyz, vtxMat[0].xyz), cross(vtxMat[0].xyz, vtxMat[1].xyz));

vec3 position = vec3(vtxMat * vec4(attr_Position, 1.0));
vec3 normal = normalize(nrmMat * attr_Normal);
#else
vec3 position = attr_Position;
vec3 normal = attr_Normal;
#endif

position = DeformPosition(position, normal, attr_TexCoord0.st);



+ 1
- 1
code/renderergl2/glsl/ssao_fp.glsl View File

@@ -61,7 +61,7 @@ float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZN
poissonDisc[7] = vec2(-0.5579782, 0.7491854);
poissonDisc[8] = vec2(0.7320465, 0.6317794);

float result = 0;
float result = 0.0;

float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear);
float scaleZ = zFarDivZNear * sampleZ;


+ 1
- 7
code/renderergl2/tr_backend.c View File

@@ -58,7 +58,7 @@ void GL_BindToTMU( image_t *image, int tmu )
ri.Printf(PRINT_WARNING, "GL_BindToTMU: NULL image\n");
}

GL_BindMultiTexture(GL_TEXTURE0_ARB + tmu, target, texture);
GL_BindMultiTexture(GL_TEXTURE0 + tmu, target, texture);
}


@@ -435,7 +435,6 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
int oldSort;
double originalTime;
FBO_t* fbo = NULL;
qboolean inQuery = qfalse;

// save original time for entity shader offsets
originalTime = backEnd.refdef.floatTime;
@@ -593,10 +592,6 @@ void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
RB_EndSurface();
}

if (inQuery) {
qglEndQuery(GL_SAMPLES_PASSED);
}

if (glRefConfig.framebufferObject)
FBO_Bind(fbo);

@@ -657,7 +652,6 @@ void RB_SetGL2D (void) {
GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );

GL_Cull( CT_TWO_SIDED );
qglDisable( GL_CLIP_PLANE0 );

// set time for 2D shaders
backEnd.refdef.time = ri.Milliseconds();


+ 2
- 2
code/renderergl2/tr_cmds.c View File

@@ -203,11 +203,11 @@ void R_AddCapShadowmapCmd( int map, int cubeSide ) {

/*
=============
R_PostProcessingCmd
R_AddPostProcessCmd

=============
*/
void R_AddPostProcessCmd( ) {
void R_AddPostProcessCmd( void ) {
postProcessCommand_t *cmd;

cmd = R_GetCommandBuffer( sizeof( *cmd ) );


+ 3
- 3
code/renderergl2/tr_dsa.c View File

@@ -35,7 +35,7 @@ static struct
}
glDsaState;

void GL_BindNullTextures()
void GL_BindNullTextures(void)
{
int i;

@@ -141,7 +141,7 @@ GLvoid APIENTRY GLDSA_GenerateTextureMipmapEXT(GLuint texture, GLenum target)
qglGenerateMipmap(target);
}

void GL_BindNullProgram()
void GL_BindNullProgram(void)
{
qglUseProgram(0);
glDsaState.program = 0;
@@ -205,7 +205,7 @@ GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fvEXT(GLuint program, GLint location,
qglUniformMatrix4fv(location, count, transpose, value);
}

void GL_BindNullFramebuffers()
void GL_BindNullFramebuffers(void)
{
qglBindFramebuffer(GL_FRAMEBUFFER, 0);
glDsaState.drawFramebuffer = glDsaState.readFramebuffer = 0;


+ 3
- 23
code/renderergl2/tr_extensions.c View File

@@ -30,27 +30,13 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "tr_local.h"
#include "tr_dsa.h"

#define GLE(ret, name, ...) name##proc * qgl##name;
QGL_1_3_PROCS;
QGL_1_5_PROCS;
QGL_2_0_PROCS;
QGL_ARB_framebuffer_object_PROCS;
QGL_ARB_vertex_array_object_PROCS;
QGL_EXT_direct_state_access_PROCS;
#undef GLE

void GLimp_InitExtraExtensions()
void GLimp_InitExtraExtensions(void)
{
char *extension;
const char* result[3] = { "...ignoring %s\n", "...using %s\n", "...%s not found\n" };
qboolean q_gl_version_at_least_3_0;
qboolean q_gl_version_at_least_3_2;

// Check OpenGL version
if ( !QGL_VERSION_ATLEAST( 2, 0 ) )
ri.Error(ERR_FATAL, "OpenGL 2.0 required!");
ri.Printf(PRINT_ALL, "...using OpenGL %s\n", glConfig.version_string);

q_gl_version_at_least_3_0 = QGL_VERSION_ATLEAST( 3, 0 );
q_gl_version_at_least_3_2 = QGL_VERSION_ATLEAST( 3, 2 );

@@ -67,15 +53,9 @@ void GLimp_InitExtraExtensions()
// GL function loader, based on https://gist.github.com/rygorous/16796a0c876cf8a5f542caddb55bce8a
#define GLE(ret, name, ...) qgl##name = (name##proc *) SDL_GL_GetProcAddress("gl" #name);

// OpenGL 1.3, was GL_ARB_texture_compression
QGL_1_3_PROCS;

// OpenGL 1.5, was GL_ARB_vertex_buffer_object and GL_ARB_occlusion_query
QGL_1_5_PROCS;
// OpenGL 1.5 - GL_ARB_occlusion_query
glRefConfig.occlusionQuery = qtrue;

// OpenGL 2.0, was GL_ARB_shading_language_100, GL_ARB_vertex_program, GL_ARB_shader_objects, and GL_ARB_vertex_shader
QGL_2_0_PROCS;
QGL_ARB_occlusion_query_PROCS;

// OpenGL 3.0 - GL_ARB_framebuffer_object
extension = "GL_ARB_framebuffer_object";


+ 0
- 4
code/renderergl2/tr_flares.c View File

@@ -526,10 +526,6 @@ void RB_RenderFlares (void) {
return; // none visible
}

if ( backEnd.viewParms.isPortal ) {
qglDisable (GL_CLIP_PLANE0);
}

Mat4Copy(glState.projection, oldprojection);
Mat4Copy(glState.modelview, oldmodelview);
Mat4Identity(matrix);


+ 129
- 24
code/renderergl2/tr_glsl.c View File

@@ -148,6 +148,8 @@ static uniformInfo_t uniformsInfo[] =
{ "u_CubeMapInfo", GLSL_VEC4 },

{ "u_AlphaTest", GLSL_INT },

{ "u_BoneMatrix", GLSL_MAT16_BONEMATRIX },
};

typedef enum
@@ -331,17 +333,6 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLchar *extra, char *
AGEN_LIGHTING_SPECULAR,
AGEN_PORTAL));

Q_strcat(dest, size,
va("#ifndef texenv_t\n"
"#define texenv_t\n"
"#define TEXENV_MODULATE %i\n"
"#define TEXENV_ADD %i\n"
"#define TEXENV_REPLACE %i\n"
"#endif\n",
GL_MODULATE,
GL_ADD,
GL_REPLACE));

fbufWidthScale = 1.0f / ((float)glConfig.vidWidth);
fbufHeightScale = 1.0f / ((float)glConfig.vidHeight);
Q_strcat(dest, size,
@@ -566,6 +557,12 @@ static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int
if(attribs & ATTR_LIGHTDIRECTION)
qglBindAttribLocation(program->program, ATTR_INDEX_LIGHTDIRECTION, "attr_LightDirection");

if(attribs & ATTR_BONE_INDEXES)
qglBindAttribLocation(program->program, ATTR_INDEX_BONE_INDEXES, "attr_BoneIndexes");

if(attribs & ATTR_BONE_WEIGHTS)
qglBindAttribLocation(program->program, ATTR_INDEX_BONE_WEIGHTS, "attr_BoneWeights");

if(attribs & ATTR_POSITION2)
qglBindAttribLocation(program->program, ATTR_INDEX_POSITION2, "attr_Position2");

@@ -671,6 +668,9 @@ void GLSL_InitUniforms(shaderProgram_t *program)
case GLSL_MAT16:
size += sizeof(vec_t) * 16;
break;
case GLSL_MAT16_BONEMATRIX:
size += sizeof(vec_t) * 16 * glRefConfig.glslMaxAnimatedBones;
break;
default:
break;
}
@@ -854,6 +854,38 @@ void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t
qglProgramUniformMatrix4fvEXT(program->program, uniforms[uniformNum], 1, GL_FALSE, matrix);
}

void GLSL_SetUniformMat4BoneMatrix(shaderProgram_t *program, int uniformNum, /*const*/ mat4_t *matrix, int numMatricies)
{
GLint *uniforms = program->uniforms;
vec_t *compare = (float *)(program->uniformBuffer + program->uniformBufferOffsets[uniformNum]);

if (uniforms[uniformNum] == -1) {
return;
}

if (uniformsInfo[uniformNum].type != GLSL_MAT16_BONEMATRIX)
{
ri.Printf( PRINT_WARNING, "GLSL_SetUniformMat4BoneMatrix: wrong type for uniform %i in program %s\n", uniformNum, program->name);
return;
}

if (numMatricies > glRefConfig.glslMaxAnimatedBones)
{
ri.Printf( PRINT_WARNING, "GLSL_SetUniformMat4BoneMatrix: too many matricies (%d/%d) for uniform %i in program %s\n",
numMatricies, glRefConfig.glslMaxAnimatedBones, uniformNum, program->name);
return;
}

if (!memcmp(matrix, compare, numMatricies * sizeof(mat4_t)))
{
return;
}

Com_Memcpy(compare, matrix, numMatricies * sizeof(mat4_t));

qglProgramUniformMatrix4fvEXT(program->program, uniforms[uniformNum], numMatricies, GL_FALSE, &matrix[0][0]);
}

void GLSL_DeleteGPUShader(shaderProgram_t *program)
{
if(program->program)
@@ -897,6 +929,12 @@ void GLSL_InitGPUShaders(void)

for (i = 0; i < GENERICDEF_COUNT; i++)
{
if ((i & GENERICDEF_USE_VERTEX_ANIMATION) && (i & GENERICDEF_USE_BONE_ANIMATION))
continue;

if ((i & GENERICDEF_USE_BONE_ANIMATION) && !glRefConfig.glslMaxAnimatedBones)
continue;

attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_NORMAL | ATTR_COLOR;
extradefines[0] = '\0';

@@ -914,6 +952,11 @@ void GLSL_InitGPUShaders(void)
Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n");
attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
}
else if (i & GENERICDEF_USE_BONE_ANIMATION)
{
Q_strcat(extradefines, 1024, va("#define USE_BONE_ANIMATION\n#define MAX_GLSL_BONES %d\n", glRefConfig.glslMaxAnimatedBones));
attribs |= ATTR_BONE_INDEXES | ATTR_BONE_WEIGHTS;
}

if (i & GENERICDEF_USE_FOG)
Q_strcat(extradefines, 1024, "#define USE_FOG\n");
@@ -954,14 +997,28 @@ void GLSL_InitGPUShaders(void)

for (i = 0; i < FOGDEF_COUNT; i++)
{
attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD;
if ((i & FOGDEF_USE_VERTEX_ANIMATION) && (i & FOGDEF_USE_BONE_ANIMATION))
continue;

if ((i & FOGDEF_USE_BONE_ANIMATION) && !glRefConfig.glslMaxAnimatedBones)
continue;

attribs = ATTR_POSITION | ATTR_NORMAL | ATTR_TEXCOORD;
extradefines[0] = '\0';

if (i & FOGDEF_USE_DEFORM_VERTEXES)
Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n");

if (i & FOGDEF_USE_VERTEX_ANIMATION)
{
Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n");
attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
}
else if (i & FOGDEF_USE_BONE_ANIMATION)
{
Q_strcat(extradefines, 1024, va("#define USE_BONE_ANIMATION\n#define MAX_GLSL_BONES %d\n", glRefConfig.glslMaxAnimatedBones));
attribs |= ATTR_BONE_INDEXES | ATTR_BONE_WEIGHTS;
}

if (!GLSL_InitGPUShader(&tr.fogShader[i], "fogpass", attribs, qtrue, extradefines, qtrue, fallbackShader_fogpass_vp, fallbackShader_fogpass_fp))
{
@@ -1012,6 +1069,12 @@ void GLSL_InitGPUShaders(void)
if ((i & LIGHTDEF_USE_SHADOWMAP) && (!lightType || !r_sunlightMode->integer))
continue;

if ((i & LIGHTDEF_ENTITY_VERTEX_ANIMATION) && (i & LIGHTDEF_ENTITY_BONE_ANIMATION))
continue;

if ((i & LIGHTDEF_ENTITY_BONE_ANIMATION) && !glRefConfig.glslMaxAnimatedBones)
continue;

attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR | ATTR_NORMAL;

extradefines[0] = '\0';
@@ -1054,11 +1117,14 @@ void GLSL_InitGPUShaders(void)

attribs |= ATTR_TANGENT;

if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY_VERTEX_ANIMATION) && !(i & LIGHTDEF_ENTITY_BONE_ANIMATION) && r_parallaxMapping->integer)
{
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
if (r_parallaxMapping->integer > 1)
Q_strcat(extradefines, 1024, "#define USE_RELIEFMAP\n");

if (r_parallaxMapShadows->integer)
Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP_SHADOWS\n");
}
}

@@ -1066,9 +1132,15 @@ void GLSL_InitGPUShaders(void)
Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n");

if (r_cubeMapping->integer)
{
Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
if (r_cubeMapping->integer == 2)
Q_strcat(extradefines, 1024, "#define USE_BOX_CUBEMAP_PARALLAX\n");
}
else if (r_deluxeSpecular->value > 0.000001f)
{
Q_strcat(extradefines, 1024, va("#define r_deluxeSpecular %f\n", r_deluxeSpecular->value));
}

switch (r_glossType->integer)
{
@@ -1104,7 +1176,7 @@ void GLSL_InitGPUShaders(void)
Q_strcat(extradefines, 1024, "#define USE_TCMOD\n");
}

if (i & LIGHTDEF_ENTITY)
if (i & LIGHTDEF_ENTITY_VERTEX_ANIMATION)
{
Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n#define USE_MODELMATRIX\n");
attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
@@ -1114,6 +1186,12 @@ void GLSL_InitGPUShaders(void)
attribs |= ATTR_TANGENT2;
}
}
else if (i & LIGHTDEF_ENTITY_BONE_ANIMATION)
{
Q_strcat(extradefines, 1024, "#define USE_MODELMATRIX\n");
Q_strcat(extradefines, 1024, va("#define USE_BONE_ANIMATION\n#define MAX_GLSL_BONES %d\n", glRefConfig.glslMaxAnimatedBones));
attribs |= ATTR_BONE_INDEXES | ATTR_BONE_WEIGHTS;
}

if (!GLSL_InitGPUShader(&tr.lightallShader[i], "lightall", attribs, qtrue, extradefines, qtrue, fallbackShader_lightall_vp, fallbackShader_lightall_fp))
{
@@ -1135,19 +1213,40 @@ void GLSL_InitGPUShaders(void)
numLightShaders++;
}

attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD;
for (i = 0; i < SHADOWMAPDEF_COUNT; i++)
{
if ((i & SHADOWMAPDEF_USE_VERTEX_ANIMATION) && (i & SHADOWMAPDEF_USE_BONE_ANIMATION))
continue;

extradefines[0] = '\0';
if ((i & SHADOWMAPDEF_USE_BONE_ANIMATION) && !glRefConfig.glslMaxAnimatedBones)
continue;

if (!GLSL_InitGPUShader(&tr.shadowmapShader, "shadowfill", attribs, qtrue, extradefines, qtrue, fallbackShader_shadowfill_vp, fallbackShader_shadowfill_fp))
{
ri.Error(ERR_FATAL, "Could not load shadowfill shader!");
}
attribs = ATTR_POSITION | ATTR_NORMAL | ATTR_TEXCOORD;

GLSL_InitUniforms(&tr.shadowmapShader);
GLSL_FinishGPUShader(&tr.shadowmapShader);
extradefines[0] = '\0';

numEtcShaders++;
if (i & SHADOWMAPDEF_USE_VERTEX_ANIMATION)
{
Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n");
attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
}

if (i & SHADOWMAPDEF_USE_BONE_ANIMATION)
{
Q_strcat(extradefines, 1024, va("#define USE_BONE_ANIMATION\n#define MAX_GLSL_BONES %d\n", glRefConfig.glslMaxAnimatedBones));
attribs |= ATTR_BONE_INDEXES | ATTR_BONE_WEIGHTS;
}

if (!GLSL_InitGPUShader(&tr.shadowmapShader[i], "shadowfill", attribs, qtrue, extradefines, qtrue, fallbackShader_shadowfill_vp, fallbackShader_shadowfill_fp))
{
ri.Error(ERR_FATAL, "Could not load shadowfill shader!");
}

GLSL_InitUniforms(&tr.shadowmapShader[i]);
GLSL_FinishGPUShader(&tr.shadowmapShader[i]);

numEtcShaders++;
}

attribs = ATTR_POSITION | ATTR_NORMAL;
extradefines[0] = '\0';
@@ -1374,7 +1473,9 @@ void GLSL_ShutdownGPUShaders(void)
for ( i = 0; i < LIGHTDEF_COUNT; i++)
GLSL_DeleteGPUShader(&tr.lightallShader[i]);

GLSL_DeleteGPUShader(&tr.shadowmapShader);
for ( i = 0; i < SHADOWMAPDEF_COUNT; i++)
GLSL_DeleteGPUShader(&tr.shadowmapShader[i]);

GLSL_DeleteGPUShader(&tr.pshadowShader);
GLSL_DeleteGPUShader(&tr.down4xShader);
GLSL_DeleteGPUShader(&tr.bokehShader);
@@ -1450,6 +1551,10 @@ shaderProgram_t *GLSL_GetGenericShaderProgram(int stage)
{
shaderAttribs |= GENERICDEF_USE_VERTEX_ANIMATION;
}
else if (glState.boneAnimation)
{
shaderAttribs |= GENERICDEF_USE_BONE_ANIMATION;
}

if (pStage->bundle[0].numTexMods)
{


+ 2
- 8
code/renderergl2/tr_image.c View File

@@ -222,7 +222,6 @@ void R_ImageList_f( void ) {
estSize *= 4;
break;
case GL_LUMINANCE8:
case GL_LUMINANCE16:
case GL_LUMINANCE:
format = "L ";
// 1 byte per pixel?
@@ -235,7 +234,6 @@ void R_ImageList_f( void ) {
estSize *= 3;
break;
case GL_LUMINANCE8_ALPHA8:
case GL_LUMINANCE16_ALPHA16:
case GL_LUMINANCE_ALPHA:
format = "LA ";
// 2 bytes per pixel?
@@ -1724,10 +1722,8 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, GLenum picForm
{
if(r_greyscale->integer)
{
if(r_texturebits->integer == 16)
if(r_texturebits->integer == 16 || r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE8;
else if(r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE16;
else
internalFormat = GL_LUMINANCE;
}
@@ -1763,10 +1759,8 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, GLenum picForm
{
if(r_greyscale->integer)
{
if(r_texturebits->integer == 16)
if(r_texturebits->integer == 16 || r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE8_ALPHA8;
else if(r_texturebits->integer == 32)
internalFormat = GL_LUMINANCE16_ALPHA16;
else
internalFormat = GL_LUMINANCE_ALPHA;
}


+ 28
- 6
code/renderergl2/tr_init.c View File

@@ -30,6 +30,7 @@ glRefConfig_t glRefConfig;
qboolean textureFilterAnisotropic = qfalse;
int maxAnisotropy = 0;
float displayAspect = 0.0f;
qboolean haveClampToEdge = qfalse;

glstate_t glState;

@@ -131,6 +132,7 @@ cvar_t *r_normalMapping;
cvar_t *r_specularMapping;
cvar_t *r_deluxeMapping;
cvar_t *r_parallaxMapping;
cvar_t *r_parallaxMapShadows;
cvar_t *r_cubeMapping;
cvar_t *r_cubemapSize;
cvar_t *r_deluxeSpecular;
@@ -243,8 +245,6 @@ int max_polyverts;
*/
static void InitOpenGL( void )
{
char renderer_buffer[1024];

//
// initialize OS specific portions of the renderer
//
@@ -260,11 +260,10 @@ static void InitOpenGL( void )
{
GLint temp;
GLimp_Init( qtrue );
GLimp_Init( qfalse );
GLimp_InitExtraExtensions();

strcpy( renderer_buffer, glConfig.renderer_string );
Q_strlwr( renderer_buffer );
glConfig.textureEnvAddAvailable = qtrue;

// OpenGL driver constants
qglGetIntegerv( GL_MAX_TEXTURE_SIZE, &temp );
@@ -275,6 +274,22 @@ static void InitOpenGL( void )
{
glConfig.maxTextureSize = 0;
}

qglGetIntegerv( GL_MAX_TEXTURE_IMAGE_UNITS, &temp );
glConfig.numTextureUnits = temp;

// reserve 160 components for other uniforms
qglGetIntegerv( GL_MAX_VERTEX_UNIFORM_COMPONENTS, &temp );
glRefConfig.glslMaxAnimatedBones = Com_Clamp( 0, IQM_MAX_JOINTS, ( temp - 160 ) / 16 );
if ( glRefConfig.glslMaxAnimatedBones < 12 ) {
glRefConfig.glslMaxAnimatedBones = 0;
}
}

// check for GLSL function textureCubeLod()
if ( r_cubeMapping->integer && !QGL_VERSION_ATLEAST( 3, 0 ) ) {
ri.Printf( PRINT_WARNING, "WARNING: Disabled r_cubeMapping because it requires OpenGL 3.0\n" );
ri.Cvar_Set( "r_cubeMapping", "0" );
}

// set default state
@@ -1055,7 +1070,7 @@ void GfxInfo_f( void )
}
ri.Printf( PRINT_ALL, "\n" );
ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_SIZE: %d\n", glConfig.maxTextureSize );
ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_UNITS_ARB: %d\n", glConfig.numTextureUnits );
ri.Printf( PRINT_ALL, "GL_MAX_TEXTURE_IMAGE_UNITS: %d\n", glConfig.numTextureUnits );
ri.Printf( PRINT_ALL, "\nPIXELFORMAT: color(%d-bits) Z(%d-bit) stencil(%d-bits)\n", glConfig.colorBits, glConfig.depthBits, glConfig.stencilBits );
ri.Printf( PRINT_ALL, "MODE: %d, %d x %d %s hz:", r_mode->integer, glConfig.vidWidth, glConfig.vidHeight, fsstrings[r_fullscreen->integer == 1] );
if ( glConfig.displayFrequency )
@@ -1235,6 +1250,7 @@ void R_Register( void )
r_specularMapping = ri.Cvar_Get( "r_specularMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH );
r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_parallaxMapShadows = ri.Cvar_Get( "r_parallaxMapShadows", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH );
r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH );
r_deluxeSpecular = ri.Cvar_Get("r_deluxeSpecular", "0.3", CVAR_ARCHIVE | CVAR_LATCH);
@@ -1541,6 +1557,12 @@ void RE_Shutdown( qboolean destroyWindow ) {
GLimp_Shutdown();

Com_Memset( &glConfig, 0, sizeof( glConfig ) );
Com_Memset( &glRefConfig, 0, sizeof( glRefConfig ) );
textureFilterAnisotropic = qfalse;
maxAnisotropy = 0;
displayAspect = 0.0f;
haveClampToEdge = qfalse;

Com_Memset( &glState, 0, sizeof( glState ) );
}



+ 83
- 18
code/renderergl2/tr_local.h View File

@@ -36,6 +36,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "../renderercommon/iqm.h"
#include "../renderercommon/qgl.h"

#define GLE(ret, name, ...) extern name##proc * qgl##name;
QGL_1_1_PROCS;
QGL_DESKTOP_1_1_PROCS;
QGL_1_3_PROCS;
QGL_1_5_PROCS;
QGL_2_0_PROCS;
QGL_3_0_PROCS;
QGL_ARB_occlusion_query_PROCS;
QGL_ARB_framebuffer_object_PROCS;
QGL_ARB_vertex_array_object_PROCS;
QGL_EXT_direct_state_access_PROCS;
#undef GLE

#define GL_INDEX_TYPE GL_UNSIGNED_INT
typedef unsigned int glIndex_t;

@@ -541,16 +554,18 @@ enum
GENERICDEF_USE_VERTEX_ANIMATION = 0x0004,
GENERICDEF_USE_FOG = 0x0008,
GENERICDEF_USE_RGBAGEN = 0x0010,
GENERICDEF_ALL = 0x001F,
GENERICDEF_COUNT = 0x0020,
GENERICDEF_USE_BONE_ANIMATION = 0x0020,
GENERICDEF_ALL = 0x003F,
GENERICDEF_COUNT = 0x0040,
};

enum
{
FOGDEF_USE_DEFORM_VERTEXES = 0x0001,
FOGDEF_USE_VERTEX_ANIMATION = 0x0002,
FOGDEF_ALL = 0x0003,
FOGDEF_COUNT = 0x0004,
FOGDEF_USE_BONE_ANIMATION = 0x0004,
FOGDEF_ALL = 0x0007,
FOGDEF_COUNT = 0x0008,
};

enum
@@ -566,12 +581,21 @@ enum
LIGHTDEF_USE_LIGHT_VECTOR = 0x0002,
LIGHTDEF_USE_LIGHT_VERTEX = 0x0003,
LIGHTDEF_LIGHTTYPE_MASK = 0x0003,
LIGHTDEF_ENTITY = 0x0004,
LIGHTDEF_ENTITY_VERTEX_ANIMATION = 0x0004,
LIGHTDEF_USE_TCGEN_AND_TCMOD = 0x0008,
LIGHTDEF_USE_PARALLAXMAP = 0x0010,
LIGHTDEF_USE_SHADOWMAP = 0x0020,
LIGHTDEF_ALL = 0x003F,
LIGHTDEF_COUNT = 0x0040
LIGHTDEF_ENTITY_BONE_ANIMATION = 0x0040,
LIGHTDEF_ALL = 0x007F,
LIGHTDEF_COUNT = 0x0080
};

enum
{
SHADOWMAPDEF_USE_VERTEX_ANIMATION = 0x0001,
SHADOWMAPDEF_USE_BONE_ANIMATION = 0x0002,
SHADOWMAPDEF_ALL = 0x0003,
SHADOWMAPDEF_COUNT = 0x0004
};

enum
@@ -582,7 +606,8 @@ enum
GLSL_VEC2,
GLSL_VEC3,
GLSL_VEC4,
GLSL_MAT16
GLSL_MAT16,
GLSL_MAT16_BONEMATRIX
};

typedef enum
@@ -673,6 +698,8 @@ typedef enum

UNIFORM_ALPHATEST,

UNIFORM_BONEMATRIX,

UNIFORM_COUNT
} uniform_t;

@@ -836,6 +863,7 @@ typedef enum {
SF_FLARE,
SF_ENTITY, // beams, rails, lightning, etc that can be determined by entity
SF_VAO_MDVMESH,
SF_VAO_IQM,

SF_NUM_SURFACE_TYPES,
SF_MAX = 0x7fffffff // ensures that sizeof( surfaceType_t ) == sizeof( int )
@@ -926,6 +954,12 @@ typedef struct srfBspSurface_s
float *heightLodError;
} srfBspSurface_t;

typedef struct {
vec3_t translate;
quat_t rotate;
vec3_t scale;
} iqmTransform_t;

// inter-quake-model
typedef struct {
int num_vertexes;
@@ -936,28 +970,37 @@ typedef struct {
int num_poses;
struct srfIQModel_s *surfaces;

int *triangles;

// vertex arrays
float *positions;
float *texcoords;
float *normals;
float *tangents;
byte *blendIndexes;
byte *colors;
int *influences; // [num_vertexes] indexes into influenceBlendVertexes

// unique list of vertex blend indexes/weights for faster CPU vertex skinning
byte *influenceBlendIndexes; // [num_influences]
union {
float *f;
byte *b;
} blendWeights;
byte *colors;
int *triangles;
} influenceBlendWeights; // [num_influences]

// depending upon the exporter, blend indices and weights might be int/float
// as opposed to the recommended byte/byte, for example Noesis exports
// int/float whereas the official IQM tool exports byte/byte
byte blendWeightsType; // IQM_UBYTE or IQM_FLOAT
int blendWeightsType; // IQM_UBYTE or IQM_FLOAT

char *jointNames;
int *jointParents;
float *jointMats;
float *poseMats;
float *bindJoints; // [num_joints * 12]
float *invBindJoints; // [num_joints * 12]
iqmTransform_t *poses; // [num_frames * num_poses]
float *bounds;
char *names;

int numVaoSurfaces;
struct srfVaoIQModel_s *vaoSurfaces;
} iqmData_t;

// inter-quake-model surface
@@ -968,8 +1011,24 @@ typedef struct srfIQModel_s {
iqmData_t *data;
int first_vertex, num_vertexes;
int first_triangle, num_triangles;
int first_influence, num_influences;
} srfIQModel_t;

typedef struct srfVaoIQModel_s
{
surfaceType_t surfaceType;

iqmData_t *iqmData;
struct srfIQModel_s *iqmSurface;

// backEnd stats
int numIndexes;
int numVerts;

// static render data
vao_t *vao;
} srfVaoIQModel_t;

typedef struct srfVaoMdvMesh_s
{
surfaceType_t surfaceType;
@@ -1313,6 +1372,8 @@ typedef struct {
uint32_t storedGlState;
float vertexAttribsInterpolation;
qboolean vertexAnimation;
int boneAnimation; // number of bones
mat4_t boneMatrix[IQM_MAX_JOINTS];
uint32_t vertexAttribsEnabled; // global if no VAOs, tess only otherwise
FBO_t *currentFBO;
vao_t *currentVao;
@@ -1342,6 +1403,7 @@ typedef struct {

int glslMajorVersion;
int glslMinorVersion;
int glslMaxAnimatedBones;

memInfo_t memInfo;

@@ -1522,7 +1584,7 @@ typedef struct {
shaderProgram_t fogShader[FOGDEF_COUNT];
shaderProgram_t dlightShader[DLIGHTDEF_COUNT];
shaderProgram_t lightallShader[LIGHTDEF_COUNT];
shaderProgram_t shadowmapShader;
shaderProgram_t shadowmapShader[SHADOWMAPDEF_COUNT];
shaderProgram_t pshadowShader;
shaderProgram_t down4xShader;
shaderProgram_t bokehShader;
@@ -1716,6 +1778,7 @@ extern cvar_t *r_normalMapping;
extern cvar_t *r_specularMapping;
extern cvar_t *r_deluxeMapping;
extern cvar_t *r_parallaxMapping;
extern cvar_t *r_parallaxMapShadows;
extern cvar_t *r_cubeMapping;
extern cvar_t *r_cubemapSize;
extern cvar_t *r_deluxeSpecular;
@@ -2003,7 +2066,7 @@ void RB_EndSurface(void);
void RB_CheckOverflow( int verts, int indexes );
#define RB_CHECKOVERFLOW(v,i) if (tess.numVertexes + (v) >= SHADER_MAX_VERTEXES || tess.numIndexes + (i) >= SHADER_MAX_INDEXES ) {RB_CheckOverflow(v,i);}

void R_DrawElements( int numIndexes, glIndex_t firstIndex );
void R_DrawElements( int numIndexes, int firstIndex );
void RB_StageIteratorGeneric( void );
void RB_StageIteratorSky( void );
void RB_StageIteratorVertexLitTexture( void );
@@ -2171,6 +2234,7 @@ void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t
void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t v);
void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v);
void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t matrix);
void GLSL_SetUniformMat4BoneMatrix(shaderProgram_t *program, int uniformNum, /*const*/ mat4_t *matrix, int numMatricies);

shaderProgram_t *GLSL_GetGenericShaderProgram(int stage);

@@ -2225,6 +2289,7 @@ void RB_MDRSurfaceAnim( mdrSurface_t *surface );
qboolean R_LoadIQM (model_t *mod, void *buffer, int filesize, const char *name );
void R_AddIQMSurfaces( trRefEntity_t *ent );
void RB_IQMSurfaceAnim( surfaceType_t *surface );
void RB_IQMSurfaceAnimVao( srfVaoIQModel_t *surface );
int R_IQMLerpTag( orientation_t *tag, iqmData_t *data,
int startFrame, int endFrame,
float frac, const char *tagName );


+ 1075
- 511
code/renderergl2/tr_model_iqm.c
File diff suppressed because it is too large
View File


+ 1
- 1
code/renderergl2/tr_scene.c View File

@@ -435,7 +435,7 @@ void RE_BeginScene(const refdef_t *fd)
}


void RE_EndScene()
void RE_EndScene(void)
{
// the next scene rendered in this frame will tack on after this one
r_firstSceneDrawSurf = tr.refdef.numDrawSurfs;


+ 48
- 4
code/renderergl2/tr_shade.c View File

@@ -38,7 +38,7 @@ R_DrawElements
==================
*/

void R_DrawElements( int numIndexes, glIndex_t firstIndex)
void R_DrawElements( int numIndexes, int firstIndex )
{
qglDrawElements(GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, BUFFER_OFFSET(firstIndex * sizeof(glIndex_t)));
}
@@ -908,6 +908,8 @@ static void RB_FogPass( void ) {

if (glState.vertexAnimation)
index |= FOGDEF_USE_VERTEX_ANIMATION;
else if (glState.boneAnimation)
index |= FOGDEF_USE_BONE_ANIMATION;
sp = &tr.fogShader[index];
}
@@ -921,6 +923,11 @@ static void RB_FogPass( void ) {
GLSL_SetUniformMat4(sp, UNIFORM_MODELVIEWPROJECTIONMATRIX, glState.modelviewProjection);

GLSL_SetUniformFloat(sp, UNIFORM_VERTEXLERP, glState.vertexAttribsInterpolation);

if (glState.boneAnimation)
{
GLSL_SetUniformMat4BoneMatrix(sp, UNIFORM_BONEMATRIX, glState.boneMatrix, glState.boneAnimation);
}
GLSL_SetUniformInt(sp, UNIFORM_DEFORMGEN, deformGen);
if (deformGen != DGEN_NONE)
@@ -1005,7 +1012,14 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input )