This program should allow the user to select the material of a teapot, that will change dynamically.So I made a menu.
I use setRGB (declared in a utility file) to set the color of an array of 3 GLfloat’s.
createMenu just creates the menu reading the voices from a va_list.
setMaterial sets the material, according to the value passed with an enumeration:
typedef enum
{
BlackPlastic= 0,
Brass,
Bronze,
Chrome,
Copper,
Gold,
Peweter,
Silver,
PolishedSilver
}MaterialType;
I will omit the body of the functions that I have tested since they work:
int createMenu(void (*callback) (int),int key, const char* const first, ...)
{
// creates a menu, the number of entries depends on the list length,
// the value starts from zero
}
void setRGB( GLfloat* color, GLfloat red, GLfloat green, GLfloat blue)
{
// Sets the color
}
void setMaterial (GLfloat** material, MaterialType type)
{
// Sets the material color (ambient, diffuse, specular).
}
That’s the whole program.My fear here is that I am doing something wrong so that the teapot isn’t drawn because OpenGL enters in an invalid state.
The problem is that sometimes I don’t see the teapot drawn in the window, I just get a black window.Incredibly sometimes work and I see the teapot, and I am able to change the material colors.
#include <OpenGL/OpenGL.h>
#include <GLUT/GLUT.h>
#include "utility.h"
#include <stdlib.h>
GLfloat width=500, height=500;
GLfloat** material;
GLfloat light[3][3]= { {1,1,0}, {1,0.5,0}, {1,0,0} };
void menuCallback (int choice)
{
setMaterial((GLfloat**)material, choice);
glutPostRedisplay();
}
void init()
{
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-width/2, width/2, -height/2, height/2, 1, 1000);
material= malloc(4*sizeof(GLfloat*));
for(GLuint i=0; i<4; i++)
{
material[i]=malloc(3*sizeof(GLfloat));
}
setRGB(material[3], 1, 1, 0);
setMaterial(material, BlackPlastic);
}
void display()
{
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glShadeModel(GL_FLAT);
glMaterialfv(GL_FRONT, GL_AMBIENT, material[0] );
glMaterialfv(GL_FRONT, GL_DIFFUSE, material[1]);
glMaterialfv(GL_FRONT, GL_SPECULAR, material[2]);
glMaterialfv(GL_FRONT, GL_SHININESS, material[3] );
glLightfv(GL_LIGHT0, GL_AMBIENT, light[0]);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light[1]);
glLightfv(GL_LIGHT0, GL_SPECULAR, light[2]);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
glutSolidTeapot(100);
glutSwapBuffers();
}
void keyboard(unsigned char key, int x, int y)
{
}
int main(int argc,char * argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE );
glutInitWindowPosition(100, 100);
glutInitWindowSize(width,height);
glutCreateWindow(*argv);
createMenu(menuCallback, GLUT_LEFT_BUTTON, "Black Plastic", "Brass", "Bronze", "Chrome", "Copper", "Gold", "Peweter", "Silver", "Polished Silver", NULL);
glutDisplayFunc(display);
glutKeyboardFunc(keyboard);
init();
glutMainLoop();
return 0;
}
You’re drawing a solid teapot? I presume you enabled depth testing (though your glutInitDisplayMode lacks the depth buffer bit). Anyway, you should probably also clear the depth buffer. Right now you’re clearing only the color buffer
Change it into