title: Getting OpenGL to render texture to screen
body: <p>I am having trouble getting an image texture to render to the screen. Nothing is displayed other than a blank black screen, and there are no obvious errors. I believe the issue has something to do with the <code>glOrtho</code> call, but i'm not sure.</p>
  
  <p>All relevant code is included below. (OnResize gets called after initialisation and before first Render call)</p>
  
  <p>OpenGL2.1 compatibility required, with a view to add shaders later. The texture stuff being hardcoded to the renderer is just temporary, I already have a texture class ready to go, once I work out what's wrong.</p>
  
  <p>I think I might need a FrameBuffer object somewhere? The tutorials I've found often differ drastically and are usually targeting OGL3</p>
  
  <pre><code>Video::Video() : running(true)
  {
      if (SDL_Init(SDL_INIT_VIDEO) &lt; 0) {
          std::string err = "Error initialising video: ";
          err += SDL_GetError();
          throw std::runtime_error(err);
      }
  
      SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
      SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
      SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1);
      SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
      SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
  
      int flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_MAXIMIZED;
  
      this-&gt;window = SDL_CreateWindow("lolpenGL", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 800, 600, flags);
      if (this-&gt;window == nullptr) {
          std::string err = "Error creating SDL window: ";
          err += SDL_GetError();
          throw std::runtime_error(err);
      }
  
      this-&gt;glcontext = SDL_GL_CreateContext(this-&gt;window);
      if (this-&gt;glcontext == nullptr) {
          std::string err = "Error creating GL context: ";
          err += SDL_GetError();
          throw std::runtime_error(err);
      }
  
      GLenum glew_err = glewInit();
      if (glew_err != GLEW_OK) {
          std::string err = "Error initialising GLEW: ";
          err += (char *)glewGetErrorString(glew_err);
          throw std::runtime_error(err);
      }
  
      if (!GLEW_VERSION_2_1) {
          throw std::runtime_error("OpenGL 2.1 not available");
      }
  
      int max_tex_size;
      glGetIntegerv(GL_MAX_TEXTURE_SIZE, &amp;max_tex_size);
      if (max_tex_size &lt; 1024) {
          throw std::runtime_error("Maximum supported texture size too small");
      }
  
      int max_tex_units;
      glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &amp;max_tex_units);
      if (max_tex_units &lt; 2) {
          throw std::runtime_error("GPU does not have enough texture unnits");
      }
  
      SDL_GL_SetSwapInterval(1); // vsync
  
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
      glDisable(GL_DEPTH_TEST); // what's drawn last is displayed on top.
  
  
  
  
  // Temp texture load
          glGenTextures(1, &amp;this-&gt;texid);
          glBindTexture(GL_TEXTURE_2D, this-&gt;texid);
          // Set our texture parameters
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
          // Set texture filtering
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
          glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
          // Load, create texture and generate mipmaps
          int width, height;
          unsigned char *image = SOIL_load_image("awesomeface.png", &amp;width, &amp;height, 0, SOIL_LOAD_RGB);
          glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
          glGenerateMipmap(GL_TEXTURE_2D);
          SOIL_free_image_data(image);
          glBindTexture(GL_TEXTURE_2D, 0);
  
          glEnable(GL_TEXTURE_2D);
  }
  
  void Video::OnResize(int w, int h)
  {
      glMatrixMode(GL_PROJECTION);
      glLoadIdentity();
  
      glViewport(0, 0, w, h);
  
      glOrtho(0, w, 0, h, 9001, -1);
  
      glMatrixMode(GL_MODELVIEW);
      glLoadIdentity();
  }
  
  void Video::Render()
  {
      glClearColor(0.0, 0.0, 0.0, 0.0);
      glClear(GL_COLOR_BUFFER_BIT);
  
      glPushMatrix();
      {
          glColor4f(1, 1, 1, 1);
          glActiveTexture(GL_TEXTURE0);
          glBindTexture(GL_TEXTURE_2D, this-&gt;texid);
          // do stuff
      }
      glPopMatrix();
  
  
      SDL_GL_SwapWindow(this-&gt;window);
  }
  </code></pre>
  
  <p>EDIT: Ok, i'm an idiot, I wasn't actually drawing anything. I found that adding the following works, where the <code>// do stuff</code> is.</p>
  
  <pre><code>glBegin(GL_QUADS);
  glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
  glTexCoord2f(0, 1); glVertex3f(0, 100, 0);
  glTexCoord2f(1, 1); glVertex3f(100, 100, 0);
  glTexCoord2f(1, 0); glVertex3f(100, 0, 0);
  glEnd();
  </code></pre>
  
  <p>Is this the best way to do this?</p>