Mercurial > touhou
comparison pytouhou/ui/opengl/framebuffer.pyx @ 586:4b0593da29d5
Simplify framebuffer rendering with glDrawArrays, and move it all to its own file.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Wed, 08 Oct 2014 16:34:24 +0200 |
parents | |
children | 6c9d8a3d853f |
comparison
equal
deleted
inserted
replaced
585:e0166cda75d5 | 586:4b0593da29d5 |
---|---|
1 # -*- encoding: utf-8 -*- | |
2 ## | |
3 ## Copyright (C) 2014 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> | |
4 ## | |
5 ## This program is free software; you can redistribute it and/or modify | |
6 ## it under the terms of the GNU General Public License as published | |
7 ## by the Free Software Foundation; version 3 only. | |
8 ## | |
9 ## This program is distributed in the hope that it will be useful, | |
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ## GNU General Public License for more details. | |
13 ## | |
14 | |
15 from pytouhou.lib.opengl cimport \ | |
16 (glPushDebugGroup, glPopDebugGroup, GL_DEBUG_SOURCE_APPLICATION, | |
17 glGenTextures, glDeleteTextures, glBindTexture, glTexParameteri, | |
18 glTexImage2D, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, | |
19 GL_TEXTURE_MAG_FILTER, GL_LINEAR, GL_RGBA, GL_UNSIGNED_BYTE, | |
20 glGenRenderbuffers, glDeleteRenderbuffers, glBindRenderbuffer, | |
21 glRenderbufferStorage, GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, | |
22 glGenFramebuffers, glDeleteFramebuffers, glBindFramebuffer, | |
23 glFramebufferTexture2D, glFramebufferRenderbuffer, | |
24 glCheckFramebufferStatus, GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, | |
25 GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_COMPLETE, glGenBuffers, | |
26 glDeleteBuffers, glBindBuffer, glBufferData, GL_ARRAY_BUFFER, | |
27 GL_STATIC_DRAW, glGenVertexArrays, glDeleteVertexArrays, | |
28 glBindVertexArray, glVertexAttribPointer, GL_SHORT, GL_FLOAT, | |
29 glEnableVertexAttribArray, glDrawArrays, GL_TRIANGLE_STRIP) | |
30 | |
31 from .backend cimport use_debug_group, use_vao | |
32 | |
33 cdef class Framebuffer: | |
34 def __init__(self, int x, int y, int width, int height): | |
35 if use_debug_group: | |
36 glPushDebugGroup(GL_DEBUG_SOURCE_APPLICATION, 0, -1, "Framebuffer creation") | |
37 | |
38 # This texture will receive the game area in native resolution. | |
39 glGenTextures(1, &self.texture) | |
40 glBindTexture(GL_TEXTURE_2D, self.texture) | |
41 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) | |
42 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) | |
43 glTexImage2D(GL_TEXTURE_2D, 0, | |
44 GL_RGBA, | |
45 width, height, | |
46 0, | |
47 GL_RGBA, GL_UNSIGNED_BYTE, | |
48 NULL) | |
49 glBindTexture(GL_TEXTURE_2D, 0) | |
50 | |
51 # We need a depth buffer, but don’t care about retrieving it. | |
52 glGenRenderbuffers(1, &self.rbo) | |
53 glBindRenderbuffer(GL_RENDERBUFFER, self.rbo) | |
54 glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height) | |
55 glBindRenderbuffer(GL_RENDERBUFFER, 0) | |
56 | |
57 # The framebuffer is there as a rendering target. | |
58 glGenFramebuffers(1, &self.fbo) | |
59 glBindFramebuffer(GL_FRAMEBUFFER, self.fbo) | |
60 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self.texture, 0) | |
61 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self.rbo) | |
62 assert glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE | |
63 glBindFramebuffer(GL_FRAMEBUFFER, 0) | |
64 | |
65 # We’ll use only those vertices, everytime. | |
66 self.buf[0] = PassthroughVertex(x, y, 0, 1) | |
67 self.buf[1] = PassthroughVertex(x + width, y, 1, 1) | |
68 self.buf[2] = PassthroughVertex(x, y + height, 0, 0) | |
69 self.buf[3] = PassthroughVertex(x + width, y + height, 1, 0) | |
70 | |
71 # Now we upload those vertices into a static vbo. | |
72 glGenBuffers(1, &self.vbo) | |
73 glBindBuffer(GL_ARRAY_BUFFER, self.vbo) | |
74 glBufferData(GL_ARRAY_BUFFER, sizeof(self.buf), self.buf, GL_STATIC_DRAW) | |
75 | |
76 # As a performance optimisation, if supported, store the rendering state into a vao. | |
77 if use_vao: | |
78 glGenVertexArrays(1, &self.vao) | |
79 glBindVertexArray(self.vao) | |
80 self.set_state() | |
81 glBindVertexArray(0) | |
82 | |
83 glBindBuffer(GL_ARRAY_BUFFER, 0) | |
84 | |
85 if use_debug_group: | |
86 glPopDebugGroup() | |
87 | |
88 def __dealloc__(self): | |
89 if use_vao: | |
90 glDeleteVertexArrays(1, &self.vao) | |
91 glDeleteTextures(1, &self.texture) | |
92 glDeleteRenderbuffers(1, &self.rbo) | |
93 glDeleteFramebuffers(1, &self.fbo) | |
94 glDeleteBuffers(1, &self.vbo) | |
95 | |
96 cpdef bind(self): | |
97 glBindFramebuffer(GL_FRAMEBUFFER, self.fbo) | |
98 | |
99 cdef void set_state(self) nogil: | |
100 glBindBuffer(GL_ARRAY_BUFFER, self.vbo) | |
101 | |
102 #TODO: find a way to use offsetof() instead of those ugly hardcoded values. | |
103 glVertexAttribPointer(0, 2, GL_SHORT, False, sizeof(PassthroughVertex), <void*>0) | |
104 glEnableVertexAttribArray(0) | |
105 glVertexAttribPointer(1, 2, GL_FLOAT, False, sizeof(PassthroughVertex), <void*>4) | |
106 glEnableVertexAttribArray(1) | |
107 | |
108 cdef void render(self) nogil: | |
109 if use_vao: | |
110 glBindVertexArray(self.vao) | |
111 else: | |
112 self.set_state() | |
113 | |
114 glBindTexture(GL_TEXTURE_2D, self.texture) | |
115 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) | |
116 glBindTexture(GL_TEXTURE_2D, 0) | |
117 | |
118 if use_vao: | |
119 glBindVertexArray(0) | |
120 else: | |
121 glBindBuffer(GL_ARRAY_BUFFER, 0) |