GLSL Compiling error when more than one char pointer (glShaderSource) - c++

What's wrong with this code for a 3.30 OpenGL and GLSL version?
const char *vertSrcs[2] = { "#define A_MACRO\n", vShaderSrc };
const char *fragSrcs[2] = { "#define A_MACRO\n", fShaderSrc };
glShaderSource(vId, 2, vertSrcs, NULL);
glShaderSource(fId, 2, fragSrcs, NULL);
I gather the shader state with GL_COMPILE_STATUS after the its compiled, get this error:
Vertex shader failed to compile with the following errors:
The purpose for this macro is to change type qualifier on a color I passed from the vertex to the fragment, maybe there is another way to do that using a uniform and the layout but the question is why would the shader fail? I wonder if there is another OpenGL command which must specify the 2 char pointers.
By the way, this works:
...
glShaderSource(vId, 1, &vertSrcs[1], NULL);
...
EDIT: since I can't answer my own questions, found the solution
Very strange problem, the string loader happens to be the problem. Without using ifstream along with std::ios::in | std::ios::binary flags, the string was loaded with some garbage information to the end even with null terminated, therefore concatenating the strings will produce the error.
For some reason the gl compiler didn't complain before with the single string version, besides calling
inStream.flags(std::ios::in | std::ios::binary)
wasn't enough, it need to be specified when opening, didn't find any doc for this.

The very first nonempty line of a GLSL shader must be a #version preprocessor statement. Anything else is an error.

Related

error C7537: OpenGL does not allow '?' after a type specifier, but there isn't

My shader doesn't include any ? at all. I've searched for unicode and unprintable characters and found none. What does this error mean?
error C7537: OpenGL does not allow '?' after a type specifier
error C7589: OpenGL does not allow a parameter to be a buffer
error C1012: abstract parameters not allowed in function definition "myfunc"
This is the function it points to (I've cut it down a fair bit from its original form).
void myfunction(int buffer)
{
}
buffer is a reserved word in GLSL for declaring SSBO interface blocks, although the error is a little misleading compared to the following:
void myfunction(int uniform)
{
}
Which gives:
error C7537: OpenGL does not allow 'uniform' after a type specifier

OpenGL MRT glDrawBuffers() argument numbers and behavior

I have a total of 5 render targets. I use the same shader to write to the first 4, then in a seperate pass write to the last one.
Before calling rendering to the first 4 targets I call:
GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3};
glDrawBuffers(4, drawBuffers);
However, when I call it for second pass and only want to write to the last one, the 5th target, why does the following give strange results?
GLenum drawBuffers[] = { GL_COLOR_ATTACHMENT4 };
glDrawBuffers(1, drawBuffers);
Why do I have to instead use:
GLenum drawBuffers[] = { GL_NONE, GL_NONE, GL_NONE, GL_NONE, GL_COLOR_ATTACHMENT4 };
glDrawBuffers(5, drawBuffers);
Is this simply how glDrawBuffers() works, or is being caused by something else?
EDIT: fixed code with regards Jarrods comment
Yes, this is simply how glDrawBuffers works. But there's a reason for that.
Fragment shaders write color outputs that map to certain "color numbers". These have no relation to GL_COLOR_ATTACHMENT''i'' numbers. The entire point of glDrawBuffers is to map those fragment color numbers to actual buffers in the framebuffer.
http://www.opengl.org/sdk/docs/man/xhtml/glDrawBuffers.xml
The 2nd parameter must be of the type const GLenum* i.e. a pointer "to an array of symbolic constants specifying the buffers into which fragment colors or data values will be written".
So just passing GL_COLOR_ATTACHMENT4 as the 2nd param is the wrong type. You need to pass a pointer to an array of GLEnum.
I find that there's something wrong in glDrawBuffers().
for exmple
tmp = {attement_color0, attachement_color2}
glDrawBuffers(tmp).
in shader:
gl_fragdata[0]=...
gl_fragdata[2]=...
or u can use layout location to define the attments output.
But sometimes, at least in my PC, it does not work. I mean the attachment_color2 does NOT have the exact output.

sprintf_s crashes

I am getting a crash while executing the following code ocassionally at sprintf_s. This code was working many years without any problems. When I gave the size in strcat_s and sprintf_s as in the statements below, the crash is not appearing. What could be the reason for this?
strcat_s(sztmpCurrDate,100,sztmpCurrTime);
sprintf_s(sztmpCurrDate,100,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds););
char sztmpCurrDate[100] = "";
char sztmpCurrTime[100] = "";
SYSTEMTIME curTime;
GetLocalTime(&curTime);
GetLocalTime(&curTime);
GetDateFormat(LOCALE_USER_DEFAULT,
DATE_SHORTDATE,
&curTime,
NULL,
sztmpCurrDate,
100);
GetTimeFormat(LOCALE_USER_DEFAULT,
TIME_FORCE24HOURFORMAT,
&curTime,
"HH':'mm':'ss",
sztmpCurrTime,
100);
strcat_s(sztmpCurrDate," ");
strcat_s(sztmpCurrDate,sztmpCurrTime);
sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
From the documentation for sprintf_s:
If copying occurs between strings that overlap, the behavior is undefined.
Your code:
sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
copies from the source to the destination sztmpCurrDate. Also, you haven't specified the size of the destination string, which is required by sprintf_s (I don't know how your code even compiled like that). Try:
sprintf_s(sztmpCurrDate + strlen(sztmpCurrDate), 100-strlen(sztmpCurrDate),
":%0.3d",curTime.wMilliseconds);
A better approach, since you're using C++, is to use std::string and then you won't have to worry about this sort of C string manipulation error.
Wrong syntax!!!
Second argument of sprintf_s is length of your buffer and in your case when program crashes you provided pointer to C string (char *). This is absolutely syntax error.
The compiler probably issued a warning, but sadly has let this pass. This is because sprintf_s takes three arguments + variable number of arguments. In your wrong case you provided three arguments so the compiler was satisfied, but he treated your "format string" as "number of arguments" and sztmpCurrDate as "format string".
If you used any other function with fixed number of arguments and you provided less than needed this would be a compile error.
You are probably using the incorrect version:
sprintf_s(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
Instead it should be:
int slen = strlen(sztmpCurrDate) + 1;
sprintf_s(sztmpCurrDate, slen, "%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
Refer to this sprintf_s for more information.
The code worked correctly, the code is not correct.
sprintf(sztmpCurrDate,"%s:%0.3d",sztmpCurrDate,curTime.wMilliseconds);
Rewrite as
sprintf(&sztmpCurrDate[strlen(sztmpCurrDate)],"%0.3d",curTime.wMilliseconds);
And for home work tell us why .....

glutBitmapString access violation

(OS: Windows 7, Compiler: Visual Studio 2010 C++ compiler)
I've got a correctly working OpenGL program that draws some spheres and models, applies some shaders etc.. etc..
Now I thought it would be nice to add some text, so I added the following three lines to my draw method:
glColor3f(0.5f, 0.5f, 0.5f);
glRasterPos2f(0, 0);
glutBitmapString(GLUT_BITMAP_HELVETICA_12, (unsigned char*)"some text");
Now somehow this all makes my program get stuck in an infinite "access violation" loop, which I can't seem to fix. I even commented all the other draw code out, to just output the text, and it still gives the access violation error, I'm at a loss here because there is nothing that seems to affect this. So does anybody have some pointers ;)) on how to fix this issue?
I could post all my draw code, but I even tried an empty project, so I'm pretty sure it's not the rest of the code.
Edit: I tried narrowing down the error even more, and it seems that glRasterPos2f is throwing the acces violation (weirdly enough). It's not between any glBegin and glEnd calls, and there is no OpenGL error.
Edit2: After some advice I tried the following code, I got rid of the access violation, but still no text is displayed
glColor3f(0.5f, 0.5f, 0.5f);
glRasterPos2f(0.0f, 0.0f);
std::string str("Hello World");
char* p = new char[strlen(str.c_str() + 1)];
strcpy(p, str.c_str());
glutBitmapString(GLUT_BITMAP_HELVETICA_12, (const unsigned char*)p);
glutBitmapString is of type const unsigned char* and not of unsigned char*. Would that help? I had problems with string casting as well.
And I found out, that I wasn't closing my string, because the unsigned char* should be 1 longer than a string. Here was a snippet that solved it for another method with the same parameter type:
string fullPath = TextureManager::s_sTEXTUREFOLDER + filename;
char *filePath = new char[strlen(fullPath.c_str())+1];
strcpy(filePath,fullPath.c_str());
And then you have your char*.
I recently got the same error while attempting to use glBitmapString(). I was using vs2008. I set a breakpoint at the function call and stepped into it (using freeglut_font.c). Inside I noticed that the exception was being thrown upon what was described to be glut not being initialized. So inside my initialization function I added...
char* argv[] = {"some","stuff"}; int argc=2;
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(800,600);
Where of course you can use whatever argc/argv you please. This, as well as what was suggested by Marnix solved the exception errors for me.
Note that I don't actually create a window with glut.
Try putting the string in a temporary variable. The fact that you have to cast should raise a red flag.
glColor3f(0.5f, 0.5f, 0.5f);
glRasterPos2f(0, 0);
unsigned char* s = "some text";
glutBitmapString(GLUT_BITMAP_HELVETICA_12, s);
if const doesn't work, then glutBitmapString() may be modifying the string.

boost memorybuffer and char array

I'm currently unpacking one of blizzard's .mpq file for reading.
For accessing the unpacked char buffer, I'm using a boost::interprocess::stream::memorybuffer.
Because .mpq files have a chunked structure always beginning with a version header (usually 12 bytes, see http://wiki.devklog.net/index.php?title=The_MoPaQ_Archive_Format#2.2_Archive_Header), the char* array representation seems to truncate at the first \0, even if the filesize (something about 1.6mb) remains constant and (probably) always allocated.
The result is a streambuffer with an effective length of 4 ('REVM' and byte nr.5 is \0). When attempting to read further, an exception is thrown. Here an example:
// (somewhere in the code)
{
MPQFile curAdt(FilePath);
size_t size = curAdt.getSize(); // roughly 1.6 mb
bufferstream memorybuf((char*)curAdt.getBuffer(), curAdt.getSize());
// bufferstream.m_buf.m_buffer is now 'REVM\0' (Debugger says so),
// but internal length field still at 1.6 mb
}
//////////////////////////////////////////////////////////////////////////////
// wrapper around a file oof the mpq_archive of libmpq
MPQFile::MPQFile(const char* filename) // I apologize my naming inconsistent convention :P
{
for(ArchiveSet::iterator i=gOpenArchives.begin(); i!=gOpenArchives.end();++i)
{
// gOpenArchives points to MPQArchive, wrapper around the mpq_archive, has mpq_archive * mpq_a as member
mpq_archive &mpq_a = (*i)->mpq_a;
// if file exists in that archive, tested via hash table in file, not important here, scroll down if you want
mpq_hash hash = (*i)->GetHashEntry(filename);
uint32 blockindex = hash.blockindex;
if ((blockindex == 0xFFFFFFFF) || (blockindex == 0)) {
continue; //file not found
}
uint32 fileno = blockindex;
// Found!
size = libmpq_file_info(&mpq_a, LIBMPQ_FILE_UNCOMPRESSED_SIZE, fileno);
// HACK: in patch.mpq some files don't want to open and give 1 for filesize
if (size<=1) {
eof = true;
buffer = 0;
return;
}
buffer = new char[size]; // note: size is 1.6 mb at this time
// Now here comes the tricky part... if I step over the libmpq_file_getdata
// function, I'll get my truncated char array, which I absolutely don't want^^
libmpq_file_getdata(&mpq_a, hash, fileno, (unsigned char*)buffer);
return;
}
}
Maybe someone could help me. I'm really new to STL and boost programming and also inexperienced in C++ programming anyways :P Hope to get a convenient answer (plz not suggest to rewrite libmpq and the underlying zlib architecture^^).
The MPQFile class and the underlying uncompress methods are acutally taken from a working project, so the mistake is either somewhere in the use of the buffer with the streambuffer class or something internal with char array arithmetic I haven't a clue of.
By the way, what is the difference between using signed/unsigned chars as data buffers? Has it anything to do with my problem (you might see, that in the code randomly char* unsigned char* is taken as function arguments)
If you need more infos, feel free to ask :)
How are you determining that your char* array is being 'truncated' as you call it? If you're printing it or viewing it in a debugger it will look truncated because it will be treated like a string, which is terminated by \0. The data in 'buffer' however (assuming libmpq_file_getdata() does what it's supposed to do) will contain the whole file or data chunk or whatever.
Sorry, messed up a bit with these terms (not memorybuffer actually, streambuffer is meant as in the code)
Yeah you where right... I had a mistake in my exception handling. Right after that first bit of code comes this:
// check if the file has been open
//if (!mpf.is_open())
pair<char*, size_t> temp = memorybuf.buffer();
if(temp.first)
throw AdtException(ADT_PARSEERR_EFILE);//Can't open the File
notice the missing ! before temp.first . I was surprized by the exception thrown, looked at the streambuffer .. internal buffer at was confused of its length (C# background :P).
Sorry for that, it's working as expected now.