对于OpenGL的不同点,请看相同的颜色

时间:2016-05-30 09:00:28

标签: c++ opengl graphics

我正在尝试显示由7600700点组成的3D矩阵,我想获得一个表面为黑色且内部为红色的平行六面体。每个点对应一个不同的能量值,我只使用不同的红色阴影来做到这一点。我有平行六面体,表面是黑色,内部是红色,但我只能看到一个红色的阴影,而不是它的不同色调。 这是我的代码的一部分:

#define MATRIX_FILE "dose_file.dat"

struct Point
{
    GLfloat x, y, z;
    GLfloat r, g, b, a;
};
static vector< Point > points; //Vettore points di elementi Point

void fill_data() {

    g_vertex_buffer_data = new GLfloat[3*p_mat_size_tot];
    int i=0;
    int k=0;

    for(int z=0; z<263; z++)
        for(int y=0; y<170; y++)
            for(int x=0; x<170; x++) {
                g_vertex_buffer_data[i]=(GLfloat)x+0.5;
                g_vertex_buffer_data[i+1]=(GLfloat)y+0.5;
                g_vertex_buffer_data[i+2]=(GLfloat)z+0.5;
                i+=3;
            }

    g_color_buffer_data=new GLfloat[3*p_mat_size_tot];

    for(int j=0;j<(3*p_mat_size_tot);j+=3) {
        if(p_val[k]!=0.0) {
            g_color_buffer_data[j]=(GLfloat)(255-13*fabs(logf(p_val[k])));//g_color_buffer_data[j]=(GLfloat)(255-30*fabs(log10f(p_val[k])));
        } else {
            g_color_buffer_data[j]=0.0;} 
            g_color_buffer_data[j+1]=0.0;
            g_color_buffer_data[j+2]=0.0;
            k++;
        }

    for( size_t i = 0; i < (3*p_mat_size_tot); i+=3 )
    {
        Point pt;
        pt.x = g_vertex_buffer_data[i];
        pt.y = g_vertex_buffer_data[i+1];
        pt.z = g_vertex_buffer_data[i+2];
        pt.r = g_color_buffer_data[i];
        pt.g = g_color_buffer_data[i+1];
        pt.b = g_color_buffer_data[i+2];
        pt.a = 255.0;
        points.push_back(pt);
    }    
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glLoadIdentity();

    gluLookAt (85.0, 85.0, 526.0, 85.0, 85.0, 131.5, 0.0, 1.0, 0.0);
    glPushMatrix();
    glRotatef(step1, 1.0f, 0.0f, 0.0f);//Rotazione attorno all'asse x
    glRotatef(step2, 0.0f, 1.0f, 0.0f);//Rotazione attorno all'asse y
    glScalef(step3, step3, step3);//Zoom
    glTranslatef(0.0f, 0.0f, step4);//Traslazione lungo z
    glTranslatef(step5, 0.0f, 0.0f);//Traslazione lungo x
    glTranslatef(0.0f, step6, 0.0f);//Traslazione lungo y

    glMatrixMode(GL_MODELVIEW); //Lavoriamo sulla matrice del modello

    // draw
    //glColor3ub( 255, 255, 255 ); //Setta il colore corrente
    glEnableClientState( GL_VERTEX_ARRAY ); //Abilita il l'array di vertici
    glEnableClientState( GL_COLOR_ARRAY );  //Abilita l'array di colori 
    glVertexPointer( 3, GL_FLOAT, sizeof(Point), &points[0].x ); //Definisce un array di dati di vertici (numero di coordinate, tipo, offset nelle coordinate tra punti consecutivi, puntatore alla prima coordinata del primo vertice nell'array)
    glColorPointer( 4, GL_FLOAT, sizeof(Point), &points[0].r ); //Come sopra, ma con i colori
    glPointSize( 3.0 );
    glDrawArrays( GL_POINTS, 0, points.size()); //Disegna points.size() punti partendo dal primo
    glDisableClientState( GL_VERTEX_ARRAY );
    glDisableClientState( GL_COLOR_ARRAY );

    glFlush(); //Forza l'esecuzione dei comandi GL in un tempo finito
    glPopMatrix();
    glutSwapBuffers(); //Swap dei buffers front e back della finestra (riserva memoria per inserire i comandi dati dall'utente)
}

void reshape(int w, int h)
{
    glViewport(0, 0, w, h);
    glMatrixMode (GL_PROJECTION);
    glLoadIdentity ();
    glFrustum (-0.5, 0.5, -0.5, 0.5, 1.0, 1000.0); //glFrustum (-0.5, 0.5, -0.5, 0.5, 1.0, 264.0);
    glMatrixMode (GL_MODELVIEW);
}

void keyPressed(unsigned char key, int x, int y)
{
    switch(key)
    {
    .
    .
    .
    glutPostRedisplay();
}


int main(int argc, char** argv)
{
    .
    .
    .
    glutInit(&argc, argv); //Inizializza glut
    glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); //Display mode iniziale

    glutInitWindowSize(800,800);
    glutInitWindowPosition (100, 100);
    glutCreateWindow("Test");

    glClearColor (255.0, 255.0, 255.0, 0.0);
    glEnable(GL_DEPTH_TEST);

    fill_data();

    glutDisplayFunc(display);
    glutReshapeFunc(reshape);
    glutKeyboardFunc(keyPressed);

    glutMainLoop();
    return 0;
}

我有漂浮值(类似于10 ^( - 7),10 ^( - 6),...,10 ^( - 1)),因此我使用对数将这些小值转换为某些值更大,我从255中减去这些新值,以获得我的R值的正确值(我想要红色阴影,所以我设置G = 0和B = 0)。
我应该添加法线吗? 谢谢你的帮助。

1 个答案:

答案 0 :(得分:1)

首先,我看到一些令人困惑的计算,混合了int s floatdouble s。由于你的代码不够完整,所以我可以编译和重现,它可能是有效的,但我发现它很难阅读。我使用fabsf()

g_color_buffer_data[j]=(GLfloat)(255.-13*fabs(logf(p_val[k])));

第二个,这可能是您的问题的原因(隐藏在难以阅读的行中),颜色缓冲区数据类型在何处以及如何定义? OpenGL中的AFAIK,float颜色会在0.01.0之间进行限制,而0.255之间会有这些颜色。这可能是你只得到一个红色细微差别的原因。尝试规范化 0.1.之间的上一行中的所有颜色值,看看你会得到什么。

希望这可以提供帮助。