Draw wide texture between two points

Started by
12 comments, last by diverlin 13 years, 9 months ago
Hi all.
Trying to implement effect of lazer shooting using 2D sprite in OpenGl with gluOrtho2D(0, width, height, 0).

What i want to have:
draw wide texture (128x26) between points A and B within 1 sec,
the coordinates of the points A and B are changed during this seccond. The texture must be dynamically scaled by weight(depends on the distance between A and B), but height must be constant(in my case 16 pixels)

The main purpose is to keep algorithm as simple as possible:
for example i want to avoid to use glRotatef function, because i have to calculate angle between A and B within game loop. I believe that exist some simple resolution of my problem. What i want is to draw wide texture between two points.

My last approach is following:
x, y - coordinate of point A
xt, yt - coordinate of point B
h - desired texture height

def draw_tex_inRect((x, y), (xt, yt), h, tex):    glBindTexture(GL_TEXTURE_2D, tex)    # Send four vertices to draw a quad    glBegin(GL_QUADS)    glTexCoord2f(0, 0); glVertex2f(x - h/2, y - h/2)    glTexCoord2f(1, 0); glVertex2f(xt + h/2, yt - h/2)    glTexCoord2f(1, 1); glVertex2f(xt + h/2, yt + h/2)    glTexCoord2f(0, 1); glVertex2f(x - h/2, y + h/2)    glEnd()


But disadvantage of this method is: when angle between A and B is aimed to 90 or 270 then texture height is aimed to 0. This problem is illustrated on the picture below
Good variant:
http://i47.tinypic.com/1z7w1z.jpg
As u may see here angle is aimed to 0
Bad variant:
http://i46.tinypic.com/21cwmb.jpg
As u may see here angle is aimed to 90(270), and that is why texture height is decreasing(effect that i want to avoid)

def resize(width, height):    glViewport(0,0,width, height)    glMatrixMode(GL_PROJECTION)    glLoadIdentity()    gluOrtho2D(0, width, height, 0)    glDisable(GL_DEPTH_TEST)    glMatrixMode(GL_MODELVIEW)    glLoadIdentity()


Maybe someone have any idea how to implement this correctly?
Many thanks in advance

[Edited by - diverlin on July 6, 2010 12:53:54 PM]
Advertisement
Right I see.

You have to rotate the lazer beam quad, either by applying a rotational matrix or by doing the math yourself.

Im going now work now, Ill post some example code on the second option in a bit :)
Hi empirical2
Quote:Original post by empirical2
You have to rotate the lazer beam quad, either by applying a rotational matrix or by doing the math yourself.

Yes, indeed. Sorry for my "many words", it's hard to generate strict question if you are beginner in graphic and + u English is not native language. Anyway, thanks for diving into my problem and "my" not brilliant English :D

Quote:
Im going now work now, Ill post some example code on the second option in a bit :)

Looking forward for u help/advices/ideas.
The easiest would be something like this (C++) off the top of my head....

I have not tested this and a suck at math so if its at the wrong angles try switching x-xt to xt-x (same with y-yt)

float XL=x-xt,YL=y-ytfloat Angle=atan2(XL,YL);float Len=sqrt((XL*XL)+(YL*YL));glPushMatrix();glRotate(Angle,0,0,1.0f);glTranslate(x,y,0);glBegin(GL_QUADS)glTexCoord2f(0, 0); glVertex2f(- h/2,0);glTexCoord2f(1, 0); glVertex2f(h/2, Len);glTexCoord2f(1, 1); glVertex2f(h/2, Len);glTexCoord2f(0, 1); glVertex2f(- h/2, 0);glEnd();glPopMatrix();


This is for if you want to do the math in your own application. Now this one I have just tested (with lines) so should work

	//Get the distance between the points on each axis	float LX=x-xt;	float LY=yt-y;	//Calculate the length the quad needs to be and the sine & cosine values required for calculate the rotation of each point	float Len=sqrt((LX*LX)+(LY*LY));	float TheSin=LX/Len;	float TheCos=LY/Len;	float h=5;	//Matrix math is hard :( 	float X1=(-h*TheCos) - (0*TheSin)+x,Y1=(-h*TheSin) + (0*TheCos)+y;	float X2=( h*TheCos) - (0*TheSin)+x,Y2=( h*TheSin) + (0*TheCos)+y;	float X3=( h*TheCos) - (Len*TheSin)+x,Y3=( h*TheSin) + (Len*TheCos)+y;	float X4=(-h*TheCos) - (Len*TheSin)+x,Y4=(-h*TheSin) + (Len*TheCos)+y;	//Draw the quad!glBegin(GL_QUADS)glTexCoord2f(0, 0); glVertex2f(X1,Y1,0);glTexCoord2f(0, 0); glVertex2f(X2,Y2,0);glTexCoord2f(0, 0); glVertex2f(X3,Y3,0);glTexCoord2f(0, 0); glVertex2f(X4,Y4,0);glEnd(GL_QUADS)


HTH
Quote:for example i want to avoid to use glRotatef function, because i have to calculate angle between A and B within game loop.
Why do you want to avoid calculating the angle within the game loop?

There are other ways you could do it though, if need be. One would be to construct a basis from the vectors A and B, and then compute the corners of the quad manually from this basis. (Ask if you need further details.)
You don't even need trigonometry: since angles are 90 degrees, all you have to do is swap the x,y coordinates to rotate.

rotate 90 deg CW: x,y -> y,-x
rotate 90 deg CCW: x,y ->-y,x

So you calculate the direction vector, you normalize it, then you rotate it in both directions and multiply it with the height/thickness of the beam. You add the two vectors to both ends of the beam, and you have your quad.
Quote:Original post by szecs
You don't even need trigonometry: since angles are 90 degrees, all you have to do is swap the x,y coordinates to rotate.
Where did the OP say the angles were multiples of 90? (I can't find it anywhere in his posts...)
Quote:Original post by jyk
Quote:Original post by szecs
You don't even need trigonometry: since angles are 90 degrees, all you have to do is swap the x,y coordinates to rotate.
Where did the OP say the angles were multiples of 90? (I can't find it anywhere in his posts...)


The OP is speaking about a rotated rectangle no? And for some reason, the OP doesn't want to use rotation to make the quad.

image
Oh, I see. (I thought you meant that the beams themselves were only oriented at 90-degree intervals.)
empirical2 it works! Thanks a lot
Quote:Original post by empirical2
The easiest would be something like this (C++) off the top of my head....
I have not tested this and a suck at math so if its at the wrong angles try switching x-xt to xt-x (same with y-yt)

I was used the first variant of you code and adapt it to my program.
I didn't check the second method because it has many of mathematic (python don't like this)
So adapted code is following:

def draw_tex_inRect((x, y), (xt, yt), h, tex):    XL= xt - x    YL= yt - y    Angle=atan2(YL,XL) * 57.295779    Len=sqrt((XL*XL)+(YL*YL))    glBindTexture(GL_TEXTURE_2D, tex)    glPushMatrix()    glTranslatef(x,y,0)    glRotatef(Angle,0,0,1.0)    glBegin(GL_QUADS)    glTexCoord2f(0, 0); glVertex2f(0,  -h/2 )    glTexCoord2f(1, 0); glVertex2f(Len,-h/2 )    glTexCoord2f(1, 1); glVertex2f(Len, h/2)    glTexCoord2f(0, 1); glVertex2f(0,  h/2)    glEnd()    glPopMatrix()


And i also changed from gluOrtho2D(0, width, height, 0) to gluOrtho2D(0, width, 0, height)
def resize(width, height):    glMatrixMode(GL_PROJECTION)    glLoadIdentity()    gluOrtho2D(0, width, 0, height)    glDisable(GL_DEPTH_TEST)    glMatrixMode(GL_MODELVIEW)    glLoadIdentity()


Quote:Why do you want to avoid calculating the angle within the game loop?

In my game i hope to use this effect very frequently(for example fire up to 100 space ships). I am using python as the programming language. As known this language is slow in mathematic(for my game it's OK, because for most objects move i use pre-calculated lists of coordinates). So i wanted to think about optimization. My thought was that exist the easiest way to draw rotated texture without angle calculation, for example using coordinates of two points A and B (the texture_width will me in Vector AB, and texture_height all time is constant and perpendicular to Vector AB). But recently i got new point(i will be able to perform length and angle re-freshing not for each frame, let's say once per 5-7 frames. This should not kill perfomance and still provide good looking :).

Quote:
There are other ways you could do it though, if need be. One would be to construct a basis from the vectors A and B, and then compute the corners of the quad manually from this basis. (Ask if you need further details.)

I may have wrong understanding but is this the same code as empirical2 provides?
If it's not may you explain a little bit more about this?
Cheers

***
Thank all for you support!

This topic is closed to new replies.

Advertisement