Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    10
  • comments
    13
  • views
    4932

About this blog

Charting my clumsy steps into game programming

Entries in this blog

 

Displaying a background

Thanks to some help from Oluseyi I managed to adapt my program so that I display a predefined map on the background.

Here is the code:


#Setup: I import all the modules here
import sys
import os
import pygame
import random
import math
from pygame.locals import *
progpath = os.getcwd()+"/"
keys=[False]*324
snow_file_name = '\snow.bmp' #this is the filename for the sprite I will use

def kill(): #this function is for killing the window and quitting
pygame.display.quit()
pygame.quit()
return

def load_image(name, colorkey=None): #this function is for loading the image to us in the program
fullname ='c:\Python24' + name
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print 'Cannot load image:,%s', name
raise SystemExit, message
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
return image, image.get_rect()

class Snow(pygame.sprite.Sprite): #this class handles loading the image that I use as a mouse pointer and tracking and drawing it
def __init__(self): #initialization
pygame.sprite.Sprite.__init__(self)
self.image, self.rect = load_image(snow_file_name, -1)
def update(self): #actions for frame update
pos = pygame.mouse.get_pos()
self.rect.midtop = pos


######################################################
def main():
pygame.init()
pygame.font.init()
w=160.0 #screen width
h=128.0 #height
w_x=w/16 #number of tiles wide screen is
h_y=h/16 #number of tiles high the screen is
print(w_x)
print(h_y)
x_map_pos = 0
y_map_pos =0
map =[0,0,0,0,0,0,0,0,0,0,
0,1,0,0,0,0,0,0,1,0,
0,1,0,0,0,0,0,0,1,0,
0,1,1,0,0,0,0,1,1,0,
0,1,1,1,0,0,1,1,1,0,
0,1,1,1,1,1,1,1,1,0,
0,1,1,1,1,1,1,1,1,0,
0,0,0,0,1,1,0,0,0,0]


screen = pygame.display.set_mode((int(w),int(h)))
background_tile, background_tile_rect = load_image(snow_file_name,-1)
pygame.display.set_caption("Trial")
pygame.mouse.set_visible(0)
clock=pygame.time.Clock()
background = pygame.Surface(screen.get_size())
background = background.convert()

i=0
screen.blit(background, (0,0))
while y_map_pos x_map_pos = 0
while x_map_pos if map > 0:
screen.blit(background_tile, (x_map_pos*16,y_map_pos*16))
x_map_pos = x_map_pos + 1
i = i + 1
y_map_pos = y_map_pos + 1

pygame.display.flip() #background is now displayed
snow = Snow() #sprite instance
allsprites = pygame.sprite.RenderPlain((snow)) #container



#Main loop
while True:

#Event handling
clock.tick(60)
for event in pygame.event.get():
if event.type==QUIT:
kill()
return
if event.type==KEYDOWN:
if event.key==K_ESCAPE:
kill()
return
keys[event.key]=True
elif event.type==KEYUP:
keys[event.key]=False
print event

allsprites.update() #calls update function of all sprites

screen.blit(background, (0,0)) #redraw background
i=0
y_map_pos = 0
while y_map_pos x_map_pos = 0
while x_map_pos if map > 0:
screen.blit(background_tile, (x_map_pos*16,y_map_pos*16))
x_map_pos = x_map_pos + 1
i = i + 1
y_map_pos = y_map_pos + 1
allsprites.draw(screen) #redraw sprites
pygame.display.flip() #show new screen


if __name__=="__main__": main()



It is pretty straightforward (still a bit ugly). First I define the map. Then I step through the map and increment my x position on the screen by 16 for each tile in the map. After I finish a row I increment my y position and start again.
I blit the 16x16 background_tile for every 1 in the map.

There is some ugliness going on here. The loop where I step through the map needs to be a function. Also the map is hard coded (grrrr) as is the tile size. I would also rather get the background sprites to the screen using a sprite class and its update function but I am having a bit of trouble with this. There should be some way to use one of the handy sprite containers to hold an array of these or something.

My next step is to clean up this code and then to load the map from a file.

Making large maps is cumbersome so I should be able to make up some way of reversing this process where I can draw the map in another program store it to a file and open it with this one. Obviously I will have to figure out how to snap to a tile edge for the drawing program. Another option would be to draw it randomly.

rmckee78

rmckee78

 

Now with sprites

In my quest to figure out how to make only the current position of the snow image show (instead of leaving a trail) I discovered that I should be using pygame sprites as they make life much easier. As a bonus I learned how to support the mouse.

Current code here:

#Setup: I import all the modules here
import sys
import os
import pygame
import random
import math
from pygame.locals import *
progpath = os.getcwd()+"/"
keys=[False]*324
snow_file_name = '\snow.bmp' #this is the filename for the sprite I will use

def kill(): #this function is for killing the window and quitting
pygame.display.quit()
pygame.quit()
return

def load_image(name, colorkey=None): #this function is for loading the image to us in the program
fullname ='c:\Python24' + name
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print 'Cannot load image:,%s', name
raise SystemExit, message
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
print('hi')
return image, image.get_rect()

class Snow(pygame.sprite.Sprite): #this class handles loading the image that I use as a mouse pointer and tracking and drawing it
def __init__(self): #initialization
pygame.sprite.Sprite.__init__(self)
self.image, self.rect = load_image(snow_file_name, -1)
def update(self): #actions for frame update
pos = pygame.mouse.get_pos()
self.rect.midtop = pos

######################################################
def main():
pygame.init()
pygame.font.init()
w=320.0 #screen width
h=200.0 #height


screen = pygame.display.set_mode((int(w*2),int(h)))
pygame.display.set_caption("Trial")
pygame.mouse.set_visible(0)
clock=pygame.time.Clock()
background = pygame.Surface(screen.get_size())
background = background.convert()
background.fill((250,250,250))
if pygame.font: #add text to background
font = pygame.font.Font(None, 36)
text = font.render("TEST", 1, (10,10,10))
textpos = text.get_rect()
textpos.centerx = background.get_rect().centerx
background.blit(text, textpos)
screen.blit(background, (0,0))
pygame.display.flip() #background is now displayed
snow = Snow() #sprite instance
allsprites = pygame.sprite.RenderPlain((snow)) #container



#Main loop
while True:

#Event handling
clock.tick(60)
for event in pygame.event.get():
if event.type==QUIT:
kill()
return
if event.type==KEYDOWN:
if event.key==K_ESCAPE:
kill()
return
keys[event.key]=True
elif event.type==KEYUP:
keys[event.key]=False
print event

allsprites.update() #calls update function of all sprites

screen.blit(background, (0,0)) #redraw background
allsprites.draw(screen) #redraw sprites
pygame.display.flip() #show new screen


if __name__=="__main__": main()



It took me a while to figure out how it all worked but it was worth it.

Basically I still have the same image loading and quitting function and most of my event handler remains unchanged. Then I define my Snow class. All this class does is load the snow image and then keep track of its position for the update.

This time I define a surface background that will be used to draw the background to the screen. This will be very useful later for drawing the non-moving parts of a level.

I create an instance of Snow() and put it in a container allsprites. The container is not really necessary for this program but seems like a good practice that will make it less hardcoded.

Most of my event handler is the same. I have removed the keyboard input. The rest is painfully easy. I just have to update all the sprites. I would assume if any of my sprites were using preprogramed or AI based movement I could imbed that in the update() function of their class and handle all of it with just one line of code in the main loop (w00t!).

Finally I redraw the background, draw all the sprites (there is only one), and the flip the new screen into place.

So easy. So nice.


rmckee78

rmckee78

 

Draw Snow with WASD

I took my event handler out a step and added drawing to the screen. I draw a 16x16 .bmp of snow I made in paint to the screen. You can move it around with the WASD keys. It leaves a trail like the spraypaint feature in paint. I guess the next step is to add a clearing function.


#Setup
import sys
import os
import pygame
import random
import math
from pygame.locals import *
progpath = os.getcwd()+"/"
keys=[False]*324
snow_file_name = '\snow.bmp'

def kill():
pygame.display.quit()
pygame.quit()
return

def load_image(name, colorkey=None):
fullname ='c:\Python24' + name
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print 'Cannot load image:,%s', name
raise SystemExit, message
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
print('hi')
return image #, image.get_rect()

def main():
pygame.init()
pygame.font.init()
w=320.0
h=200.0
x=0
y=0

window = pygame.display.set_mode((int(w*2),int(h)))
pygame.display.set_caption("Trial")
screen = pygame.display.get_surface()
clock=pygame.time.Clock()
snow_surface = load_image(snow_file_name)

#Main loop
while True:

#Event handling
clock.tick(60)
for event in pygame.event.get():
if event.type==QUIT:
kill()
return
if event.type==KEYDOWN:
if event.key==K_ESCAPE:
kill()
return
keys[event.key]=True
elif event.type==KEYUP:
keys[event.key]=False
print event

if keys[K_w]:
y = y - 5
if y 0:
y = 0

if keys[K_s]:
y = y + 5
if y > 200:
y = 200

if keys[K_a]:
x = x - 5
if x 0:
x = 0

if keys[K_d]:
x = x + 5
if x > 640:
x = 640


screen.blit(snow_surface, (x,y))
pygame.display.flip()


if __name__=="__main__": main()







Definately need to clean it up and comment it better before I move on but I keep changing everything as I experiment (all the more reason to have good comments).

The next big step after screen clearing will be to have starting graphics on the screen stored in an array.

I want to do this with file loading instead of hard coding it into the program. It looks like file handling is really easy to do in Python.

rmckee78

rmckee78

 

Python

Well, life got in the way of making it through the OpenGL project. I made it a bit further but never seemed to get around to posting about it. I was studying to get into law school and working on starting my website Crazy Hakiko's Classic Play
based on classic computer, console, and tabletop RPGs. It's not much so far, mostly my blog and a Dragon Warrior review, but it's a start.

I have had time to get back into programming (other than MATLAB, there always seems to be time for MATLAB. One of the things I realised while working through the C++/OpenGL book was that I didn't know enough about how Windows programming worked. I was constantly fighting C++, my compiler, and my complete lack of Windows programming knowledge.

I ran into one of my college professors in the Brnes and Noble and he suggested Python. I had fooled around with it a little bit before when I was messing around with Ron Penton's excellent MUD Programming book (one of my favorite learn how to do something books ever) but had never really done any more with it.

I'm in love. It is interperated like my beloved MATLAB, it is easy to read. It reminds me of when I was first learning to program on my Atari 800XL (READY...) copying BASIC text adventures out of ANALOG magazine (the key is under the mat). It is well documented right there on the site you download it from. In fact it is well documented in its own help system.

Obviously I am not going to be writing Halo 3 in this thing (but I wasn't going to write it anyway) but it seems like a great way to get up to speed on Windows and the fundementals of video game programming. I can then apply these lessons to C++ or C#.

Anyway I am having fun with it and thanks to some help from the guys on the scripting forum here I managed to get a program going where I use the WASD keys to spraypaint a window with a snow texture tile I drew in Paint.


#Setup
import sys
import os
import pygame
import random
import math
from pygame.locals import *
progpath = os.getcwd()+"/"
keys=[False]*324
snow_file_name = '\snow.bmp'

def kill():
pygame.display.quit()
pygame.quit()
return

def load_image(name, colorkey=None):
fullname ='c:\Python24' + name
try:
image = pygame.image.load(fullname)
except pygame.error, message:
print 'Cannot load image:,%s', name
raise SystemExit, message
image = image.convert()
if colorkey is not None:
if colorkey is -1:
colorkey = image.get_at((0,0))
image.set_colorkey(colorkey, RLEACCEL)
print('hi')
return image #, image.get_rect()

def main():
pygame.init()
pygame.font.init()
w=320.0
h=200.0
x=0
y=0

window = pygame.display.set_mode((int(w*2),int(h)))
pygame.display.set_caption("Trial")
screen = pygame.display.get_surface()
clock=pygame.time.Clock()
snow_surface = load_image(snow_file_name)

#Main loop
while True:

#Event handling
clock.tick(60)
for event in pygame.event.get():
if event.type==QUIT:
kill()
return
if event.type==KEYDOWN:
if event.key==K_ESCAPE:
kill()
return
keys[event.key]=True
elif event.type==KEYUP:
keys[event.key]=False
print event

if keys[K_w]:
y = y - 5
if y 0:
y = 0

if keys[K_s]:
y = y + 5
if y > 200:
y = 200

if keys[K_a]:
x = x - 5
if x 0:
x = 0

if keys[K_d]:
x = x + 5
if x > 640:
x = 640


screen.blit(snow_surface, (x,y))
pygame.display.flip()


if __name__=="__main__": main()





It is not well commented, which is unusual for me, hopefully I'll fix that up in the next day or so. I was excited and rushing. It also has some nasty hard coded hacks in it like the limits on x and y movement.

My goal is to get a Wolfenstein 3d like engine up and running. I think I have the inner workings figured out mathematically speaking. I am pretty sure these types of engines are called raycasters but I don't want to go poking around too much until I try out what I think will work. It would seem like cheating.

rmckee78

rmckee78

 

Chapter 4 Sample

The last couple of days I have been working through the program at the end of
Chapter 4 of the OpenGL book. It includes almost all of the concepts presented so far
so it makes a good review. Its over 800 lines of code so this will be a long entry.

The define/include section contains an entry I have not seen before: #inlcude
The comments identify it as Windows constants. I fished around for a while in various
help files and web sites but I could not find a more detailed definition of the file,
so I opened it up to take a look. It seems to be a large number of #defines dealing
with a large variety of subjects. So group of Windows constants it is.

The variable declaration section contains an enumerator primtypes_t that will be used
to keep track of the current primitive type when drawing.

The WinMain section is fairly straightforward. It calls his SetupWindow() function
and then enters the message loop. Here he deals with any messages, renders the scene,
swaps the buffers, and deals with window closing through the KillWindow() function.

The first functioned defined is WindProc. The variables declared at the beginning
are static so they do not have to be created every time. The usual system stuff is dealt
with here like minimizing, powersave mode etc. Closing the window is handled by posting
WM_QUIT to the message queue which will cause the message loop to call the KillWIndow()
function.

The interesting thing in this function is handling the WM_CHAR message. From the
Win32 SDK Help:



So this is where he handles the keyboard input that lets you change the display. There
is a switch statement in the DisplayScene() function that uses this information.

The next function is SetupWindow(). Much of what appears here has been covered earlier in
the book. It is here that he fills out the window class structure, registers the class etc.
He has added error handling for this program. This is done by having a message box
displayed when a function returns an error value.

The SetupWindow() function also sets up the coordinates for the window. This is
something I had not seen before and involves the structure RECT:
typedef struct _RECT { // rc

LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT;



Obviously this is used to define a rectangle.

He dimensions the rectangle adjusted for borders and style. This is done with
BOOL AdjustWindowRectEx():

He can then use the window rectangle (which was passed by reference) in the
CreateWindowEx() function.

After creating the window the call is made to get the device context. The pixel format
is set and chosen. The rendering context is created and set to current.

Then ShowWindow() is called. It is set as the foreground window and set as the keyboard
focus. SetFocus():


The perspective is set for the screen size with ResizeScene(). Finally he calls
InitializeScene().

InitializeScene() is the next function defined. It is used to set the values that
only need to be dealt with once. This includes things like point size, antialiasing,
line width etc. It also includes some stuff like shading that have not been covered
in the book yet.

The next function definition is ResizeScene(). For the most part this includes stuff
that looks like it will be covered in the next few chapters. The viewport size is set.
The projection matrix is set to the identity matrix. There is a function call for
gluOrtho2D() it is passed the left, right, top, and bottom coorditantes of the scene.
I am going to assume that it uses this information to construct a matrix that is multiplied
by the current matrix (projection) to give a 2D orthographic viewing region with the
clipping planes defined by the parameters passed to it.

Finally he selects the modelview matrix and sets it equal to the identity matrix.

The next function is DisplayScene(). This is pretty straightforward. Depending on what
g_currentPrimitive's current value is (an enumerator value set by keyboard input) he draws
a sample of one of the primitives presented in the chapter. Some of these are done with
random vertices, some not (random could be problematic if used for for the quadrilaterals).

The final function is KillWindow(). I was really looking forward to this one because
I have been having some problems getting my windows programs to exit correctly. I
have to open the task manager and end the process manually. However I found that I am
doing exactly what is in this function:

1) Restore original display settings
2) Release the rendering context
3) Delete the rendering context
4) Release the device context
5) Destroy the window
6) Unregister the window class

I guess that something may have changed since this book was published, or this could
be a problem with Dev-C++ wanting it done another way. I used all the error handling
but do not get an error message when I click on the X and the window fails to close.

So far I have only been using the Win32 SDK Help file as a way to look up functions and
other information. However I found (by accident) that it can be read like a book by flipping
through pages. It looks like its practically an instruction manual for Windows programming.
My next entry will detail my adventures in solving my window closing problems. Hopefully
with help from the SDK help file.

rmckee78

rmckee78

 

Math, states, primitives, Photoworks, and XML

The weekend was pretty busy but I did manage to get some work in on programming. I moved through chapter 3 of OpenGL Game Programming. This chapter covers some of the mathematics of 3D game programming. It was all pretty standard: vectors, cross product, dot product and matrix transformations. There is so much information available on this that I am not going back through it all here. While I do not know much about 3D programming yet, I assume that this stuff is fundamental. If you are working on learning 3D programming I would make sure that you really understood this before moving on. I have a feeling that 3D programming will require a deeper understanding of math then what is presented in the book, but it at least gives you a primer and an idea what to look for. Don't just read the chapter, draw some shapes on graph paper and rotate, translate, scale etc. them by hand. I cannot imagine being an engineer with out a strong intuitive understanding of calculus, and I imagine that the same holds true for 3D programming and matrix operations.

Chapter 4 covers the OpenGL state machine and graphics primitives. I really think that I am hitting the portion of this book where there just is no best order to explain stuff. Some times a topic involves enough different things that you have to understand a little about one thing so you can learn about a second subject which allows you to be taught more about the first subject. That seems to be the situation in Chapter 4.

Basically the state machine has hundreds of settings that affect how OpenGL renders. The chapter goes over how to query the state machine about the current value of many of these settings.

This is done with a set of functions (all return type void) that accept the name of the setting (type GLenum) and a pointer to an array to hold the information. The different functions just cover different data types (Bool, double, float, and int) that can be held in the array.

There is another query function glIsEnabled() that allows you to see if a flag is set or not on some of the settings.

The chapter doesn't go into much more detail than this on the state machine. I assume this is so we are familiar with it as more information is presented.

Drawing OpenGL primitives follows a fairly simple procedure:

Pass the primitive type to glBegin() (its a void return type)
Set the vertices of the primitive with the glVertex() function (void again)
End the shape with glEnd() (void)

The book does state that there is a limited number of functions that can be used inside the glBegin()/glEnd pair. Using another function will generate an error (I am assuming at compiling, need to test this).

One thing I am trying to look into is what happens if you specify a triangle but only give 2 vertices (or three that are co-linear). Obviously it cannot draw a triangle with this information. However with everything having return type void, how do I handle the error. Perhaps you just have to write error checking code for this one (to make sure they are not co-linear).

The book goes over points, lines, triangles, and quadrilaterals. It also touches on antialiasing, face culling, and edge hiding. I think these were presented more to just define what they are than to actual instruct in their use.

In other programming and 3D related news I have had some stuff come up at work. Just got the PhotoWorks stuff in for SolidWorks. For those of you not familiar with it SolidWorks is a 3D solid modelling design program and PhotoWorks is a fancy renderer for it that lets you apply better textures and lighting to your models. Should be fun to work with. Also it looks like I need to come up with some kind of application to handle a site survey tool we made in house that will (finally) go into use next month. I want to try to integrate the gauge with our total site survey process (can't go into more detail due to legal stuff) in one program. Our systems programmer (very busy lady) suggests that I look into XML to handle the data so some of that might make it into this journal over the next few weeks.

Edit: I went to see Bridge to Terabithia with my wife last night. I loved this book when I was a kid and the movie did a pretty good job with it.

rmckee78

rmckee78

 

Tet

I don't really have any time to spend on programming today because my wife and I have to get ready for our Vietnamese new year party. Tet is the Vietnamese new year celebration. For many Americans the word Tet has a negative connotation, however it is a period of celebration and renewal.

I should probably explain that my wife immigrated to America from Viet Nam with her family when she was 12. Otherwise it wouldn't make sense that we were celebrating it.

Of course its not just Tet, many Asian cultures will be celebrating the Chinese New Year during February (many of the celebrations are weeks long).

Why do I bring this up? If you are not doing anything this weekend, here is a chance to do something new. A fairly large number of Vietnamese have immigrated to this country and many towns have at least a small community. There will be many celebrations over the next few days, and many of them will be open to the public. It is a good chance to try another culture's food and see their traditions. I have found that American people are almost always welcomed at the parties and usually someone is eager to explain what is going on.

How do you find them?

I would suggest the Vietnamese Restaurant Locator. There will probably be signs up at the restaurants. Also if you have never eaten Vietnamese food before you should give it a try. It is very different from Chinese or Thai food. I suggest Pho (noodles) with beef (Bo) meatballs as a good starting place.

It is easy spot Vietnamese restaurants and groceries because they use the same characters for their alphabet that we do but with the phonetic marks (I have no idea how to get these from html). The French changed their written language while they were a colony.

Anyway here is a good chance to try something new and learn more about a country that to many Americans is only a place we went to war.

rmckee78

rmckee78

 

WGL, pixel formats, and some changes

Today I took a look at the next few sections of the book. My goal for the day was to get the first full program working. The first program creates a window and then draws a triangle and rotates it. As usual I want to understand how everything I use works. I did have to suspend this to a certain point. The actual drawing code works off of theories and functions not covered yet.

I have no experience at all with 3D graphics programming so I did not understand a lot of camera stuff. However I did have linear algebra and numerical methods in college so I was able to keep up with the general idea of what was going on. I drew the triangle on graph paper by reading the coordinates to make sure it worked like I thought it did, and drew a few frames of the rotation. Also I was able to understand the OpenGL function calls at a functional level as far as type etc.

WGL

It turns out that OpenGL cannot handle window functions and interface issue on its own. These still need to be handled by Windows itself. Windows has a set of functions (prefixed wgl-) that handle coordinating OpenGL rendering with the device it is presented on.

This is done with a rendering context on the OpenGL side and a device context on the Windows side. The Windows GDI uses a device context to hold settings for drawing modes and commands. OpenGL has a rendering context for its settings and commands. The two contexts both have the same pixel format (more on this later).

The wgl functions allow all of this to happen.

HGLRC wglCreateContext(HDC hDC);
//This gets passed the handle for the device context and returns the handle for the rendering context



So as you can see the device context is needed to make the rendering context. So what the heck is HGLRC?

Well we can make an educated guess that the H stands for handle again, based on the Hungarian Notation.

Searching Win32 help for device context gives us:


While this does not tell us what the GLRC type means exactly, I am going to go on the assumption that it is also a structure and therefore may contain several data types. So my guess is that HGLRC is probably a pointer to a structure that contains the information that OpenGL needs to interface with the device context. This would make sense with the definition for the rendering context.

The wglMakeCurrent() function will make your rendering context the current rendering context that OpenGL uses. You will need to pass it the rendering context and the device context. These nees to have the same pixel format. They do not have to be the rendering context matched with the device context used to create this. Obviously there is opportunity for error here. This function is a BOOL. It returns false if it fails. I was unable to determine if it fails by being passed a rendering context and a device context of different pixel formats.

wglDeleteContext() will delete your rendering context when you are done with it. It is also a BOOL. You need to make sure that it is not the rendering context set to current.

You should create the context and set it to current when the window is created, then reverse the process when the window is destroyed.

Pixel Formats

The book covers this pretty well. Basically the pixel format is a structure that contains all the parameters for the pixels drawn. You set this up and then pass it to ChoosePixelFormat() with your device context handle. However it is possible that your device may not support that exact format. This is whats cool. The function returns and int index that fits the closest available format. You then pass it to SetPixelFormat() to set it. This returns a BOOL for error checking.

As I said before the actual drawing part was not really covered and I will hold off on how all that works. However I didi have a few problems ggetting the program to run and I will address them now.

It turns out that the program calls an old auxiliary header for OpenGL called glaux.h that is no longer in use. It also calls some Windows functions that are no longer in the headers the book asks you to include (the book is a few years old at this point). However thanks to the MSDN it is easy to track down the unknown function names and add the needed libraries and includes. Here is what my include section looks like now:
#define WIN32_LEAN_AND_MEAN //trim down the libraries
#include //main windows headers
#include
#include //OpenGl include
#include //OpenGL utilities



and these are the libraries I have:


You will notice that libglaux.a was something I was able to find. However I could not locate the glaux.h header. There are a whole bunch of work arounds out there for this (you can search here on this page for some) however I was able to find all the functions I needed in other libraries so I went with that.

I am really enjoying this book and with a little bit of research the age difference doesn't really seem to hinder learning from it. In fact it makes it better because I have to think harder and research what all my functions actually are.

rmckee78

rmckee78

 

Stupid typos and moving forward

After downloading the super helpful Win32 help files I was ready to start my programming work for the day.

Goal: Get a real window (not a message box) up and understand every line of code I used. Then mess around with it a bit to increase my understanding of how all the parts work.

After reading through the section in the book and a few examples on other sites I found something I was confused about. There were many data types here that I had never heard about before. Since I wasn't about to call a function that had a return type that I didn't understand I started poking around.

I am sure most of you already know what I found, however I am writing this in hopes it could help someone with the same questions as me. Turns out there is something called Hungarian Notation. You can read more about it here. Basically for my purposes it means that the h means that it is a handle which is a pointer. This cleared up some questions.

At first I wondered why they did this. Most of these things seem to be types that already exist renamed. I guess it is for two reasons:

1) Clarity, so you know what a variable is used for
2) They can change what these types mean and we don't all have to change our programs. Lets them change Windows.

I don't know if these are the reasons. Just my guess (based on the reasons that I use type definitions myself)

I was still left with one type I had not heard of: ATOM.

ATOM RegisterClassEx(CONST WNDCLASSEX *lpWClass);



What the heck is ATOM? Well thanks to the WIN32 SDK Help I have an answer:



So my guess here (could be totally wrong) is that all of my class information is stored in an atom table and the integer is returned so Windows knows how to find it. Couldn't really find anything on this so if it works another way I'd be interested in knowing.

Well once I got all that cleared up the code was pretty straight forward. Well except one small problem. Turns out I had typed CreateWindowEX instead of CreateWindowEx. So I spent about an hour trying to figure out what #include or
library I had missed. Searching MSDN and previous posts here and banging my head against the keyboard. Finally in frustration I posted for help, thanks to EasilyConfused for spotting my typo. Moral of the story: Assume its a typo first.

So I got the program up and running and BAM! I have a window. While reading the chapter and typing in the code I noticed that WndProc (the event handler) offered a possibility for having some fun (fun being relative).

The message cases all start with WM_, a quick search on the Win32 help shows that there are a LOT of possible messages available, including one for the left mouse button being pressed. So I added the following code to WndProc:


case WM_LBUTTONDOWN:
MessageBox(NULL,"\tYou Pressed a Button", "Button Notice", NULL);
return 0;



Nothing to be proud of but it works and I have hardware interaction with my windows application from an input device (the mouse). I am not sure that this is the way that it is done in a game but at least I have interaction.

It looks like my next step will be learning something called WGL (haven't read the section yet just saw the title)and perhaps drawing something on the screen.

rmckee78

rmckee78

 

First entry

Well, this is my first journal entry. I have been fooling around with programming for a while, and I took a few C and C++ classes in college. I use MATLAB at work so I have some programming background (not much).

I currently work as a mechanical engineer designing homeland security barriers (big cables and chunks of concrete to stop vehicle bombs). I am also preparing to take the Patent Bar Exam to expand my career options (and my wallet). I have always made games for my own enjoyment (and my friends), so far these have been of the board, card, and PnP RPG variety. I have always been interested in video games.

This marks the start of my serious attempt at learning how to program. Everything I have done up till this point has been in a console box (or high level interpreted stuff like MATLAB). One of my first larger goals is to learn how to interact with Windows. This will give me some immediate gratification (useful to keep me going) and some understanding of how Windows works (chances are there is not much career future in DOS games).

Since I have a basic knowledge of C and C++ I will be using these languages to learn with. I will be using the Dev-C++ compiler because I am somewhat (but not very) comforatable with it. I downloaded Visual Studio Express the other day
but could not get some things I already knew how to do working on it. Also I could not seem to make it find . This is a hassle I don't need while I am starting.

I have purchased a whole bunch of game programming books over the years. I would start on one, then school would get in the way, and I would be put it aside. I have a good enough library from this (and picking things up when they didn't sell at the major retailers and hit the $10 rack) to start with. I spent last night looking through them for one that seems to have a good overview of starting out in Windows programming (getting a window to open would be nice). I selected OPENGL Game Programming by Hawkins and Astle, I liked the look of its Windows section the best. I will base (but not limit) the first part of my study on this book. I also have at my disposal a print out of the NeHe tutorials, and a book OpenGL Programming Guide 5th ed. that is available at work.

After reading through the first few sections my first attempt will be to make the Hello World pop-up box.


//Hello World in Windows
#define WIN32_LEAN_AND_MEAN //trim down the libraries
#include //main windows headers

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//message box with Hello World
MessageBox(NULL,"Hello World", "First",NULL);
return 0;
}





As I read through the function description for WinMain I notice that lpCmdLine is a string that holds any command line parameters. Time for an experiment:


//Hello World in Windows
#define WIN32_LEAN_AND_MEAN //trim down the libraries
#include //main windows headers

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
//message box with command line string
MessageBox(NULL,lpCmdLine, "First",NULL);
return 0;
}





Good, by running my executable from the command line I can dicatate the message box contents via command line parameters. It is always nice when stuff works like you expect it to.

rmckee78

rmckee78

Sign in to follow this  
  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!