diff options
Diffstat (limited to 'txtgameengine')
-rw-r--r-- | txtgameengine/__main__.py | 37 | ||||
-rw-r--r-- | txtgameengine/app.py | 12 | ||||
-rw-r--r-- | txtgameengine/platform.py | 63 |
3 files changed, 87 insertions, 25 deletions
diff --git a/txtgameengine/__main__.py b/txtgameengine/__main__.py index bed2972..84d71ca 100644 --- a/txtgameengine/__main__.py +++ b/txtgameengine/__main__.py @@ -1,34 +1,31 @@ -import glfw -from glfw.GLFW import * +import numpy as np from .app import TxtGameApp - - -def main(): - glfw.init() - glfw.window_hint(GLFW_CLIENT_API, GLFW_NO_API) - window = glfw.create_window(640, 480, "Vulkan window", None, None) - if not window: - glfw.terminate() - return - glfw.swap_interval(1) - while not glfw.window_should_close(window): - glfw.swap_buffers(window) - glfw.poll_events() - glfw.destroy_window(window) - glfw.terminate() +from OpenGL.GL import * class TestApp(TxtGameApp): def __init__(self): - super().__init__((640, 480), "Vulkan window") - self.requested_validation_layers += ["VK_LAYER_KHRONOS_validation"] + super().__init__((640, 480), "OpenGL window") + + def init(self): + self.render.setup_vertex_arrays() + #self.platform.check_debug() + self.default_shaders = self.shaders.load_shaders( + 'base_shaders/vertex.glsl', 'base_shaders/fragment.glsl') + self.tri_buffer = self.render.setup_triangle(np.array([ + -1.0, -1.0, 0.0, + 1.0, -1.0, 0.0, + 0.0, 1.0, 0.0, + ], np.float32)) def update(self, delta: float): super().update(delta) + with self.default_shaders: + self.render.triangle(self.tri_buffer) + if __name__ == '__main__': - # main() a = TestApp() a.start() diff --git a/txtgameengine/app.py b/txtgameengine/app.py index e651078..9f48479 100644 --- a/txtgameengine/app.py +++ b/txtgameengine/app.py @@ -1,21 +1,29 @@ import time -from .platform import PlatformComponent +from .platform import PlatformComponent, RenderComponent, ShaderComponent EPSILON = 1.e-10 class TxtGameApp: PLATFORM_CLASS = PlatformComponent + RENDER_CLASS = RenderComponent + SHADER_CLASS = ShaderComponent def __init__(self, size: (int, int), name: str): self.size = size self.name = name + self.window = None self.platform = self.PLATFORM_CLASS(self) - self.requested_validation_layers = [] + self.render = self.RENDER_CLASS(self) + self.shaders = self.SHADER_CLASS(self) + + def init(self): + pass def start(self): self.platform.init() + self.init() self.platform.set_clear_color(1, 0, 0.75, 1) last_update_time = self.platform.monotonic_time() while not self.platform.should_close: diff --git a/txtgameengine/platform.py b/txtgameengine/platform.py index 0d89213..f5b8ded 100644 --- a/txtgameengine/platform.py +++ b/txtgameengine/platform.py @@ -1,7 +1,8 @@ import glfw import typing -from OpenGL import GL +from OpenGL.GL import * +import OpenGL.GL.shaders as shaders if typing.TYPE_CHECKING: from .app import TxtGameApp @@ -20,6 +21,7 @@ class PlatformComponent: glfw.init() self.init_window() glfw.make_context_current(self.window) + glViewport(0, 0, *self.app.size) @staticmethod def monotonic_time(): @@ -32,6 +34,9 @@ class PlatformComponent: def init_window(self): glfw.window_hint(glfw.CLIENT_API, glfw.OPENGL_API) glfw.window_hint(glfw.RESIZABLE, glfw.FALSE) + glfw.window_hint(glfw.OPENGL_FORWARD_COMPAT, glfw.TRUE) + glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE) + glfw.window_hint(glfw.OPENGL_DEBUG_CONTEXT, glfw.TRUE) glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 3) glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 3) self.window = glfw.create_window( @@ -60,8 +65,60 @@ class PlatformComponent: @staticmethod def set_clear_color(r, g, b, a): - GL.glClearColor(r, g, b, a) + glClearColor(r, g, b, a) + + @staticmethod + def print_debug_message(source, msg_type, msg_id, severity, length, raw, user): + print('OPENGL ERROR', source, msg_type, msg_id, severity) + + def check_debug(self): + assert (glGetIntegerv(GL_CONTEXT_FLAGS) + & GL_CONTEXT_FLAG_DEBUG_BIT) != 0 + glDebugMessageCallback(GLDEBUGPROC(self.print_debug_message), None) @staticmethod def clear_background(depth_buffer=False): - GL.glClear(GL.GL_COLOR_BUFFER_BIT | (depth_buffer and GL.GL_DEPTH_BUFFER_BIT or 0)) + glClear(GL_COLOR_BUFFER_BIT | ( + depth_buffer and GL_DEPTH_BUFFER_BIT or 0)) + + +class ShaderComponent: + def __init__(self, app: 'TxtGameApp'): + self.app = app + + @staticmethod + def load_shaders(vertex_file, fragment_file): + with open(vertex_file) as fp: + vertex_source = fp.read() + with open(fragment_file) as fp: + fragment_source = fp.read() + vertex_shader = shaders.compileShader(vertex_source, GL_VERTEX_SHADER) + fragment_shader = shaders.compileShader( + fragment_source, GL_FRAGMENT_SHADER) + return shaders.compileProgram(vertex_shader, fragment_shader) + + +class RenderComponent: + def __init__(self, app: 'TxtGameApp'): + self.app = app + + @staticmethod + def setup_vertex_arrays(): + arr = glGenVertexArrays(1) + glBindVertexArray(arr) + + @staticmethod + def setup_triangle(arr): + buf = glGenBuffers(1) + glBindBuffer(GL_ARRAY_BUFFER, buf) + glBufferData(GL_ARRAY_BUFFER, arr.itemsize * + arr.size, arr, GL_STATIC_DRAW) + return buf + + @staticmethod + def triangle(buf): + glEnableVertexAttribArray(0) + glBindBuffer(GL_ARRAY_BUFFER, buf) + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None) + glDrawArrays(GL_TRIANGLES, 0, 3) + glDisableVertexAttribArray(0) |