2

Is it possible to determine the current matrix mode used by OpenGL?

For example, I currently have the following (triggered by a window resize):

glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrtho(-width, width, -height, height, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);

However, it's preferable to return to the previously used matrix mode, rather than assume GL_MODElVIEW. Is there a function that could be called beforehand to store the previous state?

nwn
  • 583
  • 7
  • 23
  • Why would you expect the current matrix mode to be anything else than `GL_MODELVIEW`? – Kos Dec 30 '15 at 23:34
  • 1
    @Kos Considering that there are four different matrix modes available, I assume that any of them may be in use when a resize event occurs. While I wouldn't expect it, I think it's good to at least consider the possibility. That being said, I'm new to this and so this may not be the case. – nwn Dec 30 '15 at 23:40
  • I don't buy it. Do you have N places in code that expects "the matrix mode should be as I left it" and M places that say "I should leave the matrix mode intact"? That seems overly complex. I'd rather look at the whole render loop and establish a convention what mode should be set at which stages of rendering. – Kos Dec 31 '15 at 10:08
  • @Kos The important point is that this is occurring in a callback function, not directly in the render loop. If it were directly in the render loop, I would certainly explicitly set the matrix mode to whatever I want for the following calls. However, since this function could in theory be called from anywhere, it should act completely independently of the calling state and not have any unexpected side effects (Why would a screen resize force `GL_MODELVIEW` mode?). – nwn Dec 31 '15 at 19:06
  • What do you mean, anywhere? You either have an explicit main loop where you iterate over events and handle them (WinAPI, SDL, GLFW...), or (in case of GLUT) you have the main loop hidden inside your framework. Either way, the resize event should never be an "interrupt" that can be called from anywhere, it's just a normal part of your events loop. Processing window events and rendering are different 'stages'. – Kos Jan 01 '16 at 09:24
  • @Kos Indeed, event handling and rendering _are_ different stages. This therefore raises the question of why an event handler (the above resize code) would consider it necessary to affect a rendering setting (`GL_MODELVIEW`) that is outside of its scope. Again, the expected behaviour of a resize function is to resize the framebuffer (and possibly the FOV) and _nothing else_. – nwn Jan 01 '16 at 18:38

3 Answers3

6

Getting the current value with glGetIntegerv(GL_MATRIX_MODE, ...) is the obvious answer.

However, there is a more elegant and most likely more efficient way. Legacy OpenGL has an attribute stack that allows you to save/restore attribute values without using any glGet*() calls. In this example, you would use:

glPushAttrib(GL_TRANSFORM_BIT);
// Code that modifies transform mode.
glPopAttrib();

You can look up which bit passed to glPushAttrib() saves what state in the table on the man page.

You should generally avoid glGet*() calls where you can, since they can be harmful to performance. In the specific example where you execute the code only on window resize, this obviously isn't a concern. But in code that gets executed frequently, this becomes much more critical.

The attribute stack is deprecated, and not available in the OpenGL core profile. But since you're using the matrix stack (which is deprecated as well), I figure you're comfortable using legacy features in your code.

Reto Koradi
  • 53,228
  • 8
  • 93
  • 133
  • Thanks, this answer is more complete and instructive. I wasn't aware of the performance issues of `glGet*`, but the stack is cleaner anyway. Unfortunately, this project requires LegacyGL. – nwn Dec 31 '15 at 06:54
  • @watarok: Well, the attribute stack is part of legacy OpenGL. It's been removed from modern OpenGL – datenwolf Dec 31 '15 at 14:32
  • @RetoKoradi: One downside of the attribute stack is, that it may overflow. So if you're writing, say, a plug-in you may end up in a situation, where there's no attribute stack left. The simple, foolproof version is using glGet. But one can test for stack overflow (glGetError) on pushing the attribute stack and fall back to glGet if the former fails. – datenwolf Dec 31 '15 at 14:34
3

glGetIntegerv with argument GL_MATRIX_MODE should do it.

lisyarus
  • 15,025
  • 3
  • 43
  • 68
1

so i am getting 5888, 5889 values

glMatrixMode(GL.GL_PROJECTION)
glLoadIdentity()  # Reset all graphic/shape's position
print("GL_MATRIX_MODE:", glGetIntegerv(GL_MATRIX_MODE))
# GL_MATRIX_MODE: 5889


glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
print("GL_MATRIX_MODE:", glGetIntegerv(GL_MATRIX_MODE))
# GL_MATRIX_MODE: 5888
bitbang
  • 1,804
  • 14
  • 18