반응형

OpenGL 화면에 Pygame 이미지(스프라이트)를 렌더링 해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = ((1-1-1), (11-1), (-11-1), (-1-1-1),
             (1-11), (111), (-1-11), (-111))
edges = ((0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4),
         (6,7), (5,1), (5,4), (5,7))
 
def drawCube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def drawImage(x, y):
    image = pygame.image.load("player.png").convert()
    image.set_colorkey(image.get_at((00)))
    image = pygame.transform.scale(image, (image.get_width()*1.5,
                                           image.get_height()*1.5))
    imageData = pygame.image.tostring(image, "RGBA"True)
    glWindowPos2d(x-image.get_width()/2, y-image.get_height()/2)
    glDrawPixels(image.get_width(), image.get_height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, imageData)
 
pygame.init()
clock = pygame.time.Clock()
display = (640480)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
 
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
 
gluPerspective(45, (display[0]/display[1]), 0.150.0)
glTranslatef(0.00.0-5)
 
run = True
while run:    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
 
    glRotatef(1311)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    drawCube()
    drawImage(display[0]/2, display[1]/2)
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
exit()
 

 

 

 

반응형
Posted by J-sean
:
반응형

OpenGL 화면에 Pygame 폰트를 렌더링 해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = ((1-1-1), (11-1), (-11-1), (-1-1-1),
             (1-11), (111), (-1-11), (-111))
edges = ((0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4),
         (6,7), (5,1), (5,4), (5,7))
 
def drawCube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def drawText(x, y, text):
    font = pygame.font.SysFont('arial'64)
    textSurface = font.render(text, True, (125125125255), (2552550255))
    textData = pygame.image.tostring(textSurface, "RGBA"True)
    glWindowPos2d(x-textSurface.get_width()/2, y-textSurface.get_height()/2)
    glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, textData)
 
pygame.init()
clock = pygame.time.Clock()
display = (640480)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
 
gluPerspective(45, (display[0]/display[1]), 0.150.0)
glTranslatef(0.00.0-5)
 
run = True
while run:    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
 
    glRotatef(1311)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    drawCube()
    drawText(display[0]/2, display[1]/2"Cube")
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
exit()
 

 

 

 

이번엔 폰트의 배경이 표시되지 않도록 해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = ((1-1-1), (11-1), (-11-1), (-1-1-1),
             (1-11), (111), (-1-11), (-111))
edges = ((0,1), (0,3), (0,4), (2,1), (2,3), (2,7), (6,3), (6,4),
         (6,7), (5,1), (5,4), (5,7))
 
def drawCube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def drawText(x, y, text):
    font = pygame.font.SysFont('arial'64)
    textSurface = font.render(text, True, (125125125255)).convert_alpha()
    textData = pygame.image.tostring(textSurface, "RGBA"True)
    glWindowPos2d(x-textSurface.get_width()/2, y-textSurface.get_height()/2)
    glDrawPixels(textSurface.get_width(), textSurface.get_height(), GL_RGBA,
                 GL_UNSIGNED_BYTE, textData)
 
pygame.init()
clock = pygame.time.Clock()
display = (640480)
pygame.display.set_mode(display, DOUBLEBUF | OPENGL)
 
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
 
gluPerspective(45, (display[0]/display[1]), 0.150.0)
glTranslatef(0.00.0-5)
 
run = True
while run:    
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
 
    glRotatef(1311)
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
    drawCube()
    drawText(display[0]/2, display[1]/2"Cube")
    
    pygame.display.flip()
    clock.tick(60)
 
pygame.quit()
exit()
 

 

 

 

반응형
Posted by J-sean
:

[Pygame] PyOpenGL 파이게임

Python 2023. 9. 11. 23:09 |
반응형

파이게임과 PyOpenGL을 연동해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
verticies = (
    (1-1-1), (11-1),
    (-11-1), (-1-1-1),
    (1-11), (111),
    (-1-11), (-111) )
 
edges = (
    (0,1), (0,3), (0,4),
    (2,1), (2,3), (2,7),
    (6,3), (6,4), (6,7),
    (5,1), (5,4), (5,7) )
 
def Cube():
    glBegin(GL_LINES)
    for edge in edges:
        for vertex in edge:
            glVertex3fv(verticies[vertex])
    glEnd()
 
def main():
    pygame.init()
    display = (640,480)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    clock = pygame.time.Clock()
 
    gluPerspective(45, (display[0]/display[1]), 0.150.0)
 
    glTranslatef(0.00.0-5)
 
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
 
        glRotatef(1312)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        Cube()
 
        pygame.display.flip()
        clock.tick(30)
 
if __name__ == '__main__':
   main()
 

 

 

 

※ 참고

PyOpenGL Tutorial1

PyOpenGL Tutorial2

OpenGL 강좌1

OpenGL 강좌2

 

반응형
Posted by J-sean
:

Python PyOpenGL

Python 2023. 9. 11. 22:59 |
반응형

파이썬에서 OpenGL을 사용해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
 
def Display():
    glClear(GL_COLOR_BUFFER_BIT)
 
    glBegin(GL_QUADS)
    glVertex2f(0.50.5)
    glVertex2f(-0.50.5)
    glVertex2f(-0.5-0.5)
    glVertex2f(0.5-0.5)
    glEnd()
    
    glFlush()
    
if __name__ == "__main__":
    glutInit()
 
    #glutInitDisplayMode(GLUT_RGB)
    #glutInitWindowSize(640, 480)
    #glutInitWindowPosition(400, 300)
    glutCreateWindow("OpenGL")
    glutDisplayFunc(Display)
    glutMainLoop()
 

 

 

윈도우에 사각형이 표시된다.

 

pip install PyOpenGL
pip install PyOpenGL_accelerate

위 명령으로 공식 PyOpenGL, PyOpenGL_accelerate를 설치하면 OpenGL.GLUT에 문제가 있는 경우가 있다. 예를 들어 glutinit()를 실행하면 아래와 같은 에러가 발생한다.

NullFunctionError: Attempt to call an undefined function glutInit, check for bool(glutInit) before calling.

만약 에러가 발생한다면 설치한 패키지를 삭제하고 아래 링크에서 받아 다시 설치한다.

Unofficial Windows Binaries for Python Extension Packages

 

PyOpenGL_accelerate-3.1.6-cp311-cp311-win_amd64.whl
0.34MB
PyOpenGL-3.1.6-cp311-cp311-win_amd64.whl
2.64MB

 

 

하지만 OpenGL.GLUT을 사용하지 않는다면 공식 패키지를 사용해도 상관 없다. Pygame을 사용해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import pygame
from pygame.locals import *
 
from OpenGL.GL import *
from OpenGL.GLU import *
 
def Display():
    glBegin(GL_QUADS)
    glVertex2f(0.50.5)
    glVertex2f(-0.50.5)
    glVertex2f(-0.5-0.5)
    glVertex2f(0.5-0.5)
    glEnd()
 
def main():
    pygame.init()
    display = (640,480)
    pygame.display.set_mode(display, DOUBLEBUF|OPENGL)
    clock = pygame.time.Clock()
 
    gluPerspective(45, (display[0]/display[1]), 0.150.0)
 
    glTranslatef(0.00.0-5)
 
    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
 
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        glRotatef(1312)
        Display()
 
        pygame.display.flip()
        clock.tick(30)
 
if __name__ == '__main__':
   main()
 

 

 

 

※ 참고

OpenGL 강좌

 

반응형
Posted by J-sean
:
반응형

코루틴과 데이터를 교환해서 처리해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import time
 
def MyCoroutine():
    num = 0
    while True:
        x = yield num
        num += 1
        print(x)
        time.sleep(0.5)
 
co = MyCoroutine()
next(co)
time.sleep(1)
# 코루틴을 시작하고 yield 명령에서 대기한다.
 
print(co.send(100))
time.sleep(1)
# 코루틴에 100을 전달(x에 100 대입)하고 num을 받아서 출력한다.
# num 값은 yield 명령이 실행되는 시점에 결정된 값(0)이 아니고
# 코루틴이 끝나는 시점에 결정된 값(1)이 전달된다.
 
print(co.send(200))
time.sleep(1)
# 코루틴에 200을 전달(x에 200 대입)하고 num을 받아서 출력한다.
 
next(co)
# 코루틴에 아무 값도 전달하지 않고(그래서 None이 출력된다) 다음
# yield 까지 진행하고 받아온 num 값은 무시.
 
print(next(co))
# 마찬가지로 코루틴에 아무 값도 전달하지 않고 다름 yield 까지 진행.
# 이번엔 num 값을 받아서 출력한다.
 
co.close()
 

 

 

 

반응형
Posted by J-sean
:
반응형

파이썬에서 여러 작업을 코루틴으로 동시에 진행해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import asyncio
import time
 
async def show_text(text, delay):
    for i in range(5):
        print(text + " " + str(i))
        await asyncio.sleep(delay)
        # coroutine asyncio.sleep(delay, result=None)
        # Block for delay seconds. If result is provided,
        # it is returned to the caller when the coroutine
        # completes. sleep() always suspends the current
        # task, allowing other tasks to run.
    return text
 
async def main():
    #result = await asyncio.gather(
    #    show_text("first", 0.5),
    #    show_text("second", 0.5),
    #    show_text("third", 1)
    #    )
    #print(result)
 
    task1 = asyncio.create_task(show_text("first"0.5))
    task2 = asyncio.create_task(show_text("second"0.5))
    task3 = asyncio.create_task(show_text("third"1))
    # The asyncio.create_task() function to run coroutines
    # concurrently as asyncio Tasks.
 
    await task1
    await task2
    await task3
    # Awaiting on a coroutine.
 
    print("result: " + task1.result())
    print("result: " + task2.result())
    print("result: " + task3.result())
    
if __name__ == "__main__":
    start = time.time()
    asyncio.run(main())
    # The asyncio.run() function to run the top-level
    # entry point “main()” function.
    end = time.time()
    print(end - start)
 

 

 

총 소요시간은 5초이다.

첫 번째, 두 번째, 세 번째 작업의 소요시간 총 합이 아닌, 가장 긴 작업 시간을 가진 세 번째 작업의 소요시간인 5초가 걸린다.

 

Coroutines and Tasks

 

반응형
Posted by J-sean
:
반응형

스레드 클래스를 상속받는 클래스를 정의하고 사용해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import time
import threading
 
class Worker(threading.Thread):
    def __init__(self, name, count, delay):
        super().__init__()
        self.name = name
        self.count = count
        self.delay = delay
 
    # 스레드 클래스를 상속하는 클래스는 run()를 재정의 해야 한다.
    # 객체를 만들고 start()를 실행하면 run()가 실행된다.
    def run(self):
        print(f"{self.name} job started.")
        for i in range(self.count):
            print(f"{self.name} job: {i}.")
            time.sleep(self.delay)
        print(f"{self.name} job finished.")
 
            
print("Main started.")
 
thread_1 = Worker("First"50.5)
#thread_1.daemon = True
# 데몬 스레드로 설정되면 메인 스레드 종료시 서브 스레드도 종료된다.
thread_1.start()
#thread_1.join()
# join()을 실행한 스레드가 종료할 때까지 나머지 스레드는 대기한다.
 
thread_2 = Worker("Second"50.5)
#thread_2.daemon = True
thread_2.start()
#thread_2.join()
 
print(f"■ Number of threads: {threading.active_count()}")
 
time.sleep(1)
 
print("Main finished.")
 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import time
import threading
 
class Worker(threading.Thread):
    def __init__(self, name, count, delay):
        super().__init__()
        self.name = name
        self.count = count
        self.delay = delay
        
    def run(self):
        print(f"{self.name} job started.")
        for i in range(self.count):
            print(f"{self.name} job: {i}.")
            time.sleep(self.delay)
        print(f"{self.name} job finished.")
 
thread_1 = Worker("First"50.5)
thread_2 = Worker("Second"50.5)
thread_3 = Worker("Third"50.5)
threads = [thread_1, thread_2, thread_3]
 
print(f"■ Number of threads: {threading.active_count()}")
# 활성화된 스레드는 메인스레드 뿐이므로 1이 표시된다.
 
for thread in threads:
    thread.start()
    thread.join()
 

 

 

 

thread - Thread-based parallelism

 

반응형
Posted by J-sean
:
반응형

멀티 스레드를 사용해 보자.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import time
import threading
 
def Job(name, count, delay):
    print(f"{name} job started.")
    for i in range(count):
        print(f"{name} job: {i}.")
        time.sleep(delay)
    print(f"{name} job finished.")
 
print("Main started.")
 
thread_1 = threading.Thread(target=Job, args=("First"50.5))
thread_1.start()
 
thread_2 = threading.Thread(target=Job, args=("Second"50.5))
thread_2.start()
 
print(f"■ Number of threads: {threading.active_count()}")
 
time.sleep(1)
 
print("Main finished.")
 

 

 

■ threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

- target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.
- args is a list or tuple of arguments for the target invocation. Defaults to ().

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import time
import threading
 
def Job(name, count, delay):
    print(f"{name} job started.")
    for i in range(count):
        print(f"{name} job: {i}.")
        time.sleep(delay)
    print(f"{name} job finished.")
 
print("Main started.")
 
thread_1 = threading.Thread(target=Job, args=("First"50.5))
thread_1.daemon = True
thread_1.start()
 
thread_2 = threading.Thread(target=Job, args=("Second"50.5))
thread_2.daemon = True
thread_2.start()
 
print(f"■ Number of threads: {threading.active_count()}")
 
time.sleep(1)
 
print("Main finished.")
 

 

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import time
import threading
 
def Job(name, count, delay):
    print(f"{name} job started.")
    for i in range(count):
        print(f"{name} job: {i}.")
        time.sleep(delay)
    print(f"{name} job finished.")
 
print("Main started.")
 
thread_1 = threading.Thread(target=Job, args=("First"50.5))
thread_1.start()
thread_1.join()
 
thread_2 = threading.Thread(target=Job, args=("Second"50.5))
thread_2.start()
thread_2.join()
 
print(f"■ Number of threads: {threading.active_count()}")
 
time.sleep(1)
 
print("Main finished.")
 

 

 

■ join(timeout=None)

- Wait until the thread terminates. This blocks the calling thread until the thread whose join() method is called terminates – either normally or through an unhandled exception – or until the optional timeout occurs.
- When the timeout argument is present and not None, it should be a floating point number specifying a timeout for the operation in seconds (or fractions thereof). As join() always returns None, you must call is_alive() after join() to decide whether a timeout happened – if the thread is still alive, the join() call timed out.
- When the timeout argument is not present or None, the operation will block until the thread terminates.
- A thread can be joined many times.

 

 

반응형
Posted by J-sean
: