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"
|
||||
|
||||
// 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[] = {
|
||||
{ _pycs("create_bump_LUT"), (PyCFunction)create_bump_LUT, METH_VARARGS, NULL },
|
||||
|
@ -195,6 +195,12 @@ enum {
|
||||
TEX_DETAIL_MULTIPLY = 2,
|
||||
};
|
||||
|
||||
enum {
|
||||
kOpaque = 0,
|
||||
kOnOff = 1,
|
||||
kFull = 2,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
PyObject* m_blenderImage;
|
||||
@ -476,12 +482,19 @@ static PyMethodDef pyGLTexture_Methods[] = {
|
||||
static PyObject* pyGLTexture_get_has_alpha(pyGLTexture* self, void*) {
|
||||
char* data = PyBytes_AsString(self->m_imageData);
|
||||
size_t bufsz = self->m_width * self->m_height * sizeof(uint32_t);
|
||||
for (size_t i = 3; i < bufsz; i += 4) {
|
||||
if (data[i] != 255) {
|
||||
return PyBool_FromLong(1);
|
||||
}
|
||||
bool transparency = false;
|
||||
|
||||
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*) {
|
||||
|
@ -61,19 +61,16 @@ class _Texture:
|
||||
self.detail_opacity_start = kwargs["detail_opacity_start"]
|
||||
self.detail_opacity_stop = kwargs["detail_opacity_stop"]
|
||||
self.calc_alpha = False
|
||||
self.use_alpha = True
|
||||
self.alpha_type = TextureAlpha.full
|
||||
self.allowed_formats = {"DDS"}
|
||||
self.is_cube_map = False
|
||||
else:
|
||||
self.is_detail_map = False
|
||||
use_alpha = kwargs.get("use_alpha")
|
||||
if kwargs.get("force_calc_alpha", False) or self.calc_alpha:
|
||||
self.calc_alpha = True
|
||||
self.use_alpha = True
|
||||
elif use_alpha is None:
|
||||
self.use_alpha = (image.channels == 4 and image.use_alpha)
|
||||
self.alpha_type = TextureAlpha.full
|
||||
else:
|
||||
self.use_alpha = use_alpha
|
||||
self.alpha_type = kwargs.get("alpha_type", TextureAlpha.opaque)
|
||||
self.allowed_formats = kwargs.get("allowed_formats",
|
||||
{"DDS"} if self.mipmap else {"PNG", "JPG"})
|
||||
self.is_cube_map = kwargs.get("is_cube_map", False)
|
||||
@ -124,8 +121,8 @@ class _Texture:
|
||||
def _update(self, other):
|
||||
"""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.
|
||||
if other.use_alpha:
|
||||
self.use_alpha = True
|
||||
if self.alpha_type < other.alpha_type:
|
||||
self.alpha_type = other.alpha_type
|
||||
if other.mipmap:
|
||||
self.mipmap = True
|
||||
|
||||
@ -536,8 +533,8 @@ class MaterialConverter:
|
||||
# prevent that as well, so we could theoretically slice-and-dice the single
|
||||
# image here... but... meh. Offloading taim.
|
||||
self.export_prepared_image(texture=texture, owner=layer, indent=3,
|
||||
use_alpha=False, mipmap=True, allowed_formats={"DDS"},
|
||||
is_cube_map=True, tag="cubemap")
|
||||
alpha_type=TextureAlpha.opaque, mipmap=True,
|
||||
allowed_formats={"DDS"}, is_cube_map=True, tag="cubemap")
|
||||
|
||||
|
||||
def export_dynamic_env(self, bo, layer, texture, pl_class):
|
||||
@ -650,12 +647,13 @@ class MaterialConverter:
|
||||
|
||||
# Does the image have any alpha at all?
|
||||
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:
|
||||
warning = "'{}' wants to use alpha, but '{}' is opaque".format(texture.name, texture.image.name)
|
||||
self._exporter().report.warn(warning, indent=3)
|
||||
else:
|
||||
has_alpha = True
|
||||
alpha_type, has_alpha = TextureAlpha.opaque, False
|
||||
|
||||
# First, let's apply any relevant flags
|
||||
state = layer.state
|
||||
@ -699,7 +697,7 @@ class MaterialConverter:
|
||||
|
||||
allowed_formats = {"DDS"} if mipmap else {"PNG", "BMP"}
|
||||
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,
|
||||
detail_blend=detail_blend,
|
||||
detail_fade_start=layer_props.detail_fade_start,
|
||||
@ -778,7 +776,7 @@ class MaterialConverter:
|
||||
compression = plBitmap.kUncompressed
|
||||
else:
|
||||
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
|
||||
cached_image = texcache.get_from_texture(key, compression)
|
||||
@ -1035,10 +1033,8 @@ class MaterialConverter:
|
||||
if result is not None:
|
||||
return result
|
||||
|
||||
if image.channels != 4:
|
||||
result = False
|
||||
elif not image.use_alpha:
|
||||
result = False
|
||||
if image.channels != 4 or not image.use_alpha:
|
||||
result = TextureAlpha.opaque
|
||||
else:
|
||||
# Using bpy.types.Image.pixels is VERY VERY VERY slow...
|
||||
key = _Texture(image=image)
|
||||
|
@ -13,7 +13,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Korman. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
_KORLIB_API_VERSION = 1
|
||||
_KORLIB_API_VERSION = 2
|
||||
|
||||
try:
|
||||
from _korlib import _KORLIB_API_VERSION as _C_API_VERSION
|
||||
@ -70,6 +70,7 @@ except ImportError as ex:
|
||||
|
||||
else:
|
||||
from _korlib import *
|
||||
from .texture import TextureAlpha
|
||||
|
||||
finally:
|
||||
from .console import ConsoleCursor, ConsoleToggler
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
import array
|
||||
import bgl
|
||||
import enum
|
||||
from ..helpers import ensure_power_of_two
|
||||
import math
|
||||
from PyHSPlasma import plBitmap
|
||||
@ -95,6 +96,13 @@ def scale_image(buf, srcW, srcH, dstW, dstH):
|
||||
return bytes(dst)
|
||||
|
||||
|
||||
@enum.unique
|
||||
class TextureAlpha(enum.IntEnum):
|
||||
opaque = 0
|
||||
on_off = 1
|
||||
full = 2
|
||||
|
||||
|
||||
class GLTexture:
|
||||
def __init__(self, texkey=None, image=None, bgra=False, fast=False):
|
||||
assert texkey or image
|
||||
@ -224,11 +232,13 @@ class GLTexture:
|
||||
|
||||
@property
|
||||
def has_alpha(self):
|
||||
data = self._image_data
|
||||
data, xparency = self._image_data, False
|
||||
for i in range(3, len(data), 4):
|
||||
if data[i] != 255:
|
||||
return True
|
||||
return False
|
||||
if data[i] == 0:
|
||||
xparency = True
|
||||
elif data[i] != 255:
|
||||
return TextureAlpha.full
|
||||
return TextureAlpha.on_off if xparency else TextureAlpha.opaque
|
||||
|
||||
def _get_image_data(self):
|
||||
return (self._width, self._height, self._image_data)
|
||||
|
Reference in New Issue
Block a user