Bezier Surface patch - animation, lighting, grid - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Bezier Surface patch - animation, lighting, grid

yamatoshingenyamatoshingen Posts: 1Member
Hi,

I am working with graphics for the first time; trying to emulate a Bezier Surface patch.

The surface patch is animated only on the "z" co-ordinate of the control points.

It has lighting effects on it (vertex-shader/frag-shader)

It has "l", "f" and "s" keyboard call back functionality

FILL_LINES and FULL SHADING options mapped to - f key

# of sub-divisions ( 3x3, 6x6, 12x12...96x96) is mapped to the - s key

A menu version of these options also exist and can be observed upon right click

-----------------------------------------

I am posting the code and hoping that someone who has worked with OPENGL in C++ or has knowledge on how graphics works can help me optimize the program

The program might not work on windows 7 because of the initial library calls


modification - some kind of a better animation scheme for the idle func that helps animate the surface patch along the "z", with x nd y constant.... and any others are also welcome
-----------------------------------------



// purpose - Bezier Surface patch.


//#include "stdafx.h"

#ifdef _WIN32
#include
//#include
//#include
#include
#elif defined __MACH__
#include
#endif

#include
#include

void createMenu(void);
void menu(int value);
static int menid;
static int submenid;
static int submenid1;
static int submenid2;
int windowID;
int mod = 1;

GLfloat ctrlpoints[4][4][3] = {
{{-0.5, -0.5, 0}, {-1.0/6, -0.5, 0},
{1.0/6, -0.5, 0}, {0.5, -0.5, 0}},
{{-0.5, -1.0/6, 0}, {-1.0/6, -1.0/6, 0},
{1.0/6, -1.0/6, 0.0}, {0.5, -1.0/6, 0}},
{{-0.5, 1.0/6, 0}, {-1.0/6, 1.0/6, 0},
{1.0/6, 1.0/6, 0}, {0.5, 1.0/6, 0}},
{{-0.5, 0.5, 0}, {-1.0/6, 0.5, 0},
{1.0/6, 0.5, 0.0}, {0.5, 0.5, 0}}
};

GLfloat Materials [3][4]= {
{0, .1, .9, 1},
{0, .1, .9, 1},
{.9, .9, 1, 1},
};

int shininess = 1;
int lines = 0;
int division = 3;
int light = 0;



GLuint program = 0;
GLchar *ebuffer;
GLsizei elength;




void display(void)
{
int i, j;
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4,
0, 1, 12, 4, &ctrlpoints[0][0][0]);

glPolygonMode(GL_FRONT_AND_BACK, lines ? GL_LINE : GL_FILL);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glLoadIdentity();
//glPushMatrix ();
//glRotatef(85.0, 1.0, 1.0, 1.0);
glTranslatef(0,0,-2);
for (i = 0; i < division; i++) {
for (j =0; j< division; j++){
glBegin(GL_POLYGON);
glEvalCoord2f((GLfloat)i/division, (GLfloat)j/division);
glEvalCoord2f((GLfloat)(i+1)/division, (GLfloat)(j)/division);
glEvalCoord2f((GLfloat)(i+1)/division, (GLfloat)(j+1)/division);
glEvalCoord2f((GLfloat)(i)/division, (GLfloat)(j+1)/division);
glEnd();
}
}
//glPopMatrix ();
glFlush();
}


void init(void)
{
glClearColor (0.0, 0.0, 0.0, 0.0);

glEnable(GL_MAP2_VERTEX_3);
//glMapGrid2f(20, 0.0, 1.0, 20, 0.0, 1.0);
glEnable(GL_DEPTH_TEST);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Materials[0]);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Materials[1]);
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Materials[2]);
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
}


void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(50,(GLfloat)w/h,1,50);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}


void idle()
{
int i, j;

for(i =0; i<=3; i++){
for(j=0;j<=3;j++){

if (ctrlpoints[i][j][2] > 0.25)
{
mod = -1;
}
else if (ctrlpoints[i][j][2] < -0.25)
{
mod = 1;
}
ctrlpoints[i][j][2]+= 1.0/1000* mod;
}
}
glutPostRedisplay();
}



void keyPressed(unsigned char key, int x, int y)
{
switch (key)
{
case 'f': case 'F':
lines = !lines;
break;
case 's': case 'S':
if(division >= 96)
{division =3;
}else division = division *2;
break;
case 'l': case 'L':
light = !light;
if(light)
{
glUseProgram(program);
}
else glUseProgram(0);
}
};


void createMenu()
{
// sub-menu for # of sub-divisions
submenid = glutCreateMenu(menu);
glutAddMenuEntry("0", 2);
glutAddMenuEntry("1", 3);
glutAddMenuEntry("2", 4);
glutAddMenuEntry("3", 5);
glutAddMenuEntry("4", 6);
glutAddMenuEntry("5", 7);


//sub-menu for lighting
submenid1 = glutCreateMenu(menu);
glutAddMenuEntry("light", 8 );
glutAddMenuEntry("nolight",9);



//sub-menu for fill
submenid2 = glutCreateMenu(menu);
glutAddMenuEntry("Fill", 10);
glutAddMenuEntry("Lines",11);


// main menu
menid = glutCreateMenu(menu);
glutAddSubMenu("Subdivisions", submenid);
glutAddSubMenu("Lighting", submenid1);
glutAddSubMenu("Fill", submenid2);
glutAddMenuEntry("Quit", 1);

// attach menu-options to the right click
glutAttachMenu(GLUT_RIGHT_BUTTON);
}


void menu(int value)
{
if(value == 1){
glutDestroyWindow(windowID); // to exit
exit(0);
}else if(value == 2){
division = division;
}else if(value == 3){
division = 6;
}else if(value == 4){
division = 12;
}else if(value == 5){
division = 24;
}else if(value == 6){
division = 48;
}else if(value ==7){
division = 96;
}else if(value ==8 ){
light = 1;
}else if(value ==9){
light = 0;
}else if(value ==10){
lines=0;
}else if(value ==11){
lines = 1;
}


glutPostRedisplay();
}



static char* readShaderSource(const char* shaderFile)
{
FILE* fp = fopen(shaderFile, "r");
char* buf;
long size;
if (fp==NULL) return NULL;
fseek(fp, 0L, SEEK_END);
size = ftell(fp);
fseek(fp, 0L, SEEK_SET);
buf = (char*) malloc((size + 1) * sizeof(char));
fread(buf, 1, size, fp);
fclose(fp);
return buf;
}



/* GLSL initialization */
static void initShader(const GLchar* vShaderFile, const GLchar*
fShaderFile)
{
GLint status;
GLchar *vSource, *fSource;
GLuint vShader, fShader;

/* read shader files */
vSource = readShaderSource(vShaderFile);
if(vSource==NULL)
{
printf( "Failed to read vertex shader
");
exit(EXIT_FAILURE);
}
fSource = readShaderSource(fShaderFile);
if(fSource==NULL)
{
printf("Failed to read fragment shader
");
exit(EXIT_FAILURE);
}

/* create program and shader objects */
vShader = glCreateShader(GL_VERTEX_SHADER);
fShader = glCreateShader(GL_FRAGMENT_SHADER);
program = glCreateProgram();

/* attach shaders to the program object */
glAttachShader(program, vShader);
glAttachShader(program, fShader);

/* read shaders */
glShaderSource(vShader, 1, (const GLchar**) &vSource, NULL);
glShaderSource(fShader, 1, (const GLchar**) &fSource, NULL);

/* compile vertex shader shader */
glCompileShader(vShader);

/* error check */
glGetShaderiv(vShader, GL_COMPILE_STATUS, &status);
if(status==GL_FALSE)
{
printf("Failed to compile the vertex shader.
");
glGetShaderiv(vShader, GL_INFO_LOG_LENGTH, &elength);
ebuffer = (GLchar*) malloc(elength*sizeof(char));
glGetShaderInfoLog(vShader, elength, NULL, ebuffer);
printf("%s
", ebuffer);
exit(EXIT_FAILURE);
}

/* compile fragment shader shader */
glCompileShader(fShader);

/* error check */
glGetShaderiv(fShader, GL_COMPILE_STATUS, &status);
if(status==GL_FALSE)
{
printf("Failed to compile the fragment shader.
");
glGetShaderiv(fShader, GL_INFO_LOG_LENGTH, &elength);
ebuffer = (GLchar*) malloc(elength*sizeof(char));
glGetShaderInfoLog(fShader, elength, NULL, ebuffer);
printf("%s
", ebuffer);
exit(EXIT_FAILURE);
}

/* link and error check */
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &status);
if(status==GL_FALSE)
{
printf("Failed to link program object.
");
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &elength);
ebuffer = (char*) malloc(elength*sizeof(char));
glGetProgramInfoLog(program, elength, &elength, ebuffer);
printf ("7
Sign In or Register to comment.