Page 1 of 2 12 LastLast
Results 1 to 10 of 16

Thread: Copy texture pixels to another texture.

  1. #1

    Copy texture pixels to another texture.

    I'm using OpenGL with python but I know it works pretty much the same way as with other languages. I am trying to get my game which was previously working for pygame to work with OpenGL. I need to draw textures onto other textures to do the same thing s the pygame blit method. So far I have:

    Code :
    	def blit(self,surface,offset,area=None, special_flags = 0):
    		#Create textures if not done already
    		if self.texture == None:
    			create_texture(self)
    		if surface.texture == None:
    			create_texture(surface)
    		#Render child to parent

    The texture variable for the classes contains the texture ids. Given the offset from the parent (self) how can I draw the child texture (surface) to it? And I need the process to be fast. The create_texture function simply creates the texture with any image or colour, ready to be placed onto other textures or for other textures to be placed on it.

    I've looked at pixel buffers but I don't know know to use them.

    Thank you.

  2. #2

    Re: Copy texture pixels to another texture.

    I have this on the end now:

    Code :
    #Render child to parent
    		frame_buffer = glGenFramebuffersEXT(1)
    		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer)
    		render_buffer = glGenRenderbuffersEXT(1)
    		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffer);
    		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,self.surface_size[0],self.surface_size[1])
    		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, render_buffer)
    		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, self.texture, 0)
    		print glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)
    		glPushAttrib(GL_VIEWPORT_BIT)
    		glViewport(0,0,self.surface_size[0],self.surface_size[1])
    		glMatrixMode(GL_MODELVIEW)
    		glLoadIdentity() #Loads model matrix
    		glBindTexture(GL_TEXTURE_2D, surface.texture)
    		glBegin(GL_QUADS)
    		glVertex2i(0, 0) #Top Left
    		glVertex2i(0,surface.surface_size[1]) #Bottom Left
    		glVertex2i(*surface.surface_size) #Bottom, Right
    		glVertex2i(surface.surface_size[0], 0) #Top, Right
    		glEnd()
    		glPopAttrib()
    		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
    		glDeleteFramebuffersEXT(1, frame_buffer)
    		glDeleteRenderbuffersEXT(1,render_buffer)

    I get and "invalid framebuffer operation" error.

    glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) outputs 36054

    No idea what that means. I get nothing through google. I'm clueless. I knew this wouldn't work but at east I gave it my best shot.

    If anyone can fix this I will be most happy.

  3. #3
    Senior Member OpenGL Guru
    Join Date
    Oct 2004
    Posts
    4,651

    Re: Copy texture pixels to another texture.

    Quote Originally Posted by Matthew4693434
    I get and "invalid framebuffer operation" error.

    glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) outputs 36054

    No idea what that means. I get nothing through google. I'm clueless. I knew this wouldn't work but at east I gave it my best shot.

    If anyone can fix this I will be most happy.
    You're so close. Why would you just give up?

    First of all, 36054 == 0x8cd6 == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT. See:

    * http://www.khronos.org/opengles/sdk/...fferStatus.xml
    * http://www.opengl.org/wiki/Framebuff...t_Completeness

    "Not all framebuffer attachment points are framebuffer attachment complete. This means that at least one attachment point with a renderbuffer or texture attached has its attached object no longer in existence or has an attached image with a width or height of zero, or the color attachment point has a non-color-renderable image attached, or the depth attachment point has a non-depth-renderable image attached, or the stencil attachment point has a non-stencil-renderable image attached."

    Perhaps you haven't allocated the texels for the texture you're trying to render to? Use glTexImage2D and allocate the base map.

  4. #4

    Re: Copy texture pixels to another texture.

    Ah, thank you. So you can't just use an empty texture. I understand now. I'll try to to make some changes and come back with the results.

    I need to fill the texture with a blank colour. I haven't done that yet. I'll see what I can find.

    This doesn't go well. unistr doesn't like it.

    Code :
    def create_texture(surface):
    	surface.texture =  glGenTextures(1)
    	glMatrixMode(GL_MODELVIEW)
    	glLoadIdentity() #Loads model matrix
    	glBindTexture(GL_TEXTURE_2D, surface.texture) #Binds the current 2D texture to the texture to be drawn
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) #Required to be set for maping the pixel data
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) #Similar as above
    	if surface.data == None:
    		print (surface.colour[0] << 24) |  (surface.colour[1] << 16) | (surface.colour[2] << 8) | (surface.colour[3])
    		data = unichr((surface.colour[0] << 24) |  (surface.colour[1] << 16) | (surface.colour[2] << 8) | (surface.colour[3])) * (surface.surface_size[0] * surface.surface_size[1])
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface.surface_size[0], surface.surface_size[1], 0, GL_RGBA,GL_UNSIGNED_BYTE, surface.data) #Put surface pixel data into texture

  5. #5

    Re: Copy texture pixels to another texture.

    I have a new error:
    Code :
        glDeleteFramebuffersEXT(1, frame_buffer)
      File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/OpenGL/lazywrapper.py", line 19, in __call__
        return wrapper( baseFunction, *args, **named )
      File "/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/site-packages/OpenGL/GL/EXT/framebuffer_object.py", line 32, in glDeleteFramebuffersEXT
        return baseOperation( n, framebuffers )
    ctypes.ArgumentError: argument 2: <type 'exceptions.TypeError'>: No array-type handler for type <type 'numpy.uint32'> (value: 1) registered

    I seem to be using glDeleteFramebuffersEXT wrong.

    I fixed my last error with a rather bad method,
    Code :
    def create_texture(surface):
    	surface.texture =  glGenTextures(1)
    	glMatrixMode(GL_MODELVIEW)
    	glLoadIdentity() #Loads model matrix
    	glBindTexture(GL_TEXTURE_2D, surface.texture) #Binds the current 2D texture to the texture to be drawn
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) #Required to be set for maping the pixel data
    	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) #Similar as above
    	if surface.data == None:
    		surf = pygame.Surface((1,1),SRCALPHA)
    		surf.fill(surface.colour)
    		data = pygame.image.tostring(surf, "RGBA") * (surface.surface_size[0] * surface.surface_size[1])
    	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface.surface_size[0], surface.surface_size[1], 0, GL_RGBA,GL_UNSIGNED_BYTE, surface.data) #Put surface pixel data into texture

  6. #6

    Re: Copy texture pixels to another texture.

    print glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) gives 36053.

    How do I find out what the numbers correspond to?

  7. #7

    Re: Copy texture pixels to another texture.

    I've managed to get rid of the error using a bizzare method:

    Code :
    def blit(self,surface,offset,area=None, special_flags = 0):
    		#Create textures if not done already
    		if self.texture == None:
    			create_texture(self)
    		if surface.texture == None:
    			create_texture(surface)
    		#Render child to parent
    		frame_buffer =  glGenFramebuffersEXT(1)
    		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, frame_buffer)
    		render_buffer = glGenRenderbuffersEXT(1)
    		glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, render_buffer);
    		glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT,self.surface_size[0],self.surface_size[1])
    		glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, render_buffer)
    		glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, self.texture, 0)
    		print glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT)
    		glPushAttrib(GL_VIEWPORT_BIT)
    		glViewport(0,0,self.surface_size[0],self.surface_size[1])
    		glMatrixMode(GL_MODELVIEW)
    		glLoadIdentity() #Loads model matrix
    		glBindTexture(GL_TEXTURE_2D, surface.texture)
    		glBegin(GL_QUADS)
    		glVertex2i(*offset) #Top Left
    		glVertex2i(offset[0],offset[1] + surface.surface_size[1]) #Bottom Left
    		glVertex2i(offset[0] + surface.surface_size[0],offset[1] + surface.surface_size[1]) #Bottom, Right
    		glVertex2i(surface.surface_size[0],surface.surface_size[1]) #Top, Right
    		glEnd()
    		glPopAttrib()
    		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)
    		glDeleteFramebuffersEXT(1, [int(frame_buffer)])
    		glDeleteRenderbuffersEXT(1,[int(render_buffer)])

    I had to create a list of the c type uint converted into the python int. At least it appears so.

    Now it says glFramebufferTexture2DEXT is an invalid method. I thought that only happened between glBegin and glEnd? Can it happen at any other time? It doesn't come up with that error for many of the textures. I see nothing different that will break it. I will have a larger look myself but if anyone knows why the error could have been shown, it will help me a lot.

    Thank you. It may seem as if I'll never get it working but I've got a lot working in the past. I'm quite persistant. OpenGL is important or the game will be a lot worse than people expect it to be mainly due to speed.

  8. #8
    Senior Member OpenGL Guru
    Join Date
    Oct 2004
    Posts
    4,651

    Re: Copy texture pixels to another texture.

    Quote Originally Posted by Matthew4693434
    print glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) gives 36053.

    How do I find out what the numbers correspond to?
    Well, the "hard" way is to print the number in hex (printf: %x), which yields 0x8cd5, then grep (search) for it in glext.h:

    > grep -i 0x8cd5 /usr/include/GL/glext.h
    #define GL_FRAMEBUFFER_COMPLETE 0x8CD5
    #define GL_FRAMEBUFFER_COMPLETE_EXT 0x8CD5

    which is what you want.

    However, this mechanical stuff is best left to your CPU.

    The "easy" way is to just write a function to translate the number to a string for you:

    Code :
    void checkFBOStatus ()
    {
      GLenum status = glCheckFramebufferStatus( GL_FRAMEBUFFER );
     
      const char *err_str = 0;
      char buf[80];
     
      if ( status != GL_FRAMEBUFFER_COMPLETE )
      {
        switch ( status )
        {
          case GL_FRAMEBUFFER_UNSUPPORTED:
            err_str = "UNSUPPORTED";
            break;
          case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
            err_str = "INCOMPLETE ATTACHMENT";
            break;
          case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
            err_str = "INCOMPLETE DRAW BUFFER";
            break;
          case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
            err_str = "INCOMPLETE READ BUFFER";
            break;
          case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
            err_str = "INCOMPLETE MISSING ATTACHMENT";
            break;
          case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
            err_str = "INCOMPLETE MULTISAMPLE";
            break;
          case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS:
            err_str = "INCOMPLETE LAYER TARGETS";
            break;
     
          // Removed in version #117 of the EXT_framebuffer_object spec
          //case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
     
          default:
            sprintf( buf, "0x%x", status );
            err_str = buf ;
            break;
        }
     
        printf( "ERROR: glCheckFramebufferStatus() returned '%s'", err_str );
      }
    }

    Note that depending on how old your glext.h is, you might need to slap an _EXT on some of these defines to get this to compile, or even comment some out if they're just not there.

    See this or the extension specs for more details on what these return values mean:

    * http://www.opengl.org/wiki/Framebuff...leteness_Rules

  9. #9

    Re: Copy texture pixels to another texture.

    Thank you. I'll look for that file in the future.

    I'll be looking at the texture that is causing this bizarre invalid operation problem.

    Okay, I've managed to determine the error is caused the first time this method is called on the second frame. This can also be interpreted as the second time a texture is drawn onto another texture. I suspect that once a texture has been drawn it doesn't like it the second time on another frame? The textures that are drawn to the screen texture will need to be redrawn to the screen each frame as the screen is cleared after each frame.

    Using a texture for the entire screen is stupid, I know. I will change that once I got this error sorted out.

  10. #10
    Senior Member OpenGL Lord
    Join Date
    Mar 2015
    Posts
    6,674

    Re: Copy texture pixels to another texture.

    Okay, I've managed to determine the error is caused the first time this method is called on the second frame.
    Each of the above incomplete codes corresponds to a specific kind of problem. Which code are you getting?

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 2
    Last Post: 04-24-2014, 01:52 AM
  2. OpenGL 4.2, How to Copy a color texture into a depth texture ?
    By imported_cippyboy in forum OpenGL: Advanced Coding
    Replies: 4
    Last Post: 08-26-2013, 01:17 AM
  3. texture to texture copy, running through a shader?
    By zassGL in forum OpenGL: Basic Coding
    Replies: 5
    Last Post: 07-20-2011, 03:04 PM
  4. copy pixels between RC created in different thread
    By pango in forum OpenGL: Advanced Coding
    Replies: 0
    Last Post: 12-20-2003, 09:05 PM
  5. Copy & Paste Pixels
    By glbeginner in forum OpenGL: Basic Coding
    Replies: 2
    Last Post: 01-10-2001, 02:06 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Proudly hosted by Digital Ocean