Showing posts with label opengl. Show all posts
Showing posts with label opengl. Show all posts

Sunday, September 7, 2008

Appendix B: Framework

This appendix describes the framework code that interacts with the operating system in order to give us somewhere to draw with OpenGL, as well as a way to interact with the user. The framework for pybsp is very simple, doing the minimum to show a window and allow the user some measure of camera control. This is intentional, to keep the focus on the OpenGL code. For this reason basic features you would normally find in a framework such as window resizing, mouse handling and display loops are not supported.

The pybsp framework is written against the wxwindows library for python. This library is freely available, cross platform, and relatively easy to use. In addition it is easy to set up an OpenGL window for use. The library and its documentation can be found at www.wxpython.org.

The main function pretty much says it all:

def main(pybsp):
"""Create a simple wx application to show our opengl drawing and allow simple camera commands"""
app = wx.PySimpleApp()
frame = wx.Frame(None,-1,'PyBSP',wx.DefaultPosition,(400,400))
canvas = myGLCanvas(frame)
canvas.pybsp = pybsp
frame.Show()

Create a wx application. Create a 400 by 400 window with the title PyBSP. Create a Custom GL Canvas to fill the window. Tell the custom canvas the pybsp object to use (contains the tutorial code). Show the window.

The custom GL Canvas is basically a wrapper around the GLCanvas object that calls out to the pybsp object for drawing and GL initialization. It handles two events: the paint event and the keydown event.

On the paint event the framework checks if the pybsp object has initialised OpenGL. If not it calls the OnInit function in the pybsp object. On normal execution it sets up the canvas for drawing using wx calls, calls the OnDraw function in the pybsp object to draw the screen, then calls wx to finish the drawing. In addition it times the OnDraw function as a simple performance metric.

On the keydown event, keystrokes are interpreted to move the camera. The camera is tracked with a simple x,y,z position, a direction angle that indicates the direction the camera is pointing in the xy plane, and an updown angle which indicates the direction above or below the horizon that the camera is pointing. The key press routine interprets the arrow keys to modify the camera's direction by 5 degrees on the appropriate axis, whilst the w,a,s and d keys move it forwards, left, backwards and right along the line of sight of the camera respectively. After updating the camera position, wx is asked to repaint the display, thus invoking the OnDraw function in the pybsp object again from the paint event handler.

Till Next time,
Naltai

Thursday, July 31, 2008

Source Code Available

I made the effort to figure out exactly how to get launchpad code hosting to work, and put the code up for the world to see.  As you can see it is still very messy, but serves as a simple example of an opengl program using vertex buffers.

It uses a map I downloaded for free from the internet, I do not have copyright to this map, but since it is available from many places I believe the author has placed it in the public domain.  If anyone is skilled at creating quake3 maps and wishes to donate one to this cause please let me know and I will use it in favour of the one I have at the moment.

To run the viewer run the command:
python map3.py

Once the viewer is running the left and right arrow keys can be used to rotate the view, and the w, a, s, and d keys can be used to move the camera in typical FPS style.  The script only redraws the screen on a keypress and prints the time it takes to redraw the screen to the console.  (approximately 0.05 seconds on my slow macbook).

Any comments are appreciated, but please understand that it is still in a very rough stage.

Have fun,
Naltai

Monday, July 21, 2008

Speed Demon

Well, using the C like functions makes another huge difference to the performance, It is now hitting about 20 FPS without any kind of visibility culling algorithms.  Also, I don't know how optimized the string indexing functions I am using are, they might be causing additional performance overhead.

I think the next thing to do will be texturing and light mapping, to give more impressive screenshots :)

Cheers,
Naltai 

No More Troubles

Well, that was fast.  It seems merely writing about the problem allowed me to step back from it, and realize that vertex arrays have to be explicitly enabled using glClientStateEnable before using them.

So the demo now has the same functionality as the original, only it now runs at about 9 FPS rather than 3 FPS.  Next I will try going back to c-like calls since I now know I need to enable the arrays.

Till next time,
Naltai

Sunday, July 20, 2008

glVertexPointer Troubles

I decided to optimize the drawing first by using glVertexPointer and glDrawElements, however this has turned out to be more trouble than I expected.  It seems that no matter the way I play with the functions I cannot get them to work correctly.

I started off by using the C-like versions of the functions, but have since moved on to trying to get the pythonic versions to work.  Neither will draw anything to the screen.

I'll keep chipping away at it, but it is really annoying, and there are no good references on how this is meant to work in python.

On the plus side, it appears to have improved render times by at least 500%, of course - nothing is showing on the screen, so that could be misleading.

Cheers,
Naltai

Friday, July 18, 2008

It Works!


So a couple of hours of hacking today have gotten me over the initial OpenGL pains, and given me a basic render of the map. It aint pretty, it aint fast, but it works.

Put simply I took the vertex list from my previous post, and ran it through a GL_TRIANGLES call. Put in a simple lighting model, and some appropriate camera movement code and voila, a working map viewer. Of course it has it's problems, using such a simple scheme the viewer crawls (maybe 1 fps?), but it has been great for increasing my confidence that I am getting this stuff down pat.

anyway here is the core of the code and a screenshot to prove it works, I am not sure whether to work on the speed next, or get texturing and lighting working better to give better static screenshots :)

I am not sure why I can't pass the arrays as is to glColor and glNormal, maybe it is a bug in pyopengl, it needs further investigation.

Cheers,
Naltai


glBegin(GL_TRIANGLES)
for v in self.vertices:
glColor(*v.color)
glNormal(*v.normal)
glVertex(v.position)
glEnd()



Monday, July 14, 2008

Python Quake3 BSP Parser

So I spent a few hours working up a parser for quake3 bsp files in python. I intend to start writing a couple of simple opengl display modules using various methods to show the BSP files.  Maybe I will post this to google code or something when I am done.

The main thing I like about my parser is that it is very simple, only 200 lines or so including some basic test code.  Currently it handles all of the format except for the game specific information, such as spawn points, doors, etc.  I think I will need to modify it more when I get around to rendering through vertex buffers though, as it currently pulls all data out into classes before returning it, which is great for usability, but poor for performance.  

At the moment it is more meant as a self education tool while I continue to play with 3d graphics.  stay tuned for my findings :)

Saturday, July 12, 2008

Quake3 BSP

I am thinking of writing a simple 3d game.  Something fun and easy to play for 5 minutes and put down.

As an exploration of 3d programming, something I have had only limited experience with before, I have been looking at the Quake3 BSP format.  It's interesting how the format has been optimized for quick processing.

A simple example of this is all of the data organized in vertex buffers with double indirection for simple processing by 3d hardware.  Also more subtle things like the simplicity of the BSP algorithm and pre-computed visibility data, an algorithm that would probably entirely fit in the L1 i-cache of the processor.

Anyway for anyone looking some good  references on this, google says the best are this format description and this usage description.