使用Glut在OpenGL中的多色二十面体

时间:2016-10-11 23:08:37

标签: opengl glut freeglut

我正在画一个二十面体,但我似乎无法为它的每个面部着色,所以它可能就像“多色”的二十面体。

我怎样才能做到这一点?

以下是目前的代码:

#include <freeglut.h>

void init();
void display(void);
void centerOnScreen();
void drawObject();

//  define the window position on screen
int window_x;
int window_y;

//  variables representing the window size
int window_width = 480;
int window_height = 480;

//  variable representing the window title
char *window_title = "Sample OpenGL FreeGlut App";

bool mouseDown = false;

float xrot = 0.0f;
float yrot = 0.0f;

float xdiff = 0.0f;
float ydiff = 0.0f;



static GLfloat spin = 0.0;
#define X .525731112119133606
#define Z .850650808352039932

//-----------------------------------------------------------------------

#define X .525731112119133606 
#define Z .850650808352039932

static GLfloat vdata[12][3] = {
    { -X, 0.0, Z },{ X, 0.0, Z },{ -X, 0.0, -Z },{ X, 0.0, -Z },
    { 0.0, Z, X },{ 0.0, Z, -X },{ 0.0, -Z, X },{ 0.0, -Z, -X },
    { Z, X, 0.0 },{ -Z, X, 0.0 },{ Z, -X, 0.0 },{ -Z, -X, 0.0 }
};
static GLuint tindices[20][3] = {
    { 0,4,1 },{ 0,9,4 },{ 9,5,4 },{ 4,5,8 },{ 4,8,1 },
    { 8,10,1 },{ 8,3,10 },{ 5,3,8 },{ 5,2,3 },{ 2,7,3 },
    { 7,10,3 },{ 7,6,10 },{ 7,11,6 },{ 11,0,6 },{ 0,1,6 },
    { 6,1,10 },{ 9,0,11 },{ 9,11,2 },{ 9,2,5 },{ 7,2,11 } };
int i;



//-------------------------------------------------------------------------
//  Set OpenGL program initial state.
//-------------------------------------------------------------------------
void init()
{
    //  Set the frame buffer clear color to black. 
    glClearColor(0.2, 0.3, 0.4, 0.5);
}

//-------------------------------------------------------------------------
//  This function is passed to glutDisplayFunc in order to display 
//  OpenGL contents on the window.
//-------------------------------------------------------------------------
void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();

    gluLookAt(
        0.0f, 0.0f, 3.0f,
        0.0f, 0.0f, 0.0f,
        0.0f, 1.0f, 0.0f);

    glRotatef(xrot, 1.0f, 0.0f, 0.0f);
    glRotatef(yrot, 0.0f, 1.0f, 0.0f);

    drawObject();

    glFlush();
    glutSwapBuffers();
}

//-------------------------------------------------------------------------
//  Draws our object.
//-------------------------------------------------------------------------
void drawObject()
{
    //  Draw Icosahedron

glBegin(GL_TRIANGLES);    
for (i = 0; i < 20; i++) {    
   /* color information here */ 
   glVertex3fv(&vdata[tindices[i][0]][0]); 
   glVertex3fv(&vdata[tindices[i][1]][0]); 
   glVertex3fv(&vdata[tindices[i][2]][0]); 
}
glEnd();
}

//-------------------------------------------------------------------------
//  This function sets the window x and y coordinates
//  such that the window becomes centered
//-------------------------------------------------------------------------
void centerOnScreen()
{
    window_x = (glutGet(GLUT_SCREEN_WIDTH) - window_width) / 2;
    window_y = (glutGet(GLUT_SCREEN_HEIGHT) - window_height) / 2;
}

void resize(int w, int h)
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    glViewport(0, 0, w, h);

    gluPerspective(45.0f, 1.0f * w / h, 1.0f, 100.0f);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

void idle()
{
    if (!mouseDown)
    {
        xrot += 0.3f;
        yrot += 0.4f;
    }

    glutPostRedisplay();
}

void mouse(int button, int state, int x, int y)
{
    if (button == GLUT_LEFT_BUTTON & state == GLUT_DOWN)
    {
        mouseDown = true;

        xdiff = x - yrot;
        ydiff = -y + xrot;
    }
    else
        mouseDown = false;
}

void mouseMotion(int x, int y)
{
    if (mouseDown)
    {
        yrot = x - xdiff;
        xrot = y + ydiff;

        glutPostRedisplay();
    }
}

//-------------------------------------------------------------------------
//  Program Main method.
//-------------------------------------------------------------------------
void main(int argc, char **argv)
{
    //  Connect to the windowing system + create a window
    //  with the specified dimensions and position
    //  + set the display mode + specify the window title.
    glutInit(&argc, argv);
    centerOnScreen();
    glutInitWindowSize(window_width, window_height);
    glutInitWindowPosition(window_x, window_y);
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
    glutCreateWindow(window_title);

    //  Set OpenGL program initial state.
    init();

    // Set the callback functions
    glutDisplayFunc(display);
    glutMouseFunc(mouse);
    glutMotionFunc(mouseMotion);
    glutReshapeFunc(resize);

    //  Start GLUT event processing loop
    glutMainLoop();
}

1 个答案:

答案 0 :(得分:1)

问题在于,在drawObject()函数中,您永远不会设置顶点的颜色。你只画它们。您可以使用glColor4f(red, green, blue, alpha);设置它们。您需要为侧面提供所需的颜色列表,或者在绘制每个顶点的循环中计算它们。如果你在循环开始时调用glColor4f(),那么对于所有3个顶点都会使用相同的颜色。

例如,您可以将drawObject()方法更新为:

void drawObject()
{
    //  Draw Icosahedron
    glBegin(GL_TRIANGLES);    
    for (i = 0; i < 20; i++) {
        // Set the color for this face
        glColor4f(cdata[i].red, cdata[i].green, cdata[i].blue, cdata[i].alpha);

        // Set the vertices of this face
        glVertex3fv(&vdata[tindices[i][0]][0]); 
        glVertex3fv(&vdata[tindices[i][1]][0]); 
        glVertex3fv(&vdata[tindices[i][2]][0]); 
    }
    glEnd();
}

你需要有一系列面部颜色,如下所示:

typedef struct RGBAColor {
    float red;
    float green;
    float blue;
    float alpha;
} RGBAColor;

RGBAColor cdata[] = {
    { 1.0, 0.0, 0.0, 1.0 }, // Red
    ... etc. for whatever colors you want the faces to be
};