|
Post by joeschmoe on Nov 26, 2012 18:36:53 GMT -5
Hi,
B4GL is working well on my system, now. Thanks for everyone's help.
A few months ago, I asked a question about combining sprites and GL. Mostly, got all that answered or figured it out. But, one thing is still bugging me:
I want to draw a line from one sprite to another (the Mouse). It has to be pixel perfect. But, when I attempt this all works except the line is offset by a lot. It runs from a point about 30-40 pixels away from a static sprite to a similar point (depending on angle) away from my mouse.
The line will follow my mouse around but not from the exact point to the exact point of my mouse. I cant tell what the offset is. What am doing wrong?
I tried to get a screen shot, but doesn't seem to work.
Thanks.
Joe
|
|
|
Post by matthew on Nov 27, 2012 10:48:18 GMT -5
Hi Joe, try the following and see whether it works for you. TextMode(TEXT_OVERLAID)
dim currMousePosX, currMousePosY, prevMousePosX, prevMousePosY
dim sprite = NewSprite(LoadTexture("data\ball.png"))
prevMousePosX = (windowwidth() / 2) prevMousePosY = (windowheight() / 2)
do
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT) glMatrixMode (GL_PROJECTION) glLoadIdentity () glOrtho (0, windowwidth(), windowheight(), 0, 0, 1) glDisable(GL_DEPTH_TEST) glMatrixMode (GL_MODELVIEW) glLoadIdentity() currMousePosX = (mouse_x() * windowwidth()) currMousePosY = (mouse_y() * windowheight()) glcolor3f(1.0, 1.0, 1.0) glbegin(gl_lines) glvertex2i(prevMousePosX, prevMousePosY) glvertex2i(currMousePosX, currMousePosY) glend()
DrawText() SwapBuffers() SprSetPos(SpriteAreaWidth() / 2, SpriteAreaHeight() / 2)
loop
If you're looking for a free Screen Capture program try Greenshot.
|
|
|
Post by joeschmoe on Nov 27, 2012 11:53:06 GMT -5
Thanks, Matthew.
It seems to work. With no mouse cursor, I can't be sure.
When I change:
prevMousePosX = (windowwidth() / 2) prevMousePosY = (windowheight() / 2)
to:
prevMousePosX = (180) prevMousePosY = (80)
(Just random coords)
And change:
SprSetPos(SpriteAreaWidth() / 2, SpriteAreaHeight() / 2)
to:
SprSetPos(180,80)
the line doesn't originate under the sprite. It's offset to the negative X and Y a short distance.
Greenshot is pretty nice. Thanks.
Joe
|
|
|
Post by matthew on Nov 27, 2012 12:08:22 GMT -5
Okay Joe try the following program, it will draw a 'cross' at the position of the mouse and display the mouse position in the top corner of the screen. If you want to see the actual mouse cursor then try running your program in a window rather than full-screen.
TextMode(TEXT_OVERLAID)
dim currMousePosX, currMousePosY, prevMousePosX, prevMousePosY
dim sprite = NewSprite(LoadTexture("data\ball.png"))
prevMousePosX = (windowwidth() / 2) prevMousePosY = (windowheight() / 2)
do
cls
printr "X: " currMousePosX print "Y: " currMousePosY
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
glMatrixMode (GL_PROJECTION) glLoadIdentity () glOrtho (0, windowwidth(), windowheight(), 0, 0, 1) glDisable(GL_DEPTH_TEST) glMatrixMode (GL_MODELVIEW) glLoadIdentity()
currMousePosX = (mouse_x() * windowwidth()) currMousePosY = (mouse_y() * windowheight())
glPushMatrix() glTranslatef(currMousePosX, currMousePosY, 0) glColor3f(1, 1, 1 ) glLineWidth(2.0) glBegin(GL_LINES) glVertex2f(-20, 0 ) glVertex2f( 20, 0 ) glVertex2f( 0, -20) glVertex2f( 0, 20 ) glEnd() glPopMatrix()
glcolor3f(1.0, 1.0, 1.0)
glbegin(gl_lines) glvertex2i(prevMousePosX, prevMousePosY) glvertex2i(currMousePosX, currMousePosY) glend()
DrawText() SwapBuffers()
SprSetPos(SpriteAreaWidth() / 2, SpriteAreaHeight() / 2)
loop
|
|
|
Post by joeschmoe on Nov 27, 2012 12:42:41 GMT -5
This works perfectly, Matthew. But there's something fundamental that I'm not understanding.
How would you rewrite this snippet to accept a random coord for the sprite and then go from there? Or just place a sprite at a random spot, get those coords and work? Am I making sense?
Remember in the other thread, I was working on a football game and would need to be able to draw lines from each of the 11 players to the place I want them to go (play diagram). The graphic is just to make it easier to see what all the players are being told to do on a given play and has no part in the actual game, except to get the coords I'm sending them to. But the players could be anywhere on a static field.
I'm not experienced enough, I guess, to see how to accomplish that from what you've shown me.
Joe
|
|
|
Post by matthew on Nov 27, 2012 13:01:12 GMT -5
Try the following program Joe. Everytime you run it, it will place a sprite on the screen at a random position. I've also commented the program so it should make a bit more sense.
TextMode(TEXT_OVERLAID)
dim currMousePosX, currMousePosY, ranSpritePosX, ranSpritePosY
dim sprite = NewSprite(LoadTexture("data\ball.png"))
' Place sprite at random screen co-ordinates ranSpritePosX = Rnd()%WindowWidth() ranSpritePosY = Rnd()%WindowHeight()
' Resize the SpriteArea so it fits the screen ResizeSpriteArea(WindowWidth(), WindowHeight())
do
' Print mouse co-ordinates cls printr "X: " currMousePosX print "Y: " currMousePosY
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT)
' Create a 2d screen glMatrixMode (GL_PROJECTION) glLoadIdentity () glOrtho (0, Windowwidth(), Windowheight(), 0, 0, 1) glDisable(GL_DEPTH_TEST) glMatrixMode (GL_MODELVIEW) glLoadIdentity()
' Update mouse position currMousePosX = (mouse_x() * WindowWidth()) currMousePosY = (mouse_y() * Windowheight())
' Position the sprite on the screen SprSetPos(ranSpritePosX, ranSpritePosY)
' Draw a cross at current mouse co-ordinates glPushMatrix() glTranslatef(currMousePosX, currMousePosY, 0) glColor3f(1, 1, 1 ) glLineWidth(2.0) glBegin(GL_LINES) glVertex2f(-20, 0 ) glVertex2f( 20, 0 ) glVertex2f( 0, -20) glVertex2f( 0, 20 ) glEnd() glPopMatrix()
glcolor3f(1.0, 1.0, 1.0)
' Draw a line from the sprite to the mouse glbegin(gl_lines) glvertex2i(ranSpritePosX, ranSpritePosY) glvertex2i(currMousePosX, currMousePosY) glend()
DrawText() SwapBuffers()
loop
|
|
|
Post by joeschmoe on Nov 27, 2012 14:06:12 GMT -5
I think I have some conflict with what I'm doing to get my background (field) to show up and what I do to get the line drawn.
Here's the code I'm using to create the field and draw the line. It looks awful because I've been copying and pasting like crazy.
field = LoadMipmapTexture ("Data/Football/Field3.bmp") glEnable (GL_TEXTURE_2D) glEnable (GL_CULL_FACE)
'********************************************************************
glMatrixMode(GL_PROJECTION) glLoadIdentity () gluPerspective (60, (1.0*WindowWidth()) / WindowHeight(), 1, 1000) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glEnable (GL_DEPTH_TEST) glDepthFunc (GL_LEQUAL) '********************************************************************
glTranslatef(0.0,-0.35,-4.7)
glBindTexture(GL_TEXTURE_2D, field)
glBegin(GL_QUADS) glTexCoord2f(0.0, 0.0): glVertex3f(-2.5, -1.2, 2.0) glTexCoord2f(1.0, 0.0): glVertex3f( 2.5, -1.2, 2.0) glTexCoord2f(1.0, 1.0): glVertex3f( 2.5, 1.2, 2.0) glTexCoord2f(0.0, 1.0): glVertex3f(-2.5, 1.2, 2.0) glend() glMatrixMode (GL_PROJECTION) 'glLoadIdentity () glOrtho (0, windowwidth(), windowheight(), 0, 0, 1) glDisable(GL_DEPTH_TEST) glMatrixMode (GL_MODELVIEW) glLoadIdentity() glcolor3f(1.0, 1.0, 1.0) glBegin(GL_LINES) glVertex2i(390,430) glVertex2i(X, Y) glend() DrawText() SwapBuffers ()
Loop
I can't remember how to insert code snippet.
|
|
|
Post by matthew on Nov 27, 2012 15:39:50 GMT -5
Okay download this program I've just written, it places the OpenGL graphics on-top of the background playing-field texture. If you want to post code on the forum just place your code between the code tags, like the following. [code] print "Hello, World!" drawtext() [/code] Results in... print "Hello, World!" drawtext()
|
|
|
Post by joeschmoe on Nov 27, 2012 17:33:42 GMT -5
That works, Matthew. I can see the different approach. Can you see anything in the code I posted that might indicate why I keep getting that offset? I have to admit that I've looked at the OpenGL Redbook quite a bit and still don't know why certain commands do what they do or what happens when you leave something out. When I looked at what you posted earlier (that worked perfectly) and what I jury-rigged, I can't understand why this is happening. Can't see the important difference and I feel close, like if I get that I'll be sailing again.
|
|
|
Post by matthew on Nov 27, 2012 19:43:11 GMT -5
Well from the code you posted, you seem to be using OpenGL to display the background texture. In my example I haven't, I used the built-in commands in Basic4GL for displaying a Tilemap. You don't need to be using GL_CULL_FACE either as you aren't using any 3d objects. glEnable (GL_TEXTURE_2D) glEnable (GL_CULL_FACE)
Also the following code that you've used in your example is for creating a 3d projection rather than a 2d projection which is what you actually want. glMatrixMode(GL_PROJECTION) glLoadIdentity () gluPerspective (60, (1.0*WindowWidth()) / WindowHeight(), 1, 1000) glMatrixMode(GL_MODELVIEW) glLoadIdentity() glEnable (GL_DEPTH_TEST) glDepthFunc (GL_LEQUAL)
There's a good explanation of how to use 2d graphics in OpenGL here on the Wiki.
|
|
|
Post by joeschmoe on Nov 28, 2012 13:10:05 GMT -5
Hi Matthew, I hope I'm not letting my serious frustration come through in my posts. I really appreciate your help with what must seem like pretty obvious answers. Like every dude who jumps into this, I think I have some good ideas, make positive progress and then hit the wall. I obviously don't have any kind of handle on GL. I wasn't really ready to get into GL, but I needed those stupid lines and it is fun learning to make something happen there. Anyway...does using TextMode(TEXT_OVERLAID) allow the GL graphics to appear over the tiles? Initially, I tried that with my field graphic as a big sprite but just used BUFFERED. Lines didn't show up. Now, I can't really tell why your program puts the line in the right place but my code ends up with it offset. I feel like if I understand that it's a big step. Or maybe just a small step in the right direction. Much appreciated, Matthew. Also, thanks for that link to tutorial. I looked at that before but it makes more sense now.
|
|
|
Post by matthew on Nov 28, 2012 15:25:55 GMT -5
Well when I first joined the forum back at the beginning of 2006 I didn't know anything about OpenGL, so I'll tell you how I learnt. First, take a look at the code for all the example programs that come with Basic4GL, a lot of the Programs are fully commented so you can learn a lot from them. Second, make use of the Help documentation for Basic4GL because all the Commands are documented and there are a lot of example programs showing their usage. Thirdly, take a look through the old posts on the forum because you'll find a lot of useful information. I also recommend you check out some of the legacy OpenGL lessons at the NeHe site because you'll discover a lot about OpenGL from them. If you want to combine OpenGL graphics with Sprites or Text in Basic4GL then you have to use TEXT_OVERLAID but it's important to remember that the Text and Sprites won't be displayed on the Screen until you call DrawText() and the OpenGL graphics won't be displayed until you call SwapBuffers(). In the program I uploaded in the previous post, I position the ball sprite on the Screen using... BindSprite(sprite) SprSetPos(ranSpritePosX, ranSpritePosY)
I then call DrawText() which draws the TileMap then the ball Sprite and then the Text on-top of that. I then draw the OpenGL graphics and finally call SwapBuffers() which draws the OpenGL graphics on-top of everything else. The order in which you draw everything is important because if you don't get it right you can have Textures appearing in-front of your other graphics which can be annoying.
|
|
|
Post by matthew on Nov 28, 2012 17:13:38 GMT -5
Make sure you've placed...
ResizeSpriteArea(WindowWidth(), WindowHeight()
Somewhere at the beginning of your program. Tell me then if you still get the offset or not.
|
|
|
Post by joeschmoe on Nov 28, 2012 17:45:17 GMT -5
Great! That's good to know. I think I'm a kinetic learner-I can read it, but then I have to fool with it, over and over, before it sinks in. I'll review all this and fool with it for a while. Thanks, Matthew. You've always been a huge help (along with 5 or 6 others, here). That's what got me hooked on b4gl. Joe
|
|
|
Post by joeschmoe on Nov 28, 2012 20:29:05 GMT -5
OK, I placed that resizesprite area at the start. The offset for the origin of the line improved...less than -30 on the X and Y. The offset at the mouse is better but strange. When the mouse is about 200 pixels from the origin and the line is at about a 35-40 degrees, the mouse and end point of the line are right on. But, as you rotate the mouse around the origin, the offset gets really big as the angle increases or decreases. When it passes approximately 0 degrees or 180 degrees, the offset at the mouse end starts to decrease until it coincides with the mouse at about 280 degrees but only if the mouse is about 100 pixels from the origin. Beyond my analytical abilities!
Edit: Actually, it never coincides in quadrants III or IV but gets close. I also noticed that outside of the field (in black space) the lines that it drew don't get erased, though on top of the field it does.
|
|