如何在OpenGL中旋转矩形?

0yg35tkg  于 2023-01-02  发布在  其他
关注(0)|答案(1)|浏览(160)

当我使用glRotatef时,矩形会扭曲。我知道在旋转之前将图像置于屏幕中心很重要。我非常确定我正在这样做:

import os
import pygame
from PIL import Image
from pathlib import Path
from numpy import array
import pygame
import math
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GL import glClear, GL_COLOR_BUFFER_BIT, glBegin, GL_QUADS, glEnd, glColor3f, glVertex2f, glFlush, glClearColor

os.environ['SDL_VIDEO_CENTERED'] = '1'
windowSize = (1500, 800)
Screen = pygame.display.set_mode(windowSize, pygame.DOUBLEBUF | pygame.OPENGL)

HOME = str(Path.home())
path = HOME + '\\Desktop\piston2.png'
path2 = HOME + '\\Desktop\piston3.png'
path3 = HOME + '\\Desktop\Piston Platformer2\Images\Flower1.png'

def loadTexture(texture, flip):
  try:
    text = Image.open(texture)
  except IOError as ex:
    print("Failed to open texture file: ", texture)
    text = Image.open("0.png")
  textData = array(list(text.getdata()))
  textID = glGenTextures(1)
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
  glBindTexture(GL_TEXTURE_2D, textID)
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER)
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0)
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0)
  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, text.size[0], text.size[1], 0, GL_RGBA, GL_UNSIGNED_BYTE, textData)
  text.close()
  return (text.size[0], text.size[1]), textID

def make_opengl_rect(image_sizes, cur_ID, offsets, rotate):
  texts = ((1, 0), (1, 1), (0, 1), (0, 0))
  x_ratio = image_sizes[0]/windowSize[0]
  y_ratio = image_sizes[1]/windowSize[1]
  offset_x = 2*(offsets[0]/windowSize[0])
  offset_y = 2*(offsets[1]/windowSize[1])
  verts = [(2*x_ratio, 2*y_ratio), (2*x_ratio, 0), (0, 0), (0, 2*y_ratio)] # upright, downright, downleft, upleft
  additional_offset_x, additional_offset_y = 0, 0
  verts = [(x-1+offset_x+additional_offset_x, y+1-verts[0][1]-offset_y+additional_offset_y) for (x, y) in verts]
  print('verts', verts)
  if rotate != 0:
    glPushMatrix()
    glTranslatef(-verts[0][0], -verts[0][1], 0)
    glRotatef(rotate, 0, 0, 1)
    glTranslatef(verts[0][0], verts[0][1], 0)
  glEnable(GL_TEXTURE_2D)
  glBindTexture(GL_TEXTURE_2D, cur_ID)
  glBegin(GL_QUADS)
  for i in range(4):
    glTexCoord2f(texts[i][0], texts[i][1])
    glVertex2f(verts[i][0], verts[i][1])
  glEnd()
  print('verts', verts)
  if rotate != 0:
    glPopMatrix()
  glDisable(GL_TEXTURE_2D)

my_image1_sizes, my_image1_ID = loadTexture(path, False)
my_image2_sizes, my_image2_ID = loadTexture(path2, False)
my_image3_sizes, my_image3_ID = loadTexture(path3, True)

glEnable(GL_BLEND)
glBlendEquation(GL_FUNC_ADD)

running = True

while running:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      raise SystemExit
    elif event.type == pygame.KEYDOWN:
      if event.key == pygame.K_ESCAPE:
        raise SystemExit
  #
  glClear(GL_COLOR_BUFFER_BIT)
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
  #make_opengl_rect(my_image1_sizes, my_image1_ID, (100,100), 0)
  #make_opengl_rect(my_image2_sizes, my_image2_ID, (100,100), 0)
  make_opengl_rect(my_image3_sizes, my_image3_ID, (300,300), 340)
  glFlush()
  pygame.display.flip()
  print('')

我错过什么了吗?
我附上了示例图片。
旋转:

未旋转:

axzmvihb

axzmvihb1#

由于视口的纵横比,您的图像会扭曲。您需要设置一个Orthographic projection矩阵,该矩阵将纵横比与glOrtho考虑在内。在应用程序循环之前设置一次投影矩阵:

w, h = Screen.get_size()
aspect = w / h

glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(-aspect, aspect, -1, 1, -1, 1)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            raise SystemExit
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                raise SystemExit
  
    glClear(GL_COLOR_BUFFER_BIT)
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    #make_opengl_rect(my_image1_sizes, my_image1_ID, (100,100), 0)
    #make_opengl_rect(my_image2_sizes, my_image2_ID, (100,100), 0)
    make_opengl_rect(my_image3_sizes, my_image3_ID, (300,300), 340)
    glFlush()
    pygame.display.flip()

相关问题