Sign in to follow this  
thorpe

Display lists crash

Recommended Posts

When I call my displaylist, it crashes =( I generate it with GL_COMPILE and then display it later (some displaylist might not always be displayed). My question is: What could possibly be crash (seg.fault) inside a compile list which compiled ok?

Share this post


Link to post
Share on other sites
Note: I think the display list displayed itself ok 2 times, and crashed when it was called the third time.


I'm not sure if you need to check through all the code, I'm mainly interested in all reasons which could cause a displaylist to crash (since I think there shouldn't be any). The displaylist in question calls some other displaylists internally.

For those of you who still want to :) :

PileView, which draws a pile of chips.

#include "PileView.hpp"
#include "PileModel.hpp"
#include "ChipDrawer.hpp"
#include "View.hpp"

namespace roulette{

int PileView::IDGenerator = 0;

PileView::PileView(double x, double y, PositionedDrawable * parent,
const PileModel& pileModel,
float maxDisorderFactor, float rotationDisorderFactor, float rotation): PositionedDrawable((int)x,(int)y,0,parent),
TimeDependent(),
mPileModel(pileModel),
mMaxDisorderFactor(maxDisorderFactor),
mRotationDisorderFactor(rotationDisorderFactor),
mRotation(rotation), mPileViewID(IDGenerator++),
mLastFingerPrint(-1), mDisplayList(0)
{
}
PileView::~PileView(){

dbop("X Deleting Pile View");
if(mDisplayList!=0){
glDeleteLists(mDisplayList,1);
}
}

void PileView::setMaxDisorderFactor(float maxDisorderFactor){
mMaxDisorderFactor=maxDisorderFactor;
mLastFingerPrint = -1;
}
void PileView::InternalDraw(bool mClickableObjectsOnly) const{
dbop("Calling list "+TO_STR(mDisplayList));
glCallList(mDisplayList);
}
void PileView::Update(int msPassed){
if(mPileModel.GetContentFingerPrint() != mLastFingerPrint){
dbop(">> Compiling new list!");
mLastFingerPrint = mPileModel.GetContentFingerPrint();
if(mDisplayList != 0){
dbop(">> Deleting old list "+TO_STR(mDisplayList));
glDeleteLists(mDisplayList,1);
}
mDisplayList=glGenLists(1);
dbop(">> Generating new list "+TO_STR(mDisplayList));
glNewList(mDisplayList, GL_COMPILE);
RenderPile();
glEndList();
dbop(">> Done generating list");
}

}

void PileView::RenderPile() const{

const ChipPile& cp = mPileModel.GetChipPileC();

dbop(" List contains pile of size "+TO_STR(cp.size()));

glPushMatrix();
glTranslatef(0,0,
View::Instance().GetChipDrawer()->GetHeight()*(double)cp.size());
int i=0;
for(ChipPile::const_iterator it = cp.begin();it!=cp.end();it++, i++){
dbop(" Drawing a chip");
glPushMatrix();
unsigned int seed = rand();
//srand((*it).GetChipID()); // Old solution
// New solution. 100 can be changed to any number.
// This will affect the actual look of the piles
srand(mPileViewID+100*(mPileModel.Size()-i));
// Fulhack 2000
double r = mMaxDisorderFactor*
View::Instance().GetChipDrawer()->GetRadius()*rand_01();
double a = rand_0x(2.0*M_PI);
double dx = r*cos(a);
double dy = r*sin(a);

glTranslatef(dx, dy, 0);
dbop(" - Translating "+TO_STR(dx)+" "+TO_STR(dy));
double rotation = mRotation + mRotationDisorderFactor/2-rand_0x(mRotationDisorderFactor);
glRotatef(rotation, 0.0, 0.0, 1.0);
dbop(" - Rotating "+TO_STR(rotation));
if (mMaxDisorderFactor == 0.0 && it != cp.begin()) {
// Draw topless chips in ordered piles (if not top chip)
dbop(" - Topless chip");
View::Instance().GetChipDrawer()->DrawChip((*it), true);
} else {
dbop(" - Chip has top");
View::Instance().GetChipDrawer()->DrawChip((*it));
}
srand(seed);
glPopMatrix();
dbop(" - Translating z "+TO_STR(-View::Instance().GetChipDrawer()->GetHeight()));
glTranslatef(0,0,-View::Instance().GetChipDrawer()->GetHeight());
}
glPopMatrix();
}

}





ChipDrawer, which draws a chip


#include "ChipDrawer.hpp"
#include "TextureManager.hpp"
#include "PlayerColor.hpp"
#include "GetTextureEnum.hpp"


namespace roulette{


const double CHIP_DEFAULT_HEIGHT = BP_CHIP_RADIUS/3.5;
const int SBL_SLICES = 16;
const int SBL_LOOPS = 1;
const int SBL_STACKS = 1;


ChipDrawer::ChipDrawer():mHeight(CHIP_DEFAULT_HEIGHT),
mRadius(BP_CHIP_RADIUS){

mDiskQuadric = gluNewQuadric();
mCylinderQuadric = gluNewQuadric();

gluQuadricNormals(mDiskQuadric, GLU_FLAT);
gluQuadricTexture(mDiskQuadric, GL_TRUE);

gluQuadricNormals(mCylinderQuadric, GLU_SMOOTH);
gluQuadricTexture(mCylinderQuadric, GL_TRUE);

}

ChipDrawer::~ChipDrawer(){
gluDeleteQuadric(mCylinderQuadric);
gluDeleteQuadric(mDiskQuadric);
dbop("X Deleting chip drawer");
for(int c=0;c<CH_NUMBER;c++){
for(int pl=0;pl<MAX_PLAYERS;pl++){
for(int b=0;b<2;b++){
glDeleteLists(mChipDisplayLists[c][pl][b],1);
}
}
}
}

void ChipDrawer::InitializeAfterTexturesAreCreated() {
for(int c=0;c<CH_NUMBER;c++){
for(int pl=0;pl<MAX_PLAYERS;pl++){
for(int b=0;b<2;b++){
mChipDisplayLists[c][pl][b]=glGenLists(1);
glNewList(mChipDisplayLists[c][pl][b], GL_COMPILE);
RenderChip((ChipType)c,pl,(bool)b);
glEndList();
}
}
}
}

void ChipDrawer::DrawChip(const ChipModel c, bool topless) const{
DrawChip(c.GetChipType(),c.GetPlayerID(),topless);
}

void ChipDrawer::DrawChip(ChipType c, int playerID, bool topless) const{
dbop(" -- Calling list "+TO_STR(c)+" "+TO_STR(playerID)+" "+TO_STR(topless));
glCallList(mChipDisplayLists[c][playerID][topless]);

}

void ChipDrawer::RenderChip(ChipType c, int playerID, bool topless) const{


if (c == CH_100 || c == CH_1000) {

float sizeX;
float sizeY;
if (c == CH_100) {
sizeX = BP_100_CHIP_SIZE_X;
sizeY = BP_100_CHIP_SIZE_Y;
} else {
sizeX = BP_1000_CHIP_SIZE_X;
sizeY = BP_1000_CHIP_SIZE_Y;
}

float perimeter = sizeX*2+sizeY*2;

glPushMatrix();

GLuint chipTexture = TextureManager::Instance().
GetTexture(GetChipTexEnum(c, playerID))->GetName();
GLuint chipSideTexture = TextureManager::Instance().
GetTexture(GetChipSideTexEnum(c, playerID))->GetName();
glBindTexture(GL_TEXTURE_2D, chipTexture);

glRotatef(180.0*(playerID/2), 0.0, 0.0, 1.0);

glTranslatef(0.0f,0.0f,mHeight);

//if(!topless){
// Draw top
glBegin(GL_QUADS);
glNormal3f(0.0f, 0.0f, 1.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-sizeX/2.0, -sizeY/2.0, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f( sizeX/2.0, -sizeY/2.0, 0.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f( sizeX/2.0, sizeY/2.0, 0.0f);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-sizeX/2.0, sizeY/2.0, 0.0f);
glEnd();

//}
glTranslatef(0.0f,0.0f, -mHeight);

glBindTexture(GL_TEXTURE_2D, chipSideTexture);
//glBindTexture(GL_TEXTURE_2D, 0);

// Draw left side
glBegin(GL_QUADS);
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(0.0f, 0.0f);
glVertex3f(-sizeX/2.0, sizeY/2.0, 0.0f);
glTexCoord2f(sizeY/perimeter, 0.0f);
glVertex3f(-sizeX/2.0, -sizeY/2.0, 0.0f);
glTexCoord2f(sizeY/perimeter,1.0f);
glVertex3f(-sizeX/2.0, -sizeY/2.0, mHeight);
glTexCoord2f(0.0f, 1.0f);
glVertex3f(-sizeX/2.0, sizeY/2.0, mHeight);
glEnd();
// Draw bottom side
glBegin(GL_QUADS);
glNormal3f(0.0f, -1.0f, 0.0f);
glTexCoord2f(sizeY/perimeter, 0.0f);
glVertex3f(sizeX/2.0, -sizeY/2.0, 0.0f);
glTexCoord2f((sizeY+sizeX)/perimeter, 0.0f);
glVertex3f(-sizeX/2.0, -sizeY/2.0, 0.0f);
glTexCoord2f((sizeY+sizeX)/perimeter,1.0f);
glVertex3f(-sizeX/2.0, -sizeY/2.0, mHeight);
glTexCoord2f(sizeY/perimeter, 1.0f);
glVertex3f(sizeX/2.0, -sizeY/2.0, mHeight);
glEnd();

// Draw right side
glBegin(GL_QUADS);
glNormal3f(1.0f, 0.0f, 0.0f);
glTexCoord2f((sizeY+sizeX)/perimeter, 0.0f);
glVertex3f(sizeX/2.0, -sizeY/2.0, 0.0f);
glTexCoord2f((sizeY+sizeX+sizeY)/perimeter, 0.0f);
glVertex3f(sizeX/2.0, sizeY/2.0, 0.0f);
glTexCoord2f((sizeY+sizeX+sizeY)/perimeter,1.0f);
glVertex3f(sizeX/2.0, sizeY/2.0, mHeight);
glTexCoord2f((sizeY+sizeX)/perimeter, 1.0f);
glVertex3f(sizeX/2.0, -sizeY/2.0, mHeight);
glEnd();

// Draw top side
glBegin(GL_QUADS);
glNormal3f(0.0f, 1.0f, 0.0f);
glTexCoord2f((sizeY+sizeX+sizeY)/perimeter, 0.0f);
glVertex3f(sizeX/2.0, sizeY/2.0, 0.0f);
glTexCoord2f(1.0f, 0.0f);
glVertex3f(-sizeX/2.0, sizeY/2.0, 0.0f);
glTexCoord2f(1.0f,1.0f);
glVertex3f(-sizeX/2.0, sizeY/2.0, mHeight);
glTexCoord2f((sizeY+sizeX+sizeY)/perimeter, 1.0f);
glVertex3f(sizeX/2.0, sizeY/2.0, mHeight);
glEnd();


//glColor3dv(PL2COLOR[playerID][1]);
// Fulhack: Added 0.5 to height to avoid a strange
// transparent effect

glPopMatrix();

} else {

glPushMatrix();
//GLint currentBoundTexture;
//glGetIntegerv(GL_TEXTURE_BINDING_2D, &currentBoundTexture);
GLuint chipTexture = TextureManager::Instance().
GetTexture(GetChipTexEnum(c, playerID))->GetName();
GLuint chipSideTexture = TextureManager::Instance().
GetTexture(GetChipSideTexEnum(c, playerID))->GetName();
//if(chipTexture!=(GLuint)currentBoundTexture){
glBindTexture(GL_TEXTURE_2D, chipTexture);
//}

glRotatef(-45+90.0*playerID, 0.0, 0.0, 1.0);

glTranslatef(0.0f,0.0f,mHeight);
if(!topless){
// Draw top
gluDisk(mDiskQuadric,0.0f,mRadius,SBL_SLICES,SBL_LOOPS);
}
glTranslatef(0.0f,0.0f, -mHeight);

/*
if(!topless){
gluQuadricOrientation(mDiskQuadric, GLU_INSIDE);
gluDisk(mDiskQuadric,0.0f,mRadius,SBL_SLICES,SBL_LOOPS);
gluQuadricOrientation(mDiskQuadric, GLU_OUTSIDE);
}
*/


glBindTexture(GL_TEXTURE_2D, chipSideTexture);
//glColor3dv(PL2COLOR[playerID][1]);
// Fulhack: Added 0.5 to height to avoid a strange
// transparent effect
gluCylinder(mCylinderQuadric, mRadius, mRadius, mHeight+0.5 , SBL_SLICES,
SBL_STACKS );
glPopMatrix();

}
}



double ChipDrawer::GetHeight() const {return mHeight;}
double ChipDrawer::GetRadius() const {return mRadius;}
void ChipDrawer::SetHeight(double height){mHeight=height;}
void ChipDrawer::SetRadius(double radius){mRadius=radius;}

}




What crashes is PileView::InternalDraw(bool mClickableObjectsOnly) when it calls glCallDisplayList(mDisplayList).


The display list is 111 and was deleted and recreated 3 frames before the crash.

What on earth could possibly cause a compiled display list to crash? I don't get it =/

Thanks for your time.

Share this post


Link to post
Share on other sites
The only thing I can think of, is that some of the GL commands are executed before you have created a GL context. I see that in one of the diplay lists you use a gluQuadricObj to draw a cylinder, and that quadric is created in the constructor of ChipDrawer. Are you sure the constructor is called AFTER you have a valid GL context?

Share this post


Link to post
Share on other sites
Yes, the bug appears after, on average, 15 hours of intense testing. During that time, everything runs smoothly.

Tricky tricky...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this