opengl/malloc beginner

Started by
2 comments, last by dvlfrnd 17 years, 5 months ago
hi, im trying to learn C and openGL,i gave myself an assignment for no spesific purpose,but then came across a problem. the program might not make sense,its purpose is to teach me pointers and malloc,,there is probably a way better way to solve it,but since im learning,i have to know if im on the right track. my funky program uses glut to open a window,fills it black etc.. follow from here: dragging the mouse creates white points on the screen. so im drawing a smiley face,which is represented by white dots on screen. goal: when i type 's' on the keyboard, all the points that i drew should be connected by GL_LINES my path: first i thought i should collect all the point coordinates.because the lines arent drawn right away,they are only drawn if the user asks for it.so they have to be stored somewhere. important key factor is speed, while gathering the point coordinates,the function that stores the points should be fast enough,so that it wont miss anything while trying to store things. at first i made two simple int arrays.but then realised their size would be limited. and would require lots of ram that the user might now even facilitate. so i tried to implement it with malloc: there is a struct called pointcoord. struct pointcoord { int *chunkX; int *chunkY; struct pointcoord *next; struct pointcoord *prev; }; chunkX and Y store the coordinates of the mouse while its being dragged. then we have these babies: struct pointcoord *handle1,*handle2; when the program starts, they are initialised: handle1=handle2=NULL; handle1 = (struct pointcoord *)malloc(sizeof(struct pointcoord)); handle1->chunkX = (int *)malloc(POINT_BUFFER_SIZE * sizeof(int)); handle1->chunkY = (int *)malloc(POINT_BUFFER_SIZE * sizeof(int)); handle1->prev = NULL; POINT_BUFFER_SIZE defines when the program needs to allocate more ram to store more point data. in our example it shall be 16, which means, when the program first starts, it allocates enough space to hold,16 x and 16 y coordinates. total 32. what happens if the user draws something that consists of more than 16 points, (a smiley face for example) well i thought,while drawing,if the buffer size is exceeded,handle1 and handle2 should switch places,and handle1 should allocate more ram for the pointcoord structure. after that handle1 is linked back to handle2 heres the function: void gatherPoints(int x,int y) { if (point_count < POINT_BUFFER_SIZE) { (handle1->chunkX)[point_count] = x; (handle1->chunkY)[point_count] = y; } else { point_count = 0; handle2 = handle1; handle1 = (struct pointcoord *)malloc(sizeof(struct pointcoord)); handle1->chunkX = (int *)malloc(POINT_BUFFER_SIZE * sizeof(int)); // point data will be stored here handle1->chunkY = (int *)malloc(POINT_BUFFER_SIZE * sizeof(int)); // point data will be stored here handle2->next = handle1; handle1->prev = handle2; (handle1->chunkX)[point_count] = x; (handle1->chunkY)[point_count] = y; } point_count++; } upon user's request for drawing, this function is called (partial) while (handle1->prev != NULL) { for (i=point_count-1;i>=1;i--){ //draw here with x and y glBegin(GL_LINES); glLoadIdentity(); x = (handle1->chunkX); y = (handle1->chunkY); glVertex2f(x,480.0-y); glLoadIdentity(); x = (handle1->chunkX)[i-1]; y = (handle1->chunkY)[i-1]; glVertex2f(x,480.0-y); glLoadIdentity(); glEnd(); glutPostRedisplay(); } handle2 = handle1; handle1 = handle1->prev; point_count = POINT_BUFFER_SIZE; free(handle2); handle2 = NULL; } well,result is,the program works as expected. but there is a problem,and thats why im here bugging you. the lines that are being drawn, have little gaps between them. if i increase the buffer size, they occur less frequently. and the buffer size should be a much bigger value,im aware of that,but,how do i prevent this? i counted the points,and gaps occur at the exact number where the allocation occurs.. for ex: buffer size = 16 i draw smtg that has more than 16 points ----- ----- ----- ------ -------- it looks like this. -------------------------------- but it should look like this the reason behind this is probably the time spent to allocate data.(???) while the function gatherpoints, is allocating more ram,it is missing some of the points,because the user is still drawing.(???) the problem is obvious(???),so how do i make it work without missing any points. any other approaches to this problem are welcome,but i'd rather like to hear,how to fix this particular thing. i thought about utilizing some an idle function,but still,if the user is 3 yrs old,and keeps drawing forever without taking a break, no matter how big the buffer is,the gaps will occur. when the buffer is around 512-1024, it is acceptable,the gaps are rarely seen. i think this actually cant be solved unless its approached with a different view,coz ultimately,memory will be allocated some time in the program. so the solution is either finding a way to allocate memory faster,or preemptively allocate memory when idle(which isnt our case,think about the obsessed 3 yr old guy drawing for 10 mins without releasing them mouse button) anyway, im not very experienced and all help,+/- criticism is appreciated
Advertisement
not related to your problem:

you're leaking memory. you're calling free on the handle's but not on the chunkX and chunkY member variables of the struct. C does _not_ "do the right thing" it only does exactly what you told it.

you should have:

free(handle2->chunkX);
free(handle2->chunkY);
free(handle2);


perhaps related to your problem:

Been a while since i openGL'd, but i think the glBegin and glEnd calls should be _outside_ your for loop. right now you're creating a new line with each iteration rather than one continuous line.

certainly the glutPostRedisplay should be outside the for loop. dunno what calling that multiple times per frame does. this could be more of a problem than the previous paragraph. but i don't know glut at all.

-me
And not that it should have an effect but you are making excessive number of calls to glLoadIdentity. There's no need to have more than one call to that given your code; and it should be outside the for loop.

And as a word of advice: learning pointers _and_ graphics at the same time might end up being very confusing. Generally you should already have a firm grasp of pointers before starting graphics; graphics tends to use them all over the place, so if you don't already know them the coding is going to hurt your brain. But that's just advice, it's certainly possible the route you're going just a lot more difficult.

-me
Quote:Original post by Palidine
not related to your problem:
you're leaking memory. you're calling free on the handle's but not on the chunkX and chunkY member variables of the struct. C does _not_ "do the right thing" it only does exactly what you told it.

you should have:

free(handle2->chunkX);
free(handle2->chunkY);
free(handle2);

-me


that is a very important thing indeed,thanks for pointing that out!
i never considered freeing the chunks

Quote:Original post by Palidine
perhaps related to your problem:

Been a while since i openGL'd, but i think the glBegin and glEnd calls should be _outside_ your for loop. right now you're creating a new line with each iteration rather than one continuous line.

-me


i think you are right, i noticed a detail that might be causing this;

point_count = POINT_BUFFER_SIZE;

it starts reading from the last buffer to the first.
so it draws backwards,
gap might be occuring,coz the loop is jumping from buffer to buffer.

draw buffer2 16,15,14,13...2,1,0 // this is the way buffers are drawn
draw buffer1 16,15,14....0

a continuous line would be (imagine we have a connect function)

connect(buffer2.point[0],buffer1.point[16]);

it might be skipping that first point of buffer2 and last point of buffer1,not connecting them

i will inspect it, THANK YOU!
and sorry for blaming malloc with me being the actual bug :)





This topic is closed to new replies.

Advertisement