Hello,
I use CodeXL to debug a very simple OpenGL application. In this application, I compile one vertex shader from two bits of GLSL code with something like:
glShaderSource( myShaderGLID, 2, &srcCodes[0], &lengths[0] );
Everything works perfectly. But when I display the source of the shader in CodeXL only the first part of the source code is displayed.
Should be straightforward to solve this bug I think, but would be appreciated!
Thank you for your work!
Solved! Go to Solution.
Hi Ziple,
Well, trying out the code you pasted, it seems that there's a bug in CodeXL in addition to what I mentioned.
This bug will be fixed in the next version of CodeXL. In the meantime, you can work around it by explicitly excluding the null character, by defining the lengths array as:
GLint lengths[] = {::strlen(srcs[0]) - 1, ::strlen(srcs[1]) - 1};
Sorry for the inconvenience,
Hi Ziple,
There is a possible issue with this if lengths (namely, lengths[1]) contains incorrect values, such as the value 0 (or incorrect length for lengths[0]).
CodeXL works according to the OpenGL specification, where the value of an entry in lengths has to be _LESS_THAN_ zero to be considered as a "null terminated" flag; Furthermore, the OpenGL spec requires for the string length given not to include the null termination character.
See here:
glShaderSource - OpenGL 4 Reference Pages
It might be that the OpenGL driver / runtime you are using does not exactly adhere to the spec down to the letter on this case, which is why your code works but does not appear correctly.
The two scenarios I can imagine happening here:
1. lengths[1] = 0:
The second string is read as a zero-length string, expecting the character buffer to be just the null character - i.e. an empty string.
You can remedy this situation by having your code adhere to the OpenGL spec, and setting lengths[1] = -1.
2. lengths[0] = ::strlen(srcCodes[0]) + 1
The first string buffer is read including the null terminating character. When CodeXL's OpenGL server intercepts the shader creation, it copies a buffer of the given length, including the null character, then copies the second source buffer. This null character then appears between the two sources, causing either the file writing or file display to stop when the terminating character appears (since these mechanisms do not retain the "length" input parameter).
You can remedy this situation by having your code adhere to the OpenGL spec and setting lengths[0] = ::strlen(srcCodes[0])
3. You can remedy either situation, assuming both your strings are null-terminated (thus the lengths parameter is not necessary), by passing lengths[0] = lengths[1] = -1 or by passing NULL instead of the lengths parameter.
Please answer here if the problem still happens.
Regards,
I use this code now, and it is still running perfectly with Catalyst 13.4. But I have still the same problem with CodeXL. Both provided strings are null terminated.
GLchar* profileLookupTable[] =
{
"#version 150 core\n",
"#version 330 core\n",
"#version 420 core\n"
};
myShaderGLID = glCreateShader( stype );
const GLchar* srcs[] = { profileLookupTable[ profile ], reinterpret_cast<GLchar*>(src)};
GLint lengths[] = {-1, -1};
glShaderSource( myShaderGLID, 2, &srcs[0], &lengths[0] );
Hi Ziple,
Well, trying out the code you pasted, it seems that there's a bug in CodeXL in addition to what I mentioned.
This bug will be fixed in the next version of CodeXL. In the meantime, you can work around it by explicitly excluding the null character, by defining the lengths array as:
GLint lengths[] = {::strlen(srcs[0]) - 1, ::strlen(srcs[1]) - 1};
Sorry for the inconvenience,
Ok, thank you very much for your work!