Pages: [1]
  Print  
Author Topic: Can't draw anything inside _begin _end  (Read 1469 times)
Offline (Unknown gender) TheExDeus
Posted on: November 30, 2010, 02:02:19 PM

Developer
Joined: Apr 2008
Posts: 1919

View Profile
While testing my curve functions I innially could not get why my curves drawed normally some times, but not others. I found out that a draw_circle was to blame, which I used to mark the points. When I start drawing a spline with draw_spline_begin() it just does:
Code: [Select]
    glPushAttrib(GL_CURRENT_BIT);
    glBegin(mode);
And when I draw a circle or any other shape in between it will get points on that circle, and thus mess up my curve. This is exactly the same problem with the already implemented draw_primitive functions. Try something like this and see for yourself:
Code: [Select]
draw_primitive_begin(pr_linestrip);
draw_vertex(10,10);
draw_vertex(100,50);
draw_circle(500,300,5,1);
draw_vertex(50,300);
draw_primitive_end();
In GM it does allow things like this. The way it does this is that the _end function is the one that draws it. So I guess this is how I need to do it too? I already save points in an array, so I guess its not a problem, but still. There is some DEPTHBUFFER code already done in primitive functions and in thous it does save points as well. So drawing it in _end would be the best bet I guess.

Also, if I have to save points + colors + alphas in an array, then should I use something like this:
http://www.fredosaurus.com/notes-cpp/newdelete/50dynamalloc.html
or just:
float pr_point_ar[MAXPOINTS][4];
MAXPOINTS could be changed, or just be a large number by default.
I don't want to do that dynamic deleting and allocation because I would need to do this for every point... Or I could alloc, for example, 64 points at a time, and when I run out I alloc another 64. This wouldn't waste much memory and should be faster, but then again its another if cycle.

Also, I guess I should post these as tickets in the tracker, but I might as well put it here:
draw_merge doesn't work. I wasted about 40min trying to figure out why I can't blend my curve smoothly, and it ends up that the function doesn't return the right values. For example, merge_color(c_red,c_white,1), will return c_red even thou it needs to return c_white. Either way, this is how I fixed it:
Code: [Select]
int merge_color(int c1,int c2,double amount)
{
amount = amount > 1 ? 1 : (amount < 0 ? 0 : amount);

    return
    (unsigned char)(fabs(__GETR(c1)+(__GETR(c2)-__GETR(c1))*amount))
    | (unsigned char)(fabs(__GETG(c1)+(__GETG(c2)-__GETG(c1))*amount))<<8
    | (unsigned char)(fabs(__GETB(c1)+(__GETB(c2)-__GETB(c1))*amount))<<16;
}
I think fabs can be removed somehow.

Also, draw_get_color() (or anything draw_get for that matter) returns nan all the time.. I have this code:
Code: [Select]
pr_point_ar[i][2] = (pr_curve_color1 == -1 ? draw_get_color() : merge_color(pr_curve_color1,pr_curve_color2,1/(pr_spline_points+1)))And it will return nan if pr_curve_color1 is -1 (so its calling merge_color). I just tested std::cout << merge_color(col1,col2,1) and got the same result. Couldn't find the reason thou... I looked in GScolors.cpp and everything seems fine.

edit: Anyway, as you can see this post started as a question, but by the second paragraph I realized how to fix this myself (by drawing in _end), so the first part can be ignored I guess.
« Last Edit: November 30, 2010, 02:31:39 PM by HaRRiKiRi » Logged
Offline (Male) Josh @ Dreamland
Reply #1 Posted on: November 30, 2010, 05:37:12 PM

Prince of all Goldfish
Developer
Location: Ohio, United States
Joined: Feb 2008
Posts: 2949

View Profile Email
Indeed, I chose not to use a custom vertex buffer to render primitives, and nested glBegin()s are invalid. I am unsure why you would be drawing a circle inside your primitive calls in the first place, but if you can make a case for it I'd be happy to use a dynamic array for a custom VBO (another 1980 GL spec that Intel refuses to support).

merge_color worked at one point, but serp found a more efficient way. He just never tests his efficient ways thoroughly. Notice the tabs everywhere. Not my trademark...
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) TheExDeus
Reply #2 Posted on: November 30, 2010, 05:45:44 PM

Developer
Joined: Apr 2008
Posts: 1919

View Profile
Quote
Indeed, I chose not to use a custom vertex buffer to render primitives, and nested glBegin()s are invalid. I am unsure why you would be drawing a circle inside your primitive calls in the first place, but if you can make a case for it I'd be happy to use a dynamic array for a custom VBO (another 1980 GL spec that Intel refuses to support).
Well I had code like this:
Code: [Select]
draw_spline_begin(pr_linestrip);
for (int i=0; i<points; i++){
    draw_spline_add_point_color(ar[i,0],ar[i,1],ar[i,2],ar[i,3]);
    draw_circle(ar[i,0],ar[i,1],5,1);
}
draw_spline_add_point(ar[points-1,0],ar[points-1,1]);
draw_spline_end();
So I draw a point and also draw a circle at that same point. I can, of course, make two "for cycles" for this, but that would be slower. Maybe not in this case (where point number is like 512 max), but in other cases where you draw more stuff together. Either way, how would dynamic arrays work? Is it the same as in the link I posted? Where you just create new array every time you need more space?
Logged
Offline (Male) Josh @ Dreamland
Reply #3 Posted on: December 01, 2010, 01:57:19 PM

Prince of all Goldfish
Developer
Location: Ohio, United States
Joined: Feb 2008
Posts: 2949

View Profile Email
Essentially. It would require a less-than check every primitive, which is what I consider to be a waste of time. I may offer a second set of primitive functions that have no such time consumers (and smaller names. I'm thinking just draw_begin(), draw_end()).
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) TheExDeus
Reply #4 Posted on: December 01, 2010, 03:05:36 PM

Developer
Joined: Apr 2008
Posts: 1919

View Profile
Also, when you make _end functions actually draw the primitive you can have things like "draw_add_vertex" inside, for example, a mouse click event and then just draw with _end in the draw event. So this allows adding points without using any arrays. I also thought that would increase speed, as every add_vertex function assigns arrays its values and increments, but my test showed that fps gain is minimal, or none at all.
Also, its allows drawing with _end, then have some d3d transform function in the middle, and draw again with _end thus making some interesting effects. GM allows this, as GM also draws only in _end.

Also, room_goto() doesn't work. I will test it some more and if its really not my fault, then I will post a ticket.
Logged
Offline (Male) RetroX
Reply #5 Posted on: December 03, 2010, 09:44:16 PM

Master of all things Linux
Contributor
Location: US
Joined: Apr 2008
Posts: 1055
MSN Messenger - classixretrox@gmail.com
View Profile Email
Code: [Select]
draw_spline_begin(pr_linestrip);
for (int i=0; i<points; i++){
    draw_spline_add_point_color(ar[i,0],ar[i,1],ar[i,2],ar[i,3]);
    draw_circle(ar[i,0],ar[i,1],5,1);
}
The one thing that I could see for this would be implementing a draw_add_circle function, which is essentially draw_circle without the glBegin and glEnd; that way, it draws the points in the current primitive  It would probably specify a starting angle for which point to draw first, but I can see it as being useful for speed in minor cases such as this.

You could draw the point, draw the circle starting with the angle on the line, go back to the point, then go to the next point, and repeat.
« Last Edit: December 03, 2010, 09:46:01 PM by RetroX » Logged
My Box: Phenom II 3.4GHz X4 | ASUS ATI RadeonHD 5770, 1GB GDDR5 RAM | 1x4GB DDR3 SRAM | Arch Linux, x86_64 (Cube) / Windows 7 x64 (Blob)
Quote from: Fede-lasse
Why do all the pro-Microsoft people have troll avatars? :(
Offline (Male) Josh @ Dreamland
Reply #6 Posted on: December 04, 2010, 04:56:21 AM

Prince of all Goldfish
Developer
Location: Ohio, United States
Joined: Feb 2008
Posts: 2949

View Profile Email
Well, since the draw event only clears it every time, you'd still have to keep your own array.
The speed will actually decrease from keeping your own array. It is much more efficient to outsource point management to the GPU. Not to mention the number of function calls doubles by this method. At it's simplest, now we're keeping a nonstatic array, and the GPU is keeping a static one. The difference in the long run, though, is negligible; most of the work here is probably in drawing the primitive.
But yes, I see how drawing a circle around each vertex could be useful, so if you have not, I will probably preprocess the current primitive functions manually and rename them to draw_begin, draw_vertex2d() and draw_end(). Then our Game Maker equivalents can do their craziness.

Issue is, now I have to store texture and color data in the array, too.
Logged
"That is the single most cryptic piece of code I have ever seen." -Master PobbleWobble
"I disapprove of what you say, but I will defend to the death your right to say it." -Evelyn Beatrice Hall, Friends of Voltaire
Offline (Unknown gender) TheExDeus
Reply #7 Posted on: December 04, 2010, 06:25:25 AM

Developer
Joined: Apr 2008
Posts: 1919

View Profile
RetroX: Wouldn't it connect the last point to the circle? And then connect the circles last point to the next one? Also, the circle will the draw with the currently selected mode, which cause problems (in my case it connected all of the points in the circle). I would be almost better to do something like glend and glbegin before and after the circle. Of course that could be slow thou. So drawing in _end is still the best thing I can come up with. Its also the best thing Mark could come up with. And this actually allows some neat effects like transforming before drawing. So you can add all points, then rotate it 45 degrees, scale 2 times and then draw.
Logged
Pages: [1]
  Print