API to map OpenGL buffers

This commit is contained in:
Kovid Goyal 2017-09-08 17:22:00 +05:30
parent 012b209a56
commit 281cb50780
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 48 additions and 11 deletions

View File

@ -607,10 +607,13 @@ static PyObject*
replace_or_create_buffer(PyObject UNUSED *self, PyObject *args) {
int usage, buftype;
unsigned long size, prev_sz, target;
void *data = NULL;
PyObject *address;
if (!PyArg_ParseTuple(args, "kkkO!ii", &target, &size, &prev_sz, &PyLong_Type, &address, &usage, &buftype)) return NULL;
void *data = PyLong_AsVoidPtr(address);
if (data == NULL) { PyErr_SetString(PyExc_TypeError, "Not a valid data pointer"); return NULL; }
if (size) {
data = PyLong_AsVoidPtr(address);
if (data == NULL) { PyErr_SetString(PyExc_TypeError, "Not a valid data pointer"); return NULL; }
}
glBindBuffer(buftype, target);
if (prev_sz == 0 || prev_sz != size) glBufferData(buftype, size, data, usage);
else glBufferSubData(buftype, 0, size, data);
@ -619,6 +622,23 @@ replace_or_create_buffer(PyObject UNUSED *self, PyObject *args) {
Py_RETURN_NONE;
}
static PyObject*
MapBuffer(PyObject UNUSED *self, PyObject *args) {
int target, access;
if (!PyArg_ParseTuple(args, "ii", &target, &access)) return NULL;
void *address = glMapBuffer(target, access);
if (address == NULL) { SET_GL_ERR; return NULL; }
return PyLong_FromVoidPtr(address);
}
static PyObject*
UnmapBuffer(PyObject UNUSED *self, PyObject *args) {
int target;
if (!PyArg_ParseTuple(args, "i", &target)) return NULL;
if (!glUnmapBuffer(target)) { SET_GL_ERR; return NULL; }
Py_RETURN_NONE;
}
static PyObject*
TexParameteri(PyObject UNUSED *self, PyObject *args) {
int target, name, param;
@ -810,8 +830,9 @@ int add_module_gl_constants(PyObject *module) {
GLC(GL_TEXTURE_WRAP_S); GLC(GL_TEXTURE_WRAP_T);
GLC(GL_UNPACK_ALIGNMENT);
GLC(GL_R8); GLC(GL_RED); GLC(GL_UNSIGNED_BYTE); GLC(GL_R32UI); GLC(GL_RGB32UI); GLC(GL_RGBA);
GLC(GL_TEXTURE_BUFFER); GLC(GL_STATIC_DRAW); GLC(GL_STREAM_DRAW);
GLC(GL_SRC_ALPHA); GLC(GL_ONE_MINUS_SRC_ALPHA);
GLC(GL_TEXTURE_BUFFER); GLC(GL_STATIC_DRAW); GLC(GL_STREAM_DRAW); GLC(GL_DYNAMIC_DRAW);
GLC(GL_SRC_ALPHA); GLC(GL_ONE_MINUS_SRC_ALPHA);
GLC(GL_WRITE_ONLY); GLC(GL_READ_ONLY); GLC(GL_READ_WRITE);
GLC(GL_BLEND); GLC(GL_FLOAT); GLC(GL_UNSIGNED_INT); GLC(GL_ARRAY_BUFFER); GLC(GL_UNIFORM_BUFFER);
return 1;
}
@ -873,6 +894,8 @@ int add_module_gl_constants(PyObject *module) {
METH(AttachShader, METH_VARARGS) \
METH(BindTexture, METH_VARARGS) \
METH(TexParameteri, METH_VARARGS) \
METH(MapBuffer, METH_VARARGS) \
METH(UnmapBuffer, METH_VARARGS) \
METH(PixelStorei, METH_VARARGS) \
METH(BindBuffer, METH_VARARGS) \
METH(BindBufferBase, METH_VARARGS) \

View File

@ -6,7 +6,7 @@ import os
import sys
from collections import namedtuple
from contextlib import contextmanager
from ctypes import addressof, sizeof
from ctypes import addressof, c_char, sizeof
from functools import lru_cache
from .fast_data_types import (
@ -16,7 +16,7 @@ from .fast_data_types import (
GL_TEXTURE0, GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER,
GL_TEXTURE_MIN_FILTER, GL_TEXTURE_WRAP_S, GL_TEXTURE_WRAP_T, GL_TRUE,
GL_UNIFORM_BUFFER, GL_UNPACK_ALIGNMENT, GL_UNSIGNED_BYTE, GL_VERTEX_SHADER,
ITALIC, copy_image_sub_data, get_uniform_block_offsets,
GL_WRITE_ONLY, ITALIC, copy_image_sub_data, get_uniform_block_offsets,
get_uniform_block_size, glActiveTexture, glAttachShader, glBindBuffer,
glBindBufferBase, glBindTexture, glBindVertexArray, glCompileShader,
glCopyImageSubData, glCreateProgram, glCreateShader, glDeleteBuffer,
@ -24,11 +24,12 @@ from .fast_data_types import (
glEnableVertexAttribArray, glGenBuffers, glGenTextures, glGenVertexArrays,
glGetAttribLocation, glGetBufferSubData, glGetIntegerv,
glGetProgramInfoLog, glGetProgramiv, glGetShaderInfoLog, glGetShaderiv,
glGetUniformBlockIndex, glGetUniformLocation, glLinkProgram, glPixelStorei,
glShaderSource, glTexParameteri, glTexStorage3D, glTexSubImage3D,
glUseProgram, glVertexAttribDivisor, glVertexAttribPointer,
render_dirty_sprites, replace_or_create_buffer, sprite_map_current_layout,
sprite_map_increment, sprite_map_set_layout, sprite_map_set_limits, sprite_map_free
glGetUniformBlockIndex, glGetUniformLocation, glLinkProgram, glMapBuffer,
glPixelStorei, glShaderSource, glTexParameteri, glTexStorage3D,
glTexSubImage3D, glUnmapBuffer, glUseProgram, glVertexAttribDivisor,
glVertexAttribPointer, render_dirty_sprites, replace_or_create_buffer,
sprite_map_current_layout, sprite_map_free, sprite_map_increment,
sprite_map_set_layout, sprite_map_set_limits
)
from .fonts.render import render_cell
from .utils import safe_print
@ -98,6 +99,19 @@ class BufferManager: # {{{
yield
self.unbind(buf_id)
@contextmanager
def mapped_buffer(self, buf_sz, buf_id, usage=GL_STREAM_DRAW, access=GL_WRITE_ONLY):
prev_sz = self.sizes.get(buf_id, 0)
buf_type = self.types[buf_id]
if prev_sz != buf_sz:
replace_or_create_buffer(buf_id, buf_sz, 0, 0, usage, buf_type)
self.sizes[buf_id] = buf_sz
self.ctypes_types[buf_id] = c_char
with self.bound_buffer(buf_id):
address = glMapBuffer(buf_type, access)
yield address
glUnmapBuffer(buf_type)
buffer_manager = BufferManager()
# }}}