如何给出2D结构的3D深度

时间:2011-02-09 16:35:05

标签: opengl

我正在乞求学习OpenGL作为分子建模项目的一部分,目前我正在尝试渲染7个螺旋,这些螺旋将在空间上彼此靠近并且将以某些方式相互移动,倾斜和相互作用。我的问题是如何给出二维场景三维深度,使几何结构在三维空间看起来像真正的螺旋?

我尝试过使用投影矩阵(gulPerspective,glFrustum)而没有太多运气,以及使用glDepthRange函数。

我包含了用于渲染螺旋的代码,但为了简单起见,我插入了用于渲染一个螺旋的代码(其他6个螺旋除了它们的平移矩阵和颜色函数参数之外完全相同)以及用于从对象进行映射时重新整形坐标到剪辑坐标:

非常感谢任何帮助。

void init() {

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    // Black background
    glLineWidth(8.0);

}

/* CALLED TO DRAW THE HELICES */ 

void RenderHelix() {

    GLfloat x,y,z; 
    GLfloat c = 2.5f;   //helical pitch 
    GLfloat theta;      //constant angle between tangent and x-axis 
    GLfloat r = 4.5f;   //radius 
    //GLint i = 1;      //loop through code to render 7 helices 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* GREEN HELIX */ 

    glBegin(GL_LINE_STRIP); 
    glColor3f(0.0, 1.0, 0.0);           
    for(theta = 0; theta <= 360; ++theta) { 
        x = r*(cos(theta));
        y = r*(sin(theta));
        z = c*theta; 
        glVertex3f(x,y,z);
    }
    glEnd();
    glLoadIdentity(); 
    glScalef(1.0,1.0,12.0); 
    glTranslatef(50.0, 100.0, 0.0);  //Move Position 
    glRotatef(90.0, 0.0, 0.0, 0.0);

/* Other 6 helices .... */

glFlush(); 
 glutSwapBuffers();

}

void Reshape(GLint w, GLint h) {

    if(h==0)
        h=1;

    glViewport(0,0,w,h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    GLfloat aspectratio = (GLfloat)w/(GLfloat)h;
    if(w<=h)
        glOrtho(-100,100,-100/aspectratio,100/aspectratio, -100,310);
    else
        glOrtho(-100*aspectratio,100*aspectratio,-100,100,-100,310);

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity();       
}

1 个答案:

答案 0 :(得分:0)

我编辑了你的代码并在这里和那里发表评论:

void init() {
    /* One time OpenGL initialization would be textures and
     * other static stuff. Nothing like that here */    
}

/* CALLED TO DRAW THE HELICES */ 

void RenderHelix() {

    GLfloat x,y,z; 
    float aspectratio;
    GLfloat c = 2.5f;   //helical pitch 
    GLfloat theta;      //constant angle between tangent and x-axis 
    GLfloat r = 4.5f;   //radius 
    //GLint i = 1;      //loop through code to render 7 helices 

    /* assuming w and h are globals or somehow else accessible */
    aspectratio = (float)w/(float)h;
    glViewport(0,0,w,h);

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);    // Black background
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    GLfloat aspectratio = (GLfloat)w/(GLfloat)h;
    if(w<=h)
        glFrustum(-10.f,10.f, -10.f/aspectratio, 10.f/aspectratio, 1.0f, 10.f);
    else
        glFrustum(-10.f*aspectratio,10.f*aspectratio,-10.f,10.f, 1.0f,10.f);

/* enable depth testing, also make sure the right depth func is used */
    glEnable(GL_DEPTH_TEST);
    glDepthFunc(GL_LESS);


/* GREEN HELIX */ 
    glLineWidth(8.0);    

    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity();

    glTranslatef(0.f, 0.f, -4.5f);

    glPushMatrix();
    /* this helix will be drawn in the center, as it's not moved anywhere. */

    glBegin(GL_LINE_STRIP); 
    glColor3f(0.0, 1.0, 0.0);
    /* trigonometric functions take radians, not degrees */
    for(theta = 0; theta <= M_PI2; theta += M_PI2*0.01;) { 
        /* instead of calculating the helices a new each rendering
         * pass you should store them to a vertex array. */
        x = r*cosf(theta);
        y = r*sinf(theta);
        z = c*theta; 
        glVertex3f(x,y,z);
    }
    glEnd();

    glPopMatrix();

/* Other 6 helices .... */
    glScalef(1.0,1.0,12.0); 
    glTranslatef(50.0, 100.0, 0.0);  //Move Position of next helix, you may want to use glPushMatrix/glPopMatrix
    glRotatef(90.0, 0.0, 0.0, 0.0);  // a null rotation, what's that's supposed to do?


glFlush(); // redundant, glFlush is implied by SwapBuffers
 glutSwapBuffers();

}

void Reshape(GLint w, GLint h) {
    /* Pleast don't set OpenGL stuff in the window reshape handler.
     * This just causes confusion, as soon one uses multiple projections
     * in a single rendering */
}