QMB style watershaders for non nvidia cards

Post tutorials on how to do certain tasks within game or engine code here.
Post Reply
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

QMB style watershaders for non nvidia cards

Post by revelator »

So after getting this working i thought id share the code.

Its rather simple really the hardest part is getting the darn imports right, as you might see from my somewhat blatant namings.

so first we need the initialization and shader code. you can put this in a seperate file and add it to your project but you will need typedefs for the used functions in a header (glquake.h)or you could just yank it inside gl_warp.c like i did in QMB. So after GL_SubdivideSurface add this->

Code: Select all

/*
=============================================================================

PROGRAM MANAGEMENT

=============================================================================
*/

typedef enum
{
    F_PROG_WARP = 0,
    F_PROG_WATER_DISTORT,
    NUM_FRAGMENT_PROGRAM
} _fragment_programs;

typedef enum
{
    V_PROG_DISTORT = 0,
    NUM_VERTEX_PROGRAM
} _vertex_programs;

// KRIGSSVIN: modified for visual equality with 3 pass version
static char fragment_program_warp[] =
    "!!ARBfp1.0\n"
//"OPTION ARB_precision_hint_fastest;\n"
    "OPTION ARB_precision_hint_nicest;\n"

    "PARAM rgbscale = program.local[0];\n"
    "TEMP offset, coord, dist, col;\n"

    "TEX offset, fragment.texcoord[0], texture[0], 2D;\n"
    "MUL offset, offset, 0.5;\n"

// fetch the water texture
    "ADD coord.x, fragment.texcoord[1].x, offset.z;\n"
    "ADD coord.y, fragment.texcoord[1].y, offset.w;\n"
    "TEX dist, coord, texture[1], 2D;\n"
    "MUL col, dist, fragment.color;\n"
    "MUL result.color, col, rgbscale;\n"

    "END\n";


static char fragment_program_water_distort[] =
    "!!ARBfp1.0\n"

// Scroll and scale the distortion texture coordinates.
// Scroll coordinates are specified externally.
    "PARAM scroll1 = program.local[0];\n"
    "PARAM scroll2 = program.local[1];\n"
    "PARAM texScale1 = { 0.008, 0.008, 1.0, 1.0 };\n"
    "PARAM texScale2 = { 0.007, 0.007, 1.0, 1.0 };\n"
    "TEMP texCoord1;\n"
    "TEMP texCoord2;\n"
    "MUL texCoord1, fragment.texcoord[1], texScale1;\n"
    "MUL texCoord2, fragment.texcoord[1], texScale2;\n"
    "ADD texCoord1, texCoord1, scroll1;\n"
    "ADD texCoord2, texCoord2, scroll2;\n"

// Load the distortion textures and add them together.
    "TEMP distortColor;\n"
    "TEMP distortColor2;\n"
    "TXP distortColor, texCoord1, texture[1], 2D;\n"
    "TXP distortColor2, texCoord2, texture[1], 2D;\n"
    "ADD distortColor, distortColor, distortColor2;\n"

// Subtract 1.0 and scale by 2.0.
// Textures will be distorted from -2.0 to 2.0 texels.
    "PARAM scaleFactor = { 2.0, 2.0, 2.0, 2.0 };\n"
    "PARAM one = { 1.0, 1.0, 1.0, 1.0 };\n"
    "SUB distortColor, distortColor, one;\n"
    "MUL distortColor, distortColor, scaleFactor;\n"

// Apply distortion to reflection texture coordinates.
    "TEMP distortCoord;\n"
    "TEMP endColor;\n"
    "ADD distortCoord, distortColor, fragment.texcoord[0];\n"
    "TXP endColor, distortCoord, texture, 2D;\n"

// Get a vector from the surface to the view origin
    "PARAM vieworg = program.local[2];\n"
    "TEMP eyeVec;\n"
    "TEMP trans;\n"
    "SUB eyeVec, vieworg, fragment.texcoord[1];\n"

// Normalize the vector to the eye position
    "TEMP temp;\n"
    "TEMP invLen;\n"
    "DP3 temp, eyeVec, eyeVec;\n"
    "RSQ invLen, temp.x;\n"
    "MUL eyeVec, eyeVec, invLen;\n"
    "ABS eyeVec.z, eyeVec.z;\n" // so it works underwater, too

// Load the ripple normal map
    "TEMP normalColor;\n"
    "TEMP normalColor2;\n"
// Scale texture
    "MUL texCoord1, fragment.texcoord[2], texScale2;\n"
    "MUL texCoord2, fragment.texcoord[2], texScale1;\n"
// Scroll texture
    "ADD texCoord1, texCoord1, scroll1;\n"
    "ADD texCoord2, texCoord2, scroll2;\n"
// Get texel color
    "TXP normalColor, texCoord1, texture[2], 2D;\n"
    "TXP normalColor2, texCoord2, texture[2], 2D;\n"
// Combine normal maps
    "ADD normalColor, normalColor, normalColor2;\n"
    "SUB normalColor, normalColor, 1.0;\n"

// Normalize normal texture
    "DP3 temp, normalColor, normalColor;\n"
    "RSQ invLen, temp.x;\n"
    "MUL normalColor, invLen, normalColor;\n"

// Fresenel approximation
    "DP3 trans.w, normalColor, eyeVec;\n"
    "SUB endColor.w, 1.0, trans.w;\n"
    "MAX endColor.w, endColor.w, 0.2;\n" // MAX sets the min?  How odd.
    "MIN endColor.w, endColor.w, 0.8;\n" // Leave a LITTLE bit of transparency always

// Put the color in the output (TODO: put this in final OP)
    "MOV result.color, endColor;\n"

    "END\n";


static char vertex_program_distort[] =
    "!!ARBvp1.0\n"
    "OPTION ARB_position_invariant;\n"

    "PARAM vec = { 1.0, 0.0, 0.0, 1.0 };\n"
    "PARAM dtc = { 0.0, 0.5, 0.0, 1.0 };\n"

    "TEMP R0, R1, R2;\n"

    "MOV          R0, vec;\n"
    "DP4          R0.z, vertex.position, state.matrix.modelview.row[2];\n"

    "DP4          R1, R0, state.matrix.projection.row[0];\n"
    "DP4          R2, R0, state.matrix.projection.row[3];\n"

// don't let the recip get near zero for polygons that cross the view plane
    "MAX          R2, R2, 1.0;\n"

    "RCP          R2, R2.w;\n"
    "MUL          R1, R1, R2;\n"

// clamp the distance so the deformations don't get too wacky near the view
    "MIN          R1, R1, 0.02;\n"

    "MOV          result.texcoord[0], dtc;\n"
    "DP4          result.texcoord[0].x, vertex.texcoord[0], state.matrix.texture[0].row[0];\n"
    "DP4          result.texcoord[0].y, vertex.texcoord[0], state.matrix.texture[0].row[1];\n"

    "MOV          result.texcoord[2], dtc;\n"
    "DP4          result.texcoord[2].x, vertex.texcoord[2], state.matrix.texture[2].row[0];\n"
    "DP4          result.texcoord[2].y, vertex.texcoord[2], state.matrix.texture[2].row[1];\n"

    "MUL          result.texcoord[3], R1, program.local[0];\n"

    "MOV          result.color, vertex.color;\n"

    "END\n";

static char *fragment_progs[NUM_FRAGMENT_PROGRAM] =
{
    fragment_program_warp,
    fragment_program_water_distort
};

static char *vertex_progs[NUM_VERTEX_PROGRAM] =
{
    vertex_program_distort
};

GLuint	fragment_programs[NUM_FRAGMENT_PROGRAM];
GLuint	vertex_programs[NUM_VERTEX_PROGRAM];

/*
=============
GL_InitShaders
=============
*/
void GL_InitShaders (void)
{
    int				i, error_pos;
	const char	    *errors;

    if (gl_fragment_arb)
    {
        // fragment programs
        qglGenProgramsARB(NUM_FRAGMENT_PROGRAM, &fragment_programs[0]);

        for (i = 0; i < NUM_FRAGMENT_PROGRAM; i++)
        {
            qglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fragment_programs[i]);
            qglProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei) strlen(fragment_progs[i]), fragment_progs[i]);
            glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);

            if (error_pos != -1)
            {
                errors = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
                Con_Printf ("FragmentProgram error at position %d in shader %d\nARB_ERROR: %s\n", error_pos, fragment_programs[i], errors);
                qglDeleteProgramsARB(1, &fragment_programs[i]);
                break;
            }
        }
    }

    // vertex programs
    if (gl_vertex_arb)
    {
        qglGenProgramsARB(NUM_VERTEX_PROGRAM, &vertex_programs[0]);

        for (i = 0; i < NUM_VERTEX_PROGRAM; i++)
        {
            qglBindProgramARB(GL_VERTEX_PROGRAM_ARB, vertex_programs[i]);
            qglProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei) strlen(vertex_progs[i]), vertex_progs[i]);
            glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &error_pos);

            if (error_pos != -1)
            {
                errors = glGetString(GL_PROGRAM_ERROR_STRING_ARB);
                Con_Printf ("VertexProgram error at position %d in shader %d\nARB_ERROR: %s\n", error_pos, vertex_programs[i], errors);
                qglDeleteProgramsARB(1, &vertex_programs[i]);
                break;
            }
        }
    }
}

/*
=============================================================================

PROGRAM MANAGEMENT

=============================================================================
*/

// MrG - texture shader stuffs
//Thanx MrG
#define DST_SIZE 16

unsigned int dst_texture_nv = 0;
unsigned int dst_texture_arb = 0;

/*
===============
CreateDSTTexNV

Create the texture which warps texture shaders
===============
*/
void CreateDSTTexNV(void)
{
    signed char data[DST_SIZE][DST_SIZE][2];
    int         x, y;

    if (!gl_shader_nv) return;

    for (x=0; x<DST_SIZE; x++)
    {
        for (y=0; y<DST_SIZE; y++)
        {
            data[x][y][0]=rand()%255-128;
            data[x][y][1]=rand()%255-128;
        }
    }
    memset (&dst_texture_nv, 0, sizeof (unsigned int));
    glGenTextures(1, &dst_texture_nv);
    glBindTexture(GL_TEXTURE_2D, dst_texture_nv);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_DSDT8_NV, DST_SIZE, DST_SIZE, 0, GL_DSDT_NV, GL_BYTE, data);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}

/*
===============
CreateDSTTexARB

Create the texture which warps texture shaders
===============
*/
void CreateDSTTexARB (void)
{
    signed char     data[DST_SIZE][DST_SIZE][2];
	int				x, y;

    if (!gl_fragment_arb) return;

	srand(GetTickCount());

	for (x=0; x<DST_SIZE; x++)
    {
		for (y=0; y<DST_SIZE; y++)
        {
			data[x][y][0] = rand()%255;
			data[x][y][1] = rand()%255;
			data[x][y][2] = rand()%48;
			data[x][y][3] = rand()%48;
		}
	}
    memset (&dst_texture_arb, 0, sizeof (unsigned int));
	glGenTextures(1, &dst_texture_arb);
	glBindTexture(GL_TEXTURE_2D, dst_texture_arb);
	glTexImage2D (GL_TEXTURE_2D, 0, 4, DST_SIZE, DST_SIZE, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
}
not all of the glsl scripts are used but if you know how (or look at my realm engine) you can make some funny effects like fragment shaded heathaze. you can also easily expand it.

you got this far but the above code wont do much yet so in EmitWaterPolys add this

Code: Select all

    
    float       arb_args[4] = {1.0f,1.0f,1.0f,1.0f};
    float	  nv_args[4] = {0.05f,0.0f,0.0f,0.02f};
after

Code: Select all

    float		s, ss, t, tt, os, ot;
now at the top of the function before anything else add this

Code: Select all

    
    glSelectTexture(GL_TEXTURE0_ARB);
    glBindTexture(GL_TEXTURE_2D, fa->texinfo->texture->gl_texturenum);

    /*
    Texture Shader waterwarp
    Damn this looks fantastic

    WHY texture shaders? because I can!
    - MrG
    */
    if (gl_shader_nv)
    {
        Con_DPrintf("Using NV Texture Shaders\n");
        if (!dst_texture_nv)
            CreateDSTTexNV();
        glBindTexture(GL_TEXTURE_2D, dst_texture_nv);

        glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_TEXTURE_2D);

        GL_EnableTMU(GL_TEXTURE1_ARB);
        glBindTexture(GL_TEXTURE_2D, fa->texinfo->texture->gl_texturenum);

        glTexEnvi(GL_TEXTURE_SHADER_NV, GL_SHADER_OPERATION_NV, GL_OFFSET_TEXTURE_2D_NV);
        glTexEnvi(GL_TEXTURE_SHADER_NV, GL_PREVIOUS_TEXTURE_INPUT_NV, GL_TEXTURE0_ARB);
        glTexEnvfv(GL_TEXTURE_SHADER_NV, GL_OFFSET_TEXTURE_MATRIX_NV, &nv_args[0]);

        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
        glEnable(GL_TEXTURE_SHADER_NV);
    }
    else if (gl_fragment_arb)
    {
        Con_DPrintf("Using ARB Texture Shaders\n");
        if (!dst_texture_arb)
            CreateDSTTexARB();
        glBindTexture(GL_TEXTURE_2D, dst_texture_arb);

        GL_EnableTMU(GL_TEXTURE1_ARB);
        glBindTexture(GL_TEXTURE_2D, fa->texinfo->texture->gl_texturenum);

		qglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, fragment_programs[F_PROG_WARP]);
		qglProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0, &arb_args[0]);

        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		glEnable(GL_FRAGMENT_PROGRAM_ARB);
    }
    else
    {
        GL_EnableTMU(GL_TEXTURE1_ARB);
        glBindTexture(GL_TEXTURE_2D,fa->texinfo->texture->gl_texturenum);
    }
if you dont have GL_EnableTMU you can do
glSelectTexture(target);
followed by a
glEnable(GL_TEXTURE_2D);

ok now we have the function for drawing the fragment shader. there are two here one for nvidia cards and one for the rest but tbh just stick with the ARB one it looks just as good.
now at the end of the function put this.

Code: Select all

    if (gl_shader_nv)   // MrG - texture shader waterwarp
    {
        glDisable(GL_TEXTURE_SHADER_NV);
    }
    else if (gl_fragment_arb)
    {
		glDisable(GL_FRAGMENT_PROGRAM_ARB);
    }
    GL_DisableTMU(GL_TEXTURE1_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

    glSelectTexture(GL_TEXTURE0_ARB);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
again if you dont have GL_DisableTMU do
glSelectTexture(GL_TEXTURE1_ARB);
glDisable(GL_TEXTURE_2D);

and thats that for gl_warp.c

open gl_vidnt.cand this somewhere at the top.

// vertex programs
BindBufferARB qglBindBufferARB;
DeleteBuffersARB qglDeleteBuffersARB;
GenBuffersARB qglGenBuffersARB;
BufferDataARB qglBufferDataARB;
BufferSubDataARB qglBufferSubDataARB;
MapBufferARB qglMapBufferARB;
UnmapBufferARB qglUnmapBufferARB;

// fragment programs
ProgramStringARB qglProgramStringARB;
BindProgramARB qglBindProgramARB;
DeleteProgramsARB qglDeleteProgramsARB;
GenProgramsARB qglGenProgramsARB;
ProgramEnvParameter4dARB qglProgramEnvParameter4dARB;
ProgramEnvParameter4dvARB qglProgramEnvParameter4dvARB;
ProgramEnvParameter4fARB qglProgramEnvParameter4fARB;
ProgramEnvParameter4fvARB qglProgramEnvParameter4fvARB;
ProgramLocalParameter4dARB qglProgramLocalParameter4dARB;
ProgramLocalParameter4dvARB qglProgramLocalParameter4dvARB;
ProgramLocalParameter4fARB qglProgramLocalParameter4fARB;
ProgramLocalParameter4fvARB qglProgramLocalParameter4fvARB;
GetProgramEnvParameterdvARB qglGetProgramEnvParameterdvARB;
GetProgramEnvParameterfvARB qglGetProgramEnvParameterfvARB;
GetProgramLocalParameterdvARB qglGetProgramLocalParameterdvARB;
GetProgramLocalParameterfvARB qglGetProgramLocalParameterfvARB;
GetProgramivARB qglGetProgramivARB;
GetProgramStringARB qglGetProgramStringARB;
GetVertexAttribdvARB qglGetVertexAttribdvARB;
GetVertexAttribfvARB qglGetVertexAttribfvARB;
GetVertexAttribivARB qglGetVertexAttribivARB;
GetVertexAttribPointervARB qglGetVertexAttribPointervARB;
IsProgramARB qglIsProgramARB;

qboolean gl_shader_nv = false;
qboolean gl_fragment_arb = false;

now move further down to just before GL_Init there should allready be some functions for checking extentions. in QMB i used CheckCombineExtension.
add this somewhere at the top.

Code: Select all

    if (strstr(gl_extensions, "GL_NV_texture_shader "))
    {
        Con_Printf("&c840Nvidia texture shader extension found&r.\n");
        gl_shader_nv = true;
    }
    if (strstr(gl_extensions, "GL_ARB_fragment_program "))
    {
        // fragment programs
        qglProgramStringARB = (void *) wglGetProcAddress( "glProgramStringARB" );
        qglBindProgramARB = (void *) wglGetProcAddress( "glBindProgramARB" );
        qglDeleteProgramsARB = (void *) wglGetProcAddress( "glDeleteProgramsARB" );
        qglGenProgramsARB = (void *) wglGetProcAddress( "glGenProgramsARB" );
        qglProgramEnvParameter4dARB = (void *) wglGetProcAddress( "glProgramEnvParameter4dARB" );
        qglProgramEnvParameter4dvARB = (void *) wglGetProcAddress( "glProgramEnvParameter4dvARB" );
        qglProgramEnvParameter4fARB = (void *) wglGetProcAddress( "glProgramEnvParameter4fARB" );
        qglProgramEnvParameter4fvARB = (void *) wglGetProcAddress( "glProgramEnvParameter4fvARB" );
        qglProgramLocalParameter4dARB = (void *) wglGetProcAddress( "glProgramLocalParameter4dARB" );
        qglProgramLocalParameter4dvARB = (void *) wglGetProcAddress( "glProgramLocalParameter4dvARB" );
        qglProgramLocalParameter4fARB = (void *) wglGetProcAddress( "glProgramLocalParameter4fARB" );
        qglProgramLocalParameter4fvARB = (void *) wglGetProcAddress( "glProgramLocalParameter4fvARB" );
        qglGetProgramEnvParameterdvARB = (void *) wglGetProcAddress( "glGetProgramEnvParameterdvARB" );
        qglGetProgramEnvParameterfvARB = (void *) wglGetProcAddress( "glGetProgramEnvParameterfvARB" );
        qglGetProgramLocalParameterdvARB = (void *) wglGetProcAddress( "glGetProgramLocalParameterdvARB" );
        qglGetProgramLocalParameterfvARB = (void *) wglGetProcAddress( "glGetProgramLocalParameterfvARB" );
        qglGetProgramivARB = (void *) wglGetProcAddress( "glGetProgramivARB" );
        qglGetProgramStringARB = (void *) wglGetProcAddress( "glGetProgramStringARB" );
        qglIsProgramARB = (void *) wglGetProcAddress( "glIsProgramARB" );

        if (qglProgramStringARB || qglBindProgramARB
        || qglDeleteProgramsARB || qglGenProgramsARB
        || qglProgramEnvParameter4dARB || qglProgramEnvParameter4dvARB
        || qglProgramEnvParameter4fARB || qglProgramEnvParameter4fvARB
        || qglProgramLocalParameter4dARB || qglProgramLocalParameter4dvARB
        || qglProgramLocalParameter4fARB || qglProgramLocalParameter4fvARB
        || qglGetProgramEnvParameterdvARB || qglGetProgramEnvParameterfvARB
        || qglGetProgramLocalParameterdvARB  || qglGetProgramLocalParameterfvARB
        || qglGetProgramivARB || qglGetProgramStringARB || qglIsProgramARB)
            Con_Printf("&c840Arb fragment program extension found&r.\n");
            gl_fragment_arb = true;
    }
    if (strstr(gl_extensions, "GL_ARB_vertex_program "))
    {
        // vertex programs
        qglGetVertexAttribdvARB = (void *) wglGetProcAddress("glGetVertexAttribdvARB");
        qglGetVertexAttribfvARB	= (void *) wglGetProcAddress("glGetVertexAttribfvARB");
        qglGetVertexAttribivARB	= (void *) wglGetProcAddress("glGetVertexAttribivARB");
        qglGetVertexAttribPointervARB = (void *) wglGetProcAddress("glGetVertexAttribPointervARB");

        if (qglGetVertexAttribdvARB || qglGetVertexAttribfvARB ||
            qglGetVertexAttribivARB || qglGetVertexAttribPointervARB)
            Con_Printf("&c840Arb vertex program extension found&r.\n");
            gl_vertex_arb = true;
    }
this tells the engine that these extentions are availiable (or you got a really old gfx card and in that case it will just draw like normal).

now add this in glquake.h

// added Vertex Buffer Object stuff
typedef void (APIENTRY *BindBufferARB)(GLenum, GLuint);
typedef void (APIENTRY *DeleteBuffersARB)(GLsizei, const GLuint *);
typedef void (APIENTRY *GenBuffersARB)(GLsizei, GLuint *);
typedef void (APIENTRY *BufferDataARB)(GLenum, GLsizeiptrARB, const GLvoid *, GLenum);
typedef void (APIENTRY *BufferSubDataARB)(GLenum, GLintptrARB, GLsizeiptrARB, const GLvoid *);
typedef void *(APIENTRY *MapBufferARB)(GLenum, GLenum);
typedef GLboolean ( APIENTRY *UnmapBufferARB)(GLenum);

extern BindBufferARB qglBindBufferARB;
extern DeleteBuffersARB qglDeleteBuffersARB;
extern GenBuffersARB qglGenBuffersARB;
extern BufferDataARB qglBufferDataARB;
extern BufferSubDataARB qglBufferSubDataARB;
extern MapBufferARB qglMapBufferARB;
extern UnmapBufferARB qglUnmapBufferARB;

// ARB fragment/vertex program stuff
typedef void (APIENTRY *ProgramStringARB)(GLenum, GLenum, GLsizei, const GLvoid *);
typedef void (APIENTRY *BindProgramARB)(GLenum, GLuint);
typedef void (APIENTRY *DeleteProgramsARB)(GLsizei, const GLuint *);
typedef void (APIENTRY *GenProgramsARB)(GLsizei, GLuint *);
typedef void (APIENTRY *ProgramEnvParameter4dARB)(GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
typedef void (APIENTRY *ProgramEnvParameter4dvARB)(GLenum, GLuint, const GLdouble *);
typedef void (APIENTRY *ProgramEnvParameter4fARB)(GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
typedef void (APIENTRY *ProgramEnvParameter4fvARB)(GLenum, GLuint, const GLfloat *);
typedef void (APIENTRY *ProgramLocalParameter4dARB)(GLenum, GLuint, GLdouble, GLdouble, GLdouble, GLdouble);
typedef void (APIENTRY *ProgramLocalParameter4dvARB)(GLenum, GLuint, const GLdouble *);
typedef void (APIENTRY *ProgramLocalParameter4fARB)(GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
typedef void (APIENTRY *ProgramLocalParameter4fvARB)(GLenum, GLuint, const GLfloat *);
typedef void (APIENTRY *GetProgramEnvParameterdvARB)(GLenum, GLuint, GLdouble *);
typedef void (APIENTRY *GetProgramEnvParameterfvARB)(GLenum, GLuint, GLfloat *);
typedef void (APIENTRY *GetProgramLocalParameterdvARB)(GLenum, GLuint, GLdouble *);
typedef void (APIENTRY *GetProgramLocalParameterfvARB)(GLenum, GLuint, GLfloat *);
typedef void (APIENTRY *GetProgramivARB)(GLenum, GLenum, GLint *);
typedef void (APIENTRY *GetProgramStringARB)(GLenum, GLenum, GLvoid *);
typedef void (APIENTRY *GetVertexAttribdvARB)(GLuint, GLenum, GLdouble *);
typedef void (APIENTRY *GetVertexAttribfvARB)(GLuint, GLenum, GLfloat *);
typedef void (APIENTRY *GetVertexAttribivARB)(GLuint, GLenum, GLint *);
typedef void (APIENTRY *GetVertexAttribPointervARB)(GLuint, GLenum, GLvoid* *);
typedef GLboolean (APIENTRY *IsProgramARB)(GLuint);

extern ProgramStringARB qglProgramStringARB;
extern BindProgramARB qglBindProgramARB;
extern DeleteProgramsARB qglDeleteProgramsARB;
extern GenProgramsARB qglGenProgramsARB;
extern ProgramEnvParameter4dARB qglProgramEnvParameter4dARB;
extern ProgramEnvParameter4dvARB qglProgramEnvParameter4dvARB;
extern ProgramEnvParameter4fARB qglProgramEnvParameter4fARB;
extern ProgramEnvParameter4fvARB qglProgramEnvParameter4fvARB;
extern ProgramLocalParameter4dARB qglProgramLocalParameter4dARB;
extern ProgramLocalParameter4dvARB qglProgramLocalParameter4dvARB;
extern ProgramLocalParameter4fARB qglProgramLocalParameter4fARB;
extern ProgramLocalParameter4fvARB qglProgramLocalParameter4fvARB;
extern GetProgramEnvParameterdvARB qglGetProgramEnvParameterdvARB;
extern GetProgramEnvParameterfvARB qglGetProgramEnvParameterfvARB;
extern GetProgramLocalParameterdvARB qglGetProgramLocalParameterdvARB;
extern GetProgramLocalParameterfvARB qglGetProgramLocalParameterfvARB;
extern GetProgramivARB qglGetProgramivARB;
extern GetProgramStringARB qglGetProgramStringARB;
extern GetVertexAttribdvARB qglGetVertexAttribdvARB;
extern GetVertexAttribfvARB qglGetVertexAttribfvARB;
extern GetVertexAttribivARB qglGetVertexAttribivARB;
extern GetVertexAttribPointervARB qglGetVertexAttribPointervARB;
extern IsProgramARB qglIsProgramARB;

extern qboolean gl_shader_nv;
extern qboolean gl_fragment_arb;
extern qboolean gl_vertex_arb;

void GL_InitShaders (void);

open gl_rmisc.c

and add

// compile shaders
GL_InitShaders ();

just above

playertextures = texture_extension_number;

in R_Init

gl_vertex_arb is unused atm but if youre good with shaders you can make your own extention :)

and lastly get glext.h and add it to the includes at the top of glquake.h right below this
#include <GL/gl.h>
#include <GL/glu.h>
add
#include "glext.h"

now put glext.h in your source folder next to glquake.h .

save and compile and enjoy your new water effects.
Productivity is a state of mind.
Labman
Posts: 62
Joined: Fri Nov 05, 2004 2:39 am
Location: Brisbane, Australia
Contact:

Re: QMB style watershaders for non nvidia cards

Post by Labman »

I would recommend using something like GLee or GLEW to handle the extra opengl functions and checking for what features are available. So much better than doing it by hand.
revelator
Posts: 2621
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: QMB style watershaders for non nvidia cards

Post by revelator »

indeed :)
Productivity is a state of mind.
Post Reply