16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-21 17:09:19 +02:00

opacity bugfix

This commit is contained in:
milek7
2018-07-17 17:45:06 +02:00
parent a29379ed8b
commit 61bbfe667b
10 changed files with 101 additions and 58 deletions

View File

@@ -434,7 +434,7 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( asReplacableTexture );
}
if( ( m_materialdata.replacable_skins[ 1 ] != null_handle )
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).opacity == 0.0f ) ) {
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).get_or_guess_opacity() == 0.0f ) ) {
// tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych
m_materialdata.textures_alpha = 0x31310031;
}

View File

@@ -4587,27 +4587,31 @@ void TDynamicObject::LoadMMediaFile( std::string BaseDir, std::string TypeName,
else {
m_materialdata.replacable_skins[ 1 ] = GfxRenderer.Fetch_Material( ReplacableSkin );
}
if( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).opacity == 0.0f ) {
if( GfxRenderer.Material( m_materialdata.replacable_skins[ 1 ] ).get_or_guess_opacity() == 0.0f ) {
// tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
WriteLog("alpha");
m_materialdata.textures_alpha = 0x31310031;
}
else {
// wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
WriteLog("opaque");
m_materialdata.textures_alpha = 0x30300030;
}
if( ( m_materialdata.replacable_skins[ 2 ] )
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 2 ] ).opacity == 0.0f ) ) {
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 2 ] ).get_or_guess_opacity() == 0.0f ) ) {
WriteLog("alpha");
// tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
m_materialdata.textures_alpha |= 0x02020002;
}
if( ( m_materialdata.replacable_skins[ 3 ] )
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 3 ] ).opacity == 0.0f ) ) {
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 3 ] ).get_or_guess_opacity() == 0.0f ) ) {
// tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
m_materialdata.textures_alpha |= 0x04040004;
}
if( ( m_materialdata.replacable_skins[ 4 ] )
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 4 ] ).opacity == 0.0f ) ) {
&& ( GfxRenderer.Material( m_materialdata.replacable_skins[ 4 ] ).get_or_guess_opacity() == 0.0f ) ) {
// tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
m_materialdata.textures_alpha |= 0x08080008;
}

View File

@@ -309,27 +309,27 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
else if (material.find("replacableskin") != material.npos)
{ // McZapkie-060702: zmienialne skory modelu
m_material = -1;
iFlags |= (Opacity == 1.0f) ? 1 : 0x10; // zmienna tekstura 1
iFlags |= (Opacity < 1.0) ? 1 : 0x10; // zmienna tekstura 1
}
else if (material == "-1")
{
m_material = -1;
iFlags |= (Opacity == 1.0f) ? 1 : 0x10; // zmienna tekstura 1
iFlags |= (Opacity < 1.0) ? 1 : 0x10; // zmienna tekstura 1
}
else if (material == "-2")
{
m_material = -2;
iFlags |= (Opacity == 1.0f) ? 2 : 0x10; // zmienna tekstura 2
iFlags |= (Opacity < 1.0) ? 2 : 0x10; // zmienna tekstura 2
}
else if (material == "-3")
{
m_material = -3;
iFlags |= (Opacity == 1.0f) ? 4 : 0x10; // zmienna tekstura 3
iFlags |= (Opacity < 1.0) ? 4 : 0x10; // zmienna tekstura 3
}
else if (material == "-4")
{
m_material = -4;
iFlags |= (Opacity == 1.0f) ? 8 : 0x10; // zmienna tekstura 4
iFlags |= (Opacity < 1.0) ? 8 : 0x10; // zmienna tekstura 4
}
else {
Name_Material(material);
@@ -341,14 +341,8 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
*/
m_material = GfxRenderer.Fetch_Material( material );
// renderowanie w cyklu przezroczystych tylko jeśli:
// 1. Opacity=0 (przejściowo <1, czy tam <100) oraz
// 2. tekstura ma przezroczystość
iFlags |=
( ( ( Opacity == 0.0f )
&& ( ( m_material != null_handle )
&& ( GfxRenderer.Material( m_material ).opacity == 0.0f ) ) ) ?
0x20 :
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
// 1. Opacity=0 (przejściowo <1, czy tam <100)
iFlags |= Opacity < 1.0f ? 0x20 : 0x10 ; // 0x20-przezroczysta, 0x10-nieprzezroczysta
};
}
else if (eType == TP_STARS)
@@ -359,6 +353,27 @@ int TSubModel::Load( cParser &parser, TModel3d *Model, /*int Pos,*/ bool dynamic
else
iFlags |= 0x10;
if (m_material != null_handle)
{
opengl_material &mat = GfxRenderer.Material(m_material);
// if material don't have opacity set, set legacy submodel opacity
if (std::isnan(mat.opacity))
{
if (iFlags & 0x20) // translucent
mat.opacity = 0.0f;
else if (iFlags & 0x10) // opaque
mat.opacity = 0.5f;
}
else // but if it does, replace submodel opacity with material one
{
iFlags &= ~0x30;
if (mat.opacity == 0.0f)
iFlags |= 0x20; // translucent
else
iFlags |= 0x10; // opaque
}
}
// visibility range
std::string discard;
parser.getTokens(5, false);
@@ -1683,13 +1698,20 @@ void TSubModel::BinInit(TSubModel *s, float4x4 *m, std::vector<std::string> *t,
}
*/
m_material = GfxRenderer.Fetch_Material( m_materialname );
if( ( iFlags & 0x30 ) == 0 ) {
// texture-alpha based fallback if for some reason we don't have opacity flag set yet
iFlags |= (
( ( m_material != null_handle )
&& ( GfxRenderer.Material( m_material ).opacity == 0.0f ) ) ?
0x20 :
0x10 ); // 0x10-nieprzezroczysta, 0x20-przezroczysta
// if we don't have phase flags set for some reason, try to fix it
if (!(iFlags & 0x30) && m_material != null_handle)
{
opengl_material &mat = GfxRenderer.Material(m_material);
if (std::isnan(mat.opacity))
// if material don't have opacity set, try to guess it
mat.opacity = mat.get_or_guess_opacity();
// set phase flag based on material opacity
if (mat.opacity == 0.0f)
iFlags |= 0x20; // translucent
else
iFlags |= 0x10; // opaque
}
}
else {

View File

@@ -563,15 +563,21 @@ void TTrack::Load(cParser *parser, Math3D::vector3 pOrigin)
else if (iCategoryFlag & 2)
if (m_material1 && fTexLength)
{ // dla drogi trzeba ustalić proporcje boków nawierzchni
float w, h;
GfxRenderer.Bind_Material(m_material1);
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
float w = 1.0f, h = 1.0f;
opengl_material &mat1 = GfxRenderer.Material(m_material1);
if (mat1.textures[0] != null_handle)
{
w = GfxRenderer.Texture(mat1.textures[0]).width();
h = GfxRenderer.Texture(mat1.textures[0]).height();
}
if (h != 0.0)
fTexRatio1 = w / h; // proporcja boków
GfxRenderer.Bind_Material(m_material2);
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w);
glGetTexLevelParameterfv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h);
opengl_material &mat2 = GfxRenderer.Material(m_material2);
if (mat2.textures[0] != null_handle)
{
w = GfxRenderer.Texture(mat2.textures[0]).width();
h = GfxRenderer.Texture(mat2.textures[0]).height();
}
if (h != 0.0)
fTexRatio2 = w / h; // proporcja boków
}

View File

@@ -117,6 +117,23 @@ opengl_material::deserialize_mapping( cParser &Input, int const Priority, bool c
return true; // return value marks a key: value pair was extracted, nothing about whether it's recognized
}
float opengl_material::get_or_guess_opacity()
{
if (!std::isnan(opacity))
return opacity;
if (textures[0] != null_handle)
{
opengl_texture &tex = GfxRenderer.Texture(textures[0]);
if (tex.has_alpha)
return 0.0f;
else
return 0.5f;
}
return 0.0f;
}
std::unordered_map<gl::shader::components_e, GLint> material_manager::components_mapping =
{
{ gl::shader::components_e::R, GL_RED },
@@ -183,13 +200,6 @@ material_manager::create( std::string const &Filename, bool const Loadnow ) {
GfxRenderer.Texture(handle).set_components_hint(components_mapping[entry.components]);
}
if (std::isnan(material.opacity))
{
material.opacity = 1.0f;
if (material.textures[0] != null_handle)
material.opacity = GfxRenderer.Texture( material.textures[0] ).has_alpha ? 0.0f : 1.0f;
}
material_handle handle = m_materials.size();
m_materials.emplace_back( material );
m_materialmappings.emplace( material.name, handle );

View File

@@ -36,6 +36,7 @@ struct opengl_material {
// methods
bool
deserialize( cParser &Input, bool const Loadnow );
float get_or_guess_opacity();
private:
// methods

View File

@@ -825,15 +825,15 @@ void opengl_renderer::setup_matrices()
void opengl_renderer::setup_drawing(bool const Alpha)
{
if (true == Alpha)
if (Alpha)
{
::glEnable(GL_BLEND);
m_blendphase = true;
m_blendingenabled = true;
}
else
{
::glDisable(GL_BLEND);
m_blendphase = false;
m_blendingenabled = false;
}
switch (m_renderpass.draw_mode)
@@ -853,6 +853,7 @@ void opengl_renderer::setup_drawing(bool const Alpha)
case rendermode::pickcontrols:
case rendermode::pickscenery:
{
glCullFace(GL_BACK);
break;
}
default:
@@ -1077,10 +1078,11 @@ void opengl_renderer::Bind_Material(material_handle const Material)
for (size_t i = 0; i < gl::MAX_PARAMS; i++)
model_ubs.param[i] = material.params[i];
if (m_blendphase)
model_ubs.opacity = 0.0f;
// if for some reason material don't have opacity set, guess it based on render phase
if (std::isnan(material.opacity))
model_ubs.opacity = m_blendingenabled ? 0.0f : 0.5f;
else
model_ubs.opacity = 1.0f;
model_ubs.opacity = material.opacity;
material.shader->bind();
@@ -1120,6 +1122,12 @@ opengl_material const &opengl_renderer::Material(material_handle const Material)
return m_materials.material(Material);
}
opengl_material &opengl_renderer::Material(material_handle const Material)
{
return m_materials.material(Material);
}
texture_handle opengl_renderer::Fetch_Texture(std::string const &Filename, bool const Loadnow, GLint format_hint)
{
return m_textures.create(Filename, Loadnow, format_hint);
@@ -1127,7 +1135,6 @@ texture_handle opengl_renderer::Fetch_Texture(std::string const &Filename, bool
void opengl_renderer::Bind_Texture(size_t Unit, texture_handle const Texture)
{
m_textures.bind(Unit, Texture);
}

View File

@@ -157,6 +157,7 @@ class opengl_renderer
std::shared_ptr<gl::program> Fetch_Shader(std::string const &name);
opengl_material const &Material(material_handle const Material) const;
opengl_material &Material(material_handle const Material);
// texture methods
texture_handle Fetch_Texture(std::string const &Filename, bool const Loadnow = true, GLint format_hint = GL_SRGB_ALPHA);
void Bind_Texture(size_t Unit, texture_handle const Texture);
@@ -381,7 +382,7 @@ class opengl_renderer
material_handle m_invalid_material;
bool m_blendphase; // m7t: todo: remove kludge!
bool m_blendingenabled;
bool m_widelines_supported;
};

View File

@@ -340,7 +340,7 @@ shape_node::convert( TSubModel const *Submodel ) {
m_data.lighting.diffuse = Submodel->f4Diffuse;
m_data.lighting.specular = Submodel->f4Specular;
m_data.material = Submodel->m_material;
m_data.translucent = ( GfxRenderer.Material( m_data.material ).opacity == 0.0f );
m_data.translucent = ( GfxRenderer.Material( m_data.material ).get_or_guess_opacity() == 0.0f );
// NOTE: we set unlimited view range typical for terrain, because we don't expect to convert any other 3d models
m_data.rangesquared_max = std::numeric_limits<double>::max();

View File

@@ -92,16 +92,8 @@ void main()
{
vec4 tex_color = texture(tex1, f_coord);
if (opacity == 0.0f)
{
//blending
}
else
{
//test
if (tex_color.a < 0.5f)
discard;
}
if (tex_color.a < opacity)
discard;
vec3 envcolor = texture(envmap, reflect(f_pos, normalize(f_normal))).rgb;