views:

341

answers:

2

Right now, I have more than 25 vertices that form a model. I want to interpolate color linearly between the first and last vertex. The Problem is when I write the following code

glColor3f(1.0,0.0,0.0);
vertex3f(1.0,1.0,1.0);
vertex3f(0.9,1.0,1.0);
.
.`<more vertices>;
glColor3f(0.0,0.0,1.0);
vertex3f(0.0,0.0,0.0);

All the vertices except that last one are red. Now I am wondering if there is a way to interpolate color across these vertices without me having to manually interpolate color (instead natively, like how opengl does it automatically) at each vertex since, I will be having a lot more number of colors at various vertices. Any help would be extremely appreciated.

Thank you!

+2  A: 

OpenGL will interpolate colors of pixels between one vertex and the next, but I don't know of any way to get it to automatically interpolate the values for intermediate vertexes. Normally, that's not particularly difficult though -- you don't want to write code for each individual vertex anyway, so adding the computation is pretty trivial:

class pointf { 
    GLfloat x, y, z;
};

std::vector<pointf> spots;

// ...
GLfloat start_blue = 1.0f;
GLfloat end_blue = 0.0f;
GLfloat start_green = 0.0f;
GLfloat end_green = 0.0f;
GLfloat start_red = 0.0f;
GLfloat end_red = 1.0f;

GLfloat size = spots.size();

glBegin(GL_POLYGON);
for (int i=0; i<spots.size(); i++) {
    GLfloat red = start_red + (end_red-start_red) * i/size;
    GLfloat green = start_green + (end_green-start_green) * i/size;
    GLfloat blue = start_blue + (end_blue-start_blue) * i/size;

    glColor3f(red, green, blue);
    glVertex3f(spots[i].x, spots[i].y, spots[i].z);
}
glEnd();

One thing though: this does purely linear interpolation per vertex. It does not, for example, attempt to take into account the distance between one vertex and the next. I'd guess questions of how to do things like this are (at least part of) why OpenGL doesn't attempt this on its own.

Edit: for a gradient across a hemisphere, I'd try something like this:

// Blue light on the left  
GLfloat blue[] = {0.0f, 0.0f, 1.0f, 1.0f};
GLfloat blue_pos[] = {-1.0f, 0.0f, -0.3f, 0.0f};

// red light on the right
GLfloat red[] = {1.0f, 0.0f, 0.0f, 1.0f};
GLfloat red_pos[] = {1.0f, 0.0f, -0.3f, 0.0f};

// turn on lighting:
glEnable(GL_LIGHTING);
glShadeModel(GL_SMOOTH);

// Set up the two lights:
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, blue);
glLightfv(GL_LIGHT0, GL_POSITION, blue_pos);

glEnable(GL_LIGHT1);
glLightfv(GL_LIGHT1, GL_DIFFUSE, red);
glLightfv(GL_LIGHT1, GL_POSITION, red_pos);

// set up the material for our sphere (light neutral gray):
GLfloat sph_mat[] = {0.8f, 0.8f, 0.8f, 1.0f};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, sph_mat);

// Draw a sphere:
GLUquadric *q = gluNewQuadric();
gluQuadricOrientation(q, GLU_OUTSIDE);
gluQuadricDrawStyle(q, GLU_FILL);
gluQuadricNormals(q, GLU_SMOOTH);
gluSphere(q, 1.0, 64, 64);

For the moment, I've done the outside of a sphere, but doing a hemisphere isn't drastically different.

Jerry Coffin
Thank you for your response. Your answer definitely makes sense. Now the question is can I apply this logic to a hemisphere? I have a huge hemisphere and I want to have various colors at different positions. I am not sure if this logic quite works, so do you think I might be better off, calculating color at individual vertices? Thank you once again for taking time.
gutsblow
@gutsblow: Perhaps you'd be better off telling us a bit more about what you're really trying to accomplish. Right off, it sounds like you'd be better off with a sphere in a neutral color with red and blue lights at appropriate positions.
Jerry Coffin
Sorry, for being vague. Here is what I exactly have in mind, a huge sphere/hemisphere that works as a skydome. I can apply textures to it, but I want to have a gradient of colors which can be controlled by the position of the colors. Thanks again!
gutsblow
Thank you very much. This method works really well. Since I am new to OpenGL, I didn't know there is a direct function to create a sphere, that makes my life a lot easier. Thank you!
gutsblow
+1  A: 

OpenGL will interpolate color within polygons, but not across polygons.

brainjam