Drawing an Image

82 views
Skip to first unread message

Jonathon Parker

unread,
Mar 3, 2020, 10:29:55 AM3/3/20
to pyglet-users
The Sprite class takes an image and all the examples I have seen use an image file.  Instead of using an image file, is it possible to use anything from pyglet.graphics to define an image?  How do I do this?  My goal is to take advantage of all the functions of a Sprite with a custom image created from multiple geometric shapes.

FYI, I did successfully define an image (a green square) using SolidColorPattern, convert it to a texture, and pass it to a Sprite.  After that I got stuck.


Benjamin Moran

unread,
Mar 4, 2020, 7:19:17 AM3/4/20
to pyglet-users
Hi Jonathon, 

Rather than trying to turn GL primitives in to an image to use with a Sprite, you could also make a Sprite-like class for the various shapes. This can get tricky if you want to rotate them, as you'll have to add your own math to do that work, but as an example I'll post a simple Rectangle class below. You can make similar classes for a variety of shapes: 
 

class Rectangle:
def __init__(self, x, y, width, height, color=(255, 255, 255, 255), batch=None, group=None):
self._x = x
self._y = y
self._size = [width, height]
self._color = color
self._batch = batch
self._group = group
self._vertex_list = batch.add(6, GL_TRIANGLES, group, 'v2f', 'c4B')
self._update_vertex_list()

def _update_vertex_list(self):
x = self._x
y = self._y
w, h = self._size
one = x, y
two = x + w, y
three = x + w, y + h
four = x, y + h
self._vertex_list.vertices[:] = one + two + three + three + one + four
self._vertex_list.colors[:] = self._color * 6

@property
def width(self):
return self._size[0]

@width.setter
def width(self, value):
self._size[0] = value
self._update_vertex_list()

@property
def height(self):
return self._size[1]

@height.setter
def height(self, value):
self._size[1] = value
self._update_vertex_list()

Jonathon Parker

unread,
Mar 4, 2020, 7:52:09 AM3/4/20
to pyglet-users
Benjamin,

The math for rotation was the thing I was most trying to avoid.  If I have a complex shape, I would need to know the center, rotate every point, and fill the colored portions in.  That sounds hard.

I want to use Sprites as the visual component of a simulation.  The behaviors of objects in the simulation are my focus, so I thought the visual component should be simple. What I want is to define an image using some geometric shapes (preferably not a bitmap!) and pass it to a Sprite.  Is there anyway to do that?


Jonathon

Charles M

unread,
Mar 4, 2020, 2:33:43 PM3/4/20
to pyglet-users
A sprite by definition is basically a wrapper around a texture and it's 4 vertices. If you want a Sprite class around OpenGL primitives like triangles, polygons, there is nothing out of the box that you can use other than what Benjamin showed you.

Your options are:
1) Create the shapes you need as images and use them in the Sprite class.

2) Use Benjamins advice and make helper classes that function like sprites (similar methods, attributes, etc) that wrap around GL primitives. One for each shape you'll need.

3) You could also create the shapes as image data using bytes and pass them into an ImageData instance that Pyglet can use. (If you wanted to do something programatically without loading files from disk.)

The only out of the box ready to go option is #1. The rest will involve some work.

Jonathon Parker

unread,
Mar 6, 2020, 2:39:02 PM3/6/20
to pyglet-users
Thanks for the posts. I am stubborn and went with option 3.  The code below does what I want, and I can leverage cv2 to do it:

import pyglet
import ctypes
import itertools
import numpy as np
import cv2

image = np.zeros((50503), np.uint8) 
pt1 = (11)
pt2 = (4824)
pt3 = (148)

triangle_cnt = np.array([pt1, pt2, pt3])
cv2.drawContours(image, [triangle_cnt], 0, (100255100), -1)

image = image.tolist()
px = list(itertools.chain(*list(itertools.chain(*image))))

rawData = (ctypes.c_ubyte * len(px))(*px)
player_image3 = pyglet.image.ImageData(5050'RGB', rawData).get_texture()
Reply all
Reply to author
Forward
0 new messages