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_Cursor(PyObject *);
|
||||
extern int init_Line(PyObject *);
|
||||
#include "gl.h"
|
||||
|
||||
static PyMethodDef module_methods[] = {
|
||||
GL_METHODS
|
||||
{NULL, NULL, 0, NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
||||
static struct PyModuleDef module = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"fast_data_types", /* name of module */
|
||||
NULL,
|
||||
-1,
|
||||
module_methods
|
||||
.m_base = PyModuleDef_HEAD_INIT,
|
||||
.m_name = "fast_data_types", /* name of module */
|
||||
.m_doc = NULL,
|
||||
.m_size = -1,
|
||||
.m_methods = module_methods
|
||||
};
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_fast_data_types(void) {
|
||||
PyObject *m;
|
||||
|
||||
|
||||
m = PyModule_Create(&module);
|
||||
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.fonts import set_font_family, cell_size
|
||||
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):
|
||||
@ -37,7 +38,7 @@ class Renderer:
|
||||
self.do_layout()
|
||||
|
||||
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.do_layout()
|
||||
|
||||
@ -137,6 +138,7 @@ def main():
|
||||
glfw.glfwSetErrorCallback(on_error)
|
||||
if not glfw.glfwInit():
|
||||
raise SystemExit('GLFW initialization failed')
|
||||
enable_automatic_opengl_error_checking(True)
|
||||
set_font_family('monospace', 144)
|
||||
try:
|
||||
_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
|
||||
|
||||
|
||||
def pkg_config(pkg, *args):
|
||||
return shlex.split(subprocess.check_output(['pkg-config', pkg] + list(args)).decode('utf-8'))
|
||||
|
||||
|
||||
def init_env():
|
||||
global cflags, ldflags, cc, ldpaths
|
||||
cc = os.environ.get('CC', 'gcc')
|
||||
@ -34,11 +38,12 @@ def init_env():
|
||||
ldflags += shlex.split(os.environ.get('LDFLAGS', ''))
|
||||
|
||||
cflags.append('-pthread')
|
||||
cflags.extend(pkg_config('glew', '--cflags-only-I'))
|
||||
ldflags.append('-pthread')
|
||||
ldflags.append('-shared')
|
||||
cflags.append('-I' + sysconfig.get_config_var('CONFINCLUDEPY'))
|
||||
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:
|
||||
os.mkdir(build_dir)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user