Jump to content
flyer10au

Planemaker and open GL drawing alignment

Recommended Posts

OK back again. Working my way through the API trying to understand what's possible with Gizmo. This time I'm on to the graphics API and open GL drawing. I've got a couple of questions.

 

My main question relates to how to align png images placed in planemaker with Gizmo code generated open gl drawing elements. What I can currently do is have some gl generated text and number elements drawn with font.drawString nicely align in the desired locations within a planemaker png while the screen size window is less than or equal to the panel.png resolution (1920x1080 in this case). I do this by reading the acf file for the png location (yes, I've also been playing with the IO APi too) and formatting the open gl co-ordinates such that the gizmo drawn elements are using the same reference point. The formatting is simple maths to allow for the fact that planemaker and open gl co-ordinates do not directly reference the same point on the screen.

 

What i'm struggling with is when I extend the x-plane window beyond either the 1920, 1080 or both x-plane scales and shifts the panel such that my open gl draws are now no longer aligned with the desired location of the planemaker png. I have tried some simple maths solutions using combinations of screen size and panel size information which improve a little but they don't solve the problem for all window sizes. I have a dual monitor ( 2 x 1920x1200) set-up that i used for this testing.

 

I really would like to get gizmo playing nice with my existing planemaker generated panels. Any idea's on how to make this work?

 

 

My second question relates to function calls from OnDraw_Gauges(). I tried to call a function that draws a png to the screen from OnDraw_Gauges(), but  the png just would not show. However as soon as I put a gfx.drawString into the function the png draws fine  (see code below).

 

What's happening here? Also when should I use OnDraw_Gauges() and/or OnDraw_BeforeGauges().

------file1dofile("file2.lua")function OnDraw_Gauges()	    draw_imageA()end------file2function draw_imageA()    gfx.setColor(0,0,0,1)    gfx.drawString("." , 944, 116 ) --call from OnDrawGauges() to draw_imageA() will not draw image without this        png_file = "/image_path/Bezel.png"        draw_png( 942, 114, 550, 145, 1, png_file ) --draw and place Bezel    endfunction draw_png(x, y, width, height, zoom, file)        png_texture = gfx.newTexture()    local width = width * zoom    local height = height * zoom        gl.PushMatrix()    gl.Translate (x, y, 0 )    gfx.loadPng(png_texture, file )    gfx.useTexture(png_texture)    gfx.setColor(1,1,1,1)    gl.Begin('QUADS')        gl.TexCoord( 0, 0 ); gl.Vertex( 0, 0, 0 );        gl.TexCoord( 0, 1 ); gl.Vertex( 0, height, 0 );        gl.TexCoord( 1, 1 ); gl.Vertex( width, height, 0 );        gl.TexCoord( 1, 0 ); gl.Vertex( width, 0, 0 );        gl.End()        gl.PopMatrix()end

Share this post


Link to post
Share on other sites

A couple of quick comments...

 

Using gfx.drawString will give you problems.  It's OK for drawing in the "windows" phase but not good for panel drawing. It  can change the XP "state" (this is why you're having issues with drawing the png).  I would use ...

 

font.getFont( full_path_to_font_file, font_size )

font.drawString( font_id, string_to_draw, [x,y] )

 

This Also gives you control over the size and "look" of the text.

 

Regarding the problem with drawing png: Anytime you are going to use a texture you should be using...

gfx.texOn() and gfx.texOff().

 

This will set XP "state" properly so that you're png will draw properly.

 

Side Note:  You should not "create" or "load" your texture(s) inside the drawing function (it only needs to be created and loaded once, and NOT with every call to the function).  The same would hold true if you decide to use font.getFont( full_path_to_font_file, font_size ) ... do it once at the beginning.

 

Jim

Edited by JGregory

Share this post


Link to post
Share on other sites

Jim,

I have been using the font functions with success elsewhere so thanks for the tip about gfx.drawstring.

I knew about the gfx.texOn() and gfx.texOff() but somehow managed to forget to include them. That now makes the png draw as expected from either OnDraw_Gauges() or OnDraw_BeforeGauges(). I think On_Draw_Gauges() draws stuff just the once and its likely best use is for one time drawing items that don't move or change based on changing dataref's. What I still don't understand is when to use calls from each of these functions and what the differences are. I assume anything that needs to be continually redrawn has to be called from OnDraw_Windows().

I didn't really understand your Side Note. Do you mean create and load all the required textures outside of functions as part of the initial dofile and then just use them by reference to the texture id within the functions.

All of the above is really a side show to my main problem with the alignment (see original post). Anyone have any ideas on this?

Share this post


Link to post
Share on other sites

All of the above is really a side show to my main problem with the alignment (see original post). Anyone have any ideas on this?

I'm a little confused as to what the problem is. First, I assume you're talking about the 2D panel and are using OnDraw_Gauges() or OnDrawBeforeGauges().  If you draw text at a specific position it will scale accordingly (and relative to the Planemaker instruments) as you resize the sim window.  The coordinates of instruments in the ACF file WILL NOT change as you resize the sim window.  So, if you have an instrument on the 2D panel that is at 100, 100, and you want to place text starting at the center of that instrument then you would use the same coordinates... no math necessary.  Instrument positions as shown in Planemaker are the CENTER of the instrument relative to the panel.png starting at the lower left corner. OpenGL (without using any translation) coordinates are 0, 0 at the lower left corner of the panel texture.

 

What I still don't understand is when to use calls from each of these functions and what the differences are. 

OnDraw_Gauges() and OnDrawBeforeGauges() are used for drawing to the 2D panel. The difference is simply about the "layer" that you will be drawing to, or, more specifically, the draw order.  The function names are self-explanatory... OnDraw_Gauges() will draw "on top" of, or after, OnDrawBeforeGauges().  OnDraw_Windows() draws to the X-Plane window and is NOT relative to the aircraft panel. 

 

I assume anything that needs to be continually redrawn has to be called from OnDraw_Windows().

NO.  All drawing phases are continually updated by X-Plane.

 

I didn't really understand your Side Note. Do you mean create and load all the required textures outside of functions as part of the initial dofile and then just use them by reference to the texture id within the functions.

Exactly!  The point being that you only need to create and load textures once.  If you do that in a different file (script) then the texture ID will need to be Global.

 

Jim

Edited by JGregory

Share this post


Link to post
Share on other sites

All Working. Now I understand what the built in OnDraw functions are for it makes sense. My problem was simply because I was trying to draw panel stuff with OnDraw_windows. The only thing that doesn't stack up is this. 

 

 

So, if you have an instrument on the 2D panel that is at 100, 100, and you want to place text starting at the center of that instrument then you would use the same coordinates... no math necessary.

 

 

In the aircraft I tried (including xp's C172). If I make the planemaker co-ordinates 0,0 for a gauge the centre of it is aligned with the left edge of the screen as expected. However in the vertical plane the middle of the gauge sits about 256 pixels above the bottom edge of the screen. Therefore if I add 256 to my y co-ordinate plus half the gauges height I get the top of the gauge. Weird I know.

Share this post


Link to post
Share on other sites

I was incorrect when I said that the panel coordinates are 0,0 at the bottom left in Planemaker.  I will get back to you on this.

Share this post


Link to post
Share on other sites

OK... in order to understand this (the Planemaker coordinate system) in the best way possible I spoke with Laminar directly.

 

I asked... 

Can you explain the logic behind the (instrument) coordinate system for the 2D/3D panel(s) in Planemaker?

 

The answer was...

"There is no logic - only history . The panel used to be 1024 x 768 - when Austin 'grew' it with vertical scrolling, it was set up so that additional space would be added to the bottom; since +Y = up in X-Plane, this meant the bottom of a full-size panel has to be -256.

It's just something you have to cope with - all datarefs that return panels give you the 'rect of the panel' and let you scale the coordinates, so you can be somewhat agnostic about the origin."

 

So, my suggestion is that you specify your OpenGL coordinates with reference to the PNG and NOT the Planemaker coordinates.  Since you can "reboot" Gizmo and "instantly see" your script changes, this should be easy to do.

 

Jim

Edited by JGregory

Share this post


Link to post
Share on other sites

Thanks for the clarification. It's easy to deal with as you say. Just seemed a little weird to me, but your explanation at least makes some sense to the reasoning behind it.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×