www.pudn.com > simple_fragment_program2.zip > simple_fragment_program2.cpp


/* 
	simple NV_fragment_program2 example 
	sgreen 1/2004 
*/ 
 
#if defined(WIN32) 
#  include  
#endif 
 
#define GLH_EXT_SINGLE_FILE 
#include  
#include  
 
#include  
#include  
 
using namespace glh; 
 
bool b[256]; 
glut_simple_mouse_interactor camera; 
glut_simple_mouse_interactor lights; 
GLuint vprog_id, fprog_id; 
 
GLuint light_pos_tex, light_color_tex; 
 
const int max_lights = 8; 
// light positions (w==0.0 for directional lights) 
const float d = 2.0; 
vec4f light_pos[max_lights] = { 
    vec4f(-1.0, -1.0, -1.0, 0.0),  // directional 
//    vec4f(-d, -d, -d, 1.0), 
	vec4f( d, -d, -d, 1.0), 
    vec4f( d,  d, -d, 1.0), 
	vec4f(-d,  d, -d, 1.0), 
	vec4f(-d, -d,  d, 1.0), 
	vec4f( d, -d,  d, 1.0), 
	vec4f( d,  d,  d, 1.0), 
	vec4f(-d,  d,  d, 1.0), 
}; 
vec4f light_pos_eye[max_lights]; 
 
// light colors (w component is attenuation) 
const float att = 0.2; 
vec4f light_color[max_lights] = { 
	vec4f(0.5, 0.5, 0.5, att), 
	vec4f(1.0, 0.0, 0.0, att), 
	vec4f(0.0, 1.0, 0.0, att), 
	vec4f(0.0, 0.0, 1.0, att), 
	vec4f(1.0, 1.0, 0.0, att), 
	vec4f(1.0, 0.0, 1.0, att), 
	vec4f(0.0, 1.0, 1.0, att), 
	vec4f(1.0, 0.5, 0.0, att), 
}; 
 
int nlights = max_lights; 
 
GLuint load_program(GLenum program_type, const char *code); 
GLuint load_texture_array(GLenum format, float *data, int n); 
void query_program_limits(); 
 
void init_opengl() 
{ 
    if (!glh_init_extensions( 
		"GL_ARB_vertex_program " 
		"GL_ARB_fragment_program " 
		"GL_ARB_multitexture " 
        "GL_NV_fragment_program2 " 
		)) 
    { 
        printf("Unable to load the following extension(s): %s\n\nExiting...\n",  
               glh_get_unsupported_extensions()); 
        quitapp(-1); 
    } 
 
//	printf("%s\n", glGetString(GL_EXTENSIONS)); 
    query_program_limits(); 
 
	// load programs 
	char *vprog_code = read_text_file("simple_fragment_program2/simple_fragment_program2.vp"); 
	if (!vprog_code) quitapp(-1); 
	char *fprog_code = read_text_file("simple_fragment_program2/simple_fragment_program2.fp"); 
	if (!fprog_code) quitapp(-1); 
	vprog_id = load_program(GL_VERTEX_PROGRAM_ARB, vprog_code); 
    if (!vprog_id) quitapp(-1); 
	fprog_id = load_program(GL_FRAGMENT_PROGRAM_ARB, fprog_code); 
    if (!fprog_id) quitapp(-1); 
    glEnable(GL_VERTEX_PROGRAM_ARB); 
 
	// load textures storing light positions and colors 
	light_pos_tex = load_texture_array(GL_FLOAT_RGBA32_NV, (float *) &light_pos[0], nlights); 
	light_color_tex = load_texture_array(GL_RGBA, (float *) &light_color[0], nlights); 
 
	glActiveTextureARB(GL_TEXTURE0_ARB); 
    glBindTexture(GL_TEXTURE_RECTANGLE_NV, light_pos_tex); 
 
	glActiveTextureARB(GL_TEXTURE1_ARB); 
    glBindTexture(GL_TEXTURE_RECTANGLE_NV, light_color_tex); 
 
	// create geometry 
	glNewList(1, GL_COMPILE); 
	glutSolidTeapot(1.0); 
//	glutSolidSphere(1.0, 40, 20); 
//	glutSolidTorus(0.5, 1.0, 40, 40); 
	glEndList(); 
 
    glEnable(GL_DEPTH_TEST); 
    glClearColor(0.2, 0.2, 0.2, 1.0); 
} 
 
void query_program_limits() 
{ 
    struct Query { 
      GLenum glenum; 
      char *name; 
    } limits [] = { 
      #define ENUMNAME(E) E, #E 
      ENUMNAME(GL_MAX_PROGRAM_INSTRUCTIONS_ARB), 
      ENUMNAME(GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB), 
      ENUMNAME(GL_MAX_PROGRAM_TEMPORARIES_ARB), 
      ENUMNAME(GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB), 
      ENUMNAME(GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV), 
      ENUMNAME(GL_MAX_PROGRAM_CALL_DEPTH_NV), 
      ENUMNAME(GL_MAX_PROGRAM_IF_DEPTH_NV), 
      ENUMNAME(GL_MAX_PROGRAM_LOOP_DEPTH_NV), 
      ENUMNAME(GL_MAX_PROGRAM_LOOP_COUNT_NV), 
    }; 
    for(int i=0; i 0) nlights--; 
		printf("%d lights\n", nlights); 
		break; 
	case 'l': 
		if (b['l']) { 
			lights.enable(); 
			camera.disable(); 
		} else { 
			lights.disable(); 
			camera.enable(); 
		} 
	} 
 
	if (b['l']) 
		lights.keyboard(k, x, y); 
	else 
		camera.keyboard(k, x, y); 
     
	glutPostRedisplay(); 
} 
 
void resize(int w, int h) 
{ 
    if (h == 0) h = 1; 
 
    glViewport(0, 0, w, h); 
     
    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
     
    gluPerspective(60.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0); 
     
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
 
    camera.reshape(w, h); 
	lights.reshape(w, h); 
} 
 
void mouse(int button, int state, int x, int y) 
{ 
	if (b['l']) 
		lights.mouse(button, state, x, y); 
	else 
		camera.mouse(button, state, x, y); 
} 
 
void motion(int x, int y) 
{ 
    camera.motion(x, y); 
    lights.motion(x, y); 
} 
 
void main_menu(int i) 
{ 
  key((unsigned char) i, 0, 0); 
} 
 
void init_menu() 
{ 
  glutCreateMenu(main_menu); 
  glutAddMenuEntry("Add light [+]", '+'); 
  glutAddMenuEntry("Remove light [-]", '-'); 
  glutAddMenuEntry("Toggle move light [l]", 'l'); 
  glutAddMenuEntry("Quit (esc)", '\033'); 
  glutAttachMenu(GLUT_RIGHT_BUTTON); 
} 
 
int main(int argc, char **argv) 
{ 
	glutInit(&argc, argv); 
	glutInitWindowSize(512, 512); 
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGB); 
	glutCreateWindow("simple_fragment_program2"); 
 
	init_opengl(); 
    init_menu(); 
 
    camera.configure_buttons(2); 
    camera.dolly.dolly[2] = -8; 
	glut_add_interactor(&camera); 
	camera.enable(); 
 
    lights.configure_buttons(2); 
	lights.trackball.incr = rotationf(vec3f(0.5, 0.7, 0.3), 0.1); 
	glut_add_interactor(&lights); 
	lights.disable(); 
 
	glutDisplayFunc(display); 
    glutMouseFunc(mouse); 
    glutMotionFunc(motion); 
    glutIdleFunc(idle); 
    glutKeyboardFunc(key); 
    glutReshapeFunc(resize); 
 
    b[' '] = true; 
	b['f'] = true; 
	b['s'] = true; 
 
	glutMainLoop(); 
 
	return 0; 
}