So there is no solution for this?  All I want to do is:

# imgA, imgB are identically sized instances of pyglet.image.ImageData in 
RGBA format

imgC = imgA + imgB

# imgC is now imgA with imgB superimposed on top of it. Transparent pixels 
in imgB allow translucent pixels in imgA to be visible

I never thought something so simple would be so hard!

On Thursday, March 12, 2020 at 12:45:02 PM UTC-4, Jonathon Parker wrote:
>
> Please look at my code example.  There is no math to do.  I have two 
> images the same size (50 x 50).  Each image has a shape with A=255.  The 
> rest of the image A = 0.
>
> I want to draw one image on the other.  So I convert one image into a 
> texture and blit_into with the other image.  I should be able to see 
> through the transparent parts of the top image and see the opaque parts of 
> the bottom image.  But I can't.  It won't work.
>
> On Thursday, March 12, 2020 at 12:30:32 PM UTC-4, Charles M wrote:
>>
>> Blend modes themselves aren't going to help you with combining textures 
>> into one. That's only for things like sprites and other things in the 
>> framebuffer.
>>
>> It's not OpenGL at this point, it's the data you are providing it. You 
>> need to use math to change your pixel data with the blend mode formula 
>> equation in the link I provided in the last post. 
>>
>> On Thursday, March 12, 2020 at 11:04:21 AM UTC-5, Jonathon Parker wrote:
>>>
>>> I need them as one image.  I have tried many different blend function 
>>> things and if they don't throw an error they all do the same things.  
>>> Namely, only display rect.
>>>
>>> Something has to be wrong somewhere else.  I tried 
>>> pyglet.gl.glBlendFunc(pyglet.gl.GL_ZERO,pyglet.gl.GL_ONE)
>>>
>>> If I understand it right, it should only display the destination image 
>>> (the triangle) and set the source image to have a zero factor.  But that is 
>>> not what it does.  It still displays the thin rectangle.
>>>
>>> On Thursday, March 12, 2020 at 10:53:58 AM UTC-4, Charles M wrote:
>>>>
>>>> Ah I see you want to blend them together in the same data. In your 
>>>> examples you are still overwriting the image data. If you have a red 
>>>> channel that's at 100 bytes and you replace the data with another pixel 
>>>> that's 100 bytes, it's still 100. If you are looking to blend two images 
>>>> together you have a few options:
>>>>
>>>> 1) Create separate ImageData, put them into pyglet.sprite.Sprite 
>>>> objects and draw them where you want. By default Sprites should blend, and 
>>>> it should be easier to keep track of things/move them when they are 
>>>> separate. I'm curious why the need to combine the data instead of treating 
>>>> them separate but move them where you want?
>>>>
>>>> 2) If you actually *need *them combined into one image data for some 
>>>> reason, then you can combine the pixels together with math based on 
>>>> blending formulas. https://learnopengl.com/Advanced-OpenGL/Blending Here 
>>>> is the formula and an example.
>>>>
>>>>
>>>> On Thursday, March 12, 2020 at 7:49:36 AM UTC-5, Jonathon Parker wrote:
>>>>>
>>>>> I tried that and it did not work.  I have verified that if I draw a 
>>>>> smaller image on top of the new, I can see that.  But even with using 
>>>>> RGBA, 
>>>>> I only see the last image if the sizes are the same.  Here is a more 
>>>>> expanded example of what I am trying to do.
>>>>>
>>>>> ---
>>>>>
>>>>> import pyglet
>>>>> import pyglet.gl
>>>>> import ctypes
>>>>> import itertools
>>>>> import numpy as np
>>>>> import cv2
>>>>>
>>>>> pyglet.gl.glEnable(pyglet.gl.GL_BLEND)
>>>>>
>>>>> pyglet.gl.glBlendFunc(pyglet.gl.GL_SRC_ALPHA,pyglet.gl.GL_ONE_MINUS_SRC_ALPHA)
>>>>>
>>>>> image = np.zeros((50, 50, 4), np.uint8) # type(image) = numpy.ndarray
>>>>>
>>>>> pt1 = (12, 1)
>>>>> pt2 = (48, 24)
>>>>> pt3 = (12, 48)
>>>>> pt4 = (1, 24)
>>>>> pt5 = (1, 26)
>>>>> pt6 = (48, 26)
>>>>> pt7 = (48, 24)
>>>>>
>>>>> triangle_cnt = np.array([pt1, pt2, pt3])
>>>>> cv2.drawContours(image, [triangle_cnt], 0, (100, 255, 100, 255), -1)
>>>>> image = image.tolist()
>>>>> px = list(itertools.chain(*list(itertools.chain(*image))))
>>>>>
>>>>> rawData = (ctypes.c_ubyte * len(px))(*px)
>>>>> player_image = pyglet.image.ImageData(50, 50, 'RGBA', 
>>>>> rawData).get_texture()
>>>>>
>>>>> image2 = np.zeros((50, 50, 4), np.uint8)
>>>>> rect_cnt = np.array([pt4, pt5, pt6, pt7])
>>>>> cv2.drawContours(image2, [rect_cnt], 0, (100, 255, 100, 255), -1)
>>>>> image2 = image2.tolist()
>>>>> px2 = list(itertools.chain(*list(itertools.chain(*image2))))
>>>>>
>>>>> rawData2 = (ctypes.c_ubyte * len(px2))(*px2)
>>>>> rect = pyglet.image.ImageData(50, 50, 'RGBA', rawData2) 
>>>>>
>>>>> player_image.blit_into(rect, 0, 0, 0)
>>>>>
>>>>> ---
>>>>>
>>>>> When I display player_image, I only see the thin rectangle.  What am I 
>>>>> doing wrong?
>>>>>
>>>>> My goal is to change images for sprites during a simulation depending 
>>>>> on simulation events.  If you know a better way to accomplish this, I 
>>>>> would 
>>>>> like to hear it.
>>>>>
>>>>> On Wednesday, March 11, 2020 at 7:49:46 PM UTC-4, Charles M wrote:
>>>>>>
>>>>>> Your images have no transparency (RGB). You need will need to specify 
>>>>>> an alpha channel to do transparency: RGBA and a fourth value for each 
>>>>>> pixel.
>>>>>>
>>>>>>
>>>>>> On Wednesday, March 11, 2020 at 5:57:27 PM UTC-5, Jonathon Parker 
>>>>>> wrote:
>>>>>>>
>>>>>>> In my test the images are the same size, but I thought the 
>>>>>>> background was transparent.  Any way to specify a background color is 
>>>>>>> transparent?  Or is there a better way to layer images?
>>>>>>>
>>>>>>> On Wednesday, March 11, 2020 at 6:44:00 PM UTC-4, Charles M wrote:
>>>>>>>>
>>>>>>>> This is normal behavior, blit overwrites the pixel data with new 
>>>>>>>> data you are providing. Which in this case is an entirely new image.
>>>>>>>>
>>>>>>>> On Wednesday, March 11, 2020 at 2:34:15 PM UTC-5, Jonathon Parker 
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>> A minimal example
>>>>>>>>>
>>>>>>>>> # rawdata1 and rawdata2 are a list of c_ubytes
>>>>>>>>>
>>>>>>>>> my_texture_region = pyglet.image.ImageData(x, y, 'RGB', 
>>>>>>>>> rawdata1).get_texture()
>>>>>>>>> my_image = pyglet.image.ImageData(x, y, 'RGB', rawdata2)
>>>>>>>>> my_texture_region.blit_into(my_image, 0, 0, 0)
>>>>>>>>>
>>>>>>>>> When I create a sprite using my_texture region, I only see 
>>>>>>>>> my_image.  What I want is my_image on top of my_texture_region.
>>>>>>>>>
>>>>>>>>> What am I doing wrong?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>

-- 
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 pyglet-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/pyglet-users/2c33ddad-d300-432c-9dc2-34aac9f70d51%40googlegroups.com.

Reply via email to