(Py)SDL2: рисование текстурированного полигона

PySDL2 version: 0.9.3
SDL2 version: 2.0.3

Я пытаюсь отобразить это изображение как текстуру на многоугольнике в PySDL2, используя sdl_gfx.

введите здесь описание изображения

но его отображение полностью искажено, как видно в правом нижнем углу в окне SDL:

введите здесь описание изображения

У меня есть эта программа на Python, в которой я тестирую все функции рисования sdlgfx, которые Я реализовал в класс FrameBuffer, который заботится о рисовании и рендеринг. Все они работают хорошо, за исключением сглаженного полигона (средний зеленый шестиугольник, но это другой вопрос, в другой раз) и текстурированного полигона.

Чтобы предоставить более простой сценарий, я выполнил следующие шаги, чтобы нарисовать текстурированный многоугольник:

# Initialize SDL2 and window
import sdl2
import sdl2.ext
import sdl2.sdlgfx
import ctypes
sdl2.ext.init()
window = sdl2.ext.Window(size=(800,600))
window.show()

# Create renderer and factories
renderer = sdl2.ext.Renderer(window)
renderer.clear(0)
renderer.present()
# Create sprite factory to create textures with later
texture_factory = sdl2.ext.SpriteFactory(renderer=renderer)
# Create sprite factory to create surfaces with later
surface_factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)

# Determine path to image to use as texture
RESOURCES = sdl2.ext.Resources(__file__, "LSD/resources")
image_path = RESOURCES.get_path("Memory.jpeg")

# set polygon coordinates
x = 100
row4 = 470
vx = [x, x+200, x+200, x]
vy = [row4-50, row4-50, row4+50, row4+50]

# Calculate the length of the vectors (which should be the same for x and y)
n = len(vx) 
# Make sure all coordinates are integers
vx = map(int,vx)
vy = map(int,vy)
# Cast the list to the appropriate ctypes vectors reabable by
# the sdlgfx polygon functions
vx = ctypes.cast((sdl2.Sint16*n)(*vx), ctypes.POINTER(sdl2.Sint16))
vy = ctypes.cast((sdl2.Sint16*n)(*vy), ctypes.POINTER(sdl2.Sint16))

# Load the image on an SoftwareSprite
# The underlying surface is available at SoftwareSprite.surface
texture = surface_factory.from_image(image_path)

## RENDER THE POLYGON WITH TEXTURE
sdl2.sdlgfx.texturedPolygon(renderer.renderer, vx, vy, n,\
texture.surface, 0, 0)

# Swap buffers
renderer.present()

# Handle window close events
processor = sdl2.ext.TestEventProcessor()
processor.run(window)

sdl2.ext.quit()

Этот приведенный выше пример сценария просто выводит:

введите здесь описание изображения

Я считаю, что работать с SDL2 с преобразованиями ctype и всем остальным довольно сложно, и я очень рад, что продвинулся так далеко, но, похоже, мне не удается решить эту проблему самостоятельно. Кто-нибудь знает, на каком этапе я делаю ошибку, или кто-нибудь может указать мне правильное направление?

В качестве примечания я знаю, что PySDL имеет фабричные функции для рендеринга изображений, и они работают очень хорошо, но я действительно хочу, чтобы опция текстурирования полигонов тоже работала.


person Daniel Schreij    schedule 07.05.2015    source источник


Ответы (2)


Я обнаружил, что это просто ошибка в базовой библиотеке sdl2_gfx на уровне C/DLL. Домашняя версия sdl2_gfx — 1.0.0, а версия 1.0.1 (15 июня 2014 г.) уже выпущена. Я протестировал его на Windows и Ubuntu, на которых у меня был доступен sdl2_gfx 1.0.1, и текстурированный полигон отрисовывался правильно (хотя использование параметров смещения для меня все еще немного сомнительно).

Итог: не используйте sdl2_gfx 1.0.0, если вы хотите использовать текстурированные полигоны, так как там он просто не работает. Попробуйте заполучить v1.0.1.

person Daniel Schreij    schedule 13.05.2015

Ваша проблема заключается в отсутствующей реализации цикла событий. TestEventProcessor обрабатывает не обновления окон на основе текстур, а чисто программные буферы. Вместо этого вы хотите что-то вроде строк:

## RENDER THE POLYGON WITH TEXTURE
sdl2.sdlgfx.texturedPolygon(renderer.renderer, vx, vy, n,texture.surface, 0, 0)

running = True
while running:
    events = sdl2.ext.get_events()
    for event in events:
        if event.type == sdl2.SDL_QUIT:
            running = False
            break
    # Add some time step here
    renderer.present()

sdl2.ext.quit()

Взгляните на пример gfxdrawing.py для простой реализации.

person Marcus    schedule 10.05.2015
comment
Спасибо за ответ! К сожалению, я все еще получаю такое же искаженное отображение текстуры после реализации этого цикла событий. Странно, что отображение изображений и т. Д. Работает, поскольку я также полагаю, что это делается как рендеринг текстуры под капотом? - person Daniel Schreij; 10.05.2015