Skip to main content
GameDev.net gamedev.net
🔒 Locked

Yet another OOP question.

Started by Scienthsine Sep 19, 2011 at 11:01 PM 10 replies 2.5k views
Original Post
Scienthsine
Scienthsine
I'm in the middle of writing a small graphics lib for my future games, and just found myself writing a Shader object. Something it rubs me wrong. What is the point in me wrapping glCreateShader into Shader::Create(), and glUseShader into myShader.use()? I think I'm biased towards more procedural code, so maybe that's just it... Ideally I won't ever touch opengl directly from the game code itself. Only the graphics lib will actually use the gl* commands... so is there any real benefit to the wrapping?

I'm interested in what other people do. I mean... it's already pretty OO imo...

[Edit] Yes and no seemed confusing.
Hodgman
Hodgman
Ideally I won't ever touch opengl directly from the game code itself. Only the graphics lib will actually use the gl* commands...
So... the graphics lib is your wrapper then. Are you asking if you should put another wrapper between this wrapper and GL? I heard you like wrappers...
Scienthsine
Scienthsine
Well my 'wrapper' will have a much higher level of functionality. ie: CreateSprite, CreateTileMap, etc...

Not quite sure what your getting at. Do you not believe in 'wrappers'? You seem to imply that all software is just a wrapper on top of the machine level assembly data.

I'm quite sure most people 'wrap' the gl commands in some sort of higher level draw commands. My question is: In those higher level functions, do most people call the gl* commands in their native C style API, or do they wrap those commands and GLuint datas into C++ classes? Or rather than 'most people' do 'you' (other gamedevs)?
doeme
doeme
Using wrappers or don't using wrappers has nothing to do with OO or procedural programming, but IMO there are benefits you get from wrapping stuff like shaders into classes.
Of course wrappers do not give you more functionality, as there already is, but it generally makes development easier.
First your coders do not need to know every lowlevel library that's used in your framework, which in turn makes it easier to switch the implementation behind your code. Also I often add some convenience functions to perform some of the operations more easily, for example creating a shader from a file involves quite a few gl-commands so its much easier to just say shader.load(filename) . Since you your wrapped function hopefully works well and does some error-handling you do not need to duplicate as much code every time you want to perform the stuff behind the wrapped function.
Another benefit of wrappers is easier debugging, since you can add some debug-code or even some unit-tests to the wrapper function. Say your wrapped GL-function depends on a certain state of OpenGL you can add some (conditionally compiled) glGetErrors etc. to your function.
japro
japro
I do both. Creating for example a shader involves a lot of boilerplate code so it's a prime candidate for "wrapping". But I'm not going to wrap away glViewport into "myViewport" with the exact same interface...
alh420
alh420
There is no point to just "wrap".
That is, to have a 1:1 mapping between the gl-commands and your methods.

The reason to write a class would be to add functionality, make syntax cleaner and make it easier to use for what you want to use it for.

For shaders, one example could be cleaner and more type-safe handling of shader parameters.

Or maybe advanced loading, like stitching shaders from shader fragments
Blodyavenger
Blodyavenger
I use wrapper for gl functions because it's more clear imo and I simply have readable and usable functions behind it. On the high level, I only have my own functions to work with. OpenGL and OS code are at the bottom level which I don't have to work with and I like it that way
Hodgman
Hodgman
Not quite sure what your getting at. Do you not believe in 'wrappers'?
I was just pointing out that if you're writing a graphics library (which the game-programmer will use instead of using GL directly), then that graphics library is already a GL wrapper.

As Olof Hedman posted, there's no point making a 1:1 wrapper; a wrapper should provide a different abstraction to the lower level that it is wrapping, which is what your graphics library will be doing.
Inside the graphics library though, wrapping up GL simply to make it OOP-ified (but still having a 1:1 mapping with GL commands) is of dubious benefit.
Will this wrapper-in-a-wrapper make development of the graphics library easier, by making you more comfortable with the GL API, or will it make development harder, by obfuscating the actual GL calls being made? This probably depends on the individual and their programming style.
Neilo
Neilo
I have a few classes to manage stuff like creating and binding resources like shaders, buffers, textures and things like that but they're very lightweight.

On top of that I submit render commands that are pretty much stateless which specify materials, models, positions and the like.

It seems to work well enough to have a higher level abstraction like that, I was able to implement a D3D renderer in no time at all.

In comparison to this, I found making a low level wrapper on top of an API a bit... pointless.
SimonForsman
SimonForsman

I'm in the middle of writing a small graphics lib for my future games, and just found myself writing a Shader object. Something it rubs me wrong. What is the point in me wrapping glCreateShader into Shader::Create(), and glUseShader into myShader.use()? I think I'm biased towards more procedural code, so maybe that's just it... Ideally I won't ever touch opengl directly from the game code itself. Only the graphics lib will actually use the gl* commands... so is there any real benefit to the wrapping?

I'm interested in what other people do. I mean... it's already pretty OO imo...

[Edit] Yes and no seemed confusing.


The main advantage of a thin wrapper is that it separates your gamecode from the platform it runs on, You have to avoid making the wrapper too thin though or the benefit will be lost. (If you tie it too closely to a specific API it might become difficult to change that API without rewriting the wrapper interface). Personally i wouldn't expose shaders in my graphic libraries but rather use materials (The different texture/normal/whatever maps used) and effects (each effect can then contain multiple sets of shaders the renderer can choose from based on the users hardware or quality settings and each set would contain one shader per render pass and the blend settings required when multiple passes are used), I'd also make it more of a graphics engine and include sorting, culling, batching, interpolation, lighting, animating, cameras, etc in it.
[size="1"]I don't suffer from insanity, I'm enjoying every minute of it.
The voices in my head may not be real, but they have some good ideas!
Yours3!f
Yours3!f
I use a high level wrapper. I don't directly mask opengl commands, rather I wrap certain functionality into classes.
Something like:
mesh.load_obj("...");
mesh.render();
or
shader.load("...");
shader.bind();
or
image.load("...");
image.bind();

and stuff like that. I think that wrapping opengl commands directly is useless, even if you want to use directx besides opengl.
alh420
alh420
I actually worked in a project (not game) where we had a .h-file that redefined every gl-call to another prefix.
The idea was that it would be easier to port to platforms with slightly nonstandard gl, but I don't think we ever changed that file
At least not in 99% of the cases it was used.

A pretty low level wrapper can actually be useful though if you want to write a platform independent game engine on top of it, to minimize porting work, but designing this is not trivial and better saved to maybe the third or forth iteration of your game engine

If you want a lot of platforms (including desktop) for little effort, you could write your engine to run on OpenGLES2, and a few #ifdef:s for setup and such that differ

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.