title: Blank Screen OpenGL
body: <p>I'm trying to learn how to do some basic rendering in OpenGL 2.0, with shader programs, and I'm having difficulties getting any vertex data to show up on the screen. Right now I'm at a loss for where my problem is. I've gone through a number of examples and nothing obvious stands out for me as wrong in my code, but I'm sure I'm missing something simple. I'll try to be short with my code.</p>
  
  <p>I've also asked the same question here: <a href="https://gamedev.stackexchange.com/questions/47414/blank-screen-open-gl-2-0">gamedev.stackexchange</a>, but unfortunately I have not received any answers that were able to solve my problem.</p>
  
  <p>Quick summary of the attempted answers:</p>
  
  <ol>
  <li>I can clear the background color to red, so I know my display code works.</li>
  <li>The camera code does not modify the matrix stack.</li>
  <li>There are no shader compiler errors.</li>
  </ol>
  
  <p>Thank you for any assistance.</p>
  
  <pre><code>bool GameCore::Start(int iCmdShow)
  {
      const LPCWSTR appname = TEXT("Maze Game");
      // Create the Window and kill the program if this fails.
      if(!wm-&gt;Create(appname))
      {
          return FALSE;
      }
  
      // Initialize OpenGL
      wm-&gt;InitGraphics();
      cam = wm-&gt;cam;
  
      Vector3 *v = new Vector3(0.0f,0.0f,0.0f);
      wm-&gt;testSprite = new Sprite(v);
  
      // Start the update loop.
      _beginthread(&amp;GameCore::Execute, 0, this);
  
      // Blocking function to run the application.
      wm-&gt;RunWindow(iCmdShow);
      return true;
  }
  
  // Initialize OpenGL graphics
  void OpenGLWM::InitGraphics()
  {
      hDC = GetDC(hWnd);
  
      SetupPixelFormat();
  
      hRC = wglCreateContext(hDC);
      wglMakeCurrent(hDC, hRC);
  
      glClearColor(1, 0, 0, 0);
      glClearDepth(1.0);
      glEnable(GL_DEPTH_TEST);
  
      GLenum err = glewInit();
      if (GLEW_OK != err)
      {
          // Add error handling.
      }
  
      cam = new Camera(0, 0, -10);
      program = new ShaderProgram();
      program-&gt;Initialize();
  }
  
  // Set up pixel format for graphics initialization
  void OpenGLWM::SetupPixelFormat()
  {
      PIXELFORMATDESCRIPTOR pfd, *ppfd;
      int pixelformat;
  
      ppfd = &amp;pfd;
  
      ppfd-&gt;nSize = sizeof(PIXELFORMATDESCRIPTOR);
      ppfd-&gt;nVersion = 1;
      ppfd-&gt;dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
      ppfd-&gt;dwLayerMask = PFD_MAIN_PLANE;
      ppfd-&gt;iPixelType = PFD_TYPE_COLORINDEX;
      ppfd-&gt;cColorBits = 16;
      ppfd-&gt;cDepthBits = 16;
      ppfd-&gt;cAccumBits = 0;
      ppfd-&gt;cStencilBits = 0;
  
      pixelformat = ChoosePixelFormat(hDC, ppfd);
      SetPixelFormat(hDC, pixelformat, ppfd);
  }
  
  // Camera Constructor
  Camera::Camera(double dX, double dY, double dZ)
  {
      Vector3 V(dX, dY, dZ);
      Vector3 R(0,0,0);
      Initialization(V, R);
  }
  
  bool ShaderProgram::Initialize()
  {
      GLint giLinked;
      GLbyte vShaderStr[] =
      "#version 110               \n"
      "attribute vec3 in_Position;\n"
      "void main()\n"
      "{\n"
          "gl_Position = vec4(in_Position, 1.0);\n"
      "}\n";
  
      GLbyte pShaderStr[] =
      "#version 110               \n"
      "precision mediump float;\n"
      "void main()\n"
      "{\n"
          "gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\n"
      "}\n";
  
      // Load the shaders
      vertexShader.LoadShader((const char *)&amp;vShaderStr, GL_VERTEX_SHADER);
      pixelShader.LoadShader((const char *)&amp;pShaderStr, GL_FRAGMENT_SHADER);
  
      guiProgram = glCreateProgram();
  
      if(guiProgram == 0)
      {
          return false;
      }
      // Add the shaders to the program
      glAttachShader(guiProgram, vertexShader.guiShader);
      glAttachShader(guiProgram, pixelShader.guiShader);
  
      // Bind the position coordinates
      glBindAttribLocation(guiProgram, 0, "in_Position");
  
      // Link the program
      glLinkProgram(guiProgram);
      int iError = glGetError();
      // Get the link status
      glGetProgramiv(guiProgram, GL_LINK_STATUS, &amp;giLinked);
  
      if(giLinked == 0)
      {
          // Add error handling.
          return false;
      }
      return true;
  }
  
  GLuint BaseShader::LoadShader(const char *cShaderSrc, GLenum type)
  {
      GLint guiCompiled;
      // Creates an empty shader object.
      guiShader = glCreateShader(type);
  
      if(guiShader == 0)
      {
          return 0;
      }
      // Load the shader.
      glShaderSource(guiShader, 1, &amp;cShaderSrc, NULL);
  
      // Compile the shader
      glCompileShader(guiShader);
  
      // Check the compile status
      glGetShaderiv(guiShader, GL_COMPILE_STATUS, &amp;guiCompiled);
  
      if(guiCompiled == 0)
      {
          // TODO: ADD ERROR LOGGING
          GLint infoLen = 0;
          glGetShaderiv(guiShader, GL_INFO_LOG_LENGTH, &amp;infoLen);
          if(infoLen &gt; 1)
          {
              char* infoLog = (char *)malloc(sizeof(char) * infoLen);
              glGetShaderInfoLog(guiShader, infoLen, NULL, infoLog);
              free(infoLog);
          }
          return 0;
      }
      return guiShader;
  }
  
  // Sprite inherits from Render Object
  Sprite::Sprite(Vector3 *_vPosition)
  {
      // Initialize the position.
      vPosition = _vPosition;
      // Create verticies
      vertexStruct * v = new vertexStruct[4];
      v[0].SetPosition(-2, 2, -40);
      v[0].SetColor(128, 128, 128, 255);
      v[1].SetPosition(2, 2, -40);
      v[1].SetColor(128, 128, 128, 255);
      v[2].SetPosition(2, -2, -40);
      v[2].SetColor(128, 128, 128, 255);
      v[3].SetPosition(-2, -2, -40);
      v[3].SetColor(128, 128, 128, 255);
  
      // Create the indicies.
      GLubyte * i = new GLubyte[6];
      i[0] = 0;
      i[1] = 1;
      i[2] = 2;
      i[3] = 0;
      i[4] = 2;
      i[5] = 3;
  
      Initialize(v, 4, i, 6);
  }
  
  void RenderObject::Initialize(vertexStruct *_vertices, unsigned int _uiNumVertices, GLubyte *_indices, unsigned int _uiNumIndicies)
  {
      vertices = _vertices;
      indices = _indices;
      uiNumVertices = _uiNumVertices;
      uiNumIndices = _uiNumIndicies;
      CreateBufferObjects();
  }
  
  void RenderObject::CreateBufferObjects()
  {
      // Get an id for the Vector3 buffer.
      glGenBuffers((GLsizei)1, &amp;uiVertexBuffer);
      // Bind the buffer so we can "upload" the data.
      glBindBuffer(GL_ARRAY_BUFFER, uiVertexBuffer);
      // Upload the data to OpenGL.
      glBufferData(GL_ARRAY_BUFFER, sizeof(vertexStruct) * uiNumVertices, vertices, GL_STATIC_DRAW);
  
      // Get an id for the indice buffer.
      glGenBuffers(1, &amp;uiIndiceBuffer);
      // Bind the indice buffer so we can "upload" the data.
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, uiIndiceBuffer);
      // Upload the data to OpenGL.
      glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * uiNumIndices, indices, GL_STATIC_DRAW);
  }
  
  bool WindowManager::RunWindow(int iCmdShow)
  {
      // Display the window
      ShowWindow(hWnd, iCmdShow);
      UpdateWindow(hWnd);
  
      // Event loop
      while (1)
      {
          if (PeekMessage(&amp;msg, NULL, 0, 0, PM_NOREMOVE) == TRUE)
          {
              if (!GetMessage(&amp;msg, NULL, 0, 0))
              {
                  return TRUE;
              }
  
              TranslateMessage(&amp;msg);
              DispatchMessage(&amp;msg);
          }
          // It would be better if this was its own thread.
          if(!DoWork())
          {
              return false;
          }
      }
  return true;
  }
  
  // "Draw" function.
  bool OpenGLWM::DoWork()
  {
      glClearColor(0, 0, 0, 1);
      glClear(GL_COLOR_BUFFER_BIT);
  
      glUseProgram(program-&gt;guiProgram);
  
      testSprite-&gt;Draw();
      // Show the new scene
      SwapBuffers(hDC);
      return true;
  }
  
  void RenderObject::Draw()
  {
      // Bind the vertex buffer.
      glBindBuffer(GL_ARRAY_BUFFER, uiVertexBuffer);
      // Set where the vertex data is.
      glVertexAttribPointer(VertexEnum::Data, 3, GL_FLOAT, GL_FALSE, sizeof(vertexStruct), 0);
      glEnableVertexAttribArray(0);//VertexEnum::Data);
  
      // Load the colors.
      glVertexAttribPointer(VertexEnum::Color, 4, GL_UNSIGNED_BYTE, GL_TRUE, 12, (void*)offsetof(vertexStruct, color));
  
      glEnableVertexAttribArray(1);//VertexEnum::Color);
      // Bind the indice buffer.
      glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, uiIndiceBuffer);
      glDrawElements(GL_TRIANGLE_STRIP, uiNumIndices, GL_UNSIGNED_BYTE, 0);
  }
  
  void OpenGLWM::ResizeGraphics()
  {
      // Get new window size
      RECT rect;
      int width;
      int height;
      GLfloat aspect;
  
      GetClientRect(hWnd, &amp;rect);
      width = rect.right;
      height = rect.bottom;
      aspect = (GLfloat)width / height;
  
      // Adjust graphics to window size
      glViewport(0, 0, width, height);
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
      gluPerspective(45.0, aspect, 1.0, 100.0);
      glMatrixMode(GL_MODELVIEW);
      // Call the base function
      WindowManager::ResizeGraphics();
  }
  </code></pre>