Wondering where to start with drawing

260 views
Skip to first unread message

Chris Norman

unread,
Dec 7, 2016, 10:48:34 AM12/7/16
to pyglet...@googlegroups.com
Hi all,

First let me start off by saying I won't be using Pyglet for this
system, so it's more general information that I need.


I am writing a game using wxPython for my UI toolkit, but I want to
include like a visual map. I am blind, so this isn't something I've done
before, and I don't want it to look like a half-baked effort.


I'm not expecting to set the world on fire here - initially I plan to
colour the different squares with concrete, sand, metal, water whatever.


I haven't yet hit google, but I thought I'd send out this general post
so that hopefully I can skip over some of the hundreds of things I
expect I'll start reading.


So here's my questions:


- Is there some prefered way to draw maps in Open GL?

- Do I use pure colours for my squares? Or does GL have textures I can
use for say sand and metal and water?

- If I then overlay icons (player and object avatars) on the squares,
will it look OK?

- How many squares can I realistically fit onto a screen? I plan to
implement a zoom feature, but by default I was thinking 4 squares on
either side of the player, so they'll be at the centre of a 9x9 grid
(totalling 81 squares).


Cheers, and sorry for what are probably quite stupid questions.


Cheers,


Chris

Chris Norman

unread,
Dec 7, 2016, 3:08:24 PM12/7/16
to pyglet...@googlegroups.com
OK,

I have since revised my estimate...


After much googling I can't find a way to draw wimple textures with
OpenGL, so I have looked again at the Pyglet API.


Making a HUD with Pyglet was actually surprisingly easy, so that was nice.


My next thing is I need to run Pyglet and WX event loops in tandom - as
I mentioned before there are parts of the client I really need a full
GUI solution for.



Has anyone successfully ran the Pyglet event loop from inside WX? I'm
guessing that's the easiest solution.

Thanks in advance.

magu...@gmail.com

unread,
Dec 7, 2016, 6:17:59 PM12/7/16
to pyglet-users
Getting some API's to work together can sometimes be a tricky affair. I've only just started digging into wxpython recently, and while it has a glCanvas function it seems to depend on PyOpenGL to work. I have managed to dig up a script [here] that seems to blend a pyglet GL context with wxpython though, so that may be the direction you want to go in.


As for your other questions:


- Is there some prefered way to draw maps in Open GL?

That largely depends on the requirements such as how the map is structured, how large it is, how many images are being drawn, etc. If its a single image than using a simple blit call may suffice, though if your rendering lots of images then using batch rendering may be a more efficient approach.


- Do I use pure colours for my squares? Or does GL have textures I can use for say sand and metal and water?

GL does not have built in textures, but it absolutely can use them if you supply them. You can also use pure colors, but thats up to you.


- If I then overlay icons (player and object avatars) on the squares, will it look OK?

That depends, using overlaid icons and sprites usually involves color keying, which involves removing certain colors and making them transparent as with an Alpha Channel. So assuming we have a square tile and a not square avatar on its own tile, without color keying the avatar would be surrounded by its own white square outline, but with color keying you'd only see the avatar itself overlaid on the tile instead. This involves a little prep work with the sprites image itself by either selecting a color and removing it in code, or applying an alpha channel and transparency to it and filtering them out, which is usually fairly straight forward.


- How many squares can I realistically fit onto a screen? I plan to implement a zoom feature, but by default I was thinking 4 squares on either side of the player, so they'll be at the centre of a 9x9 grid (totalling 81 squares).

This depends on what resolution you want the programs window to run at, the resolution of the host system, and the size of the tiles you want to use. A monitor is made of individual pixel dots, each their own color, the "resolution" is a description of how many pixels there are in a row, and how many rows there are. So a 640x480 resolution would be 640 pixels per horrizontal row, with 480 rows, for a total of 307200 pixels. Tiles can range in size wildly, from 8x8 or even 128x128. So knowing the resolution and the size of the tiles can tell you how many tiles you can fit on the screen, if working with a 640x480 resolution and 32x32 tiles you can fit 300 tiles on the screen, 20 per horrizontal row with 15 rows. Some of the more common resolutions on PC are around 320x240, 640x480, or 800x640 and higher. General tile sizes are usually around 8x8, 16x16, 32x32 or 64x64 to varying degrees.

I can also provide some examples on rendering or blending if you'd like.

Chris Norman

unread,
Dec 7, 2016, 6:22:55 PM12/7/16
to pyglet...@googlegroups.com

Thank you so much for your answer, that's awesome!


I've begun to suspect that anything requiring pure OpenGL is going to be a pain since I'll have to get someone to check everything I do, so I've just begun to focus my efforts on running the Pyglet event loop from within WX.


I have the code for the tiles - which even works (surprisingly), and it'll give me the added benefits of game controler support et al.


Have you managed to integrate the two libraries? I could just use a thread... but I already have twisted running inside of a further thread, and having three running consecutively seems extraneous.


Thank you again for all the info, it's been really helpful!


Take care,


Chris

--
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...@googlegroups.com.
To post to this group, send email to pyglet...@googlegroups.com.
Visit this group at https://groups.google.com/group/pyglet-users.
For more options, visit https://groups.google.com/d/optout.

magu...@gmail.com

unread,
Dec 7, 2016, 6:52:58 PM12/7/16
to pyglet-users
Twisted you say? Hmm. As I said, I've only just started playing around with wxpython recently, other than the script I linked to i'm not sure how to integrate them at this point. I have however managed to integrate pyglet with twisted before using Twisted's coiterate function, I have an exampleof that around if you like.

Working with OpenGL may be a bit tricky, I know of a few tools available that may help if your not aware of them already. There's Peter Meijers [The vOICe] sotware, which you could use to scan the active window and convert it into sound. Another option would be the accessible paint tool [BrushTone], you could take a screenshot of the window with the print screen key, paste and save it as an image in something like mspaint and run it through BrushTone to look at the results.

Chris Norman

unread,
Dec 8, 2016, 1:44:43 AM12/8/16
to pyglet...@googlegroups.com

Hi, yes, Twisted, specifically twisted.protocols.basic.NetstringReceiver.


The client I am making is for Mindspace, which is my VR idea:


https://github.com/chrisnorman7/


I have never heard of Coiterate... a quick google shows it's something to do with iterators?


If you have an example that would be amazing!


At this point I've pretty much resigned myself to using Pyglet for the whole project.


I actually don't mind using Pyglet - I love it! It's just that I know more about presenting information with WX, and I'd written me a very nice (and pretty much indespensible remote Python shell for building things on the fly within the Mindspace server instance).


I'm planning to do the unthinkable and have a third (or second if I can make your code work for me) event loop for WX, and just leave a frame around to keep the main loop chugging away.


All in all, I'm actually quite excited because I'd love to use game controller support, and I find the keyboard handling q lot nicer.


Cheers,


On 07/12/2016 23:52, magu...@gmail.com wrote:
Twisted you say? Hmm. As I said, I've only just started playing around with wxpython recently, other than the script I linked to i'm not sure how to integrate them at this point. I have however managed to integrate pyglet with twisted before using Twisted's coiterate function, I have an exampleof that around if you like.

Working with OpenGL may be a bit tricky, I know of a few tools available that may help if your not aware of them already. There's Peter Meijers [The vOICe] sotware, which you could use to scan the active window and convert it into sound. Another option would be the accessible paint tool [BrushTone], you could take a screenshot of the window with the print screen key, paste and save it as an image in something like mspaint and run it through BrushTone to look at the results.

Chris Norman

unread,
Dec 8, 2016, 1:48:23 AM12/8/16
to pyglet...@googlegroups.com

Sorry, forgot to say that I'd definitely love to see your example please! :-)


Cheers,


On 07/12/2016 23:52, magu...@gmail.com wrote:
Twisted you say? Hmm. As I said, I've only just started playing around with wxpython recently, other than the script I linked to i'm not sure how to integrate them at this point. I have however managed to integrate pyglet with twisted before using Twisted's coiterate function, I have an exampleof that around if you like.

Working with OpenGL may be a bit tricky, I know of a few tools available that may help if your not aware of them already. There's Peter Meijers [The vOICe] sotware, which you could use to scan the active window and convert it into sound. Another option would be the accessible paint tool [BrushTone], you could take a screenshot of the window with the print screen key, paste and save it as an image in something like mspaint and run it through BrushTone to look at the results.

magu...@gmail.com

unread,
Dec 8, 2016, 6:29:49 PM12/8/16
to pyglet-users
Hm, the example works fine but seems to hang on exit. Which is a bit wierd considering I have basically the same implementation in a larger program that seems to handle it fine.

import pyglet

from pyglet.window import mouse
from pyglet.window import key

from twisted.internet.endpoints import TCP4ServerEndpoint
from twisted.internet.protocol import Protocol
from twisted.internet.protocol import Factory
from twisted.internet.protocol import ClientFactory
from twisted.internet import reactor
from twisted.internet import task

import pickle
import zlib

pyglet
.options['debug_gl'] = False

#pyglet window
class example(pyglet.window.Window):
   
def __init__(self):
       
super(example, self).__init__(640, 480, resizable=False, fullscreen=False, caption="Test")
       
self.clear()

   
#connected user variable, when someone connects the Echo Class will add itself into it.
   
#then just call self.user.sendData to transmit to the connected user or self.user.dataRecieved to get data.
       
self.user = []

       
self.server = None

   
#since the Reactor is in control, to properly run the main game loop you have to manually call the clock.
   
#this variable is to keep track of the last time the clock was ticked.
       
self.old_dt = pyglet.clock.tick()
       
self.fps_display = pyglet.clock.ClockDisplay()


#main game loop
   
def update(self):
       
while not self.has_exit:
       
#Make sure events are timed properly while coiterating with network layer. That and tick clock events like the fps counter and game pacing.
            dt
= pyglet.clock.tick()
           
self.old_dt = self.old_dt + dt

       
#draw to screen
           
self.draw()

       
#manually dispatch window events (since twisted reactor is in control)
           
self.dispatch_events()


       
#return control to twisted Reactor
           
yield 1

#draw and manually flip frame buffers
   
def draw(self):
       
self.clear()
       
self.fps_display.draw()
       
self.flip()


#mouse click
   
def on_mouse_press(self,x,y,button,modifiers):
       
if button == pyglet.window.mouse.LEFT:
           
if len(self.user) != 0:
                data
= ['left_press',x,y]
               
for a in self.user:
                    a
.sendData(data)

       
if button == pyglet.window.mouse.RIGHT:
           
if len(self.user) != 0:
                data
= ['right_press',x,y]
               
for a in self.user:
                    a
.sendData(data)

   
def on_mouse_release(self,x,y,button,modifiers):
       
if button == pyglet.window.mouse.LEFT:
       
#if someone has logged in, transmit if you click the mouse
           
if len(self.user) != 0:
                data
= ['left_release',x,y]
               
for a in self.user:
                    a
.sendData(data)

       
if button == pyglet.window.mouse.RIGHT:
       
#if someone has logged in, transmit if you click the mouse
           
if len(self.user) != 0:
                data
= ['right_release',x,y]
               
for a in self.user:
                    a
.sendData(data)


   
def on_key_release(self,symbol, modifiers):
       
if symbol == key.S:
           
self.server = TCP4ServerEndpoint(reactor, 8007)
           
self.server.listen(QOTDFactory())
           
print "server initializing"

       
if symbol == key.C:
            reactor
.connectTCP('localhost', 8007, EchoClientFactory())
           
print "connecting"

       
if symbol == key.ESCAPE:
           
self.close()


#shutdown program gracefully
   
def shutdown(self, result):
        reactor
.stop()

#system error shutdown
   
def bailout(self, reason):
        reason
.printTraceback()
        reactor
.stop()


#twisted network classes
class Echo(Protocol):
#data reciever class
   
def connectionMade(self):
        data
= "An apple a day keeps the doctor away\r\n"
        data
= pickle.dumps(data)
        compressed
= zlib.compress(data)
       
self.transport.write(compressed)
        window
.user.append(self)


   
def dataReceived(self, data):
   
#have the Echo Protocol class representing the connection to the currently connected user add itself
   
#to the window.user variable so we can comminicate with the connected user in the game loop.
        data
= zlib.decompress(data)
        data
= pickle.loads(data)

       
if data[0] == 'left_press':
           
print '1'
       
if data[0] == 'left_release':
           
print '2'
       
if data[0] == 'right_press':
           
print '3'
       
if data[0] == 'right_release':
           
print '4'


#data transmitter class
   
def sendData(self,data):
        data
= pickle.dumps(data)
        data
= zlib.compress(data)
       
self.transport.write(data)

#this monitors the port and automatically calls Echo() when someone connects, passing their address to it.
class QOTDFactory(Factory):
   
def buildProtocol(self, addr):
       
print addr, "connected."
       
return Echo()

#This class establishes a connection to a server.
class EchoClientFactory(ClientFactory):
   
def startedConnecting(self, connector):
       
print 'Started to connect.'

   
def buildProtocol(self, addr):
       
print 'Connected.'
       
return Echo()

   
def clientConnectionLost(self, connector, reason):
       
print 'Lost connection. Reason:', reason

   
def clientConnectionFailed(self, connector, reason):
       
print 'Connection failed. Reason:', reason



if __name__ == '__main__':
#initialize main window
    window
= example()
#coiterate between the reactor and the window
    task
.coiterate(window.update()).addCallback(window.shutdown).addErrback(window.bailout)
#start main reactor loop
    reactor
.run()


Chris Norman

unread,
Dec 9, 2016, 7:05:34 PM12/9/16
to pyglet...@googlegroups.com
Hi,
That worked like a charm!!! I am finally able to get the two components working in the same thread!

Thank you so much, you have no idea how long I've been trying to get this to work for.

I would like to acknowledge you in the code and the acknowledgements file. What name would you like me to use? I only currently have your email address, which I'm not sure if you're happy for me to use or not.

Cheers,

magu...@gmail.com

unread,
Dec 10, 2016, 6:56:18 PM12/10/16
to pyglet-users
Well, I can't take all the credit. Nathan posted the gist of it [here] ages ago, I came across it a few years later and based my own example on it. For reference though, just magurp244 would suffice.


Chris Norman

unread,
Dec 10, 2016, 9:49:06 PM12/10/16
to pyglet...@googlegroups.com

You're in, thank you so much!


Take care,


On 10/12/2016 23:56, magu...@gmail.com wrote:
Well, I can't take all the credit. Nathan posted the gist of it [here] ages ago, I came across it a few years later and based my own example on it. For reference though, just magurp244 would suffice.


Reply all
Reply to author
Forward
0 new messages