views:

202

answers:

6

I want to modify the glBindTexture() function to keep track of the previously binded texture ID's. At the moment i just created new function for it, but then i realised that if i use other codes that use glBindTexture: then my whole system might go down to toilet.

So how do i do it?

Edit: Now when i thought it, checking if i should bind texture or not is quite useless since opengl probably does this already. But i still need to keep track on the previously used texture.

A: 

I haven't ever worked with OpenGL, so not knowing anything about that function, here's my best guess. You would want to replace the glBindTexture function call with your new function's call anywhere it occurs in your code. If you use library functions that will call glBindTexture internally, then you should probably figure out a way to reverse what glBindTexture does. Then, anytime you call something that binds a texture, you can immediately call your reversal function to undo its changes.

dublev
+1  A: 

You can intercept and replace all calls to glBindTexture. To do this you need to create your own OpenGL dll which intercepts all OpenGL function calls, does the bookkeeping you want and then forward the function calls to the real OpenGL dll. This is a lot of work so I would defintely think twice before going down this route...

Programs like GLIntercept work like this.

Andreas Brinck
A: 

One possibility is to use a macro to replace existing calls to glBindTexture:

#define glBindTexture(target, texture) myGlBindTexture(target, texture)

Then in you code, where you want to ensure against using the macro, you surround the name with parentheses:

(glBindTexture)(someTarget, someTexture);

A function-like macro is only replace where the name is followed immediately by an open-parenthesis, so this prevents macro expansion.

Since this is a macro, it will only affect source code compiled with the macro visible, not an existing DLL, static library, etc.

Jerry Coffin
Yeah, this means it wont affect other codes, so its useless for me then
Newbie
What I mean: if i compile some other code that uses glBindTexture() i would have to replace those other calls to (glBindTexture)() too?
Newbie
You only add the parens if you want them to call the *original* instead of using your macro.
Jerry Coffin
Oh, then i guess this solves the problem, or is there something else i should know?
Newbie
@Newbie: at least right off, I can't think of much else...
Jerry Coffin
Why did this get downvote? just thats bothering me...
Newbie
+3  A: 

You actually can do this. Take a look at LD_PRELOAD. Create a shared library that defines glBindTexture. To call the original implementation from within the wrapper, dlopen the real OpenGL library and use dlsym to call the right function from there.

Now have all client code LD_PRELOAD your shared lib so that their OpenGL calls go to your wrapper.

This is the most common method of intercepting and modifying calls to shared libraries.

Borealid
+6  A: 

As Andreas is saying in the comment, you should check this is necessary. Still, if you want to do such a thing, and you use gnu linker (you don't specify the operating system) you could use the linker option:

--wrap glBindTexture

(if given directly to gcc you should write):

-Wl,--wrap,glBindTexture

As this is done at linker stage, you can use your new function with an already existing library (edit: by 'library' I mean some existing code which you can recompile but which you wouldn't want to modify).

The code for the 'replacement' function will look like:

void * __wrap_glBindTexture (GLenum target, GLuint texture) {
   printf ("glBindTexture wrapper\n");
   return __real_glBindTexture (target,texture);
}
vladmihaisima
A: 

The driver WON'T do it, it's in the spec. YOU have to ensure that you don't bind the same texture twice, so it's a good idea.

However, it's even a better idea to separate the concerns : let the low-level openGL deal with its low-level stuff, and your (thin, thick, as you want) abstraction layer do the higher-level stuff.

So, create a oglWrapper::BindTexture function that does the if(), but you should not play around with LD, even if this is technically possible.

[EDIT] In fact, it's not in the ogl spec, but still.

Calvin1602
Really? i heard opengl optimizes those :/ do you have any references for this myth?
Newbie
Hum, not really. But you should always, always minimize the state changes, because a driver is so complicated that you can't possibly predict what it will actually do.
Calvin1602