0

我是一名经验丰富的 C++ 程序员,正在学习 OpenGL。其中,我正在阅读 Richard Wright 的OpenGL Super Bible。那里的支持库是hacker-head C,松散地翻译成C++。作为一个纯粹主义者,我已将大部分支持代码翻译成 C++。我在 QT 而不是 Glut 工作。我已经得到了第 2 章中的示例和第 3 章中的“Primitives”示例,但无法让“GeoTest”示例正常工作。这是问题的简化示例:

void geotest::paintGL() {
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_CULL_FACE);
    model_view_matrix.push(view_frame);
        float red[] = { 1.0f, 0.0f, 0.0f, 1.0f };
        shader.use(
            transform_pipeline.get_model_view_matrix(),
            transform_pipeline.get_projection_matrix(),
            red);
        glBegin(GL_TRIANGLES);
            glVertex3f(-1.2f, -1.2f, 0.0f);
            glVertex3f( 1.2f, -1.2f, 0.0f);
            glVertex3f( 1.2f,  1.2f, 0.0f);
        glEnd();
    model_view_matrix.pop();
}

shader是我对这本书的改编GLT_SHADER_DEFAULT_LIGHT。我已经削减了图纸以隔离问题。当我运行此代码时,我得到一个看似空白的窗口。我没有显示的代码支持旋转图像,当我围绕 x 或 y 轴旋转 180 度时,我看到三角形的另一边,但它是黑色而不是红色。所以看起来表面法线最初指向远离观察者,所以它被剔除。

我已经尝试在and调用之间我可以想象的任何地方添加 1 到 3 个调用glNormal3f(0.0f, 0.0f, -1.0f)(and ) ,但我看不到任何效果;三角形总是在显示其背面的情况下绘制。1.0fglBeginglEnd

我错过了一些关于法线的基本知识吗?我很确定着色器没问题(如果我使用书的 GLT_SHADER_FLAT,我会遇到与法线相同的问题,尽管当三角形出现时,它应该是红色的)。

编辑这里是着色器的代码:

const char *default_light_vp = "uniform mat4 mvMatrix;"
                               "uniform mat4 pMatrix;"
                               "varying vec4 vFragColor;"
                               "attribute vec4 vVertex;"
                               "attribute vec3 vNormal;"
                               "uniform vec4 vColor;"
                               "void main(void) { "
                               " mat3 mNormalMatrix;"
                               " mNormalMatrix[0] = mvMatrix[0].xyz;"
                               " mNormalMatrix[1] = mvMatrix[1].xyz;"
                               " mNormalMatrix[2] = mvMatrix[2].xyz;"
                               " vec3 vNorm = normalize(mNormalMatrix * vNormal);"
                               " vec3 vLightDir = vec3(0.0, 0.0, 1.0); "
                               " float fDot = max(0.0, dot(vNorm, vLightDir)); "
                               " vFragColor.rgb = vColor.rgb * fDot;"
                               " vFragColor.a = vColor.a;"
                               " mat4 mvpMatrix;"
                               " mvpMatrix = pMatrix * mvMatrix;"
                               " gl_Position = mvpMatrix * vVertex; "
                               "}";


const char *default_light_fp =   
#ifdef OPENGL_ES
                               "precision mediump float;"
#endif
                               "varying vec4 vFragColor; "
                               "void main(void) { "
                               " gl_FragColor = vFragColor; "
                               "}";
4

1 回答 1

3

剔除不是基于法线的方向,而是基于缠绕顺序。尝试切换绘制顶点的方向,看看是否会有所不同。要更改缠绕顺序,您可以使用glFrontFacewithGL_CWGL_CCW,它定义了哪个面是前面,哪个面是后面。

于 2012-10-28T18:51:41.243 回答