I'm writing some modules using "DirectStateAccess" capabilities. If it's not supported, I made the necessary stuff.
On a customer laptop, I was able to create an OpenGL 3.3 Core Profile context. In a first call to glGetString(GL_EXTENSIONS), GL_EXT_direct_state_access was available.
However, GLEW_EXT_direct_state_access variable definitely equals false.
Subsequent call to wglGetProcAddress("glTextureParameteriEXT") returns a non null value though. And the functions glTextureParameterxx() seem available as well...
At this point, I wonder if I can rely on GLEW variables to check if an extension is indeed supported or not.
Oh, by the way, I made my tests with a "valid OpenGL context activated"...
Related
When using opengl through lwjgl, when an opengl context is made unavailable by making no context current (using glfwMakeContextCurrent(0)), the opengl calls all return 0 as a result. This can lead to unexpected results and it is often hard to see where the problem is. Is there any way of telling when a context is switched using a callback or something, so that a proper error can be filed?
As far as I can tell, the lwjgl library uses several different APIs', including GLFW. If you are using the GLFW API to create contexts(or the library is, which it looks like it from their website), then you can request to receive the window that the context is currently bound to using:
glfwGetCurrentContext();
If this returns NULL, it is probably not currently bound to any window. You could implement this function in a glfwPollEvents() style callback(or something similar), and output an error message when it checks the contexts status.
I've a error caught which is exactly this:
Source=DEBUG_SOURCE_API Type=DEBUG_TYPE_ERROR ID=3200 Severity=DEBUG_SEVERITY_HIGH Message=Using glGetIntegerv in a Core context with parameter <pname> and enum '0xbb1' which was removed from Core OpenGL (GL_INVALID_ENUM)
Source=DEBUG_SOURCE_API Type=DEBUG_TYPE_ERROR ID=3200 Severity=DEBUG_SEVERITY_HIGH Message=Using glGetIntegerv in a Core context with parameter <pname> and enum '0xd3b' which was removed from Core OpenGL (GL_INVALID_ENUM)
OpenGL error occured: A GLenum argument was out of range.
This is the first time this error appeared and first i thought that i'm using something which does not exist anymore but i found out that theese values do not even exist in my headers.
CLIENT_ATTRIB_STACK_DEPTH = 0xbb1
MAX_CLIENT_ATTRIB_STACK_DEPTH = 0xd3b
However after some additional research i found out that its even stranger than i thought because i have something in my code which stops the debugger in debug builds when a OpenGL error occured.
#if DEBUG
Debug.HoldOnGLError();
#endif
This is inserted after every OpenGL call BUT it's not stopping at glGetIntegerv, its stopping at a random method mostly some glBindBufferor glBindFramebuffer.
I've no clue why does errors appear and would be happy about any idea.
Edit
Forgot to mention that the error is only appearing after some time and only in Debug mode in Visual Studio.
I found out that it's not my fault. Its fault of AMD, actually AMD-Gaming-Evolved uses old code for its overlay, thats also the reason it crashed after some time because the overlay appears after a couple of seconds.
Exiting the client solves the issue.
OpenGL debugging messages (through the callback) have been only introduced with OpenGL-4.3. The client attribute stack (glPushClientAttrib and friends) (which these enums are about) are functionality of OpenGL-1.1 and have been deprecated with OpenGL-3 and are only available in compatibility profiles. If you have a core profile context, then the relevant enums are indeed invalid to use.
Something in your program (a library or legacy code) makes use of the [client] attribute stack(s) and thereby triggers this error. You should find which part this is, because the attribute stack is being used to save and restore OpenGL state, and if the code in question relies on that to restore OpenGL state after it's done it may leave the OpenGL context in an undesired state.
The same also goes for the (server) attribute stack (glPushAttrib and friends).
I wrote a DLL that initializes an OpenGL context using glew. Firstly I created a dummy window to create the appropriate context. Secondly, the final context and window are created.
glewInit() function call succeeded and some boolean variable such as GLEW_ARB_texture_storage are set to 1 (I have a video adapter compatible with opengl 3.3).
Note that
glewExperimental=GL_TRUE
though.
However, when I'm writing the client program using the DLL above, the same GLEW_ARB_texture_storage variable equals GL_FALSE.
Therefore, I'm wondering where glewInit() should be finally called ?
It seems that calling it from the DLL is not enough. Should I also call it from the client program side ?
I actually would not make a point of initializing GLEW from your dummy context. Consider manually loading the one or two extensions you need to create your final context by hand (e.g. WGL_ARB_create_context and WGL_ARB_pixel_format). You are not guaranteed to get the same ICD implementation on Windows when you create two different contexts. That is why GLEW MX was created.
Now, what I suspect is happening in your case is not actually that you are getting two different ICDs (that is extremely rare in the real-world), but actually that the first context you create is a compatibility profile and the second is a core profile.
GLEW initializes the variables such as GLEW_ARB_texture_storage using the extensions string, but in a core profile GLEW is not smart enough to parse that string the right way (multiple calls to glGetStringi (...)). This is why you have to use GLEW_EXPERIMENTAL.
GLEW_EXPERIMNETAL tells GLEW to try and load every function pointer for every extension it knows about without first parsing any extension string to check availability. That is a necessary evil in core profiles, but not in compatibility (because the old extension string mechanism is still valid in compatibility). Any part of GLEW that relies on parsing the extension string is not going to work correctly in a core profile.
I wrote a DLL that initializes an OpenGL context using glew
That's not what GLEW does. GLEW does not initialize OpenGL contexts, GLEW loads OpenGL extension function addresses and initializes function pointers with them. You must call GLEW with an pre-existing OpenGL context being created and made current in the thread calling glewInit().
Your program creates an OpenGL context somewhere and after that calls glewInit() apparently. And from the way you describe it, your DLL probably just calls glewInit() through the DllMain entry function, which gets called when the DLL is loaded, which is usually before when the processes WinMain or / main function are called, so a OpenGL context has not been created. You can create a OpenGL context in your DLL of course, but you have to ask yourself, if that makes sense to the user of the DLL.
I've been playing with Derelict3&glfw to use OpenGL in D according to this, if I want to use extensions, I need to create a context first, and this is done by creating a window with glfw and set it as the current context. After the context is created and set, I need to use DerelictGL3.reload() to load all the extensions.
Now, I want to do all the preparations before I create the window. One of those preparations is to load and compile all the shader programs. But this required the shader extension, which required Derelict3GL.reload(), which refuses to run without a context...
So, I've used this hackish hack:
auto tmpWindow=glfwCreateWindow(1,1,"",null,null);
glfwMakeContextCurrent(tmpWindow);
DerelictGL3.reload();
glfwDestroyWindow(tmpWindow);
This works - I can now load and compile the shader programs and only then open the real window. But this seems a bit too hackish to me. Is there a proper way to fake a context, or to load the extensions without a context?
Is there a proper way to fake a context, or to load the extensions without a context?
That depends on the plattform:
With Windows: Doing it through the intermediary window (that doesn't have to be mapped visibly on the screen) is the only way to load extensions reliably on Windows.
With X11/GLX: Extension function pointer can be loaded immediately using glXGetProcAddress ad the extension functions are part of the GLX client library and common to all contexts. However an actual OpenGL context may not support all of the functions that can be validly obtained with glXProcAddress.
I'm running a VB6 app in WINE and the OpenGL portion of the program doesn't work. It is using PFD_DRAW_TO_BITMAP. PFD_DRAW_TO_WINDOW formats seem to work.
I've enumerated all the pixel formats (there are around 256) and a few of them match what I request. ChoosePixelFormat seems to return a correct format (in this case pixelFormat 6), but when I pass this value into SetPixelFormat it returns 0. I looked at the documentation and it says to check GetLastError() for more information, but when I call that, it returns 0 which formats to a blank error message.
Does anyone know anyway to figure out why SetPixelFormat would fail? I've done some reading and it sounds like DRAW_TO_BITMAP has been implemented since like May 2009.
I know DRAW_TO_BITMAP is not hardware accelerated. That is perfectly acceptable. This app works fine in Windows, -- I just need to figure out why a supported pixel format doesn't seem to get recognized.
I'm running Ubuntu, most recent version of WINE in their package manager, -- on a Quadro if that matters (not sure if Wine attempts to use the underlying graphics card or if it virtualizes all the pixel formats for software rendering)
I don't know why SetPixelFormat would be failing only on WINE, but it is in any case incorrect to call GetLastError manually from VB6 code. VB makes its own DLL calls behind the scenes. These will (generally) succeed, resetting the error code seen by GetLastError and making it useless from VB code.
Instead, VB calls GetLastError itself immediately after every user-initiated DLL call. It saves the value and makes it available as the property Err.LastDllError. Use that to find out the real error code.