Mercurial > touhou
diff pytouhou/ui/renderer.pyx @ 462:a71b912b45b7
Render to framebuffers first, and reposition some interface elements in the game area.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Wed, 11 Sep 2013 00:36:50 +0200 |
parents | 6af3854ed826 |
children | 36bc577b2392 |
line wrap: on
line diff
--- a/pytouhou/ui/renderer.pyx +++ b/pytouhou/ui/renderer.pyx @@ -22,8 +22,16 @@ from pytouhou.lib.opengl cimport \ glBindTexture, glDrawElements, glBindBuffer, glBufferData, GL_ARRAY_BUFFER, GL_DYNAMIC_DRAW, GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_INT, GL_FLOAT, GL_SRC_ALPHA, - GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_TEXTURE_2D, GL_TRIANGLES, - glGenBuffers) + GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO, GL_TEXTURE_2D, GL_TRIANGLES, + glGenBuffers, glBindFramebuffer, glViewport, glDeleteBuffers, + glGenTextures, glTexParameteri, glTexImage2D, glGenRenderbuffers, + glBindRenderbuffer, glRenderbufferStorage, glGenFramebuffers, + glFramebufferTexture2D, glFramebufferRenderbuffer, + glCheckFramebufferStatus, GL_FRAMEBUFFER, GL_TEXTURE_MIN_FILTER, + GL_LINEAR, GL_TEXTURE_MAG_FILTER, GL_RGBA, GL_RENDERBUFFER, + GL_DEPTH_COMPONENT, GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, + GL_FRAMEBUFFER_COMPLETE, glClear, GL_COLOR_BUFFER_BIT, + GL_DEPTH_BUFFER_BIT) from pytouhou.lib.sdl import SDLError @@ -63,6 +71,10 @@ cdef class Renderer: def __dealloc__(self): free(self.vertex_buffer) + if not self.use_fixed_pipeline: + glDeleteBuffers(1, &self.framebuffer_vbo) + glDeleteBuffers(1, &self.vbo) + def __init__(self, resource_loader): self.texture_manager = TextureManager(resource_loader, self) @@ -75,6 +87,7 @@ cdef class Renderer: if not self.use_fixed_pipeline: glGenBuffers(1, &self.vbo) + glGenBuffers(1, &self.framebuffer_vbo) def add_texture(self, int texture): @@ -202,3 +215,71 @@ cdef class Renderer: if not self.use_fixed_pipeline: glBindBuffer(GL_ARRAY_BUFFER, 0) + + + cpdef render_framebuffer(self, Framebuffer fb): + cdef PassthroughVertex[4] buf + cdef unsigned short indices[6] + indices[:] = [0, 1, 2, 2, 3, 0] + + assert not self.use_fixed_pipeline + + glBindFramebuffer(GL_FRAMEBUFFER, 0) + glViewport(0, 0, 640, 480) + glBlendFunc(GL_ONE, GL_ZERO) + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) + + glBindBuffer(GL_ARRAY_BUFFER, self.framebuffer_vbo) + + #TODO: find a way to use offsetof() instead of those ugly hardcoded values. + glVertexAttribPointer(0, 2, GL_INT, False, sizeof(PassthroughVertex), <void*>0) + glEnableVertexAttribArray(0) + glVertexAttribPointer(1, 2, GL_FLOAT, False, sizeof(PassthroughVertex), <void*>8) + glEnableVertexAttribArray(1) + + buf[0] = PassthroughVertex(fb.x, fb.y, 0, 1) + buf[1] = PassthroughVertex(fb.x + fb.width, fb.y, 1, 1) + buf[2] = PassthroughVertex(fb.x + fb.width, fb.y + fb.height, 1, 0) + buf[3] = PassthroughVertex(fb.x, fb.y + fb.height, 0, 0) + glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(PassthroughVertex), buf, GL_DYNAMIC_DRAW) + + glBindTexture(GL_TEXTURE_2D, fb.texture) + glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices) + glBindTexture(GL_TEXTURE_2D, 0) + + glBindBuffer(GL_ARRAY_BUFFER, 0) + + +cdef class Framebuffer: + def __init__(self, int x, int y, int width, int height): + self.x = x + self.y = y + self.width = width + self.height = height + + glGenTextures(1, &self.texture) + glBindTexture(GL_TEXTURE_2D, self.texture) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGBA, + width, height, + 0, + GL_RGBA, GL_UNSIGNED_BYTE, + NULL) + glBindTexture(GL_TEXTURE_2D, 0) + + glGenRenderbuffers(1, &self.rbo) + glBindRenderbuffer(GL_RENDERBUFFER, self.rbo) + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, width, height) + glBindRenderbuffer(GL_RENDERBUFFER, 0) + + glGenFramebuffers(1, &self.fbo) + glBindFramebuffer(GL_FRAMEBUFFER, self.fbo) + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, self.texture, 0) + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, self.rbo) + assert glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE + glBindFramebuffer(GL_FRAMEBUFFER, 0) + + cpdef bind(self): + glBindFramebuffer(GL_FRAMEBUFFER, self.fbo)