Start work on OpenGL bindings
This commit is contained in:
parent
8636ddf3cd
commit
3ecf3751ef
@ -1,5 +1 @@
|
|||||||
import OpenGL
|
|
||||||
|
|
||||||
# PyOpenGL error checking is extremely slow, so disable it, since by default it
|
|
||||||
# runs for every call into the OpenGL API
|
|
||||||
OpenGL.ERROR_CHECKING = False
|
|
||||||
|
|||||||
@ -9,24 +9,26 @@
|
|||||||
extern int init_LineBuf(PyObject *);
|
extern int init_LineBuf(PyObject *);
|
||||||
extern int init_Cursor(PyObject *);
|
extern int init_Cursor(PyObject *);
|
||||||
extern int init_Line(PyObject *);
|
extern int init_Line(PyObject *);
|
||||||
|
#include "gl.h"
|
||||||
|
|
||||||
static PyMethodDef module_methods[] = {
|
static PyMethodDef module_methods[] = {
|
||||||
|
GL_METHODS
|
||||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static struct PyModuleDef module = {
|
static struct PyModuleDef module = {
|
||||||
PyModuleDef_HEAD_INIT,
|
.m_base = PyModuleDef_HEAD_INIT,
|
||||||
"fast_data_types", /* name of module */
|
.m_name = "fast_data_types", /* name of module */
|
||||||
NULL,
|
.m_doc = NULL,
|
||||||
-1,
|
.m_size = -1,
|
||||||
module_methods
|
.m_methods = module_methods
|
||||||
};
|
};
|
||||||
|
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
PyInit_fast_data_types(void) {
|
PyInit_fast_data_types(void) {
|
||||||
PyObject *m;
|
PyObject *m;
|
||||||
|
|
||||||
|
|
||||||
m = PyModule_Create(&module);
|
m = PyModule_Create(&module);
|
||||||
if (m == NULL) return NULL;
|
if (m == NULL) return NULL;
|
||||||
|
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import sys
|
|||||||
from kitty.shaders import ShaderProgram, GL_VERSION, Sprites, check_for_required_extensions
|
from kitty.shaders import ShaderProgram, GL_VERSION, Sprites, check_for_required_extensions
|
||||||
from kitty.fonts import set_font_family, cell_size
|
from kitty.fonts import set_font_family, cell_size
|
||||||
from kitty.char_grid import calculate_vertices, cell_shader
|
from kitty.char_grid import calculate_vertices, cell_shader
|
||||||
|
from kitty.fast_data_types import glViewport, enable_automatic_opengl_error_checking
|
||||||
|
|
||||||
|
|
||||||
def rectangle_uv(left=0, top=0, right=1, bottom=1):
|
def rectangle_uv(left=0, top=0, right=1, bottom=1):
|
||||||
@ -37,7 +38,7 @@ class Renderer:
|
|||||||
self.do_layout()
|
self.do_layout()
|
||||||
|
|
||||||
def on_resize(self, window, w, h):
|
def on_resize(self, window, w, h):
|
||||||
gl.glViewport(0, 0, w, h)
|
glViewport(0, 0, w, h)
|
||||||
self.w, self.h = w, h
|
self.w, self.h = w, h
|
||||||
self.do_layout()
|
self.do_layout()
|
||||||
|
|
||||||
@ -137,6 +138,7 @@ def main():
|
|||||||
glfw.glfwSetErrorCallback(on_error)
|
glfw.glfwSetErrorCallback(on_error)
|
||||||
if not glfw.glfwInit():
|
if not glfw.glfwInit():
|
||||||
raise SystemExit('GLFW initialization failed')
|
raise SystemExit('GLFW initialization failed')
|
||||||
|
enable_automatic_opengl_error_checking(True)
|
||||||
set_font_family('monospace', 144)
|
set_font_family('monospace', 144)
|
||||||
try:
|
try:
|
||||||
_main()
|
_main()
|
||||||
|
|||||||
63
kitty/gl.h
Normal file
63
kitty/gl.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* gl.c
|
||||||
|
* Copyright (C) 2016 Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the GPL3 license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "data-types.h"
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
#define STRINGIFY(x) #x
|
||||||
|
#define METH(name, argtype) {STRINGIFY(gl##name), (PyCFunction)name, argtype, NULL},
|
||||||
|
|
||||||
|
static int _enable_error_checking = 1;
|
||||||
|
|
||||||
|
#define SET_GL_ERR \
|
||||||
|
switch(glGetError()) { \
|
||||||
|
case GL_NO_ERROR: break; \
|
||||||
|
case GL_INVALID_ENUM: \
|
||||||
|
PyErr_SetString(PyExc_ValueError, "An enum value is invalid (GL_INVALID_ENUM)"); break; \
|
||||||
|
case GL_INVALID_VALUE: \
|
||||||
|
PyErr_SetString(PyExc_ValueError, "An numeric value is invalid (GL_INVALID_VALUE)"); break; \
|
||||||
|
case GL_INVALID_OPERATION: \
|
||||||
|
PyErr_SetString(PyExc_ValueError, "This operation is not allowed in the current state (GL_INVALID_OPERATION)"); break; \
|
||||||
|
case GL_INVALID_FRAMEBUFFER_OPERATION: \
|
||||||
|
PyErr_SetString(PyExc_ValueError, "The framebuffer object is not complete (GL_INVALID_FRAMEBUFFER_OPERATION)"); break; \
|
||||||
|
case GL_OUT_OF_MEMORY: \
|
||||||
|
PyErr_SetString(PyExc_MemoryError, "There is not enough memory left to execute the command. (GL_OUT_OF_MEMORY)"); break; \
|
||||||
|
case GL_STACK_UNDERFLOW: \
|
||||||
|
PyErr_SetString(PyExc_OverflowError, "An attempt has been made to perform an operation that would cause an internal stack to underflow. (GL_STACK_UNDERFLOW)"); break; \
|
||||||
|
case GL_STACK_OVERFLOW: \
|
||||||
|
PyErr_SetString(PyExc_OverflowError, "An attempt has been made to perform an operation that would cause an internal stack to underflow. (GL_STACK_UNDERFLOW)"); break; \
|
||||||
|
default: \
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "An unknown OpenGL error occurred."); break; \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK_ERROR if (_enable_error_checking) { SET_GL_ERR; if (PyErr_Occurred()) return NULL; }
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
enable_automatic_error_checking(PyObject UNUSED *self, PyObject *val) {
|
||||||
|
_enable_error_checking = PyObject_IsTrue(val) ? 1 : 0;
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
Viewport(PyObject UNUSED *self, PyObject *args) {
|
||||||
|
unsigned int x, y, w, h;
|
||||||
|
if (!PyArg_ParseTuple(args, "IIII", &x, &y, &w, &h)) return NULL;
|
||||||
|
glViewport(x, y, w, h);
|
||||||
|
CHECK_ERROR;
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject*
|
||||||
|
CheckError(PyObject UNUSED *self) {
|
||||||
|
CHECK_ERROR; Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GL_METHODS \
|
||||||
|
{"enable_automatic_opengl_error_checking", (PyCFunction)enable_automatic_error_checking, METH_O, NULL}, \
|
||||||
|
METH(Viewport, METH_VARARGS) \
|
||||||
|
METH(CheckError, METH_NOARGS) \
|
||||||
|
|
||||||
7
setup.py
7
setup.py
@ -21,6 +21,10 @@ version = tuple(map(int, re.search(r"^version = \((\d+), (\d+), (\d+)\)", consta
|
|||||||
cflags = ldflags = cc = ldpaths = None
|
cflags = ldflags = cc = ldpaths = None
|
||||||
|
|
||||||
|
|
||||||
|
def pkg_config(pkg, *args):
|
||||||
|
return shlex.split(subprocess.check_output(['pkg-config', pkg] + list(args)).decode('utf-8'))
|
||||||
|
|
||||||
|
|
||||||
def init_env():
|
def init_env():
|
||||||
global cflags, ldflags, cc, ldpaths
|
global cflags, ldflags, cc, ldpaths
|
||||||
cc = os.environ.get('CC', 'gcc')
|
cc = os.environ.get('CC', 'gcc')
|
||||||
@ -34,11 +38,12 @@ def init_env():
|
|||||||
ldflags += shlex.split(os.environ.get('LDFLAGS', ''))
|
ldflags += shlex.split(os.environ.get('LDFLAGS', ''))
|
||||||
|
|
||||||
cflags.append('-pthread')
|
cflags.append('-pthread')
|
||||||
|
cflags.extend(pkg_config('glew', '--cflags-only-I'))
|
||||||
ldflags.append('-pthread')
|
ldflags.append('-pthread')
|
||||||
ldflags.append('-shared')
|
ldflags.append('-shared')
|
||||||
cflags.append('-I' + sysconfig.get_config_var('CONFINCLUDEPY'))
|
cflags.append('-I' + sysconfig.get_config_var('CONFINCLUDEPY'))
|
||||||
lib = sysconfig.get_config_var('LDLIBRARY')[3:-3]
|
lib = sysconfig.get_config_var('LDLIBRARY')[3:-3]
|
||||||
ldpaths = ['-L' + sysconfig.get_config_var('LIBDIR'), '-l' + lib]
|
ldpaths = ['-L' + sysconfig.get_config_var('LIBDIR'), '-l' + lib] + pkg_config('glew', '--libs')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.mkdir(build_dir)
|
os.mkdir(build_dir)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user