/* bumpref.c ** ** bummp-reflection-mapping using ** NVIDIA vertex-shaders register-combiners and texture-programs ** Copyright (C) 2002 Florian Berger ** Email: harpin_floh@yahoo.de, florian.berger@jk.uni-linz.ac.at ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License Version 2 as ** published by the Free Software Foundation; ** ** 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 the Free Software ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ** */ #include #include #include #include #include #include #include "bumpref.h" #include "png_loader.h" #include "options.h" #include "vmath.h" #ifndef NO_NV_BUMPREF /* force not to use bumpref */ #ifdef GL_NV_register_combiners #ifdef GL_NV_texture_shader #ifdef GL_NV_vertex_program #define USE_NV_BUMPREF #endif /*GL_NV_vertex_program*/ #endif /*GL_NV_texture_shader*/ #endif /*GL_NV_register_combiners*/ #endif /* NO_NV_BUMPREF */ int bumpref_create_cubemap( char * posx_name, char * posy_name, char * posz_name, char * negx_name, char * negy_name, char * negz_name ) { #ifdef USE_NV_BUMPREF int i, target, cube_tex_bind; unsigned char * data; DPRINTF("setting environment cube map\n"); glActiveTextureARB(GL_TEXTURE2_ARB); glEnable(GL_TEXTURE_CUBE_MAP_ARB); // glEnable(GL_TEXTURE_2D); glGenTextures( 1 , &cube_tex_bind ); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cube_tex_bind); // glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // glTexParameterf(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, options_tex_min_filter); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, options_tex_mag_filter); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); // glBindTexture(GL_TEXTURE_2D, cube_tex_bind); for(i=0;i<6;i++){ int w,h,depth; /* w=64; h=64; data=malloc(w*h*3); for(j=0;j=w)xi2-=w; yi2=yi+dy; if(yi2<0)yi2+=h; if(yi2>=h)yi2-=h; ddata[yi*w+xi]+=gauss*wdata[yi2*w+xi2]; gauss_sum+=gauss; } } ddata[yi*w+xi]/=gauss_sum; } } free(wdata); } void bump2normal(int w, int h, char * data, double strength) /* data has to be rgb */ { int xi, yi, i, xi_n, yi_n; double sd, sd_xn, sd_yn, sd_xyn, dzx, dzy, dx, dy; unsigned char * udata; double * ddata; VMvect n; udata = (unsigned char *)data; ddata = malloc(sizeof(double)*w*h); for(i=0;iinit){ // glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV,0); glCallList(bumpref->bumpref_list); glEnable(GL_REGISTER_COMBINERS_NV); glEnable(GL_TEXTURE_SHADER_NV); if(bumpref->texgen){ glEnable(GL_VERTEX_PROGRAM_NV); } /* normalmap to tex0 */ glActiveTextureARB(GL_TEXTURE0_ARB); // glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, bumpref->normalmap_bind); /* glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); glTexGenfv(GL_S, GL_OBJECT_PLANE, s_gen_params); glTexGenfv(GL_T, GL_OBJECT_PLANE, t_gen_params);*/ /* cubemap to tex3 */ glActiveTextureARB(GL_TEXTURE3_ARB); // glEnable(GL_TEXTURE_CUBE_MAP_ARB); glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, bumpref->cubemap_bind); /* glEnable(GL_TEXTURE_GEN_S); glEnable(GL_TEXTURE_GEN_T); glEnable(GL_TEXTURE_GEN_R); glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB); glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);*/ // glGetFloatv(GL_MODELVIEW_MATRIX, texmat); /* maybe set this per ball to camaera direction */ // texmat[12]=0.0; // texmat[13]=0.0; // texmat[14]=0.0; /* transpose */ // dummy=texmat[1]; texmat[1]=texmat[4]; texmat[4]=dummy; // dummy=texmat[2]; texmat[2]=texmat[8]; texmat[8]=dummy; // du^mmy=texmat[6]; texmat[6]=texmat[9]; texmat[9]=dummy; // glMatrixMode(GL_TEXTURE); // glLoadMatrixf(texmat); // glMatrixMode(GL_MODELVIEW); glActiveTextureARB(GL_TEXTURE0_ARB); /* glPolygonOffset( 0.0, -2.0 ); glEnable( GL_POLYGON_OFFSET_FILL );*/ } #endif /* ifdef USE_NV_BUMPREF */ } void bumpref_restore() { #ifdef USE_NV_BUMPREF glDisable(GL_REGISTER_COMBINERS_NV); glDisable(GL_TEXTURE_SHADER_NV); glDisable(GL_VERTEX_PROGRAM_NV); glActiveTextureARB(GL_TEXTURE3_ARB); glDisable(GL_TEXTURE_CUBE_MAP_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE2_ARB); glDisable(GL_TEXTURE_CUBE_MAP_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE1_ARB); glDisable(GL_TEXTURE_CUBE_MAP_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); glDisable(GL_TEXTURE_CUBE_MAP_ARB); glEnable(GL_TEXTURE_2D); /* glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R);*/ glActiveTextureARB(GL_TEXTURE3_ARB); glDisable(GL_TEXTURE_CUBE_MAP_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); /* glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options_tex_min_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options_tex_mag_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);*/ // glDisable( GL_POLYGON_OFFSET_FILL ); #endif } int bump_create_bumpmap( char * map_name, double strength ) { return bumpref_create_bumpmap( map_name, strength, 0 /* no hilo */ ); } BumpRefType bump_setup_vp_rc( char * map_name, double strength, int texgen ) { #ifdef USE_NV_BUMPREF BumpRefType bumpref; float const0[]={0.5,0.5,0.5,1.0}; float const1[]={0.5,0.5,0.5,1.0}; static unsigned char * vert_prog_str= "!!VP1.0 \n" // # // # c[0-3] = modelview projection (composite) matrix // # TrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV); // # c[4-7] = modelview transpose // # TrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV); // # c[8].z = offset for correct z-buffering // # c[8].x = 0.0 to avoid "ADD R0.z, R0.z, -R0.z" // # c[9] = light pos // # c[10].x = 0.5 /* for unsigend mapping */ // # // # generates light and half vectors into col0 and col1 // # /* R2 = mormal vector n */ "MOV R2, v[NRML]; \n" /* R0 = xy tangent vector n_xy */ "MOV R0.x, -R2.y; \n" "MOV R0.y, R2.x; \n" "MOV R0.z, c[8].x; \n" /* R0.z=0 */ // "ADD R0.z, R0.z, -R0.z; \n" // "ADD R0.z, R0.z, -R0.z; # R0.z=0 uarrghh \n" /* normalize */ "MOV R1, R0; \n" "DP3 R0.w, R1, R1; \n" "RSQ R0.w, R0.w; \n" "MUL R0.xyz, R1, R0.w; \n" /* R1 = other tangent vector n_t = n x n_xy */ "MUL R1, R2.zxyw, R0.yzxw; \n" "MAD R1, R2.yzxw, R0.zxyw, -R1; \n" /* R3=lightdir=dist(light,pos) */ "ADD R3, c[9], -v[OPOS]; \n" /* normalize */ "MOV R4, R3; \n" "DP3 R3.w, R4, R4; \n" "RSQ R3.w, R3.w; \n" "MUL R3.xyz, R4, R3.w; \n" /* R4=camdir=dist(cam,pos) */ "ADD R4, c[7], -v[OPOS]; \n" /* normalize */ "MOV R5, R4; \n" "DP3 R4.w, R5, R5; \n" "RSQ R4.w, R4.w; \n" "MUL R4.xyz, R5, R4.w; \n" /* R4=halfdir=add(light,cam) */ "ADD R4, R4, R3; \n" /* normalize */ "MOV R5, R4; \n" "DP3 R4.w, R5, R5; \n" "RSQ R4.w, R4.w; \n" "MUL R4.xyz, R5, R4.w; \n" /* col0 = lightdir in basis R0 R1 R2 and in unsigned notation */ "DP3 R5.x, R0, R3; \n" "DP3 R5.y, R1, R3; \n" "DP3 R5.z, R2, R3; \n" /* "DP3 o[COL0].x, R0, R3; \n" "DP3 o[COL0].y, R1, R3; \n" "DP3 o[COL0].z, R2, R3; \n"*/ "MAD o[COL0].xyz, c[10].x, R5, c[10].x; \n" /* col1 = halfdir in basis R0 R1 R2 */ "DP3 R5.x, R0, R4; \n" "DP3 R5.y, R1, R4; \n" "DP3 R5.z, R2, R4; \n" "DP3 o[COL1].x, R0, R4; \n" "DP3 o[COL1].y, R1, R4; \n" "DP3 o[COL1].z, R2, R4; \n" "MAD o[COL1].xyz, c[10].x, R5, c[10].x; \n" /* dont forget tex units */ "MOV o[TEX0], v[TEX0]; \n" "MOV o[TEX1], v[TEX0]; \n" /* copy tex0 coords to tex1 coords */ "MOV o[TEX2], v[TEX2]; \n" "MOV o[TEX3], v[TEX3]; \n" /* apply modelview + projection */ "DP4 o[HPOS].x, c[0], v[OPOS]; \n" "DP4 o[HPOS].y, c[1], v[OPOS]; \n" "DP4 R1.z, c[2], v[OPOS]; \n" "DP4 o[HPOS].w, c[3], v[OPOS]; \n" "ADD o[HPOS].z, R1.z, -c[8].z; \n" "END \n"; glGenProgramsNV(1, &bumpref.vert_prog_bind); glBindProgramNV(GL_VERTEX_PROGRAM_NV, bumpref.vert_prog_bind); glLoadProgramNV(GL_VERTEX_PROGRAM_NV, bumpref.vert_prog_bind, strlen(vert_prog_str), vert_prog_str); bumpref.bumpref_list = glGenLists(1); glNewList(bumpref.bumpref_list, GL_COMPILE); /*vertex program*/ glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV /*GL_IDENTITY_NV*/); glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 8, 0.0, 1.0, 0.000 /*no z-offset*/, 1.0); // glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 9, 100.0, 0.0, 0.0, 1.0); /* some light pos */ glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 10, 0.5, 0.0, 0., 0.0); /* const 0.5 */ glBindProgramNV(GL_VERTEX_PROGRAM_NV, bumpref.vert_prog_bind); #if 0 nvparse( "!!RC1.0 \n" " \n" "# Normalize l and h in the combiners! \n" " \n" "{ \n" " rgb { // normalize l and h (step 1) \n" " spare0 = expand(col0) . expand(col0); \n" " spare1 = expand(col1) . expand(col1); \n" " } \n" "} \n" "{ \n" " rgb { // normalize l (step 2) \n" " discard = expand(col0); \n" " discard = half_bias(col0) * \n" " unsigned_invert(spare0); \n" " col0 = sum(); \n" " } \n" "} \n" "{ \n" " rgb { // normalize h (step 2) \n" " discard = expand(col1); \n" " discard = half_bias(col1) * \n" " unsigned_invert(spare1); \n" " col1 = sum(); \n" " } \n" "} \n" "{ \n" " rgb { \n" " spare0 = col0 . expand(tex1); \n" " spare1 = col1 . expand(tex1); \n" " } \n" "} \n" "{ \n" " rgb { \n" " spare1 = unsigned(spare1) * \n" " unsigned(spare1); \n" " } \n" "} \n" "{ \n" " rgb { \n" " spare1 = spare1 * spare1; \n" " } \n" "} \n" "{ \n" " rgb { \n" " spare1 = spare1 * spare1; \n" " } \n" "} \n" "{ \n" " rgb { \n" " spare1 = spare1 * spare1; \n" " } \n" "} \n" "final_product = const0 * spare1; \n" "out.rgb = spare0 * const1 + final_product; \n" // "out.a = unsigned_invert(zero); \n" "out.a = const0.a; \n" ); nvparse_print_errors(stderr); #else /* register combiners */ // const0 = (.5, .5, .5, 1); // const1 = (.5, .3, .1, 1); // glCombinerParameterfvNV(GL_CONSTANT_COLOR1_NV,const1); glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV,8); // combiner stage 0 // spare0 = expand(col0) . expand(tex1); // spare1 = expand(col1) . expand(tex1); glCombinerOutputNV(GL_COMBINER0_NV, GL_RGB, GL_SPARE0_NV, GL_SPARE1_NV, GL_DISCARD_NV /* discard */, GL_NONE /* scale */, GL_NONE /* bias */, GL_TRUE /* dotprod ab */, GL_TRUE /* dotprod cd */, GL_FALSE /* sum discarded anyway */); glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_A_NV, GL_PRIMARY_COLOR_NV/* input */, GL_EXPAND_NORMAL_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_B_NV, GL_PRIMARY_COLOR_NV/* input */, GL_EXPAND_NORMAL_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_C_NV, GL_SECONDARY_COLOR_NV/* input */, GL_EXPAND_NORMAL_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER0_NV, GL_RGB, GL_VARIABLE_D_NV, GL_SECONDARY_COLOR_NV/* input */, GL_EXPAND_NORMAL_NV, GL_RGB /* component usage */); // combiner stage 1 glCombinerOutputNV(GL_COMBINER1_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_PRIMARY_COLOR_NV /* sum */, GL_NONE /* scale */, GL_NONE /* bias */, GL_FALSE /* dotprod ab */, GL_FALSE /* dotprod cd */, GL_FALSE /* sum discarded anyway */); glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_A_NV, GL_PRIMARY_COLOR_NV/* input */, GL_EXPAND_NORMAL_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO/* input */, GL_UNSIGNED_INVERT_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_C_NV, GL_PRIMARY_COLOR_NV/* input */, GL_HALF_BIAS_NORMAL_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER1_NV, GL_RGB, GL_VARIABLE_D_NV, GL_SPARE0_NV/* input */, GL_UNSIGNED_INVERT_NV, GL_RGB /* component usage */); // combiner stage 2 glCombinerOutputNV(GL_COMBINER2_NV, GL_RGB, GL_DISCARD_NV, GL_DISCARD_NV, GL_SECONDARY_COLOR_NV /* sum */, GL_NONE /* scale */, GL_NONE /* bias */, GL_FALSE /* dotprod ab */, GL_FALSE /* dotprod cd */, GL_FALSE /* sum discarded anyway */); glCombinerInputNV(GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SECONDARY_COLOR_NV/* input */, GL_EXPAND_NORMAL_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_B_NV, GL_ZERO/* input */, GL_UNSIGNED_INVERT_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_C_NV, GL_SECONDARY_COLOR_NV/* input */, GL_HALF_BIAS_NORMAL_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER2_NV, GL_RGB, GL_VARIABLE_D_NV, GL_SPARE1_NV/* input */, GL_UNSIGNED_INVERT_NV, GL_RGB /* component usage */); // combiner stage 3 // spare0 = expand(col0) . expand(tex1); // spare1 = expand(col1) . expand(tex1); glCombinerOutputNV(GL_COMBINER3_NV, GL_RGB, GL_SPARE0_NV, GL_SPARE1_NV, GL_DISCARD_NV /* discard */, GL_NONE /* scale */, GL_NONE /* bias */, GL_TRUE /* dotprod ab */, GL_TRUE /* dotprod cd */, GL_FALSE /* sum discarded anyway */); glCombinerInputNV(GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_A_NV, GL_PRIMARY_COLOR_NV/* input */, GL_SIGNED_IDENTITY_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV, GL_TEXTURE1_ARB/* input */, GL_EXPAND_NORMAL_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_C_NV, GL_SECONDARY_COLOR_NV/* input */, GL_SIGNED_IDENTITY_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_D_NV, GL_TEXTURE1_ARB/* input */, GL_EXPAND_NORMAL_NV, GL_RGB /* component usage */); // combiner stage 4 // spare1 = unsigned(spare1) * unsigned(spare1); glCombinerOutputNV(GL_COMBINER4_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV,/* discard 2nd prod */ GL_DISCARD_NV /* discard sum */, GL_NONE /* scale */, GL_NONE /* bias */, GL_FALSE /* dotprod ab */, GL_TRUE /* discarded anyway */, GL_FALSE /* sum discarded anyway */); glCombinerInputNV(GL_COMBINER4_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE1_NV/* input */, GL_UNSIGNED_IDENTITY_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER4_NV, GL_RGB, GL_VARIABLE_B_NV, GL_SPARE1_NV/* input */, GL_UNSIGNED_IDENTITY_NV, GL_RGB /* component usage */); // combiner stage 5 // spare1 = unsigned(spare1) * unsigned(spare1); glCombinerOutputNV(GL_COMBINER5_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV,/* discard 2nd prod */ GL_DISCARD_NV /* discard sum */, GL_NONE /* scale */, GL_NONE /* bias */, GL_FALSE /* dotprod ab */, GL_TRUE /* discarded anyway */, GL_FALSE /* sum discarded anyway */); glCombinerInputNV(GL_COMBINER5_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE1_NV /* input */, GL_UNSIGNED_IDENTITY_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER5_NV, GL_RGB, GL_VARIABLE_B_NV, GL_SPARE1_NV /* input */, GL_UNSIGNED_IDENTITY_NV, GL_RGB /* component usage */); // combiner stage 6 // spare1 = unsigned(spare1) * unsigned(spare1); glCombinerOutputNV(GL_COMBINER6_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV,/* discard 2nd prod */ GL_DISCARD_NV /* discard sum */, GL_NONE /* scale */, GL_NONE /* bias */, GL_FALSE /* dotprod ab */, GL_TRUE /* discarded anyway */, GL_FALSE /* sum discarded anyway */); glCombinerInputNV(GL_COMBINER6_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE1_NV /* input */, GL_UNSIGNED_IDENTITY_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER6_NV, GL_RGB, GL_VARIABLE_B_NV, GL_SPARE1_NV /* input */, GL_UNSIGNED_IDENTITY_NV, GL_RGB /* component usage */); // combiner stage 7 // spare1 = unsigned(spare1) * unsigned(spare1); glCombinerOutputNV(GL_COMBINER7_NV, GL_RGB, GL_SPARE1_NV, GL_DISCARD_NV,/* discard 2nd prod */ GL_DISCARD_NV /* discard sum */, GL_NONE /* scale */, GL_NONE /* bias */, GL_FALSE /* dotprod ab */, GL_TRUE /* discarded anyway */, GL_FALSE /* sum discarded anyway */); glCombinerInputNV(GL_COMBINER7_NV, GL_RGB, GL_VARIABLE_A_NV, GL_SPARE1_NV /* input */, GL_UNSIGNED_IDENTITY_NV, GL_RGB /* component usage */); glCombinerInputNV(GL_COMBINER7_NV, GL_RGB, GL_VARIABLE_B_NV, GL_SPARE1_NV /* input */, GL_UNSIGNED_IDENTITY_NV, GL_RGB /* component usage */); // final_product = const0 * spare1; glFinalCombinerInputNV(GL_VARIABLE_E_NV, GL_SPARE1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB); glFinalCombinerInputNV(GL_VARIABLE_F_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB); glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_E_TIMES_F_NV, // GL_ZERO, /* dont use specular */ GL_UNSIGNED_IDENTITY_NV, GL_RGB); // out.rgb = spare0 * const1 + final_product; glFinalCombinerInputNV(GL_VARIABLE_A_NV, GL_SPARE0_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB); glFinalCombinerInputNV(GL_VARIABLE_B_NV, GL_CONSTANT_COLOR1_NV, GL_UNSIGNED_IDENTITY_NV, GL_RGB); glFinalCombinerInputNV(GL_VARIABLE_C_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB); /* glFinalCombinerInputNV(GL_VARIABLE_D_NV, GL_ZERO, GL_UNSIGNED_IDENTITY_NV, GL_RGB);*/ /* already set by final product */ glFinalCombinerInputNV(GL_VARIABLE_G_NV, GL_CONSTANT_COLOR0_NV, GL_UNSIGNED_IDENTITY_NV, GL_ALPHA); #endif glEndList(); bumpref.normalmap_bind = bump_create_bumpmap( map_name, strength ); /* default values */ bumpref.bump_light[0] = 0.0; bumpref.bump_light[1] = 0.0; bumpref.bump_light[2] = 0.0; bumpref.bump_diff_col[0] = 0.5; bumpref.bump_diff_col[1] = 0.0; bumpref.bump_diff_col[2] = 0.0; bumpref.bump_diff_col[3] = 1.0; bumpref.bump_spec_col[0] = 0.8; bumpref.bump_spec_col[1] = 0.8; bumpref.bump_spec_col[2] = 0.8; bumpref.bump_spec_col[3] = 1.0; bumpref.init=1; return(bumpref); #endif } void bump_set_light( BumpRefType * bumpref, float x, float y, float z ) { #ifdef USE_NV_BUMPREF bumpref->bump_light[0]=x; bumpref->bump_light[1]=y; bumpref->bump_light[2]=z; glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 9, bumpref->bump_light[0], bumpref->bump_light[1], bumpref->bump_light[2], 1.0); /* some light pos */ #endif } void bump_set_diff( BumpRefType * bumpref, float r, float g, float b ) { #ifdef USE_NV_BUMPREF bumpref->bump_diff_col[0]=r; bumpref->bump_diff_col[1]=g; bumpref->bump_diff_col[2]=b; bumpref->bump_diff_col[3]=1.0; glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, bumpref->bump_diff_col); #endif } void bump_set_spec( BumpRefType * bumpref, float r, float g, float b ) { #ifdef USE_NV_BUMPREF bumpref->bump_spec_col[0]=r; bumpref->bump_spec_col[1]=g; bumpref->bump_spec_col[2]=b; bumpref->bump_spec_col[3]=1.0; glCombinerParameterfvNV(GL_CONSTANT_COLOR0_NV, bumpref->bump_spec_col); #endif } void bump_use( BumpRefType * bumpref ) { #ifdef USE_NV_BUMPREF /* double sin_,cos_; static double phi=0.0;*/ // glCombinerParameteriNV(GL_NUM_GENERAL_COMBINERS_NV,8); glCallList(bumpref->bumpref_list); glEnable(GL_REGISTER_COMBINERS_NV); glDisable(GL_TEXTURE_SHADER_NV); glEnable(GL_VERTEX_PROGRAM_NV); { /* float const0[4]={0.5,0.5,0.5,1.0}; float const1[4]={0.0,0.0,0.0,1.0};*/ glCombinerParameterfvNV( GL_CONSTANT_COLOR0_NV, bumpref->bump_spec_col ); glCombinerParameterfvNV( GL_CONSTANT_COLOR1_NV, bumpref->bump_diff_col ); } DPRINTF("light=%f %f %f\n", bumpref->bump_light[0], bumpref->bump_light[1], bumpref->bump_light[2]); glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 9, bumpref->bump_light[0], bumpref->bump_light[1], bumpref->bump_light[2], 1.0); /* some light pos */ /* normalmap to tex1 */ glActiveTextureARB(GL_TEXTURE1_ARB); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, bumpref->normalmap_bind); glActiveTextureARB(GL_TEXTURE0_ARB); glEnable(GL_TEXTURE_2D); glPolygonOffset( 0.0, -2.0 ); glEnable( GL_POLYGON_OFFSET_FILL ); #endif } void bump_restore() { #ifdef USE_NV_BUMPREF glDisable(GL_REGISTER_COMBINERS_NV); glDisable(GL_TEXTURE_SHADER_NV); glDisable(GL_VERTEX_PROGRAM_NV); /* glActiveTextureARB(GL_TEXTURE3_ARB); glDisable(GL_TEXTURE_CUBE_MAP_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE2_ARB); glDisable(GL_TEXTURE_CUBE_MAP_ARB); glDisable(GL_TEXTURE_2D);*/ glActiveTextureARB(GL_TEXTURE1_ARB); // glDisable(GL_TEXTURE_CUBE_MAP_ARB); glDisable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); // glDisable(GL_TEXTURE_CUBE_MAP_ARB); glEnable(GL_TEXTURE_2D); glActiveTextureARB(GL_TEXTURE0_ARB); glDisable( GL_POLYGON_OFFSET_FILL ); #endif }