Xcelled
Xcelled

Reputation: 2104

OpenGL Segfaulting on glDrawArrays

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

Answers (1)

Tim
Tim

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

Related Questions