Dave Jones
Dave Jones

Reputation: 193

how to change the color of a pyglet window

I am creating a program which must change the color of individual pixels in a pyglet window. I am unable to find any way to do this in the docs. Is there a way to do this?

Upvotes: 7

Views: 11917

Answers (4)

white_rabbit
white_rabbit

Reputation: 11

If you mean background color, I can help. There is one option that I know of, the pyglet.gl.glClearColor function.

for example,:

import pyglet
from pyglet.gl import glClearColor

win = pyglet.window.Window(600, 600, caption = "test")

glClearColor(255, 255, 255, 1.0) # red, green, blue, and alpha(transparency)
def on_draw():
    win.clear()

That will create a window with a white background(as opposed to the default, black)

Upvotes: 0

Torxed
Torxed

Reputation: 23500

For funsies, I'll add another answer that is more along the lines of what you might need. Because the window itself will be whatever "clear" color buffer you decide via:

window = pyglet.window.Window(width=width, height=height)
pyglet.gl.glClearColor(0.5,0,0,1) # Note that these are values 0.0 - 1.0 and not (0-255).

So changing the background is virtually impossible because it's "nothing".
You can however draw pixels on the background via the .draw() function.

import pyglet
from random import randint

width, height = 500, 500
window = pyglet.window.Window(width=width, height=height)

@window.event
def on_draw():
    window.clear()
    for i in range(10):
        x = randint(0,width)
        y = randint(0,height)
        pyglet.graphics.draw(1, pyglet.gl.GL_POINTS,
                ('v2i', (x, y)),
                ('c3B', (255, 255, 255))
            )

pyglet.app.run()

This will create 10 randomly placed white dots on the background.
To add anything above that simply place your .blit() or .draw() features after the pyglet.graphics.draw() line.

Upvotes: 12

Torxed
Torxed

Reputation: 23500

You could use the magic function SolidColorImagePattern and modify the data you need.

R,G,B,A = 255,255,255,255
pyglet.image.SolidColorImagePattern((R,G,B,A).create_image(width,height)

This is a .blit():able image. It's white, and probably not what you want.
So we'll do some more wizardry and swap out all the pixels for random ones (War of the ants):

import pyglet
from random import randint

width, height = 500, 500
window = pyglet.window.Window(width=width, height=height)
image = pyglet.image.SolidColorImagePattern((255,255,255,255)).create_image(width, height)

data = image.get_image_data().get_data('RGB', width*3)
new_image = b''

for i in range(0, len(data), 3):
    pixel = bytes([randint(0,255)]) + bytes([randint(0,255)]) + bytes([randint(0,255)])
    new_image += pixel

image.set_data('RGB', width*3, new_image)

@window.event
def on_draw():
    window.clear()
    image.blit(0, 0)

pyglet.app.run()

For educational purposes, I'll break it down into easier chunks.

image = pyglet.image.SolidColorImagePattern((255,255,255,255)).create_image(width, height)

Creates a solid white image, as mentioned. It's width and height matches the window-size.

We then grab the image data:

data = image.get_image_data().get_data('RGB', width*3)

This bytes string will contain width*height*<format>, meaning a 20x20 image will be 1200 bytes big because RGB takes up 3 bytes per pixel.

new_image = b''

for i in range(0, len(data), 3):
    pixel = bytes([randint(0,255)]) + bytes([randint(0,255)]) + bytes([randint(0,255)])
    new_image += pixel

This whole block loops over all the pixels (len(data) is just a convenience thing, you could do range(0, width*height*3, 3) as well, but meh.
The pixel contists of 3 randint(255) bytes objects combined into one string like so:

pixel = b'xffxffxff'

That's also the reason for why we step 3 in our range(0, len(data), 3). Because one pixel is 3 bytes "wide".

Once we've generated all the pixels (for some reason the bytes object image can't be modified.. I could swear I've modified bytes "strings" before.. I'm tired tho so that's probably a utopian dream or something.
Anyhow, once all that sweet image building is done, we give the image object it's new data by doing:

image.set_data('RGB', width*3, new_image)

And that's it. Easy as butter in sunshine on a -45 degree winter day.

Docs:

You can also opt in to get a region, and just modify a region.. But I'll leave the tinkering up to you :)

Upvotes: 5

msarch
msarch

Reputation: 345

You can blit pixels into background 'image'. You can look at this Stack Overflow question.

Upvotes: 0

Related Questions