c++ - 绘制三角形,无法设置法线

标签 c++ opengl

我是一名经验丰富的 C++ 程序员,正在学习 OpenGL。其中,我正在阅读 Richard Wright 的 OpenGL Super Bible。那里的支持库是 hacker-head C,松散地翻译成 C++。作为一个纯粹主义者,我已将大部分支持代码翻译成 C++。而且我在 QT 而不是 Glut 工作。我已经使第 2 章中的示例和第 3 章中的“基元”示例正常工作,但无法使“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();
}

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

我已经尝试在我能想到的任何地方添加对 glNormal3f(0.0f, 0.0f, -1.0f)(和 1.0f)的 1 到 3 个调用glBeginglEnd 调用,我看不到任何效果;绘制三角形时始终显示其背面。

我是否遗漏了法线的一些基本知识?我很确定着色器没问题(如果我使用书中的 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; "
                               "}";

最佳答案

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

关于c++ - 绘制三角形,无法设置法线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13111666/

相关文章:

c++ - 函数不会抛出 bad_alloc 异常

java - OpenGL Interleaved VBO 跨步和偏移

opengl - SDL 鼠标位置调整大小后裁剪

qt - 在任意宽度的两点之间绘制矩形

c++ - 指针值丢失

c++ - 指针输出让我困惑

c++ - 使用 makefile 将静态库与 OTL 链接时 undefined reference

c++ - 迭代器不匹配运算符=错误

OpenGL 帧缓冲区 : can clear it, 但无法绘制到它

c++ - TrueType 字体缩放会导致文本模糊?