mirror of
https://github.com/H-uru/korman.git
synced 2025-07-14 02:27:36 -04:00
Implement C korlib
NOTE: This is mostly a curiosity atm. There are many undiagnosed access violations...
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@ -35,3 +35,6 @@ pip-log.txt
|
|||||||
# Installer Stuff
|
# Installer Stuff
|
||||||
installer/Files
|
installer/Files
|
||||||
installer/korman.exe
|
installer/korman.exe
|
||||||
|
|
||||||
|
# C++ korlib build directory
|
||||||
|
korlib/build
|
||||||
|
@ -153,6 +153,7 @@ Section "Files"
|
|||||||
File "Files\HSPlasma.dll"
|
File "Files\HSPlasma.dll"
|
||||||
File "Files\PyHSPlasma.pyd"
|
File "Files\PyHSPlasma.pyd"
|
||||||
File "Files\NxCooking.dll"
|
File "Files\NxCooking.dll"
|
||||||
|
File "Files\_korlib.pyd"
|
||||||
|
|
||||||
WriteRegStr HKLM "Software\Korman" "" $INSTDIR
|
WriteRegStr HKLM "Software\Korman" "" $INSTDIR
|
||||||
WriteUninstaller "$INSTDIR\korman_uninstall.exe"
|
WriteUninstaller "$INSTDIR\korman_uninstall.exe"
|
||||||
@ -164,5 +165,6 @@ Section "Uninstall"
|
|||||||
Delete "$INSTDIR\python\lib\site-packages\HSPlasma.dll"
|
Delete "$INSTDIR\python\lib\site-packages\HSPlasma.dll"
|
||||||
Delete "$INSTDIR\python\lib\site-packages\PyHSPlasma.pyd"
|
Delete "$INSTDIR\python\lib\site-packages\PyHSPlasma.pyd"
|
||||||
Delete "$INSTDIR\python\lib\site-packages\NxCooking.dll"
|
Delete "$INSTDIR\python\lib\site-packages\NxCooking.dll"
|
||||||
|
Delete "$INSTDIR\python\lib\site-packages\_korlib.pyd"
|
||||||
DeleteRegKey /ifempty HKLM "Software\Korman"
|
DeleteRegKey /ifempty HKLM "Software\Korman"
|
||||||
SectionEnd
|
SectionEnd
|
||||||
|
38
korlib/CMakeLists.txt
Normal file
38
korlib/CMakeLists.txt
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
project(korlib)
|
||||||
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
|
# Stolen shamelessly from PyHSPlasma
|
||||||
|
find_package(PythonLibs REQUIRED)
|
||||||
|
find_package(PythonInterp "${PYTHONLIBS_VERSION_STRING}" REQUIRED)
|
||||||
|
# make sure the versions match
|
||||||
|
if (NOT "${PYTHONLIBS_VERSION_STRING}" STREQUAL "${PYTHON_VERSION_STRING}")
|
||||||
|
message(FATAL_ERROR "Versions of Python libraries (${PYTHONLIBS_VERSION_STRING}) and Python interpreter (${PYTHON_VERSION_STRING}) do not match. Please configure the paths manually.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(HSPlasma REQUIRED)
|
||||||
|
find_package(OpenGL REQUIRED)
|
||||||
|
|
||||||
|
# Da files
|
||||||
|
set(korlib_HEADERS
|
||||||
|
buffer.h
|
||||||
|
korlib.h
|
||||||
|
texture.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(korlib_SOURCES
|
||||||
|
buffer.cpp
|
||||||
|
module.cpp
|
||||||
|
texture.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
include_directories(${HSPlasma_INCLUDE_DIRS})
|
||||||
|
include_directories(${OPENGL_INCLUDE_DIR})
|
||||||
|
include_directories(${PYTHON_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
add_library(_korlib SHARED ${korlib_HEADERS} ${korlib_SOURCES})
|
||||||
|
if(NOT WIN32)
|
||||||
|
set_target_properties(_korlib PROPERTIES SUFFIX ".so")
|
||||||
|
else()
|
||||||
|
set_target_properties(_korlib PROPERTIES SUFFIX ".pyd")
|
||||||
|
endif()
|
||||||
|
target_link_libraries(_korlib HSPlasma ${OPENGL_LIBRARIES} ${PYTHON_LIBRARIES})
|
111
korlib/buffer.cpp
Normal file
111
korlib/buffer.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/* This file is part of Korman.
|
||||||
|
*
|
||||||
|
* Korman is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Korman is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
static void pyBuffer_dealloc(pyBuffer* self) {
|
||||||
|
delete[] self->m_buffer;
|
||||||
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyBuffer_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "Buffers cannot be created by mere mortals");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTypeObject pyBuffer_Type = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
"_korlib.Buffer", /* tp_name */
|
||||||
|
sizeof(pyBuffer), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
|
||||||
|
(destructor)pyBuffer_dealloc, /* tp_dealloc */
|
||||||
|
NULL, /* tp_print */
|
||||||
|
NULL, /* tp_getattr */
|
||||||
|
NULL, /* tp_setattr */
|
||||||
|
NULL, /* tp_compare */
|
||||||
|
NULL, /* tp_repr */
|
||||||
|
NULL, /* tp_as_number */
|
||||||
|
NULL, /* tp_as_sequence */
|
||||||
|
NULL, /* tp_as_mapping */
|
||||||
|
NULL, /* tp_hash */
|
||||||
|
NULL, /* tp_call */
|
||||||
|
NULL, /* tp_str */
|
||||||
|
NULL, /* tp_getattro */
|
||||||
|
NULL, /* tp_setattro */
|
||||||
|
NULL, /* tp_as_buffer */
|
||||||
|
|
||||||
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
|
"Buffer", /* tp_doc */
|
||||||
|
|
||||||
|
NULL, /* tp_traverse */
|
||||||
|
NULL, /* tp_clear */
|
||||||
|
NULL, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
NULL, /* tp_iter */
|
||||||
|
NULL, /* tp_iternext */
|
||||||
|
|
||||||
|
NULL, /* tp_methods */
|
||||||
|
NULL, /* tp_members */
|
||||||
|
NULL, /* tp_getset */
|
||||||
|
NULL, /* tp_base */
|
||||||
|
NULL, /* tp_dict */
|
||||||
|
NULL, /* tp_descr_get */
|
||||||
|
NULL, /* tp_descr_set */
|
||||||
|
0, /* tp_dictoffset */
|
||||||
|
|
||||||
|
NULL, /* tp_init */
|
||||||
|
NULL, /* tp_alloc */
|
||||||
|
pyBuffer_new, /* tp_new */
|
||||||
|
NULL, /* tp_free */
|
||||||
|
NULL, /* tp_is_gc */
|
||||||
|
|
||||||
|
NULL, /* tp_bases */
|
||||||
|
NULL, /* tp_mro */
|
||||||
|
NULL, /* tp_cache */
|
||||||
|
NULL, /* tp_subclasses */
|
||||||
|
NULL, /* tp_weaklist */
|
||||||
|
|
||||||
|
NULL, /* tp_del */
|
||||||
|
0, /* tp_version_tag */
|
||||||
|
NULL, /* tp_finalize */
|
||||||
|
};
|
||||||
|
|
||||||
|
PyObject* Init_pyBuffer_Type() {
|
||||||
|
if (PyType_Ready(&pyBuffer_Type) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Py_INCREF(&pyBuffer_Type);
|
||||||
|
return (PyObject*)&pyBuffer_Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pyBuffer_Check(PyObject* obj) {
|
||||||
|
if (obj->ob_type == &pyBuffer_Type
|
||||||
|
|| PyType_IsSubtype(obj->ob_type, &pyBuffer_Type))
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyObject* pyBuffer_Steal(uint8_t* buffer, size_t size) {
|
||||||
|
pyBuffer* obj = PyObject_New(pyBuffer, &pyBuffer_Type);
|
||||||
|
obj->m_buffer = buffer;
|
||||||
|
obj->m_size = size;
|
||||||
|
return (PyObject*)obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
37
korlib/buffer.h
Normal file
37
korlib/buffer.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
/* This file is part of Korman.
|
||||||
|
*
|
||||||
|
* Korman is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Korman is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _KORLIB_BUFFER_H
|
||||||
|
#define _KORLIB_BUFFER_H
|
||||||
|
|
||||||
|
#include "korlib.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
uint8_t* m_buffer;
|
||||||
|
size_t m_size;
|
||||||
|
} pyBuffer;
|
||||||
|
|
||||||
|
extern PyTypeObject pyBuffer_Type;
|
||||||
|
PyObject* Init_pyBuffer_Type();
|
||||||
|
int pyBuffer_Check(PyObject*);
|
||||||
|
PyObject* pyBuffer_Steal(uint8_t*, size_t);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // _KORLIB_BUFFER_H
|
35
korlib/korlib.h
Normal file
35
korlib/korlib.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* This file is part of Korman.
|
||||||
|
*
|
||||||
|
* Korman is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Korman is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _KORLIB_H
|
||||||
|
#define _KORLIB_H
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <Python.h>
|
||||||
|
|
||||||
|
#define _pycs(x) const_cast<char*>(x)
|
||||||
|
|
||||||
|
class PyObjectRef {
|
||||||
|
PyObject* m_object;
|
||||||
|
|
||||||
|
public:
|
||||||
|
PyObjectRef(PyObject* o) : m_object(o) { }
|
||||||
|
~PyObjectRef() { if (m_object) Py_DECREF(m_object); }
|
||||||
|
|
||||||
|
operator PyObject*() const { return m_object; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _KORLIB_H
|
45
korlib/module.cpp
Normal file
45
korlib/module.cpp
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/* This file is part of Korman.
|
||||||
|
*
|
||||||
|
* Korman is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Korman is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "buffer.h"
|
||||||
|
#include "texture.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
static PyModuleDef korlib_Module = {
|
||||||
|
PyModuleDef_HEAD_INIT, /* m_base */
|
||||||
|
"_korlib", /* m_name */
|
||||||
|
"C++ korlib implementation",/* m_doc */
|
||||||
|
0, /* m_size */
|
||||||
|
NULL, /* m_methods */
|
||||||
|
NULL, /* m_reload */
|
||||||
|
NULL, /* m_traverse */
|
||||||
|
NULL, /* m_clear */
|
||||||
|
NULL, /* m_free */
|
||||||
|
};
|
||||||
|
|
||||||
|
PyMODINIT_FUNC PyInit__korlib() {
|
||||||
|
PyObject* module = PyModule_Create(&korlib_Module);
|
||||||
|
|
||||||
|
// Module classes...
|
||||||
|
PyModule_AddObject(module, "Buffer", Init_pyBuffer_Type());
|
||||||
|
PyModule_AddObject(module, "GLTexture", Init_pyGLTexture_Type());
|
||||||
|
|
||||||
|
return module;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
289
korlib/texture.cpp
Normal file
289
korlib/texture.cpp
Normal file
@ -0,0 +1,289 @@
|
|||||||
|
/* This file is part of Korman.
|
||||||
|
*
|
||||||
|
* Korman is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Korman is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "texture.h"
|
||||||
|
#include "buffer.h"
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# define NOMINMAX
|
||||||
|
# include <windows.h>
|
||||||
|
#endif // _WIN32
|
||||||
|
|
||||||
|
#include <gl/gl.h>
|
||||||
|
#include <PRP/Surface/plMipmap.h>
|
||||||
|
|
||||||
|
#ifndef GL_GENERATE_MIPMAP
|
||||||
|
# define GL_GENERATE_MIPMAP 0x8191
|
||||||
|
#endif // GL_GENERATE_MIPMAP
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
PyObject* m_blenderImage;
|
||||||
|
bool m_ownIt;
|
||||||
|
GLint m_prevImage;
|
||||||
|
bool m_changedState;
|
||||||
|
GLint m_mipmapState;
|
||||||
|
} pyGLTexture;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
PyObject_HEAD
|
||||||
|
plMipmap* fThis;
|
||||||
|
bool fPyOwned;
|
||||||
|
} pyMipmap;
|
||||||
|
|
||||||
|
static void pyGLTexture_dealloc(pyGLTexture* self) {
|
||||||
|
if (self->m_blenderImage) Py_DECREF(self->m_blenderImage);
|
||||||
|
Py_TYPE(self)->tp_free((PyObject*)self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyGLTexture_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
|
||||||
|
pyGLTexture* self = (pyGLTexture*)type->tp_alloc(type, 0);
|
||||||
|
self->m_blenderImage = NULL;
|
||||||
|
self->m_ownIt = false;
|
||||||
|
self->m_prevImage = 0;
|
||||||
|
self->m_changedState = false;
|
||||||
|
self->m_mipmapState = 0;
|
||||||
|
return (PyObject*)self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pyGLTexture___init__(pyGLTexture* self, PyObject* args, PyObject* kwds) {
|
||||||
|
PyObject* blender_image;
|
||||||
|
if (!PyArg_ParseTuple(args, "O", &blender_image)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "expected a bpy.types.Image");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save a reference to the Blender image
|
||||||
|
Py_INCREF(blender_image);
|
||||||
|
self->m_blenderImage = blender_image;
|
||||||
|
|
||||||
|
// Done!
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyGLTexture__enter__(pyGLTexture* self) {
|
||||||
|
// Is the image already loaded?
|
||||||
|
PyObjectRef bindcode = PyObject_GetAttrString(self->m_blenderImage, "bindcode");
|
||||||
|
if (!PyLong_Check(bindcode)) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "Image bindcode isn't a long?");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, &self->m_prevImage);
|
||||||
|
GLuint image_bindcode = PyLong_AsLong(bindcode);
|
||||||
|
self->m_ownIt = image_bindcode == 0;
|
||||||
|
|
||||||
|
// Load image into GL
|
||||||
|
if (self->m_ownIt) {
|
||||||
|
PyObjectRef new_bind = PyObject_CallMethod(self->m_blenderImage, "gl_load", NULL);
|
||||||
|
if (!(PyObject*)new_bind) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "failed to load image into GL");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
image_bindcode = PyLong_AsLong(new_bind);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set image as current in GL
|
||||||
|
if (self->m_prevImage != image_bindcode) {
|
||||||
|
self->m_changedState = true;
|
||||||
|
glBindTexture(GL_TEXTURE_2D, image_bindcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Misc GL state
|
||||||
|
glGetTexParameteriv(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, &self->m_mipmapState);
|
||||||
|
|
||||||
|
Py_INCREF(self);
|
||||||
|
return (PyObject*)self;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyGLTexture__exit__(pyGLTexture* self, PyObject*) {
|
||||||
|
// We don't care about the args here
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, self->m_mipmapState);
|
||||||
|
if (self->m_changedState)
|
||||||
|
glBindTexture(GL_TEXTURE_2D, self->m_prevImage);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyGLTexture_generate_mipmap(pyGLTexture* self) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 1);
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t* _get_level_data(pyGLTexture* self, GLint level, bool bgra, size_t* size) {
|
||||||
|
GLint width, height;
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_WIDTH, &width);
|
||||||
|
glGetTexLevelParameteriv(GL_TEXTURE_2D, level, GL_TEXTURE_HEIGHT, &height);
|
||||||
|
GLenum fmt = bgra ? GL_BGRA_EXT : GL_RGBA;
|
||||||
|
|
||||||
|
*size = (width * height * 4);
|
||||||
|
uint8_t* buf = new uint8_t[*size];
|
||||||
|
glGetTexImage(GL_TEXTURE_2D, level, fmt, GL_UNSIGNED_BYTE, reinterpret_cast<GLvoid*>(buf));
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyGLTexture_get_level_data(pyGLTexture* self, PyObject* args, PyObject* kwargs) {
|
||||||
|
static char* kwlist[] = { _pycs("level"), _pycs("calc_alpha"), _pycs("bgra"),
|
||||||
|
_pycs("quiet"), NULL };
|
||||||
|
GLint level = 0;
|
||||||
|
bool calc_alpha = false;
|
||||||
|
bool bgra = false;
|
||||||
|
bool quiet = false;
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ibbb", kwlist, &level, &calc_alpha, &bgra, &quiet)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "get_level_data expects an optional int, bool, bool, bool");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t bufsz;
|
||||||
|
uint8_t* buf = _get_level_data(self, level, bgra, &bufsz);
|
||||||
|
if (calc_alpha) {
|
||||||
|
for (size_t i = 0; i < bufsz; i += 4)
|
||||||
|
buf[i + 3] = (buf[i + 0] + buf[i + 1] + buf[i + 2]) / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pyBuffer_Steal(buf, bufsz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject* pyGLTexture_store_in_mipmap(pyGLTexture* self, PyObject* args) {
|
||||||
|
pyMipmap* pymipmap;
|
||||||
|
PyObject* levels;
|
||||||
|
size_t compression;
|
||||||
|
if (!PyArg_ParseTuple(args, "OOn", &pymipmap, &levels, &compression) || !PySequence_Check(levels)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "store_in_mipmap expects a plMipmap, sequence of Buffer and int");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Since we actually have no way of knowing if that really is a pyMipmap...
|
||||||
|
plMipmap* mipmap = plMipmap::Convert(pymipmap->fThis, false);
|
||||||
|
if (!mipmap) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "store_in_mipmap expects a plMipmap, sequence of Buffer and int");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Py_ssize_t i = 0; i < PySequence_Size(levels); ++i) {
|
||||||
|
pyBuffer* item = (pyBuffer*)PySequence_GetItem(levels, i);
|
||||||
|
if (!pyBuffer_Check((PyObject*)item)) {
|
||||||
|
PyErr_SetString(PyExc_TypeError, "store_in_mipmap expects a plMipmap, sequence of Buffer and int");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (compression == plBitmap::kDirectXCompression)
|
||||||
|
mipmap->CompressImage(i, item->m_buffer, item->m_size);
|
||||||
|
else
|
||||||
|
mipmap->setLevelData(i, item->m_buffer, item->m_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
Py_RETURN_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyMethodDef pyGLTexture_Methods[] = {
|
||||||
|
{ _pycs("__enter__"), (PyCFunction)pyGLTexture__enter__, METH_NOARGS, NULL },
|
||||||
|
{ _pycs("__exit__"), (PyCFunction)pyGLTexture__enter__, METH_VARARGS, NULL },
|
||||||
|
|
||||||
|
{ _pycs("generate_mipmap"), (PyCFunction)pyGLTexture_generate_mipmap, METH_NOARGS, NULL },
|
||||||
|
{ _pycs("get_level_data"), (PyCFunction)pyGLTexture_get_level_data, METH_KEYWORDS | METH_VARARGS, NULL },
|
||||||
|
{ _pycs("store_in_mipmap"), (PyCFunction)pyGLTexture_store_in_mipmap, METH_VARARGS, NULL },
|
||||||
|
{ NULL, NULL, 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static PyObject* pyGLTexture_get_has_alpha(pyGLTexture* self, void*) {
|
||||||
|
size_t bufsz;
|
||||||
|
uint8_t* buf = _get_level_data(self, 0, false, &bufsz);
|
||||||
|
for (size_t i = 3; i < bufsz; i += 4) {
|
||||||
|
if (buf[i] != 255) {
|
||||||
|
delete[] buf;
|
||||||
|
return PyBool_FromLong(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete[] buf;
|
||||||
|
return PyBool_FromLong(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyGetSetDef pyGLTexture_GetSet[] = {
|
||||||
|
{ _pycs("has_alpha"), (getter)pyGLTexture_get_has_alpha, NULL, NULL, NULL },
|
||||||
|
{ NULL, NULL, NULL, NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
PyTypeObject pyGLTexture_Type = {
|
||||||
|
PyVarObject_HEAD_INIT(NULL, 0)
|
||||||
|
"_korlib.GLTexture", /* tp_name */
|
||||||
|
sizeof(pyGLTexture), /* tp_basicsize */
|
||||||
|
0, /* tp_itemsize */
|
||||||
|
|
||||||
|
(destructor)pyGLTexture_dealloc, /* tp_dealloc */
|
||||||
|
NULL, /* tp_print */
|
||||||
|
NULL, /* tp_getattr */
|
||||||
|
NULL, /* tp_setattr */
|
||||||
|
NULL, /* tp_compare */
|
||||||
|
NULL, /* tp_repr */
|
||||||
|
NULL, /* tp_as_number */
|
||||||
|
NULL, /* tp_as_sequence */
|
||||||
|
NULL, /* tp_as_mapping */
|
||||||
|
NULL, /* tp_hash */
|
||||||
|
NULL, /* tp_call */
|
||||||
|
NULL, /* tp_str */
|
||||||
|
NULL, /* tp_getattro */
|
||||||
|
NULL, /* tp_setattro */
|
||||||
|
NULL, /* tp_as_buffer */
|
||||||
|
|
||||||
|
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||||
|
"GLTexture", /* tp_doc */
|
||||||
|
|
||||||
|
NULL, /* tp_traverse */
|
||||||
|
NULL, /* tp_clear */
|
||||||
|
NULL, /* tp_richcompare */
|
||||||
|
0, /* tp_weaklistoffset */
|
||||||
|
NULL, /* tp_iter */
|
||||||
|
NULL, /* tp_iternext */
|
||||||
|
|
||||||
|
pyGLTexture_Methods, /* tp_methods */
|
||||||
|
NULL, /* tp_members */
|
||||||
|
pyGLTexture_GetSet, /* tp_getset */
|
||||||
|
NULL, /* tp_base */
|
||||||
|
NULL, /* tp_dict */
|
||||||
|
NULL, /* tp_descr_get */
|
||||||
|
NULL, /* tp_descr_set */
|
||||||
|
0, /* tp_dictoffset */
|
||||||
|
|
||||||
|
(initproc)pyGLTexture___init__, /* tp_init */
|
||||||
|
NULL, /* tp_alloc */
|
||||||
|
pyGLTexture_new, /* tp_new */
|
||||||
|
NULL, /* tp_free */
|
||||||
|
NULL, /* tp_is_gc */
|
||||||
|
|
||||||
|
NULL, /* tp_bases */
|
||||||
|
NULL, /* tp_mro */
|
||||||
|
NULL, /* tp_cache */
|
||||||
|
NULL, /* tp_subclasses */
|
||||||
|
NULL, /* tp_weaklist */
|
||||||
|
|
||||||
|
NULL, /* tp_del */
|
||||||
|
0, /* tp_version_tag */
|
||||||
|
NULL, /* tp_finalize */
|
||||||
|
};
|
||||||
|
|
||||||
|
PyObject* Init_pyGLTexture_Type() {
|
||||||
|
if (PyType_Ready(&pyGLTexture_Type) < 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
Py_INCREF(&pyGLTexture_Type);
|
||||||
|
return (PyObject*)&pyGLTexture_Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
29
korlib/texture.h
Normal file
29
korlib/texture.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* This file is part of Korman.
|
||||||
|
*
|
||||||
|
* Korman is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Korman is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _KORLIB_TEXTURE_H
|
||||||
|
#define _KORLIB_TEXTURE_H
|
||||||
|
|
||||||
|
#include "korlib.h"
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
|
||||||
|
extern PyTypeObject pyGLTexture_Type;
|
||||||
|
PyObject* Init_pyGLTexture_Type();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _KORLIB_TEXTURE_H
|
Reference in New Issue
Block a user