summaryrefslogtreecommitdiff
path: root/txtgameengine
diff options
context:
space:
mode:
Diffstat (limited to 'txtgameengine')
-rw-r--r--txtgameengine/__main__.py37
-rw-r--r--txtgameengine/app.py12
-rw-r--r--txtgameengine/platform.py63
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)