在纹理上绘制的点不会获得所需的颜色

时间:2015-02-18 15:38:24

标签: c++ opengl qt4 qtopengl

重要提示:我必须使用已修复的管道(我在这方面没有发言权。)

我必须修改一些现有的OpenGL代码(全景图片查看器,其中全景图被分割成立方体的六个面),因此我们可以在顶部绘制线条/点。加载纹理,其中点是未注册到对象坐标的鼠标坐标。

我用彩色立方体编写了一个测试程序,只是为了尝试在它上面画线:

Test program

我使用代码将 GL_DEPTH_BUFFER_BIT 属性推送到堆栈,在绘制点之前禁用它并在完成绘制后弹出stack属性。

我尝试在现有应用程序中使用相同的方法,但我得到了这些结果(在这里,我只是想画一点):

Point over texture, 1

Point over texture, 2

我指定 red 作为该点的颜色,但正如您所看到的,它没有所需的颜色。我认为这可能是由于混合并且它可能将其颜色与底层纹理混合在一起,所以我将 GL_BLEND 属性也推送到堆栈并在绘制之前禁用它,但是点不是&# 39;无论如何都得到所需的颜色。

这里发生了什么?有没有办法强迫"强迫"画红点的管道?

initCube():这是在更新GL场景之前调用的。

 void panoViewer::initCube() {
    makeCurrent();
    if(texture){
        glDisable( texture );
        textName = 0;
        texture = 0;
    }

    glDisable( GL_TEXTURE_GEN_S );
    glDisable( GL_TEXTURE_GEN_T );
    glDisable( GL_TEXTURE_GEN_R );

    glFrontFace( GL_CCW );
    glEnableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);

    texture = GL_TEXTURE_CUBE_MAP;
    textName = texnms[1];
    glEnableClientState(GL_NORMAL_ARRAY);
    glTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
    glTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
    glTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP );
    glEnable( GL_TEXTURE_GEN_S );
    glEnable( GL_TEXTURE_GEN_T );
    glEnable( GL_TEXTURE_GEN_R );

    // Add the textures to the cube faces.
    // ...
 }

initializeGL():

 void panoViewer::initializeGL() {
    qglClearColor(Qt::black);
    glShadeModel(GL_SMOOTH);
    glEnable(GL_CULL_FACE);
    glEnable( GL_DEPTH_TEST );

  // create texture objects
    glGenTextures( 1, textName );
    glBindTexture( GL_TEXTURE_CUBE_MAP, textName );

  // find the largest feasible textures
    maxTex2Dsqr = maxTexSize( GL_PROXY_TEXTURE_2D, max2d, max2d );
    maxTex2Drec = maxTexSize( GL_PROXY_TEXTURE_2D, max2d, max2d / 2 );
    maxTexCube = maxTexSize( GL_PROXY_TEXTURE_CUBE_MAP, maxcube, maxcube );

  // constant texture mapping parameters...
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  // for cube maps...
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

  // enable alpha blending for overlay
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);


    glEnable(GL_POINT_SMOOTH);
    glEnable(GL_LINE_SMOOTH);
    glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
    glDisable(GL_LIGHTING);

    // Create display list: dispList
    // ...
 }

paintGL():

 void panoViewer::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if(texture) {
        glBindTexture(texture, textName);
        glEnable( texture );
    }

    glMatrixMode(GL_TEXTURE);
    glLoadIdentity();
        glRotated( 180, 0, 1, 0 );   // camera looks at the front of the van
        glRotated( 180, 0, 0, 1 );   // van's roof points to the sky

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

//    double hFOV, vFOV;    // angular size at sphere center (deg)
//    double minFOV, maxFOV; // limits on vFOV
//    double wFOV;  // vert angle at eye (deg) sets magnification

    double  hhnear = Znear * tan( 0.5 * RAD(wFOV) ),
            hwnear = hhnear * aspectRatio,
            dxnear = 2 * hwnear * fcompx,
            dynear = 2 * hhnear * fcompy;

    glFrustum( -(hwnear + dxnear), hwnear - dxnear,
               -(hhnear + dynear), hhnear - dynear,
               Znear, Zfar
              );
    glRotated( 180, 0, 1, 0 );
    glTranslated( eyex, eyey, eyez );

    glRotated( tiltAngle, 1, 0, 0 );
    glRotated( panAngle, 0, 1, 0 );
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glCallList(dispList);

    glPushAttrib(GL_ENABLE_BIT | GL_DEPTH_BUFFER_BIT);
        glDisable(GL_BLEND);
        glDisable(GL_DEPTH_TEST);

        // Paint the point in red
        // ...
    glPopAttrib();
}

更新:我忘了提及代码位于Qt。它广泛使用QtOpenGL模块。

更新#2 :我已添加了一些代码。

1 个答案:

答案 0 :(得分:1)

在固定功能管道中,有许多状态可能导致顶点颜色完全被忽略。

正如Reto Koradi在评论中指出的那样,当启用光照时,颜色无效(除非启用GL_COLOR_MATERIAL,在这种情况下,颜色值用于更新用于照明方程的材料参数。)

正如我在评论中所指出的,另一个案例是纹理。根据所选的GL_TEX_ENV_MODE,片段的颜色(由光照确定,或直接从顶点颜色插值)由纹理颜色调制,或完全替换。在这种情况下,禁用正在使用的每个纹理单元的纹理可以解决问题。