mirror of
https://github.com/H-uru/korman.git
synced 2025-07-14 02:27:36 -04:00
@ -19,7 +19,7 @@
|
|||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
|
|
||||||
// This konstant is compared against that in the Python module to prevent sneaky errors...
|
// This konstant is compared against that in the Python module to prevent sneaky errors...
|
||||||
#define KORLIB_API_VERSION 1
|
#define KORLIB_API_VERSION 2
|
||||||
|
|
||||||
static PyMethodDef korlib_Methods[] = {
|
static PyMethodDef korlib_Methods[] = {
|
||||||
{ _pycs("create_bump_LUT"), (PyCFunction)create_bump_LUT, METH_VARARGS, NULL },
|
{ _pycs("create_bump_LUT"), (PyCFunction)create_bump_LUT, METH_VARARGS, NULL },
|
||||||
|
@ -195,6 +195,12 @@ enum {
|
|||||||
TEX_DETAIL_MULTIPLY = 2,
|
TEX_DETAIL_MULTIPLY = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
kOpaque = 0,
|
||||||
|
kOnOff = 1,
|
||||||
|
kFull = 2,
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
PyObject_HEAD
|
PyObject_HEAD
|
||||||
PyObject* m_blenderImage;
|
PyObject* m_blenderImage;
|
||||||
@ -476,12 +482,19 @@ static PyMethodDef pyGLTexture_Methods[] = {
|
|||||||
static PyObject* pyGLTexture_get_has_alpha(pyGLTexture* self, void*) {
|
static PyObject* pyGLTexture_get_has_alpha(pyGLTexture* self, void*) {
|
||||||
char* data = PyBytes_AsString(self->m_imageData);
|
char* data = PyBytes_AsString(self->m_imageData);
|
||||||
size_t bufsz = self->m_width * self->m_height * sizeof(uint32_t);
|
size_t bufsz = self->m_width * self->m_height * sizeof(uint32_t);
|
||||||
for (size_t i = 3; i < bufsz; i += 4) {
|
bool transparency = false;
|
||||||
if (data[i] != 255) {
|
|
||||||
return PyBool_FromLong(1);
|
uint32_t* datap = reinterpret_cast<uint32_t*>(data);
|
||||||
}
|
uint32_t* endp = reinterpret_cast<uint32_t*>(data + bufsz);
|
||||||
|
while (datap < endp) {
|
||||||
|
uint8_t alpha = ((*datap & 0xFF000000) >> 24);
|
||||||
|
if (alpha == 0x00)
|
||||||
|
transparency = true;
|
||||||
|
else if (alpha != 0xFF)
|
||||||
|
return PyLong_FromLong(kFull);
|
||||||
|
datap++;
|
||||||
}
|
}
|
||||||
return PyBool_FromLong(0);
|
return PyLong_FromLong(transparency ? kOnOff : kOpaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject* pyGLTexture_get_image_data(pyGLTexture* self, void*) {
|
static PyObject* pyGLTexture_get_image_data(pyGLTexture* self, void*) {
|
||||||
|
@ -61,19 +61,16 @@ class _Texture:
|
|||||||
self.detail_opacity_start = kwargs["detail_opacity_start"]
|
self.detail_opacity_start = kwargs["detail_opacity_start"]
|
||||||
self.detail_opacity_stop = kwargs["detail_opacity_stop"]
|
self.detail_opacity_stop = kwargs["detail_opacity_stop"]
|
||||||
self.calc_alpha = False
|
self.calc_alpha = False
|
||||||
self.use_alpha = True
|
self.alpha_type = TextureAlpha.full
|
||||||
self.allowed_formats = {"DDS"}
|
self.allowed_formats = {"DDS"}
|
||||||
self.is_cube_map = False
|
self.is_cube_map = False
|
||||||
else:
|
else:
|
||||||
self.is_detail_map = False
|
self.is_detail_map = False
|
||||||
use_alpha = kwargs.get("use_alpha")
|
|
||||||
if kwargs.get("force_calc_alpha", False) or self.calc_alpha:
|
if kwargs.get("force_calc_alpha", False) or self.calc_alpha:
|
||||||
self.calc_alpha = True
|
self.calc_alpha = True
|
||||||
self.use_alpha = True
|
self.alpha_type = TextureAlpha.full
|
||||||
elif use_alpha is None:
|
|
||||||
self.use_alpha = (image.channels == 4 and image.use_alpha)
|
|
||||||
else:
|
else:
|
||||||
self.use_alpha = use_alpha
|
self.alpha_type = kwargs.get("alpha_type", TextureAlpha.opaque)
|
||||||
self.allowed_formats = kwargs.get("allowed_formats",
|
self.allowed_formats = kwargs.get("allowed_formats",
|
||||||
{"DDS"} if self.mipmap else {"PNG", "JPG"})
|
{"DDS"} if self.mipmap else {"PNG", "JPG"})
|
||||||
self.is_cube_map = kwargs.get("is_cube_map", False)
|
self.is_cube_map = kwargs.get("is_cube_map", False)
|
||||||
@ -124,8 +121,8 @@ class _Texture:
|
|||||||
def _update(self, other):
|
def _update(self, other):
|
||||||
"""Update myself with any props that might be overridable from another copy of myself"""
|
"""Update myself with any props that might be overridable from another copy of myself"""
|
||||||
# NOTE: detail map properties should NEVER be overridden. NEVER. EVER. kthx.
|
# NOTE: detail map properties should NEVER be overridden. NEVER. EVER. kthx.
|
||||||
if other.use_alpha:
|
if self.alpha_type < other.alpha_type:
|
||||||
self.use_alpha = True
|
self.alpha_type = other.alpha_type
|
||||||
if other.mipmap:
|
if other.mipmap:
|
||||||
self.mipmap = True
|
self.mipmap = True
|
||||||
|
|
||||||
@ -536,8 +533,8 @@ class MaterialConverter:
|
|||||||
# prevent that as well, so we could theoretically slice-and-dice the single
|
# prevent that as well, so we could theoretically slice-and-dice the single
|
||||||
# image here... but... meh. Offloading taim.
|
# image here... but... meh. Offloading taim.
|
||||||
self.export_prepared_image(texture=texture, owner=layer, indent=3,
|
self.export_prepared_image(texture=texture, owner=layer, indent=3,
|
||||||
use_alpha=False, mipmap=True, allowed_formats={"DDS"},
|
alpha_type=TextureAlpha.opaque, mipmap=True,
|
||||||
is_cube_map=True, tag="cubemap")
|
allowed_formats={"DDS"}, is_cube_map=True, tag="cubemap")
|
||||||
|
|
||||||
|
|
||||||
def export_dynamic_env(self, bo, layer, texture, pl_class):
|
def export_dynamic_env(self, bo, layer, texture, pl_class):
|
||||||
@ -650,12 +647,13 @@ class MaterialConverter:
|
|||||||
|
|
||||||
# Does the image have any alpha at all?
|
# Does the image have any alpha at all?
|
||||||
if texture.image is not None:
|
if texture.image is not None:
|
||||||
has_alpha = texture.use_calculate_alpha or slot.use_stencil or self._test_image_alpha(texture.image)
|
alpha_type = self._test_image_alpha(texture.image)
|
||||||
|
has_alpha = texture.use_calculate_alpha or slot.use_stencil or alpha_type != TextureAlpha.opaque
|
||||||
if (texture.image.use_alpha and texture.use_alpha) and not has_alpha:
|
if (texture.image.use_alpha and texture.use_alpha) and not has_alpha:
|
||||||
warning = "'{}' wants to use alpha, but '{}' is opaque".format(texture.name, texture.image.name)
|
warning = "'{}' wants to use alpha, but '{}' is opaque".format(texture.name, texture.image.name)
|
||||||
self._exporter().report.warn(warning, indent=3)
|
self._exporter().report.warn(warning, indent=3)
|
||||||
else:
|
else:
|
||||||
has_alpha = True
|
alpha_type, has_alpha = TextureAlpha.opaque, False
|
||||||
|
|
||||||
# First, let's apply any relevant flags
|
# First, let's apply any relevant flags
|
||||||
state = layer.state
|
state = layer.state
|
||||||
@ -699,7 +697,7 @@ class MaterialConverter:
|
|||||||
|
|
||||||
allowed_formats = {"DDS"} if mipmap else {"PNG", "BMP"}
|
allowed_formats = {"DDS"} if mipmap else {"PNG", "BMP"}
|
||||||
self.export_prepared_image(texture=texture, owner=layer,
|
self.export_prepared_image(texture=texture, owner=layer,
|
||||||
use_alpha=has_alpha, force_calc_alpha=slot.use_stencil,
|
alpha_type=alpha_type, force_calc_alpha=slot.use_stencil,
|
||||||
is_detail_map=layer_props.is_detail_map,
|
is_detail_map=layer_props.is_detail_map,
|
||||||
detail_blend=detail_blend,
|
detail_blend=detail_blend,
|
||||||
detail_fade_start=layer_props.detail_fade_start,
|
detail_fade_start=layer_props.detail_fade_start,
|
||||||
@ -778,7 +776,7 @@ class MaterialConverter:
|
|||||||
compression = plBitmap.kUncompressed
|
compression = plBitmap.kUncompressed
|
||||||
else:
|
else:
|
||||||
raise RuntimeError(allowed_formats)
|
raise RuntimeError(allowed_formats)
|
||||||
dxt = plBitmap.kDXT5 if key.use_alpha or key.calc_alpha else plBitmap.kDXT1
|
dxt = plBitmap.kDXT5 if key.alpha_type == TextureAlpha.full else plBitmap.kDXT1
|
||||||
|
|
||||||
# Mayhaps we have a cached version of this that has already been exported
|
# Mayhaps we have a cached version of this that has already been exported
|
||||||
cached_image = texcache.get_from_texture(key, compression)
|
cached_image = texcache.get_from_texture(key, compression)
|
||||||
@ -1035,10 +1033,8 @@ class MaterialConverter:
|
|||||||
if result is not None:
|
if result is not None:
|
||||||
return result
|
return result
|
||||||
|
|
||||||
if image.channels != 4:
|
if image.channels != 4 or not image.use_alpha:
|
||||||
result = False
|
result = TextureAlpha.opaque
|
||||||
elif not image.use_alpha:
|
|
||||||
result = False
|
|
||||||
else:
|
else:
|
||||||
# Using bpy.types.Image.pixels is VERY VERY VERY slow...
|
# Using bpy.types.Image.pixels is VERY VERY VERY slow...
|
||||||
key = _Texture(image=image)
|
key = _Texture(image=image)
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
_KORLIB_API_VERSION = 1
|
_KORLIB_API_VERSION = 2
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from _korlib import _KORLIB_API_VERSION as _C_API_VERSION
|
from _korlib import _KORLIB_API_VERSION as _C_API_VERSION
|
||||||
@ -70,6 +70,7 @@ except ImportError as ex:
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
from _korlib import *
|
from _korlib import *
|
||||||
|
from .texture import TextureAlpha
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
from .console import ConsoleCursor, ConsoleToggler
|
from .console import ConsoleCursor, ConsoleToggler
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import array
|
import array
|
||||||
import bgl
|
import bgl
|
||||||
|
import enum
|
||||||
from ..helpers import ensure_power_of_two
|
from ..helpers import ensure_power_of_two
|
||||||
import math
|
import math
|
||||||
from PyHSPlasma import plBitmap
|
from PyHSPlasma import plBitmap
|
||||||
@ -95,6 +96,13 @@ def scale_image(buf, srcW, srcH, dstW, dstH):
|
|||||||
return bytes(dst)
|
return bytes(dst)
|
||||||
|
|
||||||
|
|
||||||
|
@enum.unique
|
||||||
|
class TextureAlpha(enum.IntEnum):
|
||||||
|
opaque = 0
|
||||||
|
on_off = 1
|
||||||
|
full = 2
|
||||||
|
|
||||||
|
|
||||||
class GLTexture:
|
class GLTexture:
|
||||||
def __init__(self, texkey=None, image=None, bgra=False, fast=False):
|
def __init__(self, texkey=None, image=None, bgra=False, fast=False):
|
||||||
assert texkey or image
|
assert texkey or image
|
||||||
@ -224,11 +232,13 @@ class GLTexture:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def has_alpha(self):
|
def has_alpha(self):
|
||||||
data = self._image_data
|
data, xparency = self._image_data, False
|
||||||
for i in range(3, len(data), 4):
|
for i in range(3, len(data), 4):
|
||||||
if data[i] != 255:
|
if data[i] == 0:
|
||||||
return True
|
xparency = True
|
||||||
return False
|
elif data[i] != 255:
|
||||||
|
return TextureAlpha.full
|
||||||
|
return TextureAlpha.on_off if xparency else TextureAlpha.opaque
|
||||||
|
|
||||||
def _get_image_data(self):
|
def _get_image_data(self):
|
||||||
return (self._width, self._height, self._image_data)
|
return (self._width, self._height, self._image_data)
|
||||||
|
Reference in New Issue
Block a user