mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 15:22:04 +00:00
Add basic support for shader "effects".
Again, based on The OpenGL Shader Wrangler. The wrangling part is not used yet, but the shader compiler has been modified to take the built up shader. Just to keep things compiling, a wrapper has been temporarily created.
This commit is contained in:
parent
3b56f0e3bf
commit
96c40cb9a1
10 changed files with 213 additions and 33 deletions
|
@ -30,6 +30,12 @@
|
|||
|
||||
#include "QF/qtypes.h"
|
||||
|
||||
typedef struct shader_s {
|
||||
int num_strings;
|
||||
const char **strings;
|
||||
const char **src;
|
||||
} shader_t;
|
||||
|
||||
typedef struct shaderparam_s {
|
||||
const char *name;
|
||||
qboolean uniform;
|
||||
|
@ -40,9 +46,15 @@ extern int glsl_palette;
|
|||
extern int glsl_colormap;
|
||||
|
||||
void GLSL_Init_Common (void);
|
||||
int GLSL_CompileShader (const char *name, const char *shader_src, int type);
|
||||
|
||||
int GLSL_CompileShader (const char *name, const shader_t *shader, int type);
|
||||
int GLSL_CompileShaderS (const char *name, const char *src, int type);
|
||||
int GLSL_LinkProgram (const char *name, int vert, int frag);
|
||||
int GLSL_ResolveShaderParam (int program, shaderparam_t *param);
|
||||
void GLSL_DumpAttribArrays (void);
|
||||
|
||||
int GLSL_RegisterEffect (const char *name, const char *src);
|
||||
shader_t *GLSL_BuildShader (const char **effect_keys);
|
||||
void GLSL_FreeShader (shader_t *shader);
|
||||
|
||||
#endif // __QF_GLSL_vid_h
|
||||
|
|
|
@ -17,8 +17,8 @@ shader_gen= \
|
|||
|
||||
glsl_src = \
|
||||
glsl_alias.c glsl_bsp.c glsl_draw.c glsl_fog.c glsl_iqm.c glsl_lightmap.c \
|
||||
glsl_main.c glsl_particles.c glsl_screen.c glsl_sprite.c glsl_textures.c \
|
||||
qfglsl.c vid_common_glsl.c
|
||||
glsl_main.c glsl_particles.c glsl_screen.c glsl_shader.c glsl_sprite.c \
|
||||
glsl_textures.c qfglsl.c vid_common_glsl.c
|
||||
|
||||
noinst_LTLIBRARIES= libglsl.la
|
||||
BUILT_SOURCES= $(shader_gen)
|
||||
|
|
|
@ -113,9 +113,9 @@ glsl_R_InitAlias (void)
|
|||
int vert;
|
||||
int frag;
|
||||
|
||||
vert = GLSL_CompileShader ("quakemdl.vert", quakemdl_vert,
|
||||
vert = GLSL_CompileShaderS ("quakemdl.vert", quakemdl_vert,
|
||||
GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("quakemdl.frag", quakemdl_frag,
|
||||
frag = GLSL_CompileShaderS ("quakemdl.frag", quakemdl_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_mdl.program = GLSL_LinkProgram ("quakemdl", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_mdl.program, &quake_mdl.mvp_matrix);
|
||||
|
|
|
@ -1244,9 +1244,9 @@ glsl_R_InitBsp (void)
|
|||
int vert;
|
||||
int frag;
|
||||
|
||||
vert = GLSL_CompileShader ("quakebsp.vert", quakebsp_vert,
|
||||
vert = GLSL_CompileShaderS ("quakebsp.vert", quakebsp_vert,
|
||||
GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("quakebsp.frag", quakebsp_frag,
|
||||
frag = GLSL_CompileShaderS ("quakebsp.frag", quakebsp_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_bsp.program = GLSL_LinkProgram ("quakebsp", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.mvp_matrix);
|
||||
|
@ -1258,7 +1258,7 @@ glsl_R_InitBsp (void)
|
|||
GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.color);
|
||||
GLSL_ResolveShaderParam (quake_bsp.program, &quake_bsp.fog);
|
||||
|
||||
frag = GLSL_CompileShader ("quaketrb.frag", quaketurb_frag,
|
||||
frag = GLSL_CompileShaderS ("quaketrb.frag", quaketurb_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_turb.program = GLSL_LinkProgram ("quaketrb", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.mvp_matrix);
|
||||
|
@ -1270,9 +1270,9 @@ glsl_R_InitBsp (void)
|
|||
GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.color);
|
||||
GLSL_ResolveShaderParam (quake_turb.program, &quake_turb.fog);
|
||||
|
||||
vert = GLSL_CompileShader ("quakesky.vert", quakesky_vert,
|
||||
vert = GLSL_CompileShaderS ("quakesky.vert", quakesky_vert,
|
||||
GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("quakeski.frag", quakeskyid_frag,
|
||||
frag = GLSL_CompileShaderS ("quakeski.frag", quakeskyid_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_skyid.program = GLSL_LinkProgram ("quakeskyid", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.mvp_matrix);
|
||||
|
@ -1284,7 +1284,7 @@ glsl_R_InitBsp (void)
|
|||
GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.realtime);
|
||||
GLSL_ResolveShaderParam (quake_skyid.program, &quake_skyid.fog);
|
||||
|
||||
frag = GLSL_CompileShader ("quakeskb.frag", quakeskybox_frag,
|
||||
frag = GLSL_CompileShaderS ("quakeskb.frag", quakeskybox_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_skybox.program = GLSL_LinkProgram ("quakeskybox", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_skybox.program, &quake_skybox.mvp_matrix);
|
||||
|
|
|
@ -381,9 +381,9 @@ glsl_Draw_Init (void)
|
|||
|
||||
draw_queue = dstring_new ();
|
||||
|
||||
vert = GLSL_CompileShader ("quakeico.vert", quakeicon_vert,
|
||||
vert = GLSL_CompileShaderS ("quakeico.vert", quakeicon_vert,
|
||||
GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("quake2d.frag", quake2d_frag,
|
||||
frag = GLSL_CompileShaderS ("quake2d.frag", quake2d_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_2d.program = GLSL_LinkProgram ("quake2d", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_2d.program, &quake_2d.texture);
|
||||
|
|
|
@ -140,8 +140,8 @@ glsl_R_InitIQM (void)
|
|||
int frag;
|
||||
int i;
|
||||
|
||||
vert = GLSL_CompileShader ("iqm.vert", iqm_vert, GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("iqm.frag", iqm_frag, GL_FRAGMENT_SHADER);
|
||||
vert = GLSL_CompileShaderS ("iqm.vert", iqm_vert, GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShaderS ("iqm.frag", iqm_frag, GL_FRAGMENT_SHADER);
|
||||
iqm_shader.program = GLSL_LinkProgram ("iqm", vert, frag);
|
||||
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.mvp_matrix);
|
||||
GLSL_ResolveShaderParam (iqm_shader.program, &iqm_shader.norm_matrix);
|
||||
|
|
|
@ -223,9 +223,9 @@ glsl_R_InitParticles (void)
|
|||
qfeglGetFloatv (GL_ALIASED_POINT_SIZE_RANGE, v);
|
||||
Sys_MaskPrintf (SYS_GLSL, "point size: %g - %g\n", v[0], v[1]);
|
||||
|
||||
vert = GLSL_CompileShader ("quakepnt.vert", quakepoint_vert,
|
||||
vert = GLSL_CompileShaderS ("quakepnt.vert", quakepoint_vert,
|
||||
GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("quakepnt.frag", quakepoint_frag,
|
||||
frag = GLSL_CompileShaderS ("quakepnt.frag", quakepoint_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_point.program = GLSL_LinkProgram ("quakepoint", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_point.program, &quake_point.mvp_matrix);
|
||||
|
@ -234,9 +234,9 @@ glsl_R_InitParticles (void)
|
|||
GLSL_ResolveShaderParam (quake_point.program, &quake_point.color);
|
||||
GLSL_ResolveShaderParam (quake_point.program, &quake_point.fog);
|
||||
|
||||
vert = GLSL_CompileShader ("quakepar.vert", quakepart_vert,
|
||||
vert = GLSL_CompileShaderS ("quakepar.vert", quakepart_vert,
|
||||
GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("quakepar.frag", quakepart_frag,
|
||||
frag = GLSL_CompileShaderS ("quakepar.frag", quakepart_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_part.program = GLSL_LinkProgram ("quakepart", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_part.program, &quake_part.mvp_matrix);
|
||||
|
|
161
libs/video/renderer/glsl/glsl_shader.c
Normal file
161
libs/video/renderer/glsl/glsl_shader.c
Normal file
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
glsl_shader.c
|
||||
|
||||
Shader management based on The OpenGL Shader Wrangler
|
||||
http://prideout.net/blog/?p=11
|
||||
|
||||
Copyright (C) 2013 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2013/02/26
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "QF/alloc.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/segtext.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
#include "QF/GLSL/qf_vid.h"
|
||||
|
||||
typedef struct glsl_effect_s {
|
||||
struct glsl_effect_s *next;
|
||||
const char *name;
|
||||
segtext_t *text;
|
||||
} glsl_effect_t;
|
||||
|
||||
static hashtab_t *effect_tab;
|
||||
static glsl_effect_t *free_effects;
|
||||
|
||||
static glsl_effect_t *
|
||||
new_effect (void)
|
||||
{
|
||||
glsl_effect_t *effect;
|
||||
ALLOC (64, glsl_effect_t, effects, effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
static const char *
|
||||
effect_get_key (const void *e, void *unused)
|
||||
{
|
||||
glsl_effect_t *effect = (glsl_effect_t *) e;
|
||||
return effect->name;
|
||||
}
|
||||
|
||||
int
|
||||
GLSL_RegisterEffect (const char *name, const char *src)
|
||||
{
|
||||
glsl_effect_t *effect;
|
||||
segtext_t *text;
|
||||
|
||||
if (!effect_tab)
|
||||
effect_tab = Hash_NewTable (61, effect_get_key, 0, 0);
|
||||
|
||||
if (Hash_Find (effect_tab, name)) {
|
||||
Sys_Printf ("WARNING: ignoring duplicate '%s' effect\n", name);
|
||||
return 0;
|
||||
}
|
||||
text = Segtext_new (src);
|
||||
if (!text) {
|
||||
Sys_Printf ("WARNING: %s: problem parsing effect source\n", name);
|
||||
return 0;
|
||||
}
|
||||
effect = new_effect ();
|
||||
effect->name = strdup (name);
|
||||
effect->text = text;
|
||||
Hash_Add (effect_tab, effect);
|
||||
return 1;
|
||||
}
|
||||
|
||||
shader_t *
|
||||
GLSL_BuildShader (const char **effect_keys)
|
||||
{
|
||||
const char *dot;
|
||||
const char **key;
|
||||
int num_keys = 0;
|
||||
shader_t *shader;
|
||||
dstring_t *ekey;
|
||||
glsl_effect_t *effect;
|
||||
const segchunk_t *chunk;
|
||||
|
||||
for (key = effect_keys; *key; key++)
|
||||
num_keys++;
|
||||
|
||||
shader = malloc (sizeof (shader_t));
|
||||
shader->num_strings = num_keys;
|
||||
shader->strings = calloc (2, num_keys);
|
||||
shader->src = shader->strings + num_keys;
|
||||
|
||||
ekey = dstring_new ();
|
||||
for (key = effect_keys; *key; key++) {
|
||||
int num = key - effect_keys;
|
||||
dot = strchr (*key, '.');
|
||||
if (!dot) {
|
||||
Sys_Printf ("Invalid effect key: '%s'\n", *key);
|
||||
goto error;
|
||||
}
|
||||
dstring_copysubstr (ekey, *key, dot - *key);
|
||||
effect = Hash_Find (effect_tab, ekey->str);
|
||||
if (!effect) {
|
||||
Sys_Printf ("Unknown effect: '%s'\n", ekey->str);
|
||||
goto error;
|
||||
}
|
||||
dot++;
|
||||
chunk = Segtext_FindChunk (effect->text, dot);
|
||||
if (!chunk) {
|
||||
Sys_Printf ("Unknown shader key: '%s'\n", dot);
|
||||
goto error;
|
||||
}
|
||||
shader->strings[num] = nva ("#line %d\n%s", chunk->start_line,
|
||||
chunk->text);
|
||||
shader->src[num] = strdup (ekey->str);
|
||||
}
|
||||
dstring_delete (ekey);
|
||||
return shader;
|
||||
error:
|
||||
// there is guaranteed to be a null in the array if an error occurs.
|
||||
for (key = shader->strings; *key; key++) {
|
||||
free ((char *) *key);
|
||||
free ((char *) shader->src[key - shader->strings]);
|
||||
}
|
||||
free (shader->strings);
|
||||
free (shader);
|
||||
dstring_delete (ekey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
GLSL_FreeShader (shader_t *shader)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < shader->num_strings; i++) {
|
||||
free ((char *) shader->strings[i]);
|
||||
free ((char *) shader->src[i]);
|
||||
}
|
||||
free (shader->strings);
|
||||
free (shader);
|
||||
}
|
|
@ -98,9 +98,9 @@ glsl_R_InitSprites (void)
|
|||
{
|
||||
int frag, vert;
|
||||
|
||||
vert = GLSL_CompileShader ("quakespr.vert", quakesprite_vert,
|
||||
vert = GLSL_CompileShaderS ("quakespr.vert", quakesprite_vert,
|
||||
GL_VERTEX_SHADER);
|
||||
frag = GLSL_CompileShader ("quakespr.frag", quakesprite_frag,
|
||||
frag = GLSL_CompileShaderS ("quakespr.frag", quakesprite_frag,
|
||||
GL_FRAGMENT_SHADER);
|
||||
quake_sprite.program = GLSL_LinkProgram ("quakespr", vert, frag);
|
||||
GLSL_ResolveShaderParam (quake_sprite.program, &quake_sprite.spritea);
|
||||
|
|
|
@ -184,33 +184,40 @@ GLSL_Init_Common (void)
|
|||
}
|
||||
|
||||
int
|
||||
GLSL_CompileShader (const char *name, const char *shader_src, int type)
|
||||
GLSL_CompileShader (const char *name, const shader_t *shader, int type)
|
||||
{
|
||||
const char *src[1];
|
||||
int shader;
|
||||
int sid;
|
||||
int compiled;
|
||||
|
||||
src[0] = shader_src;
|
||||
shader = qfeglCreateShader (type);
|
||||
qfeglShaderSource (shader, 1, src, 0);
|
||||
qfeglCompileShader (shader);
|
||||
qfeglGetShaderiv (shader, GL_COMPILE_STATUS, &compiled);
|
||||
sid = qfeglCreateShader (type);
|
||||
qfeglShaderSource (sid, shader->num_strings, shader->strings, 0);
|
||||
qfeglCompileShader (sid);
|
||||
qfeglGetShaderiv (sid, GL_COMPILE_STATUS, &compiled);
|
||||
if (!compiled || (developer->int_val & SYS_GLSL)) {
|
||||
dstring_t *log = dstring_new ();
|
||||
int size;
|
||||
qfeglGetShaderiv (shader, GL_INFO_LOG_LENGTH, &size);
|
||||
qfeglGetShaderiv (sid, GL_INFO_LOG_LENGTH, &size);
|
||||
log->size = size + 1; // for terminating null
|
||||
dstring_adjust (log);
|
||||
qfeglGetShaderInfoLog (shader, log->size, 0, log->str);
|
||||
qfeglGetShaderInfoLog (sid, log->size, 0, log->str);
|
||||
if (!compiled)
|
||||
qfeglDeleteShader (shader);
|
||||
qfeglDeleteShader (sid);
|
||||
Sys_Printf ("Shader (%s) compile log:\n----8<----\n%s----8<----\n",
|
||||
name, log->str);
|
||||
dstring_delete (log);
|
||||
if (!compiled)
|
||||
return 0;
|
||||
}
|
||||
return shader;
|
||||
return sid;
|
||||
}
|
||||
|
||||
int
|
||||
GLSL_CompileShaderS (const char *name, const char *src, int type)
|
||||
{
|
||||
const char *shader_src = src;
|
||||
const char *shader_name = "wrapped";
|
||||
shader_t shader = {1, &shader_src, &shader_name};
|
||||
return GLSL_CompileShader (name, &shader, type);
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
|
Loading…
Reference in a new issue