Reputation: 2104
I'm making a game in OpenGL on Windows using Code::Blocks (C++) and MinGW. All the drawing and logic is fine, the game works perfectly. Until, suddenly, it doesn't. After some random amount of time, the game Segfaults. As is typical with GL segfaults, the stack trace is unhelpful. The only thing I got was that the segfault occurred in the vendor's implementation of OpenGL. I've tested this on multiple graphics cards from different vendors, and they ALL do this, so the problem is on my end.
I ran the program though gDEBugger and got the same unhelpful stack trace. Lol. I also used GLIntercept, but nothing jumped out at me. So I set about finding the segfault the manual way (BuGLe refuses to compile...) and basically write trace messages to a log. I've narrowed it down to one call to glDrawArrays. I've done a lot of poking around the internet and tried a lot of the fixes I found.
Because this game wasn't coded for portability, I've been hesitant to run it in wine and valgrind. Before I go messing with that wonderful mess, I'd appreciate it if you could look at my code and find the error. (I'm sure it's something obvious...)
(Note: For readability, I've removed all of my trace lines)
void PlayerShip::Render()
{
glPushMatrix(); //Save the current state
glTranslatef(m_PosX, m_PosY, 0);
glRotatef(vect.Rotation - 90, 0, 0, 1); //Matrixes are applied in reverse order
double xl = m_SizeX / 2, yl = m_SizeY / 2; //Get values to add/subract to the midpoint for the corners
glEnable(GL_TEXTURE_2D); //Redundant
TextureManager::Inst()->BindTexture(TexIDs::Playership01); //Bind the texture
glEnableClientState(GL_VERTEX_ARRAY); //These enables and disables are redundant here
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
GLdouble* Verts;
Verts = new GLdouble[12] { -xl, -yl, -.5, xl, -yl, -.5,
xl, yl, -.5, -xl, yl, -.5}; //Calculate quad vertices
GLdouble* Texs;
Texs = new GLdouble[8] {0, 0, 1, 0, 1, 1, 0, 1}; //Calculate texture vertices
glVertexPointer(3, GL_DOUBLE, 0, Verts);
glTexCoordPointer(2, GL_DOUBLE, 0, Texs);
glDrawArrays(GL_QUADS, 0, 12);
delete [] Verts;
delete [] Texs;
glPopMatrix();
}
The interesting thing is that this code works... for awhile. I've printed the values of all variables, they're all correct, the pointers aren't null, glGetError calls spaced throughout the code always return NO_ERROR. Frankly, I'm at a loss.
A note to any who suggest I do something different: I need to use vertex arrays to support legacy (1.4) GL implementations, and I'm declaring my arrays as pointers so that I can (in the future) reuse them for drawing multiple primitives at one time (say, having exhaust come out of the ship)
Upvotes: 5
Views: 4985
Reputation: 35923
Your last argument to glDrawArrays should be 4 (number of elements), not 12 (number of floats).
You're trying to draw 12 elements (= 36 floats), and accessing past the bounds of your array.
Upvotes: 6