The program displays a teapot by default. To enable a shader program simply pass it a vertex and fragment shader source file as follows:
use: ./shader_demo <vert_src_path> <frag_src_path>
If you leave off a fragment shader, it will only load the vertex file. Here are some examples:
./shader_demo red.vert
./shader_demo color.vert
./shader_demo flatten_wavy.vert
./shader_demo toon.vert toon.frag
To use this demo, you must first edit shader_demo.c by switching the shader node render function and reorganizing the graph. To do this simply uncomment the two lines in the source code and comment the corresponding ones and recompile.
./shader_demo fireworks.vert fireworks.frag
shader_demo.c:
/* Peter Bui * CSE 40166 Computer Graphics (Fall 2010) * Example 24: shader demo */ #include "ssg.h" #include <stdio.h> #include <time.h> /* Custom render functions -------------------------------------------------- */ #define NPARTICLES 200 #define MAX_VELOCITY 10 #define MAX_TIMEOUT 5000 void fireworks_render(SSG_Node *n) { SSG_Shader *s = (SSG_Shader *)ssg_node_data(n); static float v[NPARTICLES][3]; static int prev_time = 0; int next_time; int p, c; /* Generate random velocities */ next_time = glutGet(GLUT_ELAPSED_TIME); if (prev_time == 0 || next_time - prev_time > MAX_TIMEOUT) { for (p = 0; p < NPARTICLES; p++) { for (c = 0; c < 3; c++) { v[p][c] = rand() % MAX_VELOCITY; if (c != 1) v[p][c] -= (MAX_VELOCITY/2); } } prev_time = next_time; } /* Render velocities */ glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); glBegin(GL_POINTS); { for (p = 0; p < NPARTICLES; p++) glVertex3fv(v[p]); } glEnd(); /* Set shader uniform variables */ GLint ctloc, mtloc; ctloc = glGetUniformLocation(ssg_shader_program(s), "CurrentTime"); mtloc = glGetUniformLocation(ssg_shader_program(s), "MaxTime"); glUniform1f(ctloc, next_time - prev_time); glUniform1f(mtloc, MAX_TIMEOUT); } void time_render(SSG_Node *n) { SSG_Shader *s = (SSG_Shader *)ssg_node_data(n); GLint etloc; /* Set shader uniform variable */ etloc = glGetUniformLocation(ssg_shader_program(s), "ElapsedTime"); glUniform1f(etloc, glutGet(GLUT_ELAPSED_TIME)); } /* Main execution ----------------------------------------------------------- */ int main(int argc, char *argv[]) { SSG_Node *root = NULL; SSG_Node *teapot = NULL; SSG_Node *shader = NULL; SSG_Viewer *viewer = NULL; char *vert_src_path = NULL; char *frag_src_path = NULL; srand(time(NULL)); /* Parse command line arguments */ if (argc > 3) { fprintf(stderr, "use: %s <vert_src_path> <frag_src_path>\n", argv[0]); exit(EXIT_FAILURE); } if (argc <= 3) vert_src_path = argv[1]; if (argc == 3) frag_src_path = argv[2]; /* Create viewer */ viewer = ssg_viewer_create("shader demo", 640, 480); ssg_viewer_initialize(viewer, &argc, argv); /* Create nodes */ root = ssg_node_create(NULL, SSG_NODE_RENDER, NULL); shader = ssg_node_create(time_render, SSG_NODE_SHADER, ssg_shader_create(vert_src_path, frag_src_path)); //shader = ssg_node_create(fireworks_render, SSG_NODE_SHADER, ssg_shader_create(vert_src_path, frag_src_path)); teapot = ssg_teapot_create(); /* Organize graph */ ssg_node_connect(root, shader); ssg_node_connect(shader, teapot); //ssg_node_connect(root, teapot); /* Show graph */ ssg_viewer_show(viewer, root); return (EXIT_SUCCESS); } /* vim: set sts=4 sw=4 ts=8 ft=cpp: ----------------------------------------- */