Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

fireking

wrapping up those dirty dirty functions

This topic is 5493 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

im currently building a open gl wrapper, to make life easier. I have a few simple questions. There are several versions of the glColorx function. Each one allows you to specify colors by different types (and eventually maps each one, regardless, to a value between 0 and 1, being of float type). Anyways, ive taken the oppurtunity that lay before me, to clean this up with function overloading, and default parameters (there''s only one color function now, but several versions of it, the compiler will automatically know which one, depending on the data its given) I have my doubts on trusting the compiler. Here is an example... gl.Color(1.0f,1.0f,1.0f); Now, if the compiler interprets those numbers, each as floats, it would call the correct color function within the class, which would then call... glColor4f(1.0f,1.0f,1.0f,1.0f);//1.0f is default parameter in my class, for alpha now what if we do this gl.Color(1,300,70); which one is the compiler going to choose? Is it actually smart enough to know that im not using an unsigned char (or ubyte)? Im not sure, could someone sum this up for me? (i think you get the idea of what im doing) Also, what is an easy way of expressing the following: highest value for type double highest value for type int (i know its system dependent, but that doesnt help...) highest value for type unsigned int (again, system dependent?) so far, i''ve defined each function within my class:
	void Color(GLbyte red,GLbyte green,GLbyte blue,GLbyte alpha=127);
	void Color(GLdouble red,GLdouble green,GLdouble blue,GLdouble alpha=0);//find out range (highest value?)

	void Color(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha=1.0f);
	void Color(GLint red,GLint green,GLint blue,GLint alpha=0);//find out range (system dependent)

	void Color(GLshort red,GLshort green,GLshort blue,GLshort alpha=32767);
	void Color(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha=255);
	void Color(GLuint red,GLuint green,GLuint blue,GLuint alpha=0);//find out range (system dependent)

	void Color(GLushort red,GLushort green,GLushort blue,GLushort alpha=65535);
but im not sure if the compiler is going to know which one to automatically choose when the user compiles his application using this wrapper

Share this post


Link to post
Share on other sites
Advertisement
oh also note im only interested in supporting visual studio .net''s "version" of C++

thats the compiler im using as well, if it helps

Share this post


Link to post
Share on other sites
gl.Color(1,300,70);

300 is a short. The compiler will look for a function that can accomodate it.

highest value for type double

#include<limits>
std::numeric_limits<double>::max()


highest value for type int

std::numeric_limits<int>::max()

highest value for type unsigned int

std::numeric_limits<unsigned int>::max()

but im not sure if the compiler is going to know which one to automatically choose when the user compiles his application using this wrapper

If it doesn't, it will tell you that the function call is ambiguous.



[ Start Here ! | How To Ask Smart Questions | Recommended C++ Books | C++ FAQ Lite | Function Ptrs | CppTips Archive ]
[ Header Files | File Format Docs | LNK2001 | C++ STL Doc | STLPort | Free C++ IDE | Boost C++ Lib | MSVC6 Lib Fixes ]


[edited by - Fruny on November 30, 2003 1:08:22 AM]

Share this post


Link to post
Share on other sites
If you type it yourself, append a specifier:

3.0f is treated as a float
if you append u, it becomes an unsigned type, not sure which though
Or you could use casting, eg static_cast300 would make it be treated as an unsigned byte

Share this post


Link to post
Share on other sites
just to bring up a minor point, but with this ''wrapper'' are you doing any more than calling one function from within each function?
If your not then, tbh, i dont see the point, as all you''ll be doing is adding an extra function call each time you want to call something OpenGL related, kinda pointless i feel...

Share this post


Link to post
Share on other sites
quote:
Original post by _the_phantom_
just to bring up a minor point, but with this ''wrapper'' are you doing any more than calling one function from within each function?
If your not then, tbh, i dont see the point, as all you''ll be doing is adding an extra function call each time you want to call something OpenGL related, kinda pointless i feel...



But that''s not the point. A good optimising compiler would inline the functions anyway. The idea is to unify the different glColor* functions into a single interface, letting the language semantics decide which function should be called.

One question I have with this is why are you using all the different representations of a color? One or two suffices for me. In the long run you are better choosing one representation and sticking to that throughout the code. Using different representations will only confuse you later on - e.g. was that value of 100 for red supposed to be a uint, uchar or short? It would have different meanings in each of these cases.

James

Share this post


Link to post
Share on other sites
I suppose the advantage of some formats might be bandwidth usage (assuming they aren''t all just converted to floats by the driver). 128 bits of data for glColor4f[v] or 32 bits for glColor4ub[v].

Share this post


Link to post
Share on other sites
quote:
Original post by jamessharpe
But that''s not the point. A good optimising compiler would inline the functions anyway. The idea is to unify the different glColor* functions into a single interface, letting the language semantics decide which function should be called.



ok, given that then, why use a class?
a namespace would do the same job, heck just putting the functions somewhere global would do the same job.

for example, OGL::Color(1.0f,1.0f,1.0f) would do the same job and removes the redundancy of having to have an OpenGL object laying around.

Share this post


Link to post
Share on other sites
it does much more than that...

it completely removes the possibility of redundant state changes, it unifies rundundant functions (glcolor, glvertex), it watches your ass (prevents you from sending null pointers where applicable, or negative values, and others). It doesnt operate at a per-vertex level, because that would be extreme speed loss (as someone mentioned earlier). When you call something like gl.Enable(SOME_CAPABILITY), it will only enable it if its not already enabled.

Things like this help to make opengl work better. Its like a shadow state layer over the opengl layer. Since its such at a low level, you're able to take advantage of this.

For instance, (another good example)

gl.BlendFunc(something,something)

if the current blend func is already something,something, there is no need to call it again, cuz we're already in this blending mode.

gl.BindTexture()

prevent binding of a texture that is already bound

things like this are not watched by your opengl drivers, you have to make sure it doesnt happen on your own.

check out this thread->
http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/001787.html


the wrapper even goes one step further, and makes extensions seem like their already part of open gl

gl.MultiTexCoord2f()


AND! if the extension isnt supported, the wrapper emulates the effect

i guess you could call this wrapper direct x, lmao...

[edited by - fireking on November 30, 2003 8:14:01 PM]

Share this post


Link to post
Share on other sites
taking ur point on trapping redundancies, have u considered the additional execution layers involved in wrapping the function into class functions? co assuming u''re wrapping at an extremely low level, such as Vertex(...) to substitute glVertex*, then wouldnt these be true:

1. class functions have an explicit passing of the ''this'' pointer making function initiation ever so slightly slower.
2. i dunno if object overloading works anywhere like virtual functions, but i suppose mapping the proper overloaded function could entail a speed hit.
3. though these hits are small, but at low levels, they may end up being called enuf times to accumulate their bloat

also, thinking about state changes verification, it is a nice thing to avoid state changes when its not already necessary. But that would perform some logic computation which would usually be quick. but are state changes really THAT taxing to make this necessary versus verifying?

just curious

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

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

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!