an HD image player

hi there :slight_smile: ,

I’m trying to acheive an HD player that reacts quite like framecycler unlike it does not load all the images at start but read them on the fly and relaese them just after the display.

Ok,

I’m doing this with OpenGL and glTexImage2D().

This function seems to be really unefficient for me because I must generate a new texture (by calling this function) for every image I load. If I restrict the application by saying “every image in the sequence must have the same size”, I can use the glSubtexImage2d() wich is a bit faster.

But not enough …

What would you recommand me ? I also thought using a fragment program, but I’m not an expert in this domain, and I don’t really know the steps to follow.

thanks by advance for your answers

Use something called PBO, it allows you to load data directly from disc to the graphics memory, though the data must be preformatted to achieve this.

Ok, I tried to use pbo but I certainly made something wrong as my screen render totaly black now…

Here is my main program :

    // Set up GLUT and GLEW 
    creerFenetre(); 
    glewInit(); 
		if (GLEW_ARB_vertex_shader && GLEW_ARB_fragment_shader)
			printf("Ready for GLSL
");
		else {
      MessageBox(0,"Not totally ready :( 
","",0);
			exit(1);
		}
	  if (glewIsSupported("GL_VERSION_2_0"))
			printf("Ready for OpenGL 2.0
");
		else {
			MessageBox(0,"OpenGL 2.0 not supported
","",0);
			exit(1);
		}

    

    glMatrixMode(GL_PROJECTION); 
    glLoadIdentity(); 
    gluOrtho2D(0, s_largeur_contexte, 0, s_largeur_contexte); 
    glViewport(0, 0, s_largeur_contexte, s_largeur_contexte); 




    GLuint tex;
    int w = 2048;
    int h = 2048;
    int size = w * h;
    uchar* texdata = new uchar[size*4];
    glGenTextures (1, &tex); 
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA8, w, h, 0, GL_BGRA, GL_UNSIGNED_BYTE, 0); 

    
    setupShaders();


    // fill the RGBA color data in the range 0-255
    for (int i = 0; i < w; ++i)
    {
      for (int j = 0; j < h; ++j)
      {
        texdata[(((j*w)+i)*4)] = (255 /(float)w )*i;
        texdata[(((j*w)+i)*4)+1] = (255 /(float)h )*j;
        texdata[(((j*w)+i)*4)+2] = (i/(float)w)*255;
        texdata[(((j*w)+i)*4)+3] = 255;
      }
    }




  MessageBox(0,"ok let's go","",0);

  for (int i = ITERATIONS; i; --i)
  {
      uchar * pboMemory = 0;

      // Create the PBO
      GLuint pbo; 
      glGenBuffersARB(1, &pbo); 
      glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
      // Reset the contents of the texSize-sized buffer object
      glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, size*4, 0, GL_STREAM_DRAW_ARB);

      // Map the texture image buffer (the contents of which
      // are undefined due to the previous glBufferData)
      pboMemory = (uchar *)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB);

      // Modify (sub-)buffer data
      memcpy(pboMemory, texdata, size*4);

      // Unmap the texture image buffer
      glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);

      // Update (sub-)teximage from texture image buffer
      glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, w, h, GL_BGRA, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));

      glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
      glBegin(GL_QUADS);
      
        glTexCoord2i(0,0);   glVertex2i( 0 , 0 );
        glTexCoord2i(w,0);   glVertex2i( s_largeur_contexte, 0 );
        glTexCoord2i(w,h);   glVertex2i( s_largeur_contexte , s_hauteur_contexte);
        glTexCoord2i(0,h);   glVertex2i( 0 , s_hauteur_contexte );
  
      glEnd();

      SwapBuffers(wglGetCurrentDC());

      // Clean up 
      glDeleteBuffersARB(1,&pbo); 
  }
  glDeleteTextures(1, &tex);

And here are my shaders :

void
setupShaders()
{
  char *vs,*fs;

  GLhandleARB v = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
  GLhandleARB f = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);	

  vs = 	"void main()
"
        "{
"		
        " gl_TexCoord[0] = gl_MultiTexCoord0;
"
        "	gl_Position = ftransform();
"
        "}
";

  fs = 	"uniform sampler2D tex;
"
	      "void main()
"
	      "{
"
	      "	vec4 color = texture2D(tex,gl_TexCoord[0].st);
"
        "	gl_FragColor = color;
"
	      "}
";

  const char * vv = vs;
  const char * ff = fs;

  glShaderSourceARB(v, 1, &vv,NULL);
  glShaderSourceARB(f, 1, &ff,NULL);

  glCompileShaderARB(v);
  glCompileShaderARB(f);

  p = glCreateProgramObjectARB();

  glAttachObjectARB(p,v);
  glAttachObjectARB(p,f);

  glLinkProgramARB(p);
  glUseProgramObjectARB(p);

  
  int Location = glGetUniformLocationARB(p, "tex");
  if (Location != -1)
    glUniform1iARB(Location, 0);
}

Can you see something that I did wrong ?
(the ARB_pixel_buffer_object extension is supported by ma graohic card and I 've tested the code above on 3 different desktops included Windows and MACOSX with the same results.

Ok I found the problem.

I should use sampler2DRect and texture2DRect in my fragment shader