【问题标题】:OpenGL refuses to draw a triangleOpenGL拒绝绘制三角形
【发布时间】:2018-08-20 20:33:21
【问题描述】:

我正在尝试在 OpenGL 的窗口中绘制一个大三角形。我的程序可以编译并运行,但我的窗口中只有一个黑屏。

我已经检查并仔细检查了多个教程,似乎我的步骤是正确的......我是否遗漏了一些明显的东西?

这是整个程序:

#include <stdlib.h>
#include <stdio.h>
#include <GL/glew.h>
#include <GLUT/glut.h>

GLuint VBO;

struct vector {
  float _x;
  float _y;
  float _z;
  vector() { }
  vector(float x, float y, float z) { _x = x; _y = y; _z = z; }
};

void render()
{
  glClear(GL_COLOR_BUFFER_BIT);

  glEnableVertexAttribArray(0);
  glBindBuffer(GL_ARRAY_BUFFER, VBO);
  glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);

  glDrawArrays(GL_TRIANGLES, 0, 3);

  glDisableVertexAttribArray(0);

  glutSwapBuffers();
}

void create_vbo()
{
  vector verts[3];
  verts[0] = vector(-1.0f, -1.0f, 0.0f);
  verts[1] = vector(1.0f, -1.0f, 0.0f);
  verts[2] = vector(0.0f, 1.0f, 0.0f);

    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
}

int main(int argc, char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
    glutInitWindowSize(1024, 768);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Triangle Test");
    glutDisplayFunc(render);

    glewInit();

    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);

    create_vbo();
    glutMainLoop();

    return 0;
}

更新:事实证明,在没有“程序”(即编译的着色器文件)的情况下以这种方式绘制会产生未定义的行为(您的显卡越新,它就越有可能工作,但是)。

因为我的卡正好在边缘并且只支持 OpenGL 2.1,所以找到一个合适的着色器示例有点困难——似乎有很多不同的教程在进化的不同阶段编写OpenGL。

我的顶点着色器(整个文件):

void main()
{
  gl_Position = ftransform();
}

我的片段着色器(整个文件):

void main()
{
    gl_FragColor = vec4(0.4,0.4,0.8,1.0);
}

我使用来自this OpenGL Tutorial Site 的示例LoadShaders 函数来创建程序,现在我也可以看到三角形了!

(感谢@chbaker0 为我指明了正确的方向。)

【问题讨论】:

  • 它为我画了一个三角形。您可以尝试仅用浮点数组替换 vector 数组并将其上传到缓冲区吗?从技术上讲,C++ 不保证这些结构的布局方式。
  • 没想到!我尝试只上传一个 float[9] 数组,但仍然没有三角形。代码 works 对您有用的事实是有用的信息……它可能是 OpenGL 版本吗?我从我的程序中打印了glGetString(GL_VERSION),得到了2.1 NVIDIA-10.0.43 310.41.05f0。我没有在 OpenGL 2.0 之外做任何事情,是吗?
  • 我有一个 OpenGL 4.4 兼容性上下文,所以它非常有可能。我现在正在查看一些文档。
  • 我确实想到了一些事情:您正在使用可编程管道功能而不使用着色器,因此这可能只是我们遇到的 OpenGL 未定义行为。因为我有一张 AMD 卡,而你有 NVidia,他们可能对它的反应不同。但是我不确定;我只亲自使用过 OpenGL 3.3+ 核心上下文。
  • @chbaker0,毕竟是着色器。如果您愿意,请随时以答案形式发布。我也会用我的确切步骤更新问题。

标签: c++ opengl


【解决方案1】:

我不知道这是否对您有帮助,但在您拥有的 create_vbo() 函数中:

  glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);

试试这个:

  glBufferData( GL_ARRAY_BUFFER, sizeof( verts[0] * 3 ), &verts[0], GL_STATIC_DRAW );

在这个函数调用之后,将这个函数调用添加到你的 create_vbo() 函数的末尾

// This MUST BE LAST! Used to Stop The Buffer!
glBindBuffer( GL_ARRAY_BUFFER, 0 ); 

我很难看出你的错误。在我的项目中,我确实有一些 vbo,但我也使用 vaos。我的代码能够在 OpenGL 2.0 - 4.5 中工作,但对于旧版本,由于 API 中不推荐使用的函数,逻辑上存在分歧。我也不用过剩。我希望这会有所帮助。

我还注意到的另一件事是您是否注意您的顶点缠绕顺序?意思是OpenGL以CCW顺序还是CW顺序使用它们?背面剔除是打开还是关闭?在设置和配置 OpenGL 上下文时需要考虑很多元素。自从我使用旧版本的 OpenGL 以来已经有一段时间了,但我知道一旦你开始使用特定版本或更高版本,你将不得不提供自己的模型视图投影矩阵,这只是需要考虑的事情。

【讨论】:

    【解决方案2】:

    我遇到的问题是在没有定义着色器程序的情况下使用管道功能。规范说这应该可以工作,但在我的显卡上却没有。 (有关更多细节,请参阅我在问题中的更新)。

    感谢所有评论者将我推向正确的方向。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-08
      • 2015-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多