Quantcast

Jump to content

» «
Photo

help on algorithm (HUD BAR)

4 replies to this topic
Swoorup
  • Swoorup

    innovator

  • Members
  • Joined: 28 Oct 2008

#1

Posted 11 January 2012 - 10:10 AM

Hello I am trying to draw a bar which has curves on its either side but the curves are seem imperfect. Can anyone help me on the following code?


barValue gives the amount of value the bar should have with respect to the width.
the Bar should not be drawn fully but upto the value of barValue.
The posinfo contains the coordinates of the line to be drawn.
The drawTexture draws on to the screen take the line texture address, posinfo address and color addres.


CODE

define LINE_WIDTH 0.5f

void drawHUDBar(int texNum,float X,float Y,float width,float height,float barValue)
{
float newYScale=0.0f;
float radius=height/2.0f;
float l;
for ( l=0.0f;l<=barValue;l=l+LINE_WIDTH)
{
 if (l<=radius)
 {
  newYScale=sqrtf(radius*radius-(radius-l)*(radius-l));
  posInfo.x1=X+l;
  posInfo.y1=Y+radius-newYScale;
  posInfo.x2=posInfo.x1+LINE_WIDTH;
  posInfo.y2=Y+radius+newYScale;
  drawTexture(&texturePtr,&posInfo,&default_color);
 }
 else if (l<(width-radius))
 {
  posInfo.x1=X+radius;
  posInfo.y1=Y;
  if (barValue<=(width-radius)) posInfo.x2=posInfo.x1+barValue-radius;
  else posInfo.x2=posInfo.x1+width-2*radius;
  posInfo.y2=Y+2*radius;
  drawTexture(&texturePtr,&posInfo,&default_color);
  l=width-radius-LINE_WIDTH;
 }
 else if (l>=(width-radius))
 {
  newYScale=sqrtf(radius*radius-(radius-width+l)*(radius-width+l));
  posInfo.x1=X+l;
  posInfo.y1=Y+radius-newYScale;
  posInfo.x2=posInfo.x1+LINE_WIDTH;
  posInfo.y2=Y+radius+newYScale;
  drawTexture(&texturePtr,&posInfo,&default_color);
 }
 
}
}

K^2
  • K^2

    Vidi Vici Veni

  • Moderator
  • Joined: 14 Apr 2004
  • United-States
  • Most Knowledgeable [Web Development/Programming] 2013
    Most Knowledgeable [GTA Series] 2011
    Best Debater 2010

#2

Posted 11 January 2012 - 10:57 PM

Are you drawing a bar out of bunch of tiny little rectangles whose height you're adjusting? That's very inefficient. What are you using for your graphics library?

Swoorup
  • Swoorup

    innovator

  • Members
  • Joined: 28 Oct 2008

#3

Posted 12 January 2012 - 05:02 PM

I am using VC internal texture draw function located at 0x578640.
They seem to be fine when the height is increased but if the height is small if is kind of imperfect.
I have modified them to work properly with every resolutions by putting a resolution multiplier but I think some amount of rounding errors is caused by sqrt from math.h library.
user posted image

K^2
  • K^2

    Vidi Vici Veni

  • Moderator
  • Joined: 14 Apr 2004
  • United-States
  • Most Knowledgeable [Web Development/Programming] 2013
    Most Knowledgeable [GTA Series] 2011
    Best Debater 2010

#4

Posted 12 January 2012 - 06:07 PM

Rounding error, but not at sqrt(). Math.h functions return more precision than you know what to do with. Your error happens when you store a floating point result in an integer, which is done via truncation. Here are the two lines from the first case.

CODE
posInfo.y1=Y+radius-newYScale;
posInfo.y2=Y+radius+newYScale;


Lets look at a point where the thing just begins to round. So say, radius=5.0, newYScale=4.9; Lets just set Y=0 for simplicity. So Y+radius-newYScale = 0.1, which is truncated to 0 when stored in posInfo.y1. Y+radius+newYScale = 9.9, which is truncated ot 9 when stored in posInfo.y2. (Edit: your posInfo.y1/y2 might actually be defined as float, but at any rate, this truncation is done at some point. Perhaps within the engine. Sorry, didn't catch that possibility right away. It all works the same as if these values are int, so the fix should be the same.)

What does that mean? Your bars normally run from 0 to 10. As soon as it starts rounding, instead of running from 1 to 9, it runs from 0 to 9. When radius is big, you simply don't notice this error. When radius is small, this becomes apparent.

Simplest thing you can do is replace truncation by rounding. Define a new function.

CODE
int round2int(float f)
{
   int a;

   a=(int)f;
   if(f-a>0.5)return a+1;
   if(f-a<-0.5)return a-1;
   return a;
}


Now replace the lines that compute Y coordinates accordingly.



CODE
posInfo.y1=round2int(Y+radius-newYScale);
posInfo.y2=round2int(Y+radius+newYScale);


The resulting shape might still be a bit off, but it should at list not look so flattened. See if it's good 'nough.

Swoorup
  • Swoorup

    innovator

  • Members
  • Joined: 28 Oct 2008

#5

Posted 14 January 2012 - 05:44 AM Edited by Swoorup, 14 January 2012 - 06:50 AM.

The curve is now symmetrical but still it is not a perfect curve as it should be. Is there an other way around using VC function's?

A guy from cboard recommended me this but I don't know how will I implement it using 0x578640 function.
The function can do supports alpha texture along with the real one but I cant figure it out how to as the HUD value keeps on changing.
I meant If the health got decreased the width of rectangle should decrease too but if the width decreases would'nt the alpha texture decrease too?

QUOTE
The problem here is that if the amount that needs to be shaded in is less than or higher than a certain amount (see attachment), using triangle fans is difficult.

user posted image

I think that your alpha blending route is probably the best one to pursue. One could draw the entire capsule shape (rect + triangle fans would work here) onto a texture, then simply draw a rectangle with that texture as the alpha mask. ie,

user posted image




1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users