I'm currently programming a primary flight display using Python and OpenGL. As I have zero experience with OpenGL (and little experience with coding in general) I do struggle with most simple feature implementation but until now I got this far:
What my problem now is to rotate the artificial horizon around the center point of the viewport (400x240) according to the roll data. My viewport is 800x480 with the quad representing the artificial horizon having the size of 1000x2880.
Displaying the pitch data is easy because 1 degree equals 8 pixels on the viewport/horizon texture.
Numbers.p_offset = -Data.pitch*8
, which I can just add to all four y-coordinates of the quad.
def horizon():
glBindTexture(GL_TEXTURE_2D, horizontexture)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_TEXTURE_2D)
glColor4f(1, 1, 1, 1)
glBegin(GL_QUADS)
glTexCoord2f(0, 1); glVertex2f(-100, -1200+Numbers.p_offset)
glTexCoord2f(1, 1); glVertex2f(900, -1200+Numbers.p_offset)
glTexCoord2f(1, 0); glVertex2f(900, 1680+Numbers.p_offset)
glTexCoord2f(0, 0); glVertex2f(-100, 1680+Numbers.p_offset)
glEnd()
glDisable(GL_TEXTURE_2D)
What isn't easy is to display the roll data (-180° to 180°), as a change in roll would change the x- and y-coordinate of the quad. First, the pitch offset would need to be applied (to keep the vertical center-line of the quad in the center of the viewport) and then the rotation corresponding to the roll. I cannot figure out the math on how to calculate the offsets roll would cause, so I'm looking for a solution on how to do it with some OpenGL functionality I do not know of yet.
All the tutorials and questions/answers I found were specifically asking on how to rotate the quad around its own center point and not another coordinate.
Question: How is it possible to rotate a quad around a specific coordinate in an orthographic projection in OpenGL and Python?
First you have to define the pivot:
pivot_x = (900 + (-100)) / 2
pivot_y = (-1200 + 1680) / 2
If you want to rotate an object around a pivot then you've to:
Translate the object in that way that way, that the pivot is on the origin (0, 0, 0): glTranslatef(-pivot_x, -pivot_y, 0)
Rotate the object in the xy plane of the view: glRotate(angle, 0, 0, 1)
Translate the rectangle in that way that the pivot is back at its original position: glTranslatef(pivot_x, pivot_y, 0)
Since operations like glTranslated
and glRotated
define a new matrix and multiply it to the current matrix, this instructions have to be done in the reverse order.
Use glPushMatrix
/ glPopMatrix
to save and restore the current matrix before and after the operations. e.g.:
def horizon():
pivot_x = (900 + (-100)) / 2
pivot_y = (-1200 + 1680) / 2
glPushMatrix()
# rotate around pivot (roll)
glTranslatef(pivot_x, pivot_y, 0)
glRotatef(angle, 0, 0, 1)
glTranslatef(-pivot_x, -pivot_y, 0)
# apply pitch
glTranslatef(0, Numbers.p_offset, 0)
glBindTexture(GL_TEXTURE_2D, horizontexture)
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
glEnable(GL_TEXTURE_2D)
glColor4f(1, 1, 1, 1)
glBegin(GL_QUADS)
glTexCoord2f(0, 1); glVertex2f(-100, -1200)
glTexCoord2f(1, 1); glVertex2f(900, -1200)
glTexCoord2f(1, 0); glVertex2f(900, 1680)
glTexCoord2f(0, 0); glVertex2f(-100, 1680)
glEnd()
glDisable(GL_TEXTURE_2D)
glPopMatrix()
(See also How to use Pivot Point in Transformations and How to rotate a 2D line in PyOpenGL?)