/* GLP library implementation v0.1 by Antoine Mine 4/07/98 Find any help in glp.html. */ #include <GL/gl.h> #include <GL/glu.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "glp.h" static GLfloat* tex = NULL; static GLuint tex2Dl,tex2Drgb; static GLuint tex3Dl,tex3Drgb; static GLuint texId; static int mode3D = 0; static int modeRgb = 1; static GLuint octave = 4; static GLfloat freq_mult = 2.0; static GLfloat amp_div = 2.0; static GLfloat amplitude = 1.0; static GLuint max = 16; static GLboolean noisedirty = GL_TRUE; static GLfloat noise_amp = 0.5; static GLfloat noise_begin = 0.0; static GLfloat noise_end = 1.0; static GLuint maxfun = 256; static GLenum funmode = GLP_MODE_RAMP; static GLfloat fun_amp = 0.5; static GLboolean iddirty = GL_TRUE; static GLfloat* id = NULL; static GLuint mapcoord; static GLenum error = GLP_NO_ERROR; static const GLubyte* error_msg[] = { "out of memory", "bad parameter", "bad value", "harward capacity exceded", "not supported by harward" }; static GLfloat* colormap = NULL; static GLfloat* gcolormap = NULL; static GLboolean colormapdirty = GL_TRUE; static GLfloat colormap_gamma = 1.0; static GLboolean texture_ext; static GLboolean texture_object_ext; static GLboolean texture_color_table_ext; static GLboolean pixel_texture_ext; static GLboolean texture_3D_ext; static GLboolean color_matrix_ext; static GLboolean color_table_ext; static GLboolean blend_ext; static GLint vp[4]; /* Some actions are delayed in order to optimize successives procedure calls pass says where last action has been interrupted call glpFinalize to compleet interupted action */ #define PASS_NOTHING 0 #define PASS_DRAW_PATTERN 1 #define PASS_DRAW_NOISE 2 static int pass = PASS_NOTHING; /* Error Gestion */ GLenum glpGetError() { int e = error; error = GLP_NO_ERROR; return (e==GLP_NO_ERROR)?glGetError():e; } const GLubyte* glpErrorString(GLenum error) { if (error>=GLP_FIRST_ERROR_CODE && error<GLP_LAST_ERROR_CODE) return error_msg[error-GLP_FIRST_ERROR_CODE]; return gluErrorString(error); } static void seterror(int err) { error = (error==GLP_NO_ERROR)?err:error; } static int ispowerof2(GLuint i) { if (!i) return 0; while (!(i&1)) i>>=1; if (i==1) return 1; return 0; } /* Extension support verification */ GLboolean glpQueryExtension(const char *extName) { char *p; char *end; int extNameLen; extNameLen = strlen(extName); p = (char *)glGetString(GL_EXTENSIONS); if (NULL == p) { return GL_FALSE; } end = p + strlen(p); while (p < end) { int n = strcspn(p, " "); if ((extNameLen == n) && (strncmp(extName, p, n) == 0)) { return GL_TRUE; } p += (n + 1); } return GL_FALSE; } /* Initialisation */ void glpInit() { float s[4] = { 1.0, 0.0, 0.0, 0.0}; float t[4] = { 0.0, 1.0, 0.0, 0.0}; float r[4] = { 0.0, 0.0, 1.0, 0.0}; printf("GLP initialisation...\n\n"); /* Verify extensions */ texture_ext = glpQueryExtension("GL_EXT_texture"); texture_object_ext = glpQueryExtension("GL_EXT_texture_object"); texture_3D_ext = glpQueryExtension("GL_EXT_texture3D"); color_matrix_ext = glpQueryExtension("GL_SGI_color_matrix"); color_table_ext = glpQueryExtension("GL_SGI_color_table"); blend_ext = glpQueryExtension("GL_EXT_blend_color") & glpQueryExtension("GL_EXT_blend_subtract"); texture_color_table_ext = glpQueryExtension("GL_SGI_texture_color_table"); pixel_texture_ext = glpQueryExtension("GL_SGIX_pixel_texture"); printf("Color matrix extension : %s\n",color_matrix_ext?"Yes":"No"); printf("Color table extension : %s\n",color_table_ext?"Yes":"No"); printf("Blend extensions : %s\n",blend_ext?"Yes":"No"); printf("Texture extension : %s\n",texture_ext?"Yes":"No"); printf("Texture object extension : %s\n",texture_object_ext?"Yes":"No"); printf("Texture 3D extension : %s\n",texture_3D_ext?"Yes":"no"); printf("Texture color table extension : %s\n",texture_color_table_ext?"yes":"No"); printf("Pixel texture extension : %s\n",pixel_texture_ext?"Yes":"No"); /* Init texture coord lists */ mapcoord = glGenLists(1); glNewList(mapcoord, GL_COMPILE); glEnable(GL_TEXTURE_GEN_R); 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); glTexGeni(GL_R,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); glTexGenfv(GL_S,GL_OBJECT_PLANE,s); glTexGenfv(GL_T,GL_OBJECT_PLANE,t); glTexGenfv(GL_R,GL_OBJECT_PLANE,r); glEndList(); printf("\nGLP initialisation completed\n\n"); } static long seed = 0x12345678; static void buildnoise() { int i,j,k,l; GLint dummy; /* Init random noise table */ srand48(seed); if (tex) { free(tex); glDeleteTexturesEXT(1,&tex3Drgb); glDeleteTexturesEXT(1,&tex3Dl); glDeleteTexturesEXT(1,&tex2Drgb); glDeleteTexturesEXT(1,&tex2Dl); } tex = (GLfloat*) malloc(max*max*max*3*sizeof(GLfloat)); if (!tex) { seterror(GLP_OUT_OF_MEMORY); return; } for (i=0;i<max;i++) for (j=0;j<max;j++) for (k=0;k<max;k++) for (l=0;l<3;l++) tex[((i*max+j)*max+k)*3+l] = drand48(); /* Init noise texture objects */ glPixelStorei(GL_UNPACK_ALIGNMENT,1); if (!texture_object_ext) seterror(GLP_NOT_SUPPORTED); if (!texture_ext) seterror(GLP_NOT_SUPPORTED); glGenTexturesEXT(1,&tex3Drgb); glBindTextureEXT(GL_TEXTURE_3D_EXT,tex3Drgb); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_S , GL_REPEAT); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_T , GL_REPEAT); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_R_EXT, GL_REPEAT); glTexImage3DEXT(GL_PROXY_TEXTURE_3D_EXT,0,GL_RGB, max,max,max, 0, GL_RGB, GL_FLOAT, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D_EXT,0,GL_TEXTURE_WIDTH,&dummy); if (!dummy) seterror(GLP_HARD); glTexImage3DEXT(GL_TEXTURE_3D_EXT,0,GL_RGB, max,max,max, 0, GL_RGB, GL_FLOAT, tex); glGenTexturesEXT(1,&tex3Dl); glBindTextureEXT(GL_TEXTURE_3D_EXT,tex3Dl); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_S , GL_REPEAT); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_T , GL_REPEAT); glTexParameteri(GL_TEXTURE_3D_EXT, GL_TEXTURE_WRAP_R_EXT, GL_REPEAT); glTexImage3DEXT(GL_PROXY_TEXTURE_3D_EXT,0,GL_INTENSITY_EXT, max,max,max, 0, GL_LUMINANCE, GL_FLOAT, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D_EXT,0,GL_TEXTURE_WIDTH,&dummy); if (!dummy) seterror(GLP_HARD); glTexImage3DEXT(GL_TEXTURE_3D_EXT,0,GL_INTENSITY_EXT, max,max,max, 0, GL_LUMINANCE, GL_FLOAT, tex); glGenTexturesEXT(1,&tex2Drgb); glBindTextureEXT(GL_TEXTURE_2D,tex2Drgb); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S , GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T , GL_REPEAT); glTexImage2D(GL_PROXY_TEXTURE_2D_EXT,0,GL_RGB, max,max, 0, GL_RGB, GL_FLOAT, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D_EXT,0,GL_TEXTURE_WIDTH,&dummy); if (!dummy) seterror(GLP_HARD); glTexImage2D(GL_TEXTURE_2D,0,GL_RGB, max,max, 0, GL_RGB, GL_FLOAT, tex); glGenTexturesEXT(1,&tex2Dl); glBindTextureEXT(GL_TEXTURE_2D,tex2Dl); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S , GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T , GL_REPEAT); glTexImage2D(GL_PROXY_TEXTURE_2D_EXT,0,GL_INTENSITY_EXT, max,max, 0, GL_LUMINANCE, GL_FLOAT, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D_EXT,0,GL_TEXTURE_WIDTH,&dummy); if (!dummy) seterror(GLP_HARD); glTexImage2D(GL_TEXTURE_2D,0,GL_INTENSITY_EXT, max,max, 0, GL_LUMINANCE, GL_FLOAT, tex); noisedirty = GL_FALSE; } static void buildid() { GLint dummy; int i; if (id) { free(id); glDeleteTexturesEXT(1,&texId); } id = (GLfloat*) malloc(sizeof(GLfloat)*maxfun); if (!id) { seterror(GLP_OUT_OF_MEMORY); return; } switch (funmode) { case GLP_MODE_TRIANGULAR: for (i=0;i<maxfun/2;i++) { id[i] = 2.0/maxfun*i; id[i+maxfun/2] = 1.0-2.0/maxfun*i; } break; case GLP_MODE_RAMP: for (i=0;i<maxfun;i++) id[i] = 1.0/(maxfun-1)*i; break; case GLP_MODE_SINUSOIDAL: for (i=0;i<maxfun;i++) id[i] = (cos(2.0*M_PI*i/maxfun+M_PI)+1.0)/2.0; break; } glGenTexturesEXT(1,&texId); glBindTextureEXT(GL_TEXTURE_1D,texId); if (funmode==GLP_MODE_RAMP) { glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); } else { glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S , GL_REPEAT); glTexImage1D(GL_PROXY_TEXTURE_1D_EXT,0,GL_INTENSITY_EXT, maxfun, 0, GL_LUMINANCE, GL_FLOAT, NULL); glGetTexLevelParameteriv(GL_PROXY_TEXTURE_3D_EXT,0,GL_TEXTURE_WIDTH,&dummy); if (!dummy) seterror(GLP_HARD); glTexImage1D(GL_TEXTURE_1D,0,GL_INTENSITY_EXT, maxfun, 0, GL_LUMINANCE, GL_FLOAT, id); iddirty = GL_FALSE; } static void buildcolormap(); void glpFlush() { if (iddirty) buildid(); if (noisedirty) buildnoise(); if (colormapdirty) buildcolormap(); } /* Set/Get parameters */ void glpSetParameteri(GLenum param,GLuint value) { switch (param) { case GLP_DIMENSION : switch (value) { case GLP_MODE_2D : mode3D = 0; break; case GLP_MODE_3D : mode3D = 1; if (!texture_3D_ext) { seterror(GLP_NOT_SUPPORTED); mode3D = 0; } break; default : seterror(GLP_BAD_VALUE); } break; case GLP_COMPONENT : switch (value) { case GLP_MODE_RGB : modeRgb = 1; break; case GLP_MODE_L : modeRgb = 0; break; default : seterror(GLP_BAD_VALUE); } break; case GLP_FUN_MODE : switch (value) { case GLP_MODE_RAMP : case GLP_MODE_TRIANGULAR : case GLP_MODE_SINUSOIDAL : funmode = value; iddirty = GL_TRUE; break; default : seterror(GLP_BAD_VALUE); } break; case GLP_OCTAVE : octave = value; break; case GLP_NOISE_SIZE : if (!ispowerof2(value)) { seterror(GLP_BAD_VALUE); return; } max = value; noisedirty = GL_TRUE; break; case GLP_FUN_SIZE : if (!ispowerof2(value)) { seterror(GLP_BAD_VALUE); return; } maxfun = value; iddirty = GL_TRUE; break; case GLP_FREQ_MULT : case GLP_AMP_DIV : case GLP_NOISE_AMP : case GLP_FUN_AMP : case GLP_NOISE_BEGIN: case GLP_NOISE_END: case GLP_GAMMA: glpSetParameterf(param,value); break; default : seterror(GLP_BAD_PARAMETER); } } void glpSetParameterf(GLenum param,GLfloat value) { switch (param) { case GLP_FREQ_MULT : if (value<=0.0) { seterror(GLP_BAD_VALUE); return; } freq_mult = value; break; case GLP_AMP_DIV : if (value<=0.0) { seterror(GLP_BAD_VALUE); return; } amp_div = value; break; case GLP_FUN_AMP : if (value<0.0 || value>1.0) { seterror(GLP_BAD_VALUE); return; } fun_amp = value; break; case GLP_NOISE_AMP : if (value<0.0 || value>1.0) { seterror(GLP_BAD_VALUE); return; } noise_amp = value; break; case GLP_NOISE_BEGIN : if (value<0.0 || value>1.0) { seterror(GLP_BAD_VALUE); return; } noise_begin = value; break; case GLP_NOISE_END : if (value<0.0 || value>1.0) { seterror(GLP_BAD_VALUE); return; } noise_end = value; break; case GLP_GAMMA : if (value<=0.0) { seterror(GLP_BAD_VALUE); return; } colormap_gamma = value; colormapdirty = GL_TRUE; break; case GLP_FUN_MODE: case GLP_FUN_SIZE: case GLP_NOISE_SIZE: case GLP_DIMENSION: case GLP_COMPONENT: case GLP_OCTAVE: glpSetParameteri(param,value); break; default : seterror(GLP_BAD_PARAMETER); } } void glpGetParameteri(GLenum param,GLuint* value) { switch (param) { case GLP_DIMENSION: *value = mode3D?GLP_MODE_3D:GLP_MODE_2D; break; case GLP_COMPONENT: *value = modeRgb?GLP_MODE_RGB:GLP_MODE_L; break; case GLP_OCTAVE: *value = octave; break; case GLP_FUN_MODE: *value = funmode; break; case GLP_FUN_SIZE: *value = maxfun; break; case GLP_NOISE_SIZE: *value = max; break; case GLP_FREQ_MULT : case GLP_AMP_DIV : case GLP_NOISE_AMP: case GLP_FUN_AMP: case GLP_NOISE_BEGIN: case GLP_NOISE_END: case GLP_GAMMA: seterror(GLP_BAD_VALUE); break; default : seterror(GLP_BAD_PARAMETER); } } void glpGetParameterf(GLenum param,GLfloat* value) { switch (param) { case GLP_FREQ_MULT : *value = freq_mult; break; case GLP_AMP_DIV : *value = amp_div; break; case GLP_NOISE_AMP : *value = noise_amp; break; case GLP_FUN_AMP : *value = fun_amp; break; case GLP_NOISE_BEGIN : *value = noise_begin; break; case GLP_NOISE_END : *value = noise_end; break; case GLP_GAMMA : *value = colormap_gamma; break; case GLP_DIMENSION: case GLP_COMPONENT: case GLP_OCTAVE: case GLP_FUN_MODE: case GLP_FUN_SIZE: case GLP_NOISE_SIZE: seterror(GLP_BAD_VALUE); break; default : seterror(GLP_BAD_PARAMETER); } } /* Draw noise changed state : texture changed & disabled texture coord generation changed & disabled texture environement function is changed blending changed & disabled depth mask set to GL_FALSE (function not changed) polygon offset disabled (not changed) */ static GLfloat qpow(GLfloat q,int p) { GLfloat f = 1.0; for (;p;p>>=1,q*=q) if (p&1) f*=q; return f; } void glpDrawNoise(GLuint list) { int i; GLfloat f,a; if (!octave) return; glpFinalize(); if (noisedirty) buildnoise(); glCallList(mapcoord); if (mode3D) { glEnable(GL_TEXTURE_3D_EXT); glBindTextureEXT(GL_TEXTURE_3D_EXT,modeRgb?tex3Drgb:tex3Dl); } else { glEnable(GL_TEXTURE_2D); glBindTextureEXT(GL_TEXTURE_2D,modeRgb?tex2Drgb:tex2Dl); } glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glMatrixMode(GL_TEXTURE); glPushMatrix(); f = 1.0; a = noise_amp; for (i=0;i<octave;i++,f*=freq_mult,a/=amp_div) { glScalef(f,f,f); glColor3f(a,a,a); glCallList(list); glMatrixMode(GL_TEXTURE); glPopMatrix(); glPushMatrix(); if (!i) { if (!blend_ext) { seterror(GLP_NOT_SUPPORTED); return; } glDepthMask(GL_FALSE); glDisable(GL_POLYGON_OFFSET_EXT); glBlendFunc(GL_ONE,GL_ONE); glEnable(GL_BLEND); glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); } } glPopMatrix(); glDisable(GL_BLEND); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); if (mode3D) glDisable(GL_TEXTURE_3D_EXT); else glDisable(GL_TEXTURE_2D); if ((noise_begin>0.0 || noise_end<1.0) && noise_begin!=noise_end) { glPushAttrib(GL_PIXEL_MODE_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glPixelTransferf(GL_RED_SCALE ,1.0/(noise_end-noise_begin)); glPixelTransferf(GL_GREEN_SCALE,1.0/(noise_end-noise_begin)); glPixelTransferf(GL_BLUE_SCALE ,1.0/(noise_end-noise_begin)); glPixelTransferf(GL_RED_BIAS ,-noise_begin/(noise_end-noise_begin)); glPixelTransferf(GL_GREEN_BIAS ,-noise_begin/(noise_end-noise_begin)); glPixelTransferf(GL_BLUE_BIAS ,-noise_begin/(noise_end-noise_begin)); glGetIntegerv(GL_VIEWPORT,vp); glDisable(GL_DEPTH_TEST); glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); /* Must be continued... in glpDoColormap or glpFinalize */ pass = PASS_DRAW_NOISE; } } /* Colormap */ static GLuint cmap_sizetab = 0; void glpSetColormap(GLuint sizetab,GLuint nbtab,GLenum mode, GLuint size,float* tab) { int i,j,k; int minitab = sizetab/nbtab+1; if (mode!=GLP_NORM) { seterror(GLP_BAD_PARAMETER); return; } if (!ispowerof2(sizetab) || !nbtab || nbtab>sizetab) { seterror(GLP_BAD_PARAMETER); return; } if (colormap) free(colormap); colormap = (GLfloat*) malloc(sizeof(GLfloat)*4*minitab*nbtab); if (!colormap) { seterror(GLP_OUT_OF_MEMORY); return; } if (size) { for (j=0;j<minitab*tab[0];j++) { colormap[j*4+0] = tab[1]; colormap[j*4+1] = tab[2]; colormap[j*4+2] = tab[3]; colormap[j*4+3] = tab[4]; } for (j=minitab*tab[(size-1)*5];j<minitab;j++) { colormap[j*4+0] = tab[(size-1)*5+1]; colormap[j*4+1] = tab[(size-1)*5+2]; colormap[j*4+2] = tab[(size-1)*5+3]; colormap[j*4+3] = tab[(size-1)*5+4]; } } else for (j=0;j<minitab*4;j++) colormap[j] = 1.00; if (size) for (i=0;i<size-1;i++) { float r,g,b,a; float dr,dg,db,da; r = tab[i*5+1]; g = tab[i*5+2]; b = tab[i*5+3]; a = tab[i*5+4]; dr = (tab[(i+1)*5+1]-tab[i*5+1])/(tab[(i+1)*5]-tab[i*5])/minitab; dg = (tab[(i+1)*5+2]-tab[i*5+2])/(tab[(i+1)*5]-tab[i*5])/minitab; db = (tab[(i+1)*5+3]-tab[i*5+3])/(tab[(i+1)*5]-tab[i*5])/minitab; da = (tab[(i+1)*5+4]-tab[i*5+4])/(tab[(i+1)*5]-tab[i*5])/minitab; for (j=minitab*tab[i*5];j<minitab*tab[(i+1)*5]; j++,r+=dr,g+=dg,b+=db,a+=da) { colormap[j*4+0] = r; colormap[j*4+1] = g; colormap[j*4+2] = b; colormap[j*4+3] = a; } } for (i=1;i<nbtab;i++) memcpy(colormap+((int)((float)i*sizetab/nbtab))*4,colormap,sizeof(GLfloat)*4*minitab); cmap_sizetab = sizetab; colormapdirty = GL_TRUE; } void glpResetColormap() { if (!color_table_ext) { seterror(GLP_NOT_SUPPORTED); return; } if (colormapdirty) { buildcolormap(); return; } if (colormap_gamma==1.0) if (!colormap) return; else glColorTableSGI(GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI,GL_RGBA, cmap_sizetab,GL_RGBA,GL_FLOAT,colormap); else if (!gcolormap) return; else glColorTableSGI(GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI,GL_RGBA, cmap_sizetab,GL_RGBA,GL_FLOAT,gcolormap); } static void buildcolormap() { if (gcolormap) free(gcolormap); gcolormap = NULL; colormapdirty = GL_FALSE; if (!colormap) return; if (colormap_gamma!=1.0) { int i; gcolormap = (GLfloat*) malloc(sizeof(GLfloat)*4*cmap_sizetab); if (!gcolormap) { seterror(GLP_OUT_OF_MEMORY); return; } for (i=0;i<cmap_sizetab;i++) { int j = pow((float)i/cmap_sizetab,colormap_gamma)*cmap_sizetab; gcolormap[i*4+0] = colormap[j*4+0]; gcolormap[i*4+1] = colormap[j*4+1]; gcolormap[i*4+2] = colormap[j*4+2]; gcolormap[i*4+3] = colormap[j*4+3]; } } glpResetColormap(); } /* Applys colormap state changed : post_color_matrix_color_table disabled (table not changed, should have been set by glpSetColormap or glpResetColormap) */ void glpDoColormap() { if (colormapdirty) buildcolormap(); if (pass!=PASS_DRAW_PATTERN && pass!=PASS_DRAW_NOISE) { glpFinalize(); glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glDisable(GL_DEPTH_TEST); glGetIntegerv(GL_VIEWPORT,vp); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); } glRasterPos2f(-1,-1); glEnable(GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI); glCopyPixels(0,0,vp[2],vp[3],GL_COLOR); glDisable(GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI); glPopAttrib(); switch (pass) { case PASS_DRAW_NOISE: glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); pass = PASS_NOTHING; break; case PASS_DRAW_PATTERN: glMatrixMode(GL_COLOR); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); pass = PASS_NOTHING; break; default: glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); } } /* Draw pattern, passes may be delayed state changed (valid only after a glpFinalize) : texture changed & disabled texture coord generation changed & disabled blending changed & disabled polygon offset disabled (not changed) color mask set to all GL_TRUE */ void glpDrawPattern(GLuint scene,GLenum func) { glpFinalize(); glCallList(mapcoord); if (iddirty) buildid(); glEnable(GL_TEXTURE_1D); glBindTextureEXT(GL_TEXTURE_1D,texId); glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE); glColor3f(fun_amp,fun_amp,fun_amp); /* First pass in 3D */ switch (func) { case GLP_FUNC_GRADIENT: glCallList(scene); glDepthMask(GL_FALSE); glDisable(GL_POLYGON_OFFSET_EXT); break; case GLP_FUNC_CYLINDER: glColorMask(GL_TRUE,GL_FALSE,GL_FALSE,GL_FALSE); glCallList(scene); glDepthMask(GL_FALSE); glDisable(GL_POLYGON_OFFSET_EXT); glColorMask(GL_FALSE,GL_TRUE,GL_FALSE,GL_FALSE); glMatrixMode(GL_TEXTURE); glPushMatrix(); glRotatef(90.0,0.0,0.0,1.0); glCallList(scene); glMatrixMode(GL_TEXTURE); glPopMatrix(); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); break; case GLP_FUNC_SPHERE: glColorMask(GL_TRUE,GL_FALSE,GL_FALSE,GL_FALSE); glCallList(scene); glDepthMask(GL_FALSE); glDisable(GL_POLYGON_OFFSET_EXT); glColorMask(GL_FALSE,GL_TRUE,GL_FALSE,GL_FALSE); glMatrixMode(GL_TEXTURE); glPushMatrix(); glRotatef(90.0,0.0,0.0,1.0); glCallList(scene); glMatrixMode(GL_TEXTURE); glPopMatrix(); glColorMask(GL_FALSE,GL_FALSE,GL_TRUE,GL_FALSE); glPushMatrix(); glRotatef(90.0,0.0,1.0,0.0); glCallList(scene); glMatrixMode(GL_TEXTURE); glPopMatrix(); glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); break; default: seterror(GLP_BAD_VALUE); break; } glDisable(GL_TEXTURE_1D); glDisable(GL_TEXTURE_GEN_S); glDisable(GL_TEXTURE_GEN_T); glDisable(GL_TEXTURE_GEN_R); if (func==GLP_FUNC_GRADIENT) { glDisable(GL_BLEND); return; } /* Second pass in 2D */ glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); glGetIntegerv(GL_VIEWPORT,vp); glDisable(GL_DEPTH_TEST); glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); switch (func) { case GLP_FUNC_CYLINDER: { GLfloat mat[16] = { 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 }; if (!color_matrix_ext) seterror(GLP_NOT_SUPPORTED); glRasterPos2f(-1,-1); glEnable(GL_BLEND); glBlendFunc(GL_ZERO,GL_SRC_COLOR); glReadBuffer(GL_BACK); glCopyPixels(0,0,vp[2],vp[3],GL_COLOR); glDisable(GL_BLEND); glMatrixMode(GL_COLOR); glPushMatrix(); glLoadMatrixf(mat); /* Must be continued... in glpDoColormap or glpFinalize */ pass = PASS_DRAW_PATTERN; } break; case GLP_FUNC_SPHERE: { GLfloat mat[16] = { 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.33, 0.00, 0.00, 0.00, 0.00 }; if (!color_matrix_ext) seterror(GLP_NOT_SUPPORTED); glRasterPos2f(-1,-1); glEnable(GL_BLEND); glBlendFunc(GL_DST_COLOR,GL_NONE); glCopyPixels(0,0,vp[2],vp[3],GL_COLOR); glDisable(GL_BLEND); glMatrixMode(GL_COLOR); glPushMatrix(); glLoadMatrixf(mat); /* Must be continued... in glpDoColormap or glpFinalize */ pass = PASS_DRAW_PATTERN; } break; default: seterror(GLP_BAD_VALUE); break; } } /* Flush any begun pass */ void glpFinalize() { switch (pass) { case PASS_DRAW_PATTERN: glRasterPos2f(-1,-1); glCopyPixels(0,0,vp[2],vp[3],GL_COLOR); glMatrixMode(GL_COLOR); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); break; case PASS_DRAW_NOISE: glRasterPos2f(-1,-1); glCopyPixels(0,0,vp[2],vp[3],GL_COLOR); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); glPopAttrib(); break; } pass = PASS_NOTHING; }