30 #include "../../shared/parse.h"
31 #include "../../shared/shared.h"
33 #define SHADER_BUF_SIZE 16384
38 {
"world_low",
"model_low"},
39 {
"world_med",
"model_med"},
40 {
"world_med",
"model_high"}
58 qglUseProgram(prog->
id);
88 if (i == MAX_PROGRAM_VARS) {
89 Com_Printf(
"R_ProgramVariable: MAX_PROGRAM_VARS reached.\n");
138 qglUniform1fv(v->
location, size, value);
148 qglUniform2fv(v->
location, 1, value);
158 qglUniform2fv(v->
location, size, value);
168 qglUniform3fv(v->
location, 1, value);
178 qglUniform3fv(v->
location, size, value);
188 qglUniform4fv(v->
location, 1, value);
198 qglUniform4fv(v->
location, size, value);
208 qglUniformMatrix4fv(v->
location, 1, GL_FALSE, value);
218 qglVertexAttribPointer(v->
location, size, GL_FLOAT, GL_FALSE, 0, array);
228 qglEnableVertexAttribArray(v->
location);
238 qglDisableVertexAttribArray(v->
location);
243 qglDeleteShader(sh->
id);
250 qglDetachShader(prog->
id, prog->
v->
id);
255 qglDetachShader(prog->
id, prog->
f->
id);
260 qglDeleteProgram(prog->
id);
267 if (!qglDeleteProgram)
291 const size_t inLength = strlen(in);
311 size_t initialChars = 0;
312 const char* hwHack, *defines;
318 hwHack =
"#ifndef ATI\n#define ATI\n#endif\n";
321 hwHack =
"#ifndef INTEL\n#define INTEL\n#endif\n";
324 hwHack =
"#ifndef NVIDIA\n#define NVIDIA\n#endif\n";
327 hwHack =
"#ifndef MESA\n#define MESA\n#endif\n";
340 defines =
va(
"#version %d\n", shaderVersion);
347 defines =
va(
"#define glsl%d\n", shaderVersion);
364 initialChars +=
R_PreprocessShaderAddToShaderBuf(name,
"#ifndef glsl110\n#define in_qualifier in\n#define out_qualifier out\n#else\n#define in_qualifier attribute\n#define out_qualifier varying\n#endif\n", &out, &len);
369 initialChars +=
R_PreprocessShaderAddToShaderBuf(name,
"#ifndef glsl110\n#define in_qualifier in\n#else\n#define in_qualifier varying\n#endif\n", &out, &len);
392 static size_t R_PreprocessShaderR (
const char*
name,
const char** inPtr,
char* out,
long* remainingOutChars,
bool nested,
bool inElse)
394 const size_t INITIAL_REMAINING_OUT_CHARS = (size_t)*remainingOutChars;
397 if (
'#' == **inPtr) {
401 endBlockToken = !strncmp(*inPtr,
"endif", 5);
403 if (!strncmp(*inPtr,
"else", 4)) {
408 endBlockToken =
true;
417 return (INITIAL_REMAINING_OUT_CHARS - (
size_t)*remainingOutChars);
420 if (!strncmp((*inPtr),
"if ", 3)) {
427 if (out) out +=
size;
429 if (!strncmp((*inPtr),
"else", 4)) {
436 if (!strncmp((*inPtr),
"else", 4)) {
441 if (out) out +=
size;
445 if (!strncmp((*inPtr),
"endif", 5))
447 }
else if (!strncmp((*inPtr),
"ifndef", 6) || !strncmp((*inPtr),
"ifdef", 5)) {
450 if (*remainingOutChars <= 0)
453 (*remainingOutChars)--;
457 if (out) out +=
size;
459 if (!strncmp((*inPtr),
"else", 4)) {
461 if (*remainingOutChars <= 0)
464 (*remainingOutChars)--;
467 if (out) out +=
size;
471 if (*remainingOutChars <= 0)
474 (*remainingOutChars)--;
477 }
else if (!strncmp((*inPtr),
"include", 7)) {
480 const char* bufAsChar = (
const char*)0;
481 const char** bufAsCharPtr = (
const char**)0;
485 Com_Printf(
"Failed to resolve #include: %s.\n", path);
488 bufAsChar = (
const char*)buf;
489 bufAsCharPtr = &bufAsChar;
496 }
else if (!strncmp((*inPtr),
"unroll", 6)) {
498 size_t subLength = 0;
503 if (!strncmp((*inPtr),
"#endunroll", 10)) {
507 buffer[subLength++] = *(*inPtr)++;
512 for (
int j = 0; j < z; j++) {
513 for (
int l = 0; l < subLength; l++) {
514 if (buffer[l] ==
'$') {
515 byte insertedLen = (j / 10) + 1;
516 if (!
Com_sprintf(out, (
size_t)*remainingOutChars,
"%d", j))
519 (*remainingOutChars) -= insertedLen;
521 if (*remainingOutChars <= 0)
524 (*remainingOutChars)--;
530 }
else if (!strncmp((*inPtr),
"replace", 7)) {
535 byte insertedLen = 0;
536 if (!
Com_sprintf(out, (
size_t)*remainingOutChars,
"%d", r))
538 insertedLen = (r / 10) + 1;
540 (*remainingOutChars) -= insertedLen;
545 if (*remainingOutChars <= 0)
548 (*remainingOutChars)--;
554 if (*remainingOutChars <= 0)
557 (*remainingOutChars)--;
563 return (INITIAL_REMAINING_OUT_CHARS - *remainingOutChars);
583 long remainingOutCharsAsLong = *remainingOutChars;
584 size_t numCharactersAddedToOutBuffer =
R_PreprocessShaderR(name, &in, out, &remainingOutCharsAsLong,
false,
false);
585 *remainingOutChars = remainingOutCharsAsLong;
586 return numCharactersAddedToOutBuffer;
604 size_t initializeLength;
611 snprintf(path,
sizeof(path),
"shaders/%s", name);
623 srcBuf += initializeLength;
624 bufLength -= initializeLength;
630 length[0] = strlen(source);
639 if (i == MAX_SHADERS) {
640 Com_Printf(
"R_LoadShader: MAX_SHADERS reached.\n");
649 sh->
id = qglCreateShader(sh->
type);
656 qglShaderSource(sh->
id, 1, src, length);
659 qglCompileShader(sh->
id);
665 qglGetShaderInfoLog(sh->
id,
sizeof(log) - 1,
nullptr, log);
671 qglGetShaderInfoLog(sh->
id,
sizeof(log) - 1,
nullptr, log);
675 qglDeleteShader(sh->
id);
710 if (i == MAX_PROGRAMS) {
711 Com_Printf(
"R_LoadProgram: MAX_PROGRAMS reached.\n");
717 prog->
id = qglCreateProgram();
723 qglAttachShader(prog->
id, prog->
v->
id);
725 qglAttachShader(prog->
id, prog->
f->
id);
727 qglLinkProgram(prog->
id);
730 if (!e || !prog->
v || !prog->
f) {
732 qglGetProgramInfoLog(prog->
id,
sizeof(log) - 1,
nullptr, log);
751 Com_Printf(
"R_LoadProgram: '%s' loaded.\n", name);
916 static vec4_t defaultColor = {0.0, 0.0, 0.0, 1.0};
917 static vec4_t cityLightColor = {1.0, 1.0, 0.8, 1.0};
918 static vec2_t uvScale = {2.0, 1.0};
935 if (row <= 1 || col <= 1 || col >= row)
941 #define FILTER_SIZE 3
951 for (i = 0; i <
size; i++) {
956 for (i = 0; i <
size; i++)
957 filter[i] = (filter[i] / sum);
968 const float* userdata= (
float*)prog->
userdata;
971 const float offset = 1.2f / userdata[0];
972 const float x = userdata[1] *
offset;
975 const float y = (float)
i - halfWidth;
976 const float z = x * y;
977 offsets[
i * 2 + 0] = offset * y - z;
978 offsets[
i * 2 + 1] = z;
985 GLfloat defaultColor[4] = {0.0, 0.0, 0.0, 0.0};
995 static vec4_t defaultColor = {0.0, 0.0, 0.0, 1.0};
996 static vec2_t uvScale = {2.0, 1.0};
1024 if (!qglCreateProgram) {
1049 Com_Printf(
"disabled shaders because they failed to compile\n");
1061 Com_Printf(
"glsl restart to a version of v%s\n",
Cvar_Get(
"r_glsl_version",
nullptr, 0,
nullptr)->
string);
const char * shaderQualityLevelNames[SHQ_NUM][2]
static void R_InitConvolveProgram(r_program_t *prog)
void R_DisableAttribute(const char *name)
void R_UseProgram(r_program_t *prog)
r_program_t * warp_program
#define GL_FRAGMENT_SHADER
void R_RestartPrograms_f(void)
Reloads the glsl shaders.
static size_t R_PreprocessShaderR(const char *name, const char **inPtr, char *out, long *remainingOutChars, bool nested, bool inElse)
Do our own preprocessing to the shader file, before the GLSL implementation calls it's preprocessor...
r_program_t * R_LoadProgram(const char *name, programInitFunc_t init, programUseFunc_t use)
QGL_EXTERN GLint GLenum type
#define FILTER_SIZE
width of convolution filter (for blur/bloom effects)
void R_InitParticleProgram(r_program_t *prog)
void R_ProgramParameter2fv(const char *name, GLfloat *value)
const char * va(const char *format,...)
does a varargs printf into a temp buffer, so I don't need to have varargs versions of all text functi...
static size_t R_InitializeShader(const GLenum type, const char *name, char *out, size_t len)
Prefixes the shader string with user settings and the video hardware manufacturer.
r_program_t * atmosphere_program
r_program_t * active_program
bool Com_sprintf(char *dest, size_t size, const char *fmt,...)
copies formatted string with buffer-size checking
const GLenum *typedef GLint
static void R_InitAtmosphereProgram(r_program_t *prog)
r_program_t * combine2_program
static r_shader_t * R_LoadShader(const GLenum type, const char *name)
Reads/Preprocesses/Compiles the specified shader into a program.
local graphics definitions
int FS_LoadFile(const char *path, byte **buffer)
Filenames are relative to the quake search path.
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
void Com_Printf(const char *const fmt,...)
static void R_InitCombine2Program(r_program_t *prog)
static r_progvar_t * R_ProgramVariable(int type, const char *name)
const GLuint *typedef GLuint *typedef GLenum
static void R_UseConvolveProgram(r_program_t *prog)
Use the filter convolution glsl program.
void Com_Error(int code, const char *fmt,...)
void R_ProgramParameter2fvs(const char *name, GLint size, GLfloat *value)
r_progvar_t vars[MAX_PROGRAM_VARS]
void Q_strncpyz(char *dest, const char *src, size_t destsize)
Safe strncpy that ensures a trailing zero.
void(* programInitFunc_t)(struct r_program_s *prog)
static void R_InitGeoscapeProgram(r_program_t *prog)
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
float Cvar_GetValue(const char *varName)
Returns the float value of a cvar.
QGL_EXTERN GLuint GLsizei GLsizei * length
void R_ProgramParameter3fv(const char *name, GLfloat *value)
static void R_UseModelProgram(r_program_t *prog)
void R_UseParticleProgram(r_program_t *prog)
void R_ProgramParameter1i(const char *name, GLint value)
void(* programUseFunc_t)(struct r_program_s *prog)
void R_InitFBObjects(void)
static void R_InitWorldProgram(r_program_t *prog)
void R_ShutdownPrograms(void)
static void R_UseWorldProgram(r_program_t *prog)
r_program_t * geoscape_program
hardwareType_t hardwareType
r_program_t programs[MAX_PROGRAMS]
material_t defaultMaterial
void Com_DPrintf(int level, const char *fmt,...)
A Com_Printf that only shows up if the "developer" cvar is set.
r_program_t * simple_glow_program
static void R_InitWarpProgram(r_program_t *prog)
void R_ProgramParameter4fv(const char *name, GLfloat *value)
void R_ProgramParameterMatrix4fv(const char *name, GLfloat *value)
cvar_t * r_glsl_version
The GLSL version being used (not necessarily a supported version by the OpenGL implementation). Stored as a c-string and integer.
void R_ProgramParameter4fvs(const char *name, GLint size, GLfloat *value)
static void R_UseWarpProgram(r_program_t *prog)
#define Mem_PoolAllocTypeN(type, n, pool)
void R_ProgramParameter1fvs(const char *name, GLint size, GLfloat *value)
const char * Com_Parse(const char *data_p[], char *target, size_t size, bool replaceWhitespaces)
Parse a token out of a string.
r_program_t * world_program
static int R_PascalTriangle(int row, int col)
void R_EnableAttribute(const char *name)
QGL_EXTERN GLuint GLchar GLuint * len
void R_AttributePointer(const char *name, GLuint size, const GLvoid *array)
r_shader_t shaders[MAX_SHADERS]
QGL_EXTERN GLuint GLsizei GLsizei GLint GLenum GLchar * name
static void R_ShutdownShader(r_shader_t *sh)
static size_t R_PreprocessShader(const char *name, const char *in, char *out, size_t *remainingOutChars)
Do our own preprocessing to the shader file, before the GLSL implementation calls it's preprocessor...
memPool_t * vid_imagePool
void R_ProgramParameter3fvs(const char *name, GLint size, GLfloat *value)
r_program_t * model_program
cvar_t * Cvar_Set(const char *varName, const char *value,...)
Sets a cvar value.
r_program_t * convolve_program
static void R_InitSimpleGlowProgram(r_program_t *prog)
static size_t R_PreprocessShaderAddToShaderBuf(const char *name, const char *in, char **out, size_t *len)
Prefixes shader string (out) with in.
void GLVectorTransform(const float m[16], const vec4_t in, vec4_t out)
Multiply 4*4 matrix by 4d vector.
static void R_ShutdownProgram(r_program_t *prog)
QGL_EXTERN int GLboolean GLfloat * v
void R_ProgramParameter1f(const char *name, GLfloat value)
void R_InitPrograms(void)
#define GL_COMPILE_STATUS
static void R_InitModelProgram(r_program_t *prog)
void FS_FreeFile(void *buffer)