📄 bumpref.c
字号:
/* 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 <GL/gl.h>#include <GL/glu.h>#include <string.h>#include <stdio.h>#include <stdlib.h>#include <math.h>#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*h;j++){ if( ((j%w)%9)<1 || ((j/w)%9)<1 ){ data[j*3+0]=255*(j%w)/w; data[j*3+1]=255*(j/w)/w; data[j*3+2]=0; }else{ data[j*3+0]=((i%3)==0 || i==5)?0xFF:0; data[j*3+1]=((i%3)==1 || i==3)?0xFF:0; data[j*3+2]=((i%3)==2 || i==4)?0xFF:0; } }*/// load_png("chic2.png", &w, &h, &depth, &data); DPRINTF("setting cube map #%d\n",i); switch(i){ case 0: load_png(posx_name, &w, &h, &depth, (char **)&data); break; case 1: load_png(posy_name, &w, &h, &depth, (char **)&data); break; case 2: load_png(posz_name, &w, &h, &depth, (char **)&data); break; case 3: load_png(negx_name, &w, &h, &depth, (char **)&data); break; case 4: load_png(negy_name, &w, &h, &depth, (char **)&data); break; case 5: load_png(negz_name, &w, &h, &depth, (char **)&data); break; } switch(i){ case 0: target=GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; break; case 1: target=GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; break; case 2: target=GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; break; case 3: target=GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; break; case 4: target=GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; break; case 5: target=GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; break; } DPRINTF("rendering mipmaps for #%d\n",i); gluBuild2DMipmaps(target, 3, w, h, GL_RGB, GL_UNSIGNED_BYTE, data);/* glTexImage2D(target, 0, 3, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, data);*/ DPRINTF("freeing data #%d\n",i); free(data); }// g_cubemap_bind = cube_tex_bind; return(cube_tex_bind);#else return(0);#endif}void gaussian_blur( int w, int h, double * ddata, int d ){ int xi, yi, xi2, yi2, dx, dy, i; double * wdata; double gauss_sum, gauss; wdata = malloc(sizeof(double)*w*h); for(i=0;i<w*h;i++){ wdata[i]=ddata[i]; } for(yi=0;yi<h;yi++){ for(xi=0;xi<w;xi++){ ddata[yi*w+xi]=0.0; gauss_sum=0.0; for(dy=-d;dy<=d;dy++){ for(dx=-d;dx<=d;dx++){ gauss=exp(-2.0*(double)(dx*dx+dy*dy)/(double)(d*d)); xi2=xi+dx; if(xi2<0)xi2+=w; if(xi2>=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;i<w*h;i++){ ddata[i]=udata[i*3]; }// gaussian_blur( w,h, ddata, 3 ); for(yi=0;yi<h;yi++){ for(xi=0;xi<w;xi++){ i=(yi*w+xi)*3; xi_n = (xi+1<w)?xi+1:0; yi_n = (yi+1<h)?yi+1:0;/* sd = udata[(yi*w+xi)*3]; sd_xn = udata[(yi*w+xi_n)*3]; sd_yn = udata[(yi_n*w+xi)*3]; sd_xyn = udata[(yi_n*w+xi_n)*3];*/ sd = ddata[yi*w+xi]; sd_xn = ddata[yi*w+xi_n]; sd_yn = ddata[yi_n*w+xi]; sd_xyn = ddata[yi_n*w+xi_n]; dzx = (sd_xn-sd)*strength; dzy = (sd_yn-sd)*strength; dx=1.0; dy=1.0; n=vec_scale(vec_unit(vec_cross(vec_xyz(dx,0,dzx),vec_xyz(0,-dy,dzy))),-1.0); udata[i+2]=0x80+127.4*1.0*n.z; udata[i+1]=0x80+127.4*1.0*n.y; udata[i+0]=0x80+127.4*1.0*n.x; } } free(ddata);}signed short * bump2normal_HILO(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; signed short * sdata; double * ddata; VMvect n; udata = (unsigned char *)data; ddata = malloc(sizeof(double)*w*h); sdata = malloc(sizeof(signed short)*w*h*2); for(i=0;i<w*h;i++){ ddata[i]=udata[i*3]; } gaussian_blur( w,h, ddata, 3 ); for(yi=0;yi<h;yi++){ for(xi=0;xi<w;xi++){ i=(yi*w+xi)*3; xi_n = (xi+1<w)?xi+1:0; yi_n = (yi+1<h)?yi+1:0;/* sd = udata[(yi*w+xi)*3]; sd_xn = udata[(yi*w+xi_n)*3]; sd_yn = udata[(yi_n*w+xi)*3]; sd_xyn = udata[(yi_n*w+xi_n)*3];*/ sd = ddata[yi*w+xi]; sd_xn = ddata[yi*w+xi_n]; sd_yn = ddata[yi_n*w+xi]; sd_xyn = ddata[yi_n*w+xi_n]; dzx = (sd_xn-sd)*strength; dzy = (sd_yn-sd)*strength; dx=1.0; dy=1.0; n=vec_scale(vec_unit(vec_cross(vec_xyz(dx,0,dzx),vec_xyz(0,-dy,dzy))),-1.0); sdata[(yi*w+xi)*2+1]=32767.4*n.y; sdata[(yi*w+xi)*2+0]=32767.4*n.x; } } free(ddata); return(sdata);}int bumpref_create_bumpmap( char * map_name, double strength, int hilo )/* returns texture-bind-id */{#ifdef USE_NV_BUMPREF int texbind, w, h, depth; unsigned char * data; signed short * sdata; load_png(map_name, &w, &h, &depth, (char **)&data); if(hilo){ sdata = bump2normal_HILO(w, h, data, strength); } else { bump2normal(w, h, data, strength); } glGenTextures( 1 , &texbind ); glBindTexture(GL_TEXTURE_2D,texbind); if(!hilo){ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, options_tex_min_filter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, options_tex_mag_filter); } else { 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_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); if(!hilo){ gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB8, w, h, GL_RGB, GL_UNSIGNED_BYTE, data);/* glTexImage2D(GL_TEXTURE_2D, 0,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -