Cannot render a single triangle...

Hello,

I’m probably missing something obvious here, but following some tutorials, I cannot render a single triangle. My display is cleared correctly (I can see the clear color when I change it) but no triangle is rendered…

Here’s the initialization/rendering code (I use GLUT to create a window):



const std::string strVertexShader(
  "#version 330
"
  "layout(location = 0) in vec4 position;
"
  "void main()
"
  "{
"
  "   gl_Position = position;
"
  "}
"
);

const std::string strFragmentShader(
  "#version 330
"
  "out vec4 outputColor;
"
  "void main()
"
  "{
"
  "   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
"
  "}
"
);

const float vertexPositions[] = {
   0.0f,  0.5f,  0.0f, 1.0f,
   0.5f, -0.5f,  0.0f, 1.0f,
  -0.5f, -0.5f,  0.0f, 1.0f
};


class GLTest
{
    public:
        GLTest();
        ~GLTest();
        bool init();
        void render();

    protected:
    private:
        GLuint mProgram;
        GLuint mPositionBO;
        GLuint mVArray;
};


bool GLTest::init()
{
  // Create shader program
  std::vector<GLuint> shaderList;
  addShader(shaderList, GL_VERTEX_SHADER, strVertexShader);
  addShader(shaderList, GL_FRAGMENT_SHADER, strFragmentShader);
  mProgram = linkProgram(shaderList);
  std::for_each(shaderList.begin(), shaderList.end(), glDeleteShader);

  // Create VBOs
  glGenBuffers(1, &mPositionBO);
  glBindBuffer(GL_ARRAY_BUFFER, mPositionBO);
  glBufferData(GL_ARRAY_BUFFER, 12*sizeof(float), vertexPositions, GL_STATIC_DRAW);
  glBindBuffer(GL_ARRAY_BUFFER, 0);

  // Create vertex array
  glGenVertexArrays(1, &mVArray);
  glBindVertexArray(mVArray);

  return true;
}



void GLTest::render()
{
  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
  glClear(GL_COLOR_BUFFER_BIT);

  glUseProgram(mProgram);

  glEnableVertexAttribArray(0);

  glBindBuffer(GL_ARRAY_BUFFER, mPositionBO);
  glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

  glDrawArrays(GL_TRIANGLES, 0, 3);

  glDisableVertexAttribArray(0);
  glUseProgram(0);

  glutSwapBuffers();
}


And here are the helper functions used to compile the shaders:


bool addShader(std::vector<GLuint> shaderList, GLenum type, const std::string& code)
{
  GLuint shader = glCreateShader(type);
  const char *strFileData = code.c_str();
  glShaderSource(shader, 1, &strFileData, NULL);

  glCompileShader(shader);

  GLint status;
  glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
  if (status == GL_FALSE)
  {
    GLint infoLogLength;
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);

    GLchar *strInfoLog = new GLchar[infoLogLength + 1];
    glGetShaderInfoLog(shader, infoLogLength, NULL, strInfoLog);

    const char *strShaderType = NULL;
    switch(type)
    {
    case GL_VERTEX_SHADER: strShaderType = "vertex"; break;
    case GL_GEOMETRY_SHADER: strShaderType = "geometry"; break;
    case GL_FRAGMENT_SHADER: strShaderType = "fragment"; break;
    }

    printf("Compile failure in %s shader:
%s
", strShaderType, strInfoLog);
    delete[] strInfoLog;
    return false;
  }

  shaderList.push_back(shader);
  return true;
}

GLuint linkProgram(std::vector<GLuint> shaderList)
{
  GLuint program = glCreateProgram();

  for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
    glAttachShader(program, shaderList[iLoop]);

  glLinkProgram(program);

  GLint status;
  glGetProgramiv (program, GL_LINK_STATUS, &status);
  if (status == GL_FALSE)
  {
    GLint infoLogLength;
    glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);

    GLchar *strInfoLog = new GLchar[infoLogLength + 1];
    glGetProgramInfoLog(program, infoLogLength, NULL, strInfoLog);
    printf("Linker failure: %s
", strInfoLog);
    delete[] strInfoLog;
  }

  for(size_t iLoop = 0; iLoop < shaderList.size(); iLoop++)
    glDetachShader(program, shaderList[iLoop]);

  return program;
}

Any idea what obvious thing I forgot ?

Okay, nailed it. I should not have passed my std::vectors by value. Moving to pointers did the trick.