为什么此代码不会在屏幕上显示任何内容

时间:2017-10-02 14:21:14

标签: opengl

我已经遵循了几个教程,我不明白为什么这段代码没有显示任何内容。

请注意,LoadShaders效果不错。

我已经复制并粘贴了,所以我认为问题不是来自它......

#include <iostream>
#include <fstream>
#include <vector>  
#include <GL/glew.h>
#include <GL/gl.h>      
#include <GLFW/glfw3.h>

GLFWwindow* window;

int main(int argc, const char * argv[])
{
    if( !glfwInit() )
    {
        return -1;
    }
    glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.3
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);

    window = glfwCreateWindow(640, 480, "Test1", NULL, NULL);
    if( window == NULL )
    {
        return -1;
    }
    glfwMakeContextCurrent(window);

    glewExperimental = true; // Needed for core profile
    if (glewInit() != GLEW_OK)
    {
        return -1;
    }

    GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );

    glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
    glClearColor(0.0f, 1.0f, 1.0f, 1.0f);

    do
    {
        glfwPollEvents();

        glUseProgram(programID);
        float vertices[] = {-0.5, -0.5,   0.0, 0.5,   0.5, -0.5};
        glClear(GL_COLOR_BUFFER_BIT);
        glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices);
        glEnableVertexAttribArray(0);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glDisableVertexAttribArray(0);

        glfwSwapBuffers(window);
    }
    while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 );

    glfwTerminate();

    return 0;
}

感谢您的帮助

注意:

这是SimpleFragmentShader.fragmentshader:

#version 330 core
out vec3 color;
void main()
{
    color = vec3(1,0,0);
}

这里是SimpleVertexShader.vertexshader:

#version 330 core
layout(location = 0) in vec3 vertexPosition_modelspace;
void main()
{
    gl_Position.xyz = vertexPosition_modelspace;
    gl_Position.w = 1.0;
}

请注意我也尝试过这样的3D坐标:

float vertices[] = {-0.5, -0.5,0.0,   0.0, 0.5,0.0,   0.5, -0.5,0.0};

glClear(GL_COLOR_BUFFER_BIT);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(0);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);

2 个答案:

答案 0 :(得分:0)

请参阅docs.GL - OpenGL 3.3 - glVertexAttribPointer

  如果没有绑定顶点数组对象,则在核心上下文中生成

GL_INVALID_OPERATION

您必须创建Vertex Array ObjectVertex Buffer Object

生成(glGenVertexArrays)并绑定(glBindVertexArray)a Vertex Array Object

GLuint vao;
glGenVertexArrays( 1, &vao );
glBindVertexArray( vao );

生成(glGenBuffers)并绑定(glBindBuffer)a Vertex Buffer Object

GLuint vbo;
glGenBuffers( 1, &vbo );
glBindBuffer( GL_ARRAY_BUFFER, vbo );

绑定缓冲区数据(glBufferData),启用顶点属性并定义通用顶点属性数据数组:

float vertices[] = {-0.5, -0.5,   0.0, 0.5,   0.5, -0.5};
glBufferData( GL_ARRAY_BUFFER, 6 * sizeof( float ), vertices, GL_STATIC_DRAW );
glEnableVertexAttribArray( 0 );
glVertexAttribPointer( 0, 2, GL_FLOAT, GL_FALSE, 0, nullptr );
glBindVertexArray( 0 );

绘制网格时,只需绑定顶点数组对象:

glBindVertexArray( vao );
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray( 0 );


请注意,由于您在片段着色器中使用了用户定义的out变量,因此应将片段数据位置与glBindFragDataLocation绑定。请注意,必须在将片段着色器附加到着色器程序之后但在着色器程序已链接之前完成此操作。

答案 1 :(得分:0)

您没有绑定输出片段数据位置:

GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );

// make sure you set which colour is the output from the fragment shader!
glBindFragDataLocation(programID, 0, "color");

(假设您在桌面上使用的是OpenGL 3.3,而不是OpenGL ES 3)

/ edit如果你想要一个OpenGL 4.5版本:

#include <iostream>
#include <fstream>
#include <vector>  
#include <GL/glew.h>
#include <GL/gl.h>      
#include <GLFW/glfw3.h>

GLFWwindow* window;

int main(int argc, const char * argv[])
{
  if( !glfwInit() )
  {
    return -1;
  }
  glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); 
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 5);

  window = glfwCreateWindow(640, 480, "Test1", NULL, NULL);
  if( window == NULL )
  {
    return -1;
  }
  glfwMakeContextCurrent(window);

  glewExperimental = true; // Needed for core profile
  if (glewInit() != GLEW_OK)
  {
    return -1;
  }
  glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);

  GLuint programID = LoadShaders( "SimpleVertexShader.vertexshader", "SimpleFragmentShader.fragmentshader" );

  // make sure you set which colour is the output from the fragment shader!
  glBindFragDataLocation(programID, 0, "color");

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

  GLuint vbo = 0, vao = 0;
  const float vertices[] = {-0.5, -0.5,   0.0, 0.5,   0.5, -0.5};

  // create the vbo identifier
  glCreateBuffers(1, &vbo);

  // load the vertex data into the vertex buffer object (using immutable read only storage)
  glNamedBufferStorage(vbo, 6 * sizeof(float), vertices, 0);

  // create the vertex array object (vao)
  GLuint vao = 0;
  glCreateVertexArrays(1, &vao);

  // attach vbo to slot 0 on the vao
  glVertexArrayVertexBuffer(vao, 0, vbo, 0, sizeof(float) * 2);

  // fetch attribute 0 from the buffer bound to slot 0
  glVertexArrayAttribBinding(vao, 0, 0);

  // enable the vertex attribute 0
  glEnableVertexArrayAttrib(vao, 0);

  // specify the data type found in attribute 0
  glVertexArrayAttribFormat(vao, 0, 2, GL_FLOAT, false, 0);

  do
  {
    glfwPollEvents();

    // specify which program to use
    glUseProgram(programID);

    // specify which buffers to bind to the shader inputs
    glBindVertexArray(vao);

    // draw the data 
    glDrawArrays(GL_TRIANGLES, 0, 3);

    // done with the vao binding
    glBindVertexArray(0);    

    glfwSwapBuffers(window);
  }
  while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0 );

  glfwTerminate();

  return 0;
}