From d758c48761a2be2a6c9b3d80f8fe06d32b5dd0d3 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 2 Nov 2008 11:49:46 -0800 Subject: i965: Fix copy'n'paste issue that made brw->urb.constrained useless. Also, add a comment explaining what brw->urb.constrained tries to do. --- src/mesa/drivers/dri/i965/brw_urb.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_urb.c b/src/mesa/drivers/dri/i965/brw_urb.c index 1116ade0a..1a004176d 100644 --- a/src/mesa/drivers/dri/i965/brw_urb.c +++ b/src/mesa/drivers/dri/i965/brw_urb.c @@ -92,9 +92,9 @@ static void recalculate_urb_fence( struct brw_context *brw ) if (brw->urb.vsize < vsize || brw->urb.sfsize < sfsize || brw->urb.csize < csize || - (brw->urb.constrained && (brw->urb.vsize > brw->urb.vsize || - brw->urb.sfsize > brw->urb.sfsize || - brw->urb.csize > brw->urb.csize))) { + (brw->urb.constrained && (brw->urb.vsize > vsize || + brw->urb.sfsize > sfsize || + brw->urb.csize > csize))) { brw->urb.csize = csize; @@ -114,6 +114,10 @@ static void recalculate_urb_fence( struct brw_context *brw ) brw->urb.nr_sf_entries = limits[SF].min_nr_entries; brw->urb.nr_cs_entries = limits[CS].min_nr_entries; + /* Mark us as operating with constrained nr_entries, so that next + * time we recalculate we'll resize the fences in the hope of + * escaping constrained mode and getting back to normal performance. + */ brw->urb.constrained = 1; if (!check_urb_layout(brw)) { -- cgit v1.2.3 From 34b1776e8d965605d12807884c9c447214d57281 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 2 Nov 2008 12:15:53 -0800 Subject: i965: Merge GM45 into the G4X chipset define. The mobile and desktop chipsets are the same, and having them separate is more typing and more chances to screw up. --- src/mesa/drivers/dri/i965/brw_clip_line.c | 2 +- src/mesa/drivers/dri/i965/brw_clip_state.c | 2 +- src/mesa/drivers/dri/i965/brw_clip_tri.c | 2 +- src/mesa/drivers/dri/i965/brw_defines.h | 7 +++---- src/mesa/drivers/dri/i965/brw_eu_emit.c | 16 ++++++++-------- src/mesa/drivers/dri/i965/brw_misc_state.c | 8 ++++---- src/mesa/drivers/dri/i965/brw_structs.h | 4 ++-- src/mesa/drivers/dri/i965/brw_vs_emit.c | 2 +- src/mesa/drivers/dri/intel/intel_chipset.h | 6 +++--- 9 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c index c87e5b9a1..c45d48dff 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_line.c +++ b/src/mesa/drivers/dri/i965/brw_clip_line.c @@ -148,7 +148,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c ) brw_clip_init_clipmask(c); /* -ve rhw workaround */ - if (!(BRW_IS_GM45(p->brw) || BRW_IS_G4X(p->brw))) { + if (!BRW_IS_G4X(p->brw)) { brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<20)); diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c index 82d1e8735..740c7cbd1 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_state.c +++ b/src/mesa/drivers/dri/i965/brw_clip_state.c @@ -102,7 +102,7 @@ clip_unit_create_from_key(struct brw_context *brw, clip.clip5.api_mode = BRW_CLIP_API_OGL; clip.clip5.clip_mode = key->clip_mode; - if (BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) + if (BRW_IS_G4X(brw)) clip.clip5.negative_w_clip_test = 1; clip.clip6.clipper_viewport_state_ptr = 0; diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c index 8459b59b4..1dbba37fe 100644 --- a/src/mesa/drivers/dri/i965/brw_clip_tri.c +++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c @@ -526,7 +526,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c ) /* if -ve rhw workaround bit is set, do cliptest */ - if (!(BRW_IS_GM45(p->brw) || BRW_IS_G4X(p->brw))) { + if (!BRW_IS_G4X(p->brw)) { brw_set_conditionalmod(p, BRW_CONDITIONAL_NZ); brw_AND(p, brw_null_reg(), get_element_ud(c->reg.R0, 2), brw_imm_ud(1<<20)); diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h index 0593e8d5f..39c32255f 100644 --- a/src/mesa/drivers/dri/i965/brw_defines.h +++ b/src/mesa/drivers/dri/i965/brw_defines.h @@ -798,10 +798,9 @@ #include "intel_chipset.h" -#define BRW_IS_GM45(brw) (IS_GM45_GM((brw)->intel.intelScreen->deviceID)) #define BRW_IS_G4X(brw) (IS_G4X((brw)->intel.intelScreen->deviceID)) -#define CMD_PIPELINE_SELECT(brw) ((BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965) -#define CMD_VF_STATISTICS(brw) ((BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965) -#define URB_SIZES(brw) ((BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) ? 384 : 256) /* 512 bit unit */ +#define CMD_PIPELINE_SELECT(brw) (BRW_IS_G4X(brw) ? CMD_PIPELINE_SELECT_GM45 : CMD_PIPELINE_SELECT_965) +#define CMD_VF_STATISTICS(brw) (BRW_IS_G4X(brw) ? CMD_VF_STATISTICS_GM45 : CMD_VF_STATISTICS_965) +#define URB_SIZES(brw) (BRW_IS_G4X(brw) ? 384 : 256) /* 512 bit units */ #endif diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c index 58d97465d..ce4cf46cf 100644 --- a/src/mesa/drivers/dri/i965/brw_eu_emit.c +++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c @@ -333,14 +333,14 @@ static void brw_set_sampler_message(struct brw_context *brw, { brw_set_src1(insn, brw_imm_d(0)); - if (BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) { - insn->bits3.sampler_gm45_g4x.binding_table_index = binding_table_index; - insn->bits3.sampler_gm45_g4x.sampler = sampler; - insn->bits3.sampler_gm45_g4x.msg_type = msg_type; - insn->bits3.sampler_gm45_g4x.response_length = response_length; - insn->bits3.sampler_gm45_g4x.msg_length = msg_length; - insn->bits3.sampler_gm45_g4x.end_of_thread = eot; - insn->bits3.sampler_gm45_g4x.msg_target = BRW_MESSAGE_TARGET_SAMPLER; + if (BRW_IS_G4X(brw)) { + insn->bits3.sampler_g4x.binding_table_index = binding_table_index; + insn->bits3.sampler_g4x.sampler = sampler; + insn->bits3.sampler_g4x.msg_type = msg_type; + insn->bits3.sampler_g4x.response_length = response_length; + insn->bits3.sampler_g4x.msg_length = msg_length; + insn->bits3.sampler_g4x.end_of_thread = eot; + insn->bits3.sampler_g4x.msg_target = BRW_MESSAGE_TARGET_SAMPLER; } else { insn->bits3.sampler.binding_table_index = binding_table_index; insn->bits3.sampler.sampler = sampler; diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c index 5bba8c84e..627705fa9 100644 --- a/src/mesa/drivers/dri/i965/brw_misc_state.c +++ b/src/mesa/drivers/dri/i965/brw_misc_state.c @@ -211,7 +211,7 @@ static void emit_depthbuffer(struct brw_context *brw) { struct intel_context *intel = &brw->intel; struct intel_region *region = brw->state.depth_region; - unsigned int len = (BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) ? sizeof(struct brw_depthbuffer_gm45_g4x) / 4 : sizeof(struct brw_depthbuffer) / 4; + unsigned int len = BRW_IS_G4X(brw) ? 6 : 5; if (region == NULL) { BEGIN_BATCH(len, IGNORE_CLIPRECTS); @@ -222,7 +222,7 @@ static void emit_depthbuffer(struct brw_context *brw) OUT_BATCH(0); OUT_BATCH(0); - if (BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) + if (BRW_IS_G4X(brw)) OUT_BATCH(0); ADVANCE_BATCH(); @@ -259,7 +259,7 @@ static void emit_depthbuffer(struct brw_context *brw) ((region->height - 1) << 19)); OUT_BATCH(0); - if (BRW_IS_GM45(brw) || BRW_IS_G4X(brw)) + if (BRW_IS_G4X(brw)) OUT_BATCH(0); ADVANCE_BATCH(); @@ -344,7 +344,7 @@ static void upload_aa_line_parameters(struct brw_context *brw) { struct brw_aa_line_parameters balp; - if (!(BRW_IS_GM45(brw) || BRW_IS_G4X(brw))) + if (!BRW_IS_G4X(brw)) return; /* use legacy aa line coverage computation */ diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h index ec865c925..4e577d0f6 100644 --- a/src/mesa/drivers/dri/i965/brw_structs.h +++ b/src/mesa/drivers/dri/i965/brw_structs.h @@ -175,7 +175,7 @@ struct brw_depthbuffer } dword4; }; -struct brw_depthbuffer_gm45_g4x +struct brw_depthbuffer_g4x { union header_union header; @@ -1405,7 +1405,7 @@ struct brw_instruction GLuint msg_target:4; GLuint pad1:3; GLuint end_of_thread:1; - } sampler_gm45_g4x; + } sampler_g4x; struct brw_urb_immediate urb; diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 9de05408b..0b6c6b2a0 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -867,7 +867,7 @@ static void emit_vertex_write( struct brw_vs_compile *c) * Later, clipping will detect ucp[6] and ensure the primitive is * clipped against all fixed planes. */ - if (!(BRW_IS_GM45(p->brw) || BRW_IS_G4X(p->brw)) && !c->key.know_w_is_one) { + if (!BRW_IS_G4X(p->brw) && !c->key.know_w_is_one) { brw_CMP(p, vec8(brw_null_reg()), BRW_CONDITIONAL_L, diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h index 170efd060..d1b494160 100644 --- a/src/mesa/drivers/dri/intel/intel_chipset.h +++ b/src/mesa/drivers/dri/intel/intel_chipset.h @@ -68,11 +68,12 @@ devid == PCI_CHIP_I965_GME || \ devid == PCI_CHIP_GM45_GM) -#define IS_GM45_GM(devid) (devid == PCI_CHIP_GM45_GM) -#define IS_G4X(devid) (devid == PCI_CHIP_IGD_E_G || \ +#define IS_G45(devid) (devid == PCI_CHIP_IGD_E_G || \ devid == PCI_CHIP_Q45_G || \ devid == PCI_CHIP_G45_G || \ devid == PCI_CHIP_G41_G) +#define IS_GM45(devid) (devid == PCI_CHIP_GM45_GM) +#define IS_G4X(devid) (IS_G45(devid) || IS_GM45(devid)) #define IS_915(devid) (devid == PCI_CHIP_I915_G || \ devid == PCI_CHIP_E7221_G || \ @@ -91,7 +92,6 @@ devid == PCI_CHIP_I965_GM || \ devid == PCI_CHIP_I965_GME || \ devid == PCI_CHIP_I946_GZ || \ - IS_GM45_GM(devid) || \ IS_G4X(devid)) #define IS_9XX(devid) (IS_915(devid) || \ -- cgit v1.2.3 From 9fd4c27ae3e189df804b86843a6aad0e70640533 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 2 Nov 2008 12:19:02 -0800 Subject: i965: Avoid vs header computation for negative rhw on G4X. This cuts one MOV out when setting a zero header. --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index 0b6c6b2a0..ed0e1d527 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -829,12 +829,12 @@ static void emit_vertex_write( struct brw_vs_compile *c) ndc = pos; } - /* This includes the workaround for -ve rhw, so is no longer an - * optional step: + /* Update the header for point size, user clipping flags, and -ve rhw + * workaround. */ if ((c->prog_data.outputs_written & (1<key.nr_userclip || - !c->key.know_w_is_one) + (!BRW_IS_G4X(p->brw) && !c->key.know_w_is_one)) { struct brw_reg header1 = retype(get_tmp(c), BRW_REGISTER_TYPE_UD); GLuint i; -- cgit v1.2.3 From 4be624d693554ad3950afab90e331a6725cc5004 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sun, 2 Nov 2008 12:29:03 -0800 Subject: i965: Clean up stale NDC comment. --- src/mesa/drivers/dri/i965/brw_vs_emit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c index ed0e1d527..25b4ee85c 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_emit.c +++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c @@ -818,8 +818,7 @@ static void emit_vertex_write( struct brw_vs_compile *c) } - /* Build ndc coords? TODO: Shortcircuit when w is known to be one. - */ + /* Build ndc coords */ if (!c->key.know_w_is_one) { ndc = get_tmp(c); emit_math1(c, BRW_MATH_FUNCTION_INV, ndc, brw_swizzle1(pos, 3), BRW_MATH_PRECISION_FULL); -- cgit v1.2.3 From d3222cb1d465cf49ff5b2119f7515c5f57024964 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Nov 2008 15:11:56 -0700 Subject: remove old debug glFlush/Finish calls from demos --- progs/glsl/bump.c | 3 --- progs/glsl/convolutions.c | 2 -- progs/glsl/mandelbrot.c | 2 -- progs/glsl/toyball.c | 2 -- 4 files changed, 9 deletions(-) diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c index a2e091686..b93ab44b5 100644 --- a/progs/glsl/bump.c +++ b/progs/glsl/bump.c @@ -141,9 +141,6 @@ Redisplay(void) glPopMatrix(); - glFinish(); - glFlush(); - CheckError(__LINE__); glutSwapBuffers(); diff --git a/progs/glsl/convolutions.c b/progs/glsl/convolutions.c index 13c7eab0e..c5caa8ffe 100644 --- a/progs/glsl/convolutions.c +++ b/progs/glsl/convolutions.c @@ -438,8 +438,6 @@ static void draw() glPopMatrix(); - glFlush(); - glutSwapBuffers(); } diff --git a/progs/glsl/mandelbrot.c b/progs/glsl/mandelbrot.c index e6361b429..24e199266 100644 --- a/progs/glsl/mandelbrot.c +++ b/progs/glsl/mandelbrot.c @@ -74,8 +74,6 @@ Redisplay(void) glPopMatrix(); - glFinish(); - glFlush(); glutSwapBuffers(); } diff --git a/progs/glsl/toyball.c b/progs/glsl/toyball.c index 2daaedd6d..37ad6bf29 100644 --- a/progs/glsl/toyball.c +++ b/progs/glsl/toyball.c @@ -79,8 +79,6 @@ Redisplay(void) glPopMatrix(); - glFinish(); - glFlush(); glutSwapBuffers(); } -- cgit v1.2.3 From 35a9f1bccf2284c853cd20ccf2192ebc382a4706 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Nov 2008 15:19:28 -0700 Subject: print err msg if unable to open shader file --- progs/util/shaderutil.c | 1 + 1 file changed, 1 insertion(+) diff --git a/progs/util/shaderutil.c b/progs/util/shaderutil.c index 4f17dd7ef..745851395 100644 --- a/progs/util/shaderutil.c +++ b/progs/util/shaderutil.c @@ -80,6 +80,7 @@ CompileShaderFile(GLenum shaderType, const char *filename) FILE *f = fopen(filename, "r"); if (!f) { + fprintf(stderr, "Unable to open shader file %s\n", filename); return 0; } -- cgit v1.2.3 From 6c8274078d08e5d87c993603b9bfcdf1ffa51278 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Nov 2008 16:52:53 -0700 Subject: mesa: fix float-valued GLSL vertex attribute variables The swizzle mask for such variables wasn't set up properly. --- src/mesa/shader/slang/slang_codegen.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index d8a92e23c..e7b2bad8c 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -3811,6 +3811,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, if (dbg) printf("VARYING "); } else if (var->type.qualifier == SLANG_QUAL_ATTRIBUTE) { + GLuint swizzle; + GLint index; /* attributes must be float, vec or mat */ if (!_slang_type_is_float_vec_mat(var->type.specifier.type)) { slang_info_log_error(A->log, @@ -3822,20 +3824,18 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var, if (prog) { /* user-defined vertex attribute */ const GLint attr = -1; /* unknown */ - GLint index = _mesa_add_attribute(prog->Attributes, varName, - size, datatype, attr); + swizzle = _slang_var_swizzle(size, 0); + index = _mesa_add_attribute(prog->Attributes, varName, + size, datatype, attr); assert(index >= 0); - store = _slang_new_ir_storage(PROGRAM_INPUT, - VERT_ATTRIB_GENERIC0 + index, size); + index = VERT_ATTRIB_GENERIC0 + index; } else { /* pre-defined vertex attrib */ - GLuint swizzle; - GLint index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB, - &swizzle); + index = _slang_input_index(varName, GL_VERTEX_PROGRAM_ARB, &swizzle); assert(index >= 0); - store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle); } + store = _slang_new_ir_storage_swz(PROGRAM_INPUT, index, size, swizzle); if (dbg) printf("ATTRIB "); } else if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT) { -- cgit v1.2.3 From aab429c8df228271786890691a43786baf091b37 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 4 Nov 2008 16:56:59 -0700 Subject: added glsl/skinning.c test to test matrix blending/weighting --- progs/glsl/Makefile | 8 ++ progs/glsl/multitex.frag | 24 +++- progs/glsl/skinning.c | 280 +++++++++++++++++++++++++++++++++++++++++++++++ progs/glsl/skinning.frag | 6 + progs/glsl/skinning.vert | 24 ++++ 5 files changed, 340 insertions(+), 2 deletions(-) create mode 100644 progs/glsl/skinning.c create mode 100644 progs/glsl/skinning.frag create mode 100644 progs/glsl/skinning.vert diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile index 850b6bdbd..41d584991 100644 --- a/progs/glsl/Makefile +++ b/progs/glsl/Makefile @@ -20,6 +20,7 @@ PROGS = \ noise \ points \ pointcoord \ + skinning \ texdemo1 \ toyball \ twoside \ @@ -140,6 +141,13 @@ pointcoord: pointcoord.o readtex.o shaderutil.o $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) pointcoord.o readtex.o shaderutil.o $(LIBS) -o $@ +skinning.o: skinning.c readtex.h extfuncs.h shaderutil.h + $(CC) -c -I$(INCDIR) $(CFLAGS) skinning.c + +skinning: skinning.o readtex.o shaderutil.o + $(CC) -I$(INCDIR) $(CFLAGS) $(LDFLAGS) skinning.o readtex.o shaderutil.o $(LIBS) -o $@ + + texdemo1.o: texdemo1.c readtex.h extfuncs.h shaderutil.h $(CC) -c -I$(INCDIR) $(CFLAGS) texdemo1.c diff --git a/progs/glsl/multitex.frag b/progs/glsl/multitex.frag index a2633ceba..61ef95f3f 100644 --- a/progs/glsl/multitex.frag +++ b/progs/glsl/multitex.frag @@ -7,9 +7,29 @@ uniform sampler2D tex1; uniform sampler2D tex2; -void main() +vec4 sample(sampler2D t, vec2 coord) +{ + return texture2D(t, coord); +} + +void main0() { vec4 t1 = texture2D(tex1, gl_TexCoord[0].xy); - vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy); + //vec4 t1 = sample(tex1, gl_TexCoord[0].xy); + //vec4 t2 = texture2D(tex2, gl_TexCoord[1].xy); + vec4 t2 = sample(tex2, gl_TexCoord[0].xy); gl_FragColor = mix(t1, t2, t2.w); } + +void main() +{ + vec4 t1 = sample(tex1, gl_TexCoord[0].xy); + vec4 t2 = sample(tex2, gl_TexCoord[0].xy); + gl_FragColor = t1 + t2; +} +/* + 0: MOV SAMPLER[0].x, SAMPLER[0]; + 1: MOV TEMP[1], INPUT[4]; + 2: TEX OUTPUT[0], TEMP[1], texture[0], 2D; + 3: END +*/ diff --git a/progs/glsl/skinning.c b/progs/glsl/skinning.c new file mode 100644 index 000000000..8a65d0667 --- /dev/null +++ b/progs/glsl/skinning.c @@ -0,0 +1,280 @@ +/** + * Vertex "skinning" example. + * The idea is there are multiple modeling matrices applied to every + * vertex. Weighting values in [0,1] control the influence of each + * matrix on each vertex. + * + * 4 Nov 2008 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "extfuncs.h" +#include "shaderutil.h" + + +static char *FragProgFile = "skinning.frag"; +static char *VertProgFile = "skinning.vert"; + +/* program/shader objects */ +static GLuint fragShader; +static GLuint vertShader; +static GLuint program; + + +static GLint win = 0; +static GLboolean Anim = GL_TRUE; +static GLboolean WireFrame = GL_TRUE; +static GLfloat xRot = 0.0f, yRot = 90.0f, zRot = 0.0f; + +#define NUM_MATS 2 + +static GLfloat Matrices[NUM_MATS][16]; +static GLint uMat0, uMat1; +static GLint WeightAttr; + + +static void +Idle(void) +{ + yRot = 90 + glutGet(GLUT_ELAPSED_TIME) * 0.005; + glutPostRedisplay(); +} + + +static void +Cylinder(GLfloat length, GLfloat radius, GLint slices, GLint stacks) +{ + float dw = 1.0 / (stacks - 1); + float dz = length / stacks; + int i, j; + + for (j = 0; j < stacks; j++) { + float w0 = j * dw; + float z0 = j * dz; + + glBegin(GL_TRIANGLE_STRIP); + for (i = 0; i < slices; i++) { + float a = (float) i / (slices - 1) * M_PI * 2.0; + float x = radius * cos(a); + float y = radius * sin(a); + glVertexAttrib1f_func(WeightAttr, w0); + glNormal3f(x, y, 0.0); + glVertex3f(x, y, z0); + + glVertexAttrib1f_func(WeightAttr, w0 + dw); + glNormal3f(x, y, 0.0); + glVertex3f(x, y, z0 + dz); + } + glEnd(); + } +} + + +/** + * Update/animate the two matrices. One rotates, the other scales. + */ +static void +UpdateMatrices(void) +{ + GLfloat t = glutGet(GLUT_ELAPSED_TIME) * 0.0025; + GLfloat scale = 0.5 * (1.1 + sin(0.5 * t)); + GLfloat rot = cos(t) * 90.0; + + glPushMatrix(); + glLoadIdentity(); + glScalef(1.0, scale, 1.0); + glGetFloatv(GL_MODELVIEW_MATRIX, Matrices[0]); + glPopMatrix(); + + glPushMatrix(); + glLoadIdentity(); + glRotatef(rot, 0, 0, 1); + glGetFloatv(GL_MODELVIEW_MATRIX, Matrices[1]); + glPopMatrix(); +} + + +static void +Redisplay(void) +{ + UpdateMatrices(); + + glUniformMatrix4fv_func(uMat0, 1, GL_FALSE, Matrices[0]); + glUniformMatrix4fv_func(uMat1, 1, GL_FALSE, Matrices[1]); + + if (WireFrame) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + else + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(xRot, 1.0f, 0.0f, 0.0f); + glRotatef(yRot, 0.0f, 1.0f, 0.0f); + glRotatef(zRot, 0.0f, 0.0f, 1.0f); + + glPushMatrix(); + glTranslatef(0, 0, -2.5); + Cylinder(5.0, 1.0, 10, 20); + glPopMatrix(); + + glPopMatrix(); + + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, -15.0f); +} + + +static void +CleanUp(void) +{ + glDeleteShader_func(fragShader); + glDeleteShader_func(vertShader); + glDeleteProgram_func(program); + glutDestroyWindow(win); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 2.0; + (void) x; + (void) y; + + switch(key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'w': + WireFrame = !WireFrame; + break; + case 'z': + zRot += step; + break; + case 'Z': + zRot -= step; + break; + case 27: + CleanUp(); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 2.0; + + (void) x; + (void) y; + + switch(key) { + case GLUT_KEY_UP: + xRot += step; + break; + case GLUT_KEY_DOWN: + xRot -= step; + break; + case GLUT_KEY_LEFT: + yRot -= step; + break; + case GLUT_KEY_RIGHT: + yRot += step; + break; + } + glutPostRedisplay(); +} + + + +static void +Init(void) +{ + if (!ShadersSupported()) + exit(1); + + GetExtensionFuncs(); + + vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertProgFile); + fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragProgFile); + program = LinkShaders(vertShader, fragShader); + + glUseProgram_func(program); + + uMat0 = glGetUniformLocation_func(program, "mat0"); + uMat1 = glGetUniformLocation_func(program, "mat1"); + + WeightAttr = glGetAttribLocation_func(program, "weight"); + + assert(glGetError() == 0); + + glClearColor(0.4f, 0.4f, 0.8f, 0.0f); + + glEnable(GL_DEPTH_TEST); + + glColor3f(1, 0, 0); +} + + +static void +ParseOptions(int argc, char *argv[]) +{ + int i; + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-fs") == 0) { + FragProgFile = argv[i+1]; + } + else if (strcmp(argv[i], "-vs") == 0) { + VertProgFile = argv[i+1]; + } + } +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(500, 500); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + win = glutCreateWindow(argv[0]); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Redisplay); + ParseOptions(argc, argv); + Init(); + if (Anim) + glutIdleFunc(Idle); + glutMainLoop(); + return 0; +} + diff --git a/progs/glsl/skinning.frag b/progs/glsl/skinning.frag new file mode 100644 index 000000000..9053755a8 --- /dev/null +++ b/progs/glsl/skinning.frag @@ -0,0 +1,6 @@ +// color pass-through + +void main() +{ + gl_FragColor = gl_Color; +} diff --git a/progs/glsl/skinning.vert b/progs/glsl/skinning.vert new file mode 100644 index 000000000..28970eee5 --- /dev/null +++ b/progs/glsl/skinning.vert @@ -0,0 +1,24 @@ +// Vertex weighting/blendin shader +// Brian Paul +// 4 Nov 2008 + +uniform mat4 mat0, mat1; +attribute float weight; + +void main() +{ + // simple diffuse shading + // Note that we should really transform the normal vector along with + // the postion below... someday. + vec3 lightVec = vec3(0, 0, 1); + vec3 norm = gl_NormalMatrix * gl_Normal; + float dot = 0.2 + max(0.0, dot(norm, lightVec)); + gl_FrontColor = vec4(dot); + + // compute sum of weighted transformations + vec4 pos0 = mat0 * gl_Vertex; + vec4 pos1 = mat1 * gl_Vertex; + vec4 pos = mix(pos0, pos1, weight); + + gl_Position = gl_ModelViewProjectionMatrix * pos; +} -- cgit v1.2.3