简体   繁体   English

如何在 OpenGL 中旋转矩形?

[英]How can I rotate rectangles in OpenGL?

Rectangles become distorted when I use glRotatef.当我使用 glRotatef 时,矩形会变形。 I know that it's important to bring images to the center of the screen before rotating.我知道在旋转之前将图像置于屏幕中央很重要。 I'm pretty sure I'm doing that:我很确定我正在这样做:

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('')

Am I missing something?我错过了什么吗?

I attached example images.我附上了示例图像。

Rotated:旋转:

旋转的

Not rotated:不旋转:

没有旋转

Your images are distorted because of the aspect ratio of the viewport.由于视口的纵横比,您的图像失真。 You need to set up an Orthographic projection matrix that takes the aspect ratio into account with glOrtho .您需要设置一个Orthographic 投影矩阵,使用glOrtho考虑纵横比。 Set the projection matrix once before the application loop:在应用程序循环之前设置一次投影矩阵:

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM