Jump to content

  • Log In with Google      Sign In   
  • Create Account

Kazade's GDNet Life



My current project - KGL

Posted by , 28 December 2007 - - - - - - · 170 views

Recently I've been working on a sort of consolidation of all of the useful code that I have lying around. I've called it KGL or Kazade's Game Library. It's a library that allows me to easily do common stuff when writing games. For example, it will create an OpenGL window for me, it comes with a built-in Quake-like console, I have 2D TTF fonts, TGA and 3D .obj model loading and a simple resource manager. It could do with more documenting and tidying up before I release it for others to use, but it seems to be working really well for me.

Here's a little example of how it works, below the code is a screen shot of what the output looks like:


#include <boost/foreach.hpp>
#include "MyGame.h"

using namespace kgl;

MyGame::MyGame():
Game("app-config.txt") {
m_ResourceManager = shared_ptr<resources::ResourceManager> ( new resources::ResourceManager);
}

MyGame::~MyGame() {

}

bool MyGame::onInitialize() {
//Set the caption at the top of the window
getWindow().setTitle("KGL - Lesson 01");
getWindow().setWidth(1024);
getWindow().setHeight(768);
getWindow().applySettings();

createConsole();
getConsole().setBackgroundImage("console-back.tga");
getConsole().setBackgroundColour(colours::White);

getConsole().getFont().setHeight(12);

m_Model = m_ResourceManager->load<resources::StaticModel3D>("farn.obj", "fern_model");

BOOST_FOREACH(shared_ptr<resources::ModelMaterial> mat, m_Model->getMaterials()){
shared_ptr<Texture2D> newTex = m_ResourceManager->load<resources::Texture2D>(mat->m_TextureFile, mat->m_Name);

if (!newTex) {
std::cout << "Could not load texture: " << mat->m_TextureFile << std::endl;
}
m_ModelTextures.push_back(newTex);
}

return true;
}

void MyGame::onRender() {
static float angle = 0.0f;

(angle > 360.0f)? angle -= 360.0f : angle+=0.5f;

//Clear the colour and depth buffer and clear to grey
getWindow().clear(colours::Grey);
//OpenGL code goes here
glLoadIdentity();

glPushMatrix();
glTranslatef(0, -0.5, -2.0f);
glRotatef(angle, 0, 1, 0);


glEnable(GL_ALPHA_TEST);
glAlphaFunc(GL_GREATER, 0.3);
for (uint i = 0; i < m_ModelTextures.size(); ++i) {
m_ModelTextures[i]->bind();
m_Model->renderByMaterial(i);
}
glDisable(GL_ALPHA_TEST);

glPopMatrix();
}





Other stuff that you can't see includes:

* A strings namespace that contains a load of handy string functions
* A filesystem namespace that contains functions such as isFile(), isDir(), and path manipulation functions
* A game timer
* An ini config file reader
* An event handling system
* A load of predefined colours (see the Window::clear method above)
* Probably more stuff that I can't remember [smile]


Some nice C++ string functions

Posted by , 26 December 2007 - - - - - - · 262 views

I just thought I'd post some code that has built up over the last few days as I have been working on my game framework. Below is a load of cool little string methods which act/look like the Python string methods. There may be some bugs but they seem to work OK. Let me know what you think...


Usage:

string s = "Hello world";
vector<string> words = strings::split(s);
//words now contains "Hello" and "world"

string s = "1.0";
float f = strings::toFloat(s);
//f now holds 1.0

string s = "#some comment";
if (strings::startsWith(s, "#")) {
continue; //This if statement will be entered
}

etc.



strings.h

#ifndef STRING_H_INCLUDED
#define STRING_H_INCLUDED

#include <string>
#include <vector>

using std::string;
using std::vector;

namespace strings {

bool startsWith(const string& s, const string& s2);
bool endsWith(const string& s, const string& s2);
vector<string> split(string str, string delim = " ");
void ljust(string& s, uint length, char padChar = ' ');
void rjust(string& s, uint length, char padChar = ' ');
string strip(const string& s);
void replace(string& s, const string& find, const string& replace);

float toFloat(const string& s);
int toInt(const string& s);

int findCountOf(const string& s, const string& word);
}

#endif // STRING_H_INCLUDED



strings.cpp

#include <string>
#include <vector>
#include <sstream>
#include <stdexcept>

using std::string;
using std::vector;
using std::istringstream;

namespace strings {
/**
Returns true if s starts with the string s2
*/

bool startsWith(const string& s, const string& s2) {
return s.find(s2) == 0;
}

/**
Returns true if s ends with the string s2
*/

bool endsWith(const string& s, const string& s2) {
return s.find_last_of(s2) == (s.length() - s2.length());
}

/**
Splits a string on the delimeter and returns each part in a
vector.
*/

vector<string> split(string str, string delim = " ") {
string::size_type cutAt;
vector<string> results;
while( (cutAt = str.find_first_of(delim)) != string::npos ) {
if(cutAt > 0) {
results.push_back(str.substr(0,cutAt));
}
str = str.substr(cutAt+1);
}
if (str.length() > 0) {
results.push_back(str);
}

return results;
}

/**
Adds padding characters to the left of a string until
the string is a certain length. If the string is longer
than the length passed then the string is left unchanged
*/

void ljust(string& s, uint length, char padChar = ' ') {
std::string::difference_type whitespace = length - s.size();

if (whitespace > 0)
s = s + string (whitespace, padChar);

return s;
}

void rjust(string& s, uint length, char padChar = ' ') {

std::string::difference_type whitespace = length - s.size();

if (whitespace > 0)
s = string (whitespace, padChar) + s;

}

/**
Strips spaces from the beginning and end of a string
*/

string strip(const string& s) {
string sep = " ";
const std::string::size_type first = s.find_first_not_of(sep);
return (first == std::string::npos) ? s : s.substr(first, s.find_last_not_of(sep) - first + 1);
}

/**
Replace occurrances of 'find' with 'replace' in 's'
*/

void replace(string& s, const string& find, const string& replace) {
string::size_type j;

for (; (j = s.find(find)) != string::npos;) {
s.replace(j, find.length(), replace);
}
}

/**
Attempts a type-safe cast from string to float, throws
a std::runtime_error on failure
*/

float toFloat(const string& s) {
float result;

istringstream iss(s);

if ((iss >> std::dec >> result).fail()) {
throw std::runtime_error("Error converting string to float");
}

return result;
}

/**
Attempts a type-safe cast from string to integer, throws
a std::runtime_error on failure
*/

int toInt(const string& s) {
int result;

istringstream iss(s);

if ((iss >> std::dec >> result).fail()) {
throw std::runtime_error("Error converting string to integer");
}

return result;
}


/**
Find the number of occurances of a word in a string (s)
*/

int findCountOf(const string& s, const string& word) {
int count = 0;
string::size_type wordPos = 0;

while (wordPos != string::npos) {
wordPos = s.find(word, wordPos);
if (wordPos != string::npos) {
++count;
// start next search after this word
wordPos += word.length();
}
}

return count;
}
}







Cross-platform HiResTimer

Posted by , 09 November 2007 - - - - - - · 494 views

It's been a while since I've updated this, I'll make an effort to do so more often.

If anyone reading this has read OpenGL Game Programming or Beginning OpenGL Game Programming, you may remember the game timer class that is used in the source code by Dave Astle.

I've just spent a little while making this work on Linux by reimplementing QueryPerformanceFrequency, and QueryPerformanceTimer as private methods the code for these functions has been adapted from the equivalents in the Wine implementation.

I haven't tried recompiling on Windows yet, but I assume it will work as I haven't changed any of the Windows code. Anyway, here it is, I hope it's useful for someone:


/****************************************************************************
HiResTimer.h

Cross-platform implementation of the HiResTimer originally written
by Dave Astle for the book OpenGL Game Programming.

Author : Luke Benstead

Wrapper for the high-resolution timer. Can't be used (on Windows) if the
hi-res timer doesn't exist.

*****************************************************************************/



#ifndef __TIMER_H_INCLUDED__
#define __TIMER_H_INCLUDED__

#ifdef WIN32
#include <windows.h>
#endif

#ifdef unix
#include <sys/time.h>

/*
This is the definition of LARGE_INTEGER
for unix platforms only, Windows already has
this defined.
*/

typedef union _LARGE_INTEGER
{
struct
{
unsigned long LowPart;
long HighPart;
};
struct
{
unsigned long LowPart;
long HighPart;
} u;
long long QuadPart;
} LARGE_INTEGER;

//This is the number of ticks per second for
//unix platforms
const long TicksPerSecond = 10000000;
#endif

class HiResTimer
{
public:

/*****************************************************************************
Init()

If the hi-res timer is present, the tick rate is stored and the function
returns true. Otherwise, the function returns false, and the timer should
not be used.
*****************************************************************************/

bool Init()
{
if (!QueryPerformanceFrequency(&m_ticksPerSecond))
{
// system doesn't support hi-res timer
return false;
}
else
{
QueryPerformanceCounter(&m_startTime);
return true;
}
} // end Init()

float GetElapsedSeconds(unsigned long elapsedFrames = 1)
{
static LARGE_INTEGER s_lastTime = m_startTime;
LARGE_INTEGER currentTime;

QueryPerformanceCounter(&currentTime);

float seconds = ((float)currentTime.QuadPart - (float)s_lastTime.QuadPart) / (float)m_ticksPerSecond.QuadPart;

// reset the timer
s_lastTime = currentTime;

return seconds;
} // end GetElapsedSeconds()

/***************************************************************************
GetFPS()

Returns the average frames per second over elapsedFrames, which defaults to
one. If this is not called every frame, the client should track the number
of frames itself, and reset the value after this is called.
***************************************************************************/

float GetFPS(unsigned long elapsedFrames = 1)
{
static LARGE_INTEGER s_lastTime = m_startTime;
LARGE_INTEGER currentTime;

QueryPerformanceCounter(&currentTime);

float fps = (float)elapsedFrames * (float)m_ticksPerSecond.QuadPart / ((float)currentTime.QuadPart - (float)s_lastTime.QuadPart);

// reset the timer
s_lastTime = currentTime;

return fps;
} // end GetFPS

/***************************************************************************
LockFPS()

Used to lock the frame rate to a set amount. This will block until enough
time has passed to ensure that the fps won't go over the requested amount.
Note that this can only keep the fps from going above the specified level;
it can still drop below it. It is assumed that if used, this function will
be called every frame. The value returned is the instantaneous fps, which
will be <= targetFPS.
***************************************************************************/

float LockFPS(unsigned char targetFPS)
{
if (targetFPS == 0)
targetFPS = 1;

static LARGE_INTEGER s_lastTime = m_startTime;
LARGE_INTEGER currentTime;
float fps;

// delay to maintain a constant frame rate
do {
QueryPerformanceCounter(&currentTime);
fps = (float)m_ticksPerSecond.QuadPart/((float)(currentTime.QuadPart - s_lastTime.QuadPart));
} while (fps > (float)targetFPS);

// reset the timer
s_lastTime = m_startTime;

return fps;
} // end LockFPS()

private:
#ifdef unix
/*
These next 2 functions are reimplementations of the Windows
functions of the same name for unix. If we are compiling
on Windows these 2 methods will not be compiled and the
Windows built-in ones will be used instead.
*/

bool QueryPerformanceFrequency(LARGE_INTEGER* frequency)
{
frequency->QuadPart = TicksPerSecond;
return true;
}

bool QueryPerformanceCounter(LARGE_INTEGER* currentTime)
{
unsigned long long Ticks1601To1970 = (369 * 365 + 89) * 86400 * (unsigned long long) TicksPerSecond;
struct timeval now;
gettimeofday( &now, 0 );
currentTime->QuadPart = now.tv_sec * TicksPerSecond + Ticks1601To1970;
currentTime->QuadPart += now.tv_usec * 10;

return true;
}
#endif

LARGE_INTEGER m_startTime;
LARGE_INTEGER m_ticksPerSecond;
};

#endif





Just a quick entry

Posted by , 04 September 2006 - - - - - - · 204 views

Hey just thought id quickly post what I'm up to.

My game engine is improving steadily I have just started rewriting my dissertation project from scratch (which some of you may remember was a map editing system called SMES)

Here is a quick pic of my engine so far, I know its not that impressive but theres not much done yet :)



Luke.


Random post

Posted by , 26 June 2006 - - - - - - · 175 views

My last post here was back in January, so I thought I'd better post something. Since last time I completed writing a Deferred Shading Engine. After which I decided that I couldnt develop it any further, it made a good learning experience.

I'm currently spending a little bit of time per week writing a new engine. I have modularised it so much that I can remove any component (sound, video etc.) and it will still run without any other code changes. Each module contains its own message queue and any module can send messages to any other module via the kernel. Although this is only used occasionally at the moment, it could be useful tool in future.

Alongside this I am taking part in a commercial venture with a friend (i cant release details at the moment) and I'm also developing a method of streaming video from ANY webserver to any javascript enabled browser, which is still in the preliminary testing phase but should be an exciting utility if I get it to work :D


Also I am now part of the team developing content for Nehe. I'm very busy at the moment :D

I hope to post some interesting news soon,

Luke.



Life is always in the way of coding!

Posted by , 14 January 2006 - - - - - - · 184 views

Hi everyone,

I thought it might be an idea to add another post to my journal. Since last time i've moved to Pinner in North-west London, and continued work on my game engine without internet access. (grr)

I have written a very pretty and useful quake style console for the KEngine, I can link pretty much any function to a console command with in minutes so i'm quite pleased with it considering I was working with no resources. I've nearly finished static model loading (*.obj files) and will soon add animated md2 and ms3d model loading, when I have time.

If anyone know of ANY jobs in London please let me know, my contract runs out on Friday and then im jobless :( Any offers considered ;)

As soon as I have a new job i'm going to get the internet installed and (hopefully) then i'll have a version of the KEngine ready for testing.

Luke.






You wanted a pictar! :p

Posted by , 19 October 2005 - - - - - - · 215 views

Hey,

Here is a screenshot of my new engine...



Impressive huh? :)

There is actually more there than meets the eye. Features so far...

Task based kernel system (similar to Enginuity series)
Simple physics system (that square actually falls with realistic gravity)
Targa Image loading
Log System
Game Timer
Texture Management
Incomplete Collision Detection Functions (to merge with the physics system)

Ok so not that much, but ive written it in a week with none of my previous base code with me (im staying at a friends house) and about an hour a day, so im pleased with myself, and its the cleanest code i've ever written and its the first time i've written a proper physics system. (Instead of adding CVec3(0, -100, 0) to everything for gravity) :)


I'm a GDNet+ member!

Posted by , 13 October 2005 - - - - - - · 201 views

Hi all,

I've finally become a paid up member of GDNet. Stupid posts are sure to follow :)

Luke.





August 2016 »

S M T W T F S
 123456
78910111213
14151617181920
21222324252627
2829 30 31   

Recent Entries

Recent Comments

Recent Entries

Recent Comments



PARTNERS