Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    73
  • comments
    131
  • views
    55001

Interfaces!

Sign in to follow this  
okonomiyaki

288 views

Ok, so tonight wasn't completely a waste. I've made some headway on designing a flexible and simple render system (among other things). I found what is key in good design: interfaces. I was minimizing interfaces because I'm not going for runs-on-any-os-with-any-rendering-api-as-well-as-your-mom. I realize that it's more important to get something small scale done on one system configuration (Windows and DirectX).

However, interfaces are still wonderful in my scenario. I underestimated how much they simplify and beautify everything. It forces me to be clear and concise because I can't do any hacks that depend on a certain implementation.

So, even though I will only be using DirectX, I came up with this tonight:

/* This specifies the on-screen back buffer */
static const unsigned int AXRENDERTARGET_DEFAULT = 0;

/* Structure defining the fullscreen modes */
struct AXFullscreenMode {
AXDimension2D Resolution;
unsigned int RefreshRate;
};

class AXRenderer {
public:
AXRenderer();
virtual ~AXRenderer();

/* These functions initialize and shutdown the renderer.
Initialize MUST be called before doing anything else with the renderer. */

virtual AXResult Initialize()=0;
virtual void Shutdown()=0;

/* Functions dealing with whatever rendering device/method the API uses.
These signal the API to either create a new one, re-create one according
to new settings, or destroy it. */

virtual AXResult CreateDevice()=0;
virtual AXResult RecreateDevice()=0;
virtual void DestroyDevice()=0;

/* These are the settings for the renderer (very important!).
It's public which allows you to add/change settings at will. The ValidateSettings()
function will make sure everything is there in a correct format so nothing goes
wrong when the renderer uses the settings. */

AXSettings RenderSettings;
virtual void ValidateSettings()=0;

/* Gets the current size of the screen */
AXDimension GetRenderingSize();

/* The rendering API must support some way of retrieving valid fullscreen modes
so that we know how to validate them. */

AXResult GetResolutionList(vector &ModeList);
AXResult IsResolutionSupported(const AXFullscreenMode &Mode);

/* Generic rendering functions */
virtual void ClearBuffers(unsigned int Buffers, AXColorARGB Color, float Depth, unsigned int Stencil)=0;
virtual void FlipBuffers()=0;

virtual unsigned int CreateOffscreenRenderTarget()=0;
virtual void DestroyOffscreenRenderTarget(unsigned int TargetID)=0;
virtual void UseRenderTarget(unsigned int TargetID)=0;

/* Matrix operations */
virtual void LoadViewMatrix(Matrix4 Mat)=0;
virtual void LoadWorldMatrix(Matrix4 Mat)=0;
virtual void LoadProjectionMatrix(Matrix4 Mat)=0;

protected:
AXDimension RenderingSize;
};





Obviously it hasn't been fleshed out yet, but the important part for now is the device creation and getting it up and running (and supported fullscreen toggle, etc.). I like the idea of having a settings class and just including that in any object that needs settings; it's so much more flexible than creating all these private variable and get/set accessors, etc. Since I'll be using my settings class a lot I'm thinking about extending it to support validation. I could write Constraint classes and every setting would be tied to a type of contraint, and just use the Constraint interface to check every setting.

It's also cool because it's easy to save the state of the class (I don't mean serialization) as you would just write out all the settings to the file (of course the settings class does this for you), and load them when it's created. That's what my Window class does, so it remembers if it was fullscreen and what size it was last time it ran.

Because I'm stressing abstraction now, I'm beginning to write as much code as possible to help with this. I whipped this up tonight to help with colors and such.

/* --------------------------------------------------------------
File: AXColor.h
Description: This file contains macros and inline functions that abstract dealing with RGB and RGBA colors.
It supports unsigned char compaction as well as floating point colors.
Date: June 29, 2005
Author: James Long
-------------------------------------------------------------- */



#if !defined(AXCOLOR_INCLUDED)
#define AXCOLOR_INCLUDED


typedef unsigned int AXColorRGBi;
typedef unsigned int AXColorRGBAi;
typedef unsigned int AXColorARGBi;

struct AXColorRGBf {
AXColorRGBf(float fr, float fg, float fb) : r(fr), g(fg), b(fb) {}
float r;
float g;
float b;
};
struct AXColorRGBAf {
AXColorRGBAf(float fr, float fg, float fb, float fa) : r(fr), g(fg), b(fb), a(fa) {}
float r;
float g;
float b;
float a;
};

typedef AXColorARGBf AXColorRGBAf;

typedef AXColorRGBi AXColorRGB;
typedef AXColorRGBAi AXColorRGBA;

inline AXColorRGBi AXColorToRGB(int r, int g, int b) {
return (0 | ((unsigned char)r << 24) | ((unsigned char)g << 16) | ((unsigned char)b << 8));
}
inline AXColorRGBi AXColorToRGBA(int r, int g, int b, int a) {
return (0 | ((unsigned char)r << 24) | ((unsigned char)g << 16) | ((unsigned char)b << 8) | (unsigned char)a);
}
inline AXColorRGBf AXColorToRGB(float r, float g, float b) {
return AXColorRGBf(r,g,b);
}
inline AXColorRGBAf AXColorToRGBA(float r, float g, float b, float a) {
return AXColorRGBAf(r,g,b,a);
}

inline unsigned char AXColorR(AXColorRGBi Color) {
return (unsigned char)((Color & 0xff000000) >> 24);
}
inline unsigned char AXColorG(AXColorRGBi Color) {
return (unsigned char)((Color & 0x00ff0000) >> 16);
}
inline unsigned char AXColorB(AXColorRGBi Color) {
return (unsigned char)((Color & 0x0000ff00) >> 8);
}
inline unsigned char AXColorA(AXColorRGBAi Color) {
return (unsigned char)(Color & 0x000000ff);
}

inline float AXColorR(AXColorRGBf Color) {
return Color.r;
}
inline float AXColorG(AXColorRGBf Color) {
return Color.g;
}
inline float AXColorB(AXColorRGBf Color) {
return Color.b;
}
inline float AXColorR(AXColorRGBAf Color) {
return Color.r;
}
inline float AXColorG(AXColorRGBAf Color) {
return Color.g;
}
inline float AXColorB(AXColorRGBAf Color) {
return Color.b;
}
inline float AXColorA(AXColorRGBAf Color) {
return Color.a;
}

inline AXColorRGBi AXColorFloatToInt(AXColorRGBf &Color) {
return AXColorToRGB((unsigned char)(Color.r*255), (unsigned char)(Color.g*255), (unsigned char)(Color.b*255));
}
inline AXColorRGBAi AXColorFloatToInt(AXColorRGBAf &Color) {
return AXColorToRGBA((unsigned char)(Color.r*255), (unsigned char)(Color.g*255), (unsigned char)(Color.b*255), (unsigned char)(Color.a*255));
}

inline AXColorRGBf AXColorIntToFloat(AXColorRGBi &Color) {
return AXColorToRGB((float)((Color & 0xff000000) >> 24), (float)((Color & 0x00ff0000) >> 16), (float)((Color & 0x0000ff00) >> 8));
}
inline AXColorRGBAf AXColorIntToFloat(AXColorRGBAi &Color) {
return AXColorToRGB((float)((Color & 0xff000000) >> 24), (float)((Color & 0x00ff0000) >> 16), (float)((Color & 0x0000ff00) >> 8), (float)(Color & 0x000000ff));
}

inline AXColorARGBi AXColorRGBAToARGB(AXColorRGBAi &Color) {
return (((Color & 0xffffff00) >> 8) | ((Color & 0x000000ff) << 24));
}

#endif




I'm a little worried about matrices, vectors, and quaternions though. I have my own classes but they are weak. I don't mind using DX's classes, but that means I'd have to make the Renderer interface dependant on DX files. For now, since they would be included anyway, it's not horrible I guess. At some point I'll flesh out my own math classes. I'll just add a 'typedef D3DXMATRIX Matrix4' to the top of my code, and when I write my own I can switch it out.

Anyway, glad I finally got things going again...

Can't wait until I get to shaders! I'm thinking of even abstracting out the shaders and creating my own higher level language. Maybe not a language, but more of a description (XML?). This would then be compiled to the appropriate language for the renderer (HLSL or GLSL). This is just thought though, but I think that would speed up development so much... we'll see.
Sign in to follow this  


2 Comments


Recommended Comments

Quote:
Maybe not a language, but more of a description (XML?).
This is a good idea for scripting the shaders!

Share this comment


Link to comment
Yeah! I wish I thought of it first [grin]

I do have some interesting thoughts about streamlining effects in the game, as well making it really easy to specialize effects per-mesh instance. I look forward to working on that part of the system.

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • 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!