title: Why i should generate texture in initializeGL qt
body: <p>I'm trying to draw yuv image using Qt OpenGL.</p>
  
  <p>I've create a 'CameraSurface_GL' class inherited from QGLWidget, drawing yuv image received from ip camera.</p>
  
  <p>I introduce my code here.</p>
  
  <pre><code>#include "camerasurface_gl.h"
  #include &lt;QtWidgets&gt;
  #include &lt;QtGui&gt;
  #include &lt;QOpenGLFunctions_3_0&gt;
  
  
  const char* YUV420P_VS = ""
    "#version 330\n"
    ""
    "uniform mat4 u_pm;"
    "uniform vec4 draw_pos;"
    ""
    "const vec2 verts[4] = vec2[] ("
    "  vec2(-0.5,  0.5), "
    "  vec2(-0.5, -0.5), "
    "  vec2( 0.5,  0.5), "
    "  vec2( 0.5, -0.5)  "
    ");"
    ""
    "const vec2 texcoords[4] = vec2[] ("
    "  vec2(0.0, 1.0), "
    "  vec2(0.0, 0.0), "
    "  vec2(1.0, 1.0), "
    "  vec2(1.0, 0.0)  "
    "); "
    ""
    "out vec2 v_coord; "
    ""
    "void main() {"
    "   vec2 vert = verts[gl_VertexID];"
    "   vec4 p = vec4((0.5 * draw_pos.z) + draw_pos.x + (vert.x * draw_pos.z), "
    "                 (0.5 * draw_pos.w) + draw_pos.y + (vert.y * draw_pos.w), "
    "                 0, 1);"
    "   gl_Position = u_pm * p;"
    "   v_coord = texcoords[gl_VertexID];"
    "}"
    "";
  
  
  const char* YUV420P_FS = ""
   "#version 330\n"
    "uniform sampler2D y_tex;"
    "uniform sampler2D u_tex;"
    "uniform sampler2D v_tex;"
    "in vec2 v_coord;"
    "layout( location = 0 ) out vec4 fragcolor;"
    ""
      "const vec3 R_cf = vec3(1,  0.000000,  1.13983);"
      "const vec3 G_cf = vec3(1, -0.39465, -0.58060);"
      "const vec3 B_cf = vec3(1,  2.03211,  0.000000);"
    "const vec3 offset = vec3(-0.0625, -0.5, -0.5);"
    ""
    "void main() {"
    "  float y = texture(y_tex, v_coord).r;"
    "  float u = texture(u_tex, v_coord).r;"
    "  float v = texture(v_tex, v_coord).r;"
    "  vec3 yuv = vec3(y,u,v);"
    "  yuv += offset;"
    "  fragcolor = vec4(0.0, 0.0, 0.0, 1.0);"
    "  fragcolor.r = dot(yuv, R_cf);"
    "  fragcolor.g = dot(yuv, G_cf);"
    "  fragcolor.b = dot(yuv, B_cf);"
    "}"
    "";
  
  CameraSurface_GL::CameraSurface_GL(QWidget *parent) :
      QGLWidget(parent)
    ,vid_w(0)
    ,vid_h(0)
    ,win_w(0)
    ,win_h(0)
    ,vao(0)
    ,y_tex(0)
    ,u_tex(0)
    ,v_tex(0)
    ,vert(0)
    ,frag(0)
    ,prog(0)
    ,u_pos(-1)
    ,textures_created(false)
    ,shader_created(false)
  {
      qRegisterMetaType&lt;YUVFrame&gt;("YUVFrame");
      m_ipCamera = new IpCamera;
  
      connect(m_ipCamera, SIGNAL(frameChanged(YUVFrame)), this, SLOT(slotFrameChanged(YUVFrame)));
  
      m_frameCount = 0;
      m_setup = 0;
  }
  
  CameraSurface_GL::~CameraSurface_GL()
  {
      glDeleteTextures(1, &amp;y_tex);
      glDeleteTextures(1, &amp;u_tex);
      glDeleteTextures(1, &amp;v_tex);
  
      glDeleteProgram(prog);
  }
  
  void CameraSurface_GL::openCamera(QString ipAddress, QString userName, QString password)
  {
      if(m_ipCamera-&gt;isRunning())
          m_ipCamera-&gt;close();
  
      bool opend = m_ipCamera-&gt;open(ipAddress, userName, password);
      if(opend == false)
          return;
  }
  
  void CameraSurface_GL::closeCamera()
  {
      m_ipCamera-&gt;close();
  }
  
  void CameraSurface_GL::slotFrameChanged(YUVFrame frame)
  {
      m_yuvFrame = frame;
          update();
  }
  
  void CameraSurface_GL::setup_gl(int width, int height)
  {
      vid_w = width;
      vid_h = height;
  
      if(!vid_w || !vid_h) {
        printf("Invalid texture size.\n");
        return;
      }
  
      if(!setupTextures()) {
        return;
      }
  
      if(!setupShader()) {
        return;
      }
  
      glGenVertexArrays(1, &amp;vao);
  
      return;
  }
  
  void CameraSurface_GL::resize_gl(int width, int height)
  {
      win_w = width;
      win_h = height;
  
      pm.setToIdentity();
      pm.ortho(0, win_w, win_h, 0, 0.0, 100.0f);
  
      glUseProgram(prog);
      glUniformMatrix4fv(glGetUniformLocation(prog, "u_pm"), 1, GL_FALSE, pm.data());
  }
  
  
  
  void CameraSurface_GL::initializeGL()
  {
      initializeOpenGLFunctions();
      glClearColor(0, 0, 0, 1);
  
      setup_gl(1920, 1080);
  }
  
  
  void CameraSurface_GL::paintGL()
  {
      glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  
      if(m_yuvFrame.yuvData.size())
      {
          setYPixels((unsigned char*)m_yuvFrame.yuvData.data(), yuvFrame.width);
          setUPixels((unsigned char*)m_yuvFrame.yuvData.data() + yuvFrame.width * yuvFrame.height, yuvFrame.width / 2);
          setVPixels((unsigned char*)m_yuvFrame.yuvData.data() + yuvFrame.width * yuvFrame.height * 5 / 4, yuvFrame.width / 2);
  
          glBindVertexArray(vao);
          glUseProgram(prog);
  
          QRect frameRect = rect();
  
          glUniform4f(u_pos, frameRect.left(), frameRect.top(), frameRect.width(), frameRect.height());
  
          glActiveTexture(GL_TEXTURE0);
          glBindTexture(GL_TEXTURE_2D, y_tex);
  
          glActiveTexture(GL_TEXTURE1);
          glBindTexture(GL_TEXTURE_2D, u_tex);
  
          glActiveTexture(GL_TEXTURE2);
          glBindTexture(GL_TEXTURE_2D, v_tex);
  
          glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
      }
  }
  
  
  void CameraSurface_GL::resizeGL(int width, int height)
  {
      glViewport(0, 0, width, height);
      resize_gl(width, height);
  }
  
  bool CameraSurface_GL::setupTextures()
  {
      if(textures_created) {
        printf("Textures already created.\n");
        return false;
      }
  
      glGenTextures(1, &amp;y_tex);
      glBindTexture(GL_TEXTURE_2D, y_tex);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w, vid_h, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  
      glGenTextures(1, &amp;u_tex);
      glBindTexture(GL_TEXTURE_2D, u_tex);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w/2, vid_h/2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  
      glGenTextures(1, &amp;v_tex);
      glBindTexture(GL_TEXTURE_2D, v_tex);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, vid_w/2, vid_h/2, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  
      textures_created = true;
  
      return true;
  }
  
  bool CameraSurface_GL::setupShader()
  {
      if(shader_created) {
        printf("Already creatd the shader.\n");
        return false;
      }
  
      vert = glCreateShader(GL_VERTEX_SHADER);
      glShaderSource(vert, 1, &amp;YUV420P_VS, 0);
      glCompileShader(vert);
  
      frag = glCreateShader(GL_FRAGMENT_SHADER);
      glShaderSource(frag, 1, &amp;YUV420P_FS, 0);
      glCompileShader(frag);
  
      prog = glCreateProgram();
      glAttachShader(prog, vert);
      glAttachShader(prog, frag);
      glLinkProgram(prog);
  
      glUseProgram(prog);
      glUniform1i(glGetUniformLocation(prog, "y_tex"), 0);
      glUniform1i(glGetUniformLocation(prog, "u_tex"), 1);
      glUniform1i(glGetUniformLocation(prog, "v_tex"), 2);
  
      u_pos = glGetUniformLocation(prog, "draw_pos");
  
      return true;
  }
  
  
  void CameraSurface_GL::setYPixels(uint8_t* pixels, int stride)
  {
      glBindTexture(GL_TEXTURE_2D, y_tex);
      glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w, vid_h, GL_RED, GL_UNSIGNED_BYTE, pixels);
  }
  
  void CameraSurface_GL::setUPixels(uint8_t* pixels, int stride)
  {
      glBindTexture(GL_TEXTURE_2D, u_tex);
      glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w/2, vid_h/2, GL_RED, GL_UNSIGNED_BYTE, pixels);
  }
  
  void CameraSurface_GL::setVPixels(uint8_t* pixels, int stride)
  {
      glBindTexture(GL_TEXTURE_2D, v_tex);
      glPixelStorei(GL_UNPACK_ROW_LENGTH, stride);
      glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, vid_w/2, vid_h/2, GL_RED, GL_UNSIGNED_BYTE, pixels);
  }
  </code></pre>
  
  <p>I call 'setup' function in initializeGL, using static parameter 1920, 1080.</p>
  
  <p>This is not my idea.</p>
  
  <p>I want to call 'setup' function when received yuv frame from ip camera, so I changed my code to the following.</p>
  
  <pre><code>void CameraSurface_GL::initializeGL()
  {
      initializeOpenGLFunctions();
      glClearColor(0, 0, 0, 1);
  }
  
  void CameraSurface_GL::slotFrameChanged(YUVFrame frame)
  {
      if(m_setup == 0)
      {
          setup_gl(frame.width, frame.height);
          resize_gl(frame.width, frame.height);
          m_setup = 1;
      }
  
      m_yuvFrame = frame;
          update();
  }
  </code></pre>
  
  <p>At this time, I can't show drawn image on view.</p>
  
  <p>Why I receive the issue?</p>
  
  <p>Can't I call 'setup' function in other place, in not initializeGL?</p>