Just letting people know I found a better way to capture your whole render 
scene:

            mapWidth, mapHeight = <the size of the scene you want to 
capture>
            mapTexture = pyglet.image.Texture.create(mapWidth, mapHeight, 
internalformat=GL_RGB) # Force RGB because RGBA will mess up your blending.

            glViewport(0, 0, mapWidth, mapHeight)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()

            glOrtho(0, mapWidth, 0, mapHeight, -1, 1)
            glMatrixMode(GL_MODELVIEW)
            glLoadIdentity()

            id = GLuint(0)
            glGenFramebuffersEXT(1, byref(id))
            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id)
            glFramebufferTexture2DEXT(
                GL_FRAMEBUFFER_EXT,
                GL_COLOR_ATTACHMENT0_EXT,
                mapTexture.target,
                mapTexture.id,
                mapTexture.level)


            glClear(GL_COLOR_BUFFER_BIT)
            glEnable(GL_BLEND)
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)


            <draw your entire scene here or whatever you want>


            glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0)

            # Use overridden get_image_data so it can pull as RGB, not RGBA
            get_image_data(mapTexture.owner).get_region(mapTexture.x,
                                                        mapTexture.y,
                                                        mapTexture.width,
                                                        
mapTexture.height).save('full_screenshot.png')
            # Reset your viewport back to normal
            glViewport(0, 0, windowWidth, windowHeight)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()

            glOrtho(0, windowWidth, 0, windowHeight, -1, 1)
            glMatrixMode(GL_MODELVIEW)
            glLoadIdentity()
            
            


However upon doing this I discovered that blending did not work correctly 
as everything was being blended with the invisible alpha, not the black 
background you normally see.

I discovered alpha was still being written with the encoder despite the 
texture being created as GL_RGB, and traced it back to the get_image_data. 
It defaults all to RGBA. So you need to override the default get_image_data 
to remove the alpha channel:

def get_image_data(texture, z=0):
    '''Get the image data of this texture.

    Changes to the returned instance will not be reflected in this
    texture.

    ---- Overridden to format as RGB and GL_RGB instead of forced RGBA and 
GL_RGBA

    :Parameters:
        `z` : int
            For 3D textures, the image slice to retrieve.

    :rtype: `ImageData`
    '''

    glBindTexture(texture.target, texture.id)

    # Always extract complete RGBA data.  Could check internalformat
    # to only extract used channels. XXX
    format = 'RGB'
    gl_format = GL_RGB

    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT)
    glPixelStorei(GL_PACK_ALIGNMENT, 1)
    buffer = \
        (GLubyte * (texture.width * texture.height * texture.images * 
len(format)))()
    glGetTexImage(texture.target, texture.level,
                  gl_format, GL_UNSIGNED_BYTE, buffer)
    glPopClientAttrib()

    data = ImageData(texture.width, texture.height, format, buffer)
    if texture.images > 1:
        data = data.get_region(0, z * texture.height, texture.width, 
texture.height)

    return data

After I did that everything worked perfectly.


On Sunday, November 12, 2017 at 2:31:36 PM UTC-6, Charlie wrote:
>
> This method worked, thanks! 
>
> On a side note, I tried to do multiple viewports using glViewport, but for 
> some reason the whole window defaults to the second viewport even if I set 
> another viewport right after. Not sure what I am missing on that one.
>
> On Wednesday, November 1, 2017 at 3:44:21 AM UTC-5, Benjamin Moran wrote:
>>
>> I can think of a hacky way to do it that might work, but would be a bit 
>> wasteful. 
>> Maybe you can save the current window buffer, and then use gltranslate to 
>> move the view, and take another screenshot.
>> All of these images could then be saved to one big texture, which you can 
>> save out as a single png.
>> You would need to force a screen redraw in between each translate. 
>>
>> I have no idea if that would work, but maybe! 
>>
>>
>>
>> On Wednesday, November 1, 2017 at 2:16:32 AM UTC+9, Charles wrote:
>>>
>>> Yeah I figured that was the case with the culling.
>>>
>>> I am trying to get a screenshot with a 1:1 ratio, kind of like a level 
>>> editor can save a shot, but without zoom so I don't lose quality and 
>>> detail. I've tried messing with viewport and projection settings, but seems 
>>> the GL buffer still can't go outside that. The screenshot produced shows 
>>> the correct dimensions of the viewport, but only the window part has 
>>> anything on it, the rest ends up black.
>>>
>>> On Sunday, October 29, 2017 at 4:59:18 AM UTC-5, Benjamin Moran wrote:
>>>>
>>>> Hi Charles,
>>>>
>>>> I don't think there are any GL buffers that would normally have this 
>>>> image data, because the GPU would cull this off-screen data from the final 
>>>> fragment rasterization. 
>>>>
>>>> Are you trying to just capture the data to save a screen shot, or do a 
>>>> mini map type effect? 
>>>>
>>>> I would guess that most level editors simply render the scene twice. 
>>>> The main view, and a second view with different viewport and projection 
>>>> settings. That would be zoomed out in this case. 
>>>>
>>>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"pyglet-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/pyglet-users.
For more options, visit https://groups.google.com/d/optout.

Reply via email to