axmol/extensions/Effekseer/EffekseerRendererGL/EffekseerRenderer/EffekseerRendererGL.RenderS...

280 lines
7.8 KiB
C++

//----------------------------------------------------------------------------------
// Include
//----------------------------------------------------------------------------------
#include "EffekseerRendererGL.RenderState.h"
#include "EffekseerRendererGL.Renderer.h"
#include "EffekseerRendererGL.RendererImplemented.h"
#include "EffekseerRendererGL.GLExtension.h"
//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------
namespace EffekseerRendererGL
{
//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------
RenderState::RenderState(RendererImplemented* renderer)
: m_renderer(renderer)
{
if (m_renderer->GetDeviceType() == OpenGLDeviceType::OpenGL3 || m_renderer->GetDeviceType() == OpenGLDeviceType::OpenGLES3)
{
glGenSamplers(Effekseer::TextureSlotMax, m_samplers.data());
}
GLint frontFace = 0;
glGetIntegerv(GL_FRONT_FACE, &frontFace);
if (GL_CW == frontFace)
{
m_isCCW = false;
}
}
//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------
RenderState::~RenderState()
{
if (m_renderer->GetDeviceType() == OpenGLDeviceType::OpenGL3 || m_renderer->GetDeviceType() == OpenGLDeviceType::OpenGLES3)
{
glDeleteSamplers(Effekseer::TextureSlotMax, m_samplers.data());
}
}
//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------
void RenderState::Update(bool forced)
{
GLCheckError();
if (m_active.DepthTest != m_next.DepthTest || forced)
{
if (m_next.DepthTest)
{
glEnable(GL_DEPTH_TEST);
}
else
{
glDisable(GL_DEPTH_TEST);
}
}
GLCheckError();
if (m_active.DepthWrite != m_next.DepthWrite || forced)
{
glDepthMask(m_next.DepthWrite);
}
GLCheckError();
if (m_active.CullingType != m_next.CullingType || forced)
{
if (m_isCCW)
{
if (m_next.CullingType == Effekseer::CullingType::Front)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
}
else if (m_next.CullingType == Effekseer::CullingType::Back)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
else if (m_next.CullingType == Effekseer::CullingType::Double)
{
glDisable(GL_CULL_FACE);
glCullFace(GL_FRONT_AND_BACK);
}
}
else
{
if (m_next.CullingType == Effekseer::CullingType::Front)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
}
else if (m_next.CullingType == Effekseer::CullingType::Back)
{
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);
}
else if (m_next.CullingType == Effekseer::CullingType::Double)
{
glDisable(GL_CULL_FACE);
glCullFace(GL_FRONT_AND_BACK);
}
}
}
GLCheckError();
if (m_active.AlphaBlend != m_next.AlphaBlend || forced)
{
{
glEnable(GL_BLEND);
if (m_next.AlphaBlend == ::Effekseer::AlphaBlendType::Opacity)
{
glBlendEquationSeparate(GL_FUNC_ADD, GL_MAX);
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ONE, GL_ONE);
}
else if (m_next.AlphaBlend == ::Effekseer::AlphaBlendType::Sub)
{
glBlendEquationSeparate(GL_FUNC_REVERSE_SUBTRACT, GL_FUNC_ADD);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
}
else
{
glBlendEquationSeparate(GL_FUNC_ADD, GL_FUNC_ADD);
if (m_next.AlphaBlend == ::Effekseer::AlphaBlendType::Blend)
{
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
}
else if (m_next.AlphaBlend == ::Effekseer::AlphaBlendType::Add)
{
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ONE, GL_ONE);
}
else if (m_next.AlphaBlend == ::Effekseer::AlphaBlendType::Mul)
{
glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
}
}
}
}
GLCheckError();
static const GLint glfilterMin[] = {GL_NEAREST, GL_LINEAR_MIPMAP_LINEAR};
static const GLint glfilterMin_NoneMipmap[] = {GL_NEAREST, GL_LINEAR};
static const GLint glfilterMag[] = {GL_NEAREST, GL_LINEAR};
static const GLint glwrap[] = {GL_REPEAT, GL_CLAMP_TO_EDGE};
if (m_renderer->GetDeviceType() == OpenGLDeviceType::OpenGL3 || m_renderer->GetDeviceType() == OpenGLDeviceType::OpenGLES3)
{
for (int32_t i = 0; i < (int32_t)m_renderer->GetCurrentTextures().size(); i++)
{
// If a texture is not assigned, skip it.
const auto& texture = m_renderer->GetCurrentTextures()[i];
if (texture == nullptr)
continue;
if (m_active.TextureFilterTypes[i] != m_next.TextureFilterTypes[i] || forced || m_active.TextureIDs[i] != m_next.TextureIDs[i])
{
glActiveTexture(GL_TEXTURE0 + i);
// for webngl
#ifndef NDEBUG
// GLint bound = 0;
// glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound);
// assert(bound > 0);
#endif
int32_t filter_ = (int32_t)m_next.TextureFilterTypes[i];
glSamplerParameteri(m_samplers[i], GL_TEXTURE_MAG_FILTER, glfilterMag[filter_]);
if (texture->GetParameter().MipLevelCount != 1)
{
glSamplerParameteri(m_samplers[i], GL_TEXTURE_MIN_FILTER, glfilterMin[filter_]);
}
else
{
glSamplerParameteri(m_samplers[i], GL_TEXTURE_MIN_FILTER, glfilterMin_NoneMipmap[filter_]);
}
// glSamplerParameteri( m_samplers[i], GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
// glSamplerParameteri( m_samplers[i], GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glBindSampler(i, m_samplers[i]);
}
if (m_active.TextureWrapTypes[i] != m_next.TextureWrapTypes[i] || forced || m_active.TextureIDs[i] != m_next.TextureIDs[i])
{
glActiveTexture(GL_TEXTURE0 + i);
int32_t wrap_ = (int32_t)m_next.TextureWrapTypes[i];
glSamplerParameteri(m_samplers[i], GL_TEXTURE_WRAP_S, glwrap[wrap_]);
glSamplerParameteri(m_samplers[i], GL_TEXTURE_WRAP_T, glwrap[wrap_]);
glBindSampler(i, m_samplers[i]);
}
}
}
else
{
GLCheckError();
for (int32_t i = 0; i < (int32_t)m_renderer->GetCurrentTextures().size(); i++)
{
// If a texture is not assigned, skip it.
const auto& texture = m_renderer->GetCurrentTextures()[i];
if (texture == nullptr)
continue;
// always changes because a flag is assigned into a texture
// if (m_active.TextureFilterTypes[i] != m_next.TextureFilterTypes[i] || forced)
{
glActiveTexture(GL_TEXTURE0 + i);
GLCheckError();
// for webngl
#ifndef NDEBUG
GLint bound = 0;
glGetIntegerv(GL_TEXTURE_BINDING_2D, &bound);
assert(bound > 0);
#endif
int32_t filter_ = (int32_t)m_next.TextureFilterTypes[i];
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, glfilterMag[filter_]);
GLCheckError();
if (texture->GetParameter().MipLevelCount != 1)
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glfilterMin[filter_]);
}
else
{
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, glfilterMin_NoneMipmap[filter_]);
}
}
// always changes because a flag is assigned into a texture
// if (m_active.TextureWrapTypes[i] != m_next.TextureWrapTypes[i] || forced)
{
glActiveTexture(GL_TEXTURE0 + i);
GLCheckError();
int32_t wrap_ = (int32_t)m_next.TextureWrapTypes[i];
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glwrap[wrap_]);
GLCheckError();
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glwrap[wrap_]);
GLCheckError();
}
}
GLCheckError();
}
glActiveTexture(GL_TEXTURE0);
m_active = m_next;
GLCheckError();
}
//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------
} // namespace EffekseerRendererGL
//-----------------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------------