Howdy, Stranger!

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

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

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.