diff --git a/binaries/data/config/default.cfg b/binaries/data/config/default.cfg
index b5411399f9..6bcd07fabd 100644
--- a/binaries/data/config/default.cfg
+++ b/binaries/data/config/default.cfg
@@ -139,7 +139,7 @@ textures.maxanisotropy = 2
gpuskinning = false
; Use smooth LOS interpolation
-smoothlos = false
+smoothlos = true
; Use screen-space postprocessing filters (HDR, bloom, DOF, etc). Incompatible with fixed renderpath.
postproc = false
diff --git a/binaries/data/mods/public/shaders/arb/los_interp.fp b/binaries/data/mods/public/shaders/arb/los_interp.fp
index ba97bc3424..6172d9b0ed 100644
--- a/binaries/data/mods/public/shaders/arb/los_interp.fp
+++ b/binaries/data/mods/public/shaders/arb/los_interp.fp
@@ -12,6 +12,6 @@ TEX los2_tex, v_los, texture[1], 2D;
TEMP smoothing;
MOV_SAT smoothing, delta.x;
-LRP result.color.a, smoothing, los1_tex.a, los2_tex.a;
+LRP result.color, smoothing, los1_tex.rrrr, los2_tex.rrrr;
END
diff --git a/binaries/data/mods/public/shaders/arb/minimap.fp b/binaries/data/mods/public/shaders/arb/minimap.fp
index d82c2b8813..eef978d00d 100644
--- a/binaries/data/mods/public/shaders/arb/minimap.fp
+++ b/binaries/data/mods/public/shaders/arb/minimap.fp
@@ -21,12 +21,11 @@
TEMP tex;
TEX tex, fragment.texcoord[0], texture[0], 2D;
- SUB tex.a, 1.0, tex.a;
- MOV result.color.r, 0.0;
- MOV result.color.g, 0.0;
- MOV result.color.b, 0.0;
- MOV result.color.a, tex.a;
+ MOV result.color.r, tex.r;
+ MOV result.color.g, tex.r;
+ MOV result.color.b, tex.r;
+ MOV result.color.a, tex.r;
#endif
#if MINIMAP_POINT
diff --git a/binaries/data/mods/public/shaders/arb/model_common.fp b/binaries/data/mods/public/shaders/arb/model_common.fp
index c943654add..ba9376e2f9 100644
--- a/binaries/data/mods/public/shaders/arb/model_common.fp
+++ b/binaries/data/mods/public/shaders/arb/model_common.fp
@@ -148,8 +148,8 @@ TEX tex, v_tex, texture[0], 2D;
#if !IGNORE_LOS
// Multiply everything by the LOS texture
- TEX tex.a, v_los, texture[2], 2D;
- MUL color.rgb, color, tex.a;
+ TEX tex.r, v_los, texture[2], 2D;
+ MUL color.rgb, color, tex.r;
#endif
MUL result.color.rgb, color, shadingColor;
diff --git a/binaries/data/mods/public/shaders/arb/overlayline.fp b/binaries/data/mods/public/shaders/arb/overlayline.fp
index bde918c33d..f6f96c641f 100644
--- a/binaries/data/mods/public/shaders/arb/overlayline.fp
+++ b/binaries/data/mods/public/shaders/arb/overlayline.fp
@@ -16,10 +16,10 @@ TEX mask, fragment.texcoord[0], texture[1], 2D;
#if IGNORE_LOS
MOV result.color.rgb, color;
#else
- // Multiply RGB by LOS texture (alpha channel)
+ // Multiply RGB by LOS texture (red channel)
TEMP los;
TEX los, fragment.texcoord[1], texture[2], 2D;
- MUL result.color.rgb, color, los.a;
+ MUL result.color.rgb, color, los.r;
#endif
// Use alpha from base texture, combined with the object color/fragment alpha.
diff --git a/binaries/data/mods/public/shaders/arb/particle.fp b/binaries/data/mods/public/shaders/arb/particle.fp
index a981f676c8..ed12b5051c 100644
--- a/binaries/data/mods/public/shaders/arb/particle.fp
+++ b/binaries/data/mods/public/shaders/arb/particle.fp
@@ -17,7 +17,7 @@ MUL color.rgb, color, tex;
// Multiply everything by the LOS texture
TEX losTex, v_los, texture[1], 2D;
-MUL result.color.rgb, color, losTex.a;
+MUL result.color.rgb, color, losTex.r;
MUL result.color.a, tex, fragment.color;
END
diff --git a/binaries/data/mods/public/shaders/arb/terrain_common.fp b/binaries/data/mods/public/shaders/arb/terrain_common.fp
index 133078f742..37044d3270 100644
--- a/binaries/data/mods/public/shaders/arb/terrain_common.fp
+++ b/binaries/data/mods/public/shaders/arb/terrain_common.fp
@@ -87,8 +87,8 @@ TEX color, fragment.texcoord[0], texture[0], 2D;
#endif
// Multiply everything by the LOS texture
-TEX tex.a, fragment.texcoord[3], texture[3], 2D;
-MUL color.rgb, color, tex.a;
+TEX tex.r, fragment.texcoord[3], texture[3], 2D;
+MUL color.rgb, color, tex.r;
#if DECAL
MUL result.color.rgb, color, shadingColor;
diff --git a/binaries/data/mods/public/shaders/arb/water_simple.fp b/binaries/data/mods/public/shaders/arb/water_simple.fp
index 3e85c48b6b..48865547c5 100644
--- a/binaries/data/mods/public/shaders/arb/water_simple.fp
+++ b/binaries/data/mods/public/shaders/arb/water_simple.fp
@@ -11,7 +11,7 @@ MUL diffuse, diffuse, color;
TEMP los;
TEX los, v_losCoords, texture[1], 2D;
-MUL diffuse, diffuse, los.a;
+MUL diffuse, diffuse, los.r;
MOV result.color, diffuse;
END
diff --git a/binaries/data/mods/public/shaders/effects/minimap_los.xml b/binaries/data/mods/public/shaders/effects/minimap_los.xml
new file mode 100644
index 0000000000..2eb9d416d0
--- /dev/null
+++ b/binaries/data/mods/public/shaders/effects/minimap_los.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/binaries/data/mods/public/shaders/glsl/common/los_fragment.h b/binaries/data/mods/public/shaders/glsl/common/los_fragment.h
index 661865f95f..9427f6d4be 100644
--- a/binaries/data/mods/public/shaders/glsl/common/los_fragment.h
+++ b/binaries/data/mods/public/shaders/glsl/common/los_fragment.h
@@ -10,7 +10,7 @@
float getLOS()
{
#if !IGNORE_LOS
- float los = texture2D(losTex, v_los).a;
+ float los = texture2D(losTex, v_los).r;
float threshold = 0.03;
return (los - threshold) / (1.0 - threshold);
#else
diff --git a/binaries/data/mods/public/shaders/glsl/los_interp.fs b/binaries/data/mods/public/shaders/glsl/los_interp.fs
index 54e60d3f12..fe035e1540 100644
--- a/binaries/data/mods/public/shaders/glsl/los_interp.fs
+++ b/binaries/data/mods/public/shaders/glsl/los_interp.fs
@@ -9,9 +9,9 @@ uniform float delta;
void main(void)
{
- float los2 = texture2D(losTex1, v_tex).a;
- float los1 = texture2D(losTex2, v_tex).a;
+ vec4 los2 = texture2D(losTex1, v_tex).rrrr;
+ vec4 los1 = texture2D(losTex2, v_tex).rrrr;
- gl_FragColor.a = mix(los1, los2, clamp(delta, 0.0, 1.0));
+ gl_FragColor = mix(los1, los2, clamp(delta, 0.0, 1.0));
}
diff --git a/binaries/data/mods/public/shaders/glsl/minimap.fs b/binaries/data/mods/public/shaders/glsl/minimap.fs
index f8f7d18869..92673c97ac 100644
--- a/binaries/data/mods/public/shaders/glsl/minimap.fs
+++ b/binaries/data/mods/public/shaders/glsl/minimap.fs
@@ -35,7 +35,7 @@ void main()
#endif
#if MINIMAP_LOS
- gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0 - texture2D(baseTex, v_tex).a);
+ gl_FragColor = texture2D(baseTex, v_tex).rrrr;
#endif
#if MINIMAP_POINT
diff --git a/source/graphics/LOSTexture.cpp b/source/graphics/LOSTexture.cpp
index 7eb70a9b04..7380b7f5c4 100644
--- a/source/graphics/LOSTexture.cpp
+++ b/source/graphics/LOSTexture.cpp
@@ -248,25 +248,37 @@ void CLOSTexture::ConstructTexture(Renderer::Backend::IDeviceCommandContext* dev
Renderer::Backend::Sampler::Filter::LINEAR,
Renderer::Backend::Sampler::AddressMode::CLAMP_TO_EDGE);
+ if (backendDevice->IsFramebufferFormatSupported(Renderer::Backend::Format::R8_UNORM))
+ {
+ m_TextureFormat = Renderer::Backend::Format::R8_UNORM;
+ m_TextureFormatStride = 1;
+ }
+ else
+ {
+ m_TextureFormat = Renderer::Backend::Format::R8G8B8A8_UNORM;
+ m_TextureFormatStride = 4;
+ }
+
m_Texture = backendDevice->CreateTexture2D("LOSTexture",
- Renderer::Backend::Format::A8_UNORM, textureSize, textureSize, defaultSamplerDesc);
+ m_TextureFormat, textureSize, textureSize, defaultSamplerDesc);
// Initialise texture with SoD color, for the areas we don't
// overwrite with uploading later.
- std::unique_ptr texData = std::make_unique(textureSize * textureSize);
- memset(texData.get(), 0x00, textureSize * textureSize);
+ const size_t textureDataSize = textureSize * textureSize * m_TextureFormatStride;
+ std::unique_ptr texData = std::make_unique(textureDataSize);
+ memset(texData.get(), 0x00, textureDataSize);
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS())
{
m_SmoothTextures[0] = backendDevice->CreateTexture2D("LOSSmoothTexture0",
- Renderer::Backend::Format::A8_UNORM, textureSize, textureSize, defaultSamplerDesc);
+ m_TextureFormat, textureSize, textureSize, defaultSamplerDesc);
m_SmoothTextures[1] = backendDevice->CreateTexture2D("LOSSmoothTexture1",
- Renderer::Backend::Format::A8_UNORM, textureSize, textureSize, defaultSamplerDesc);
+ m_TextureFormat, textureSize, textureSize, defaultSamplerDesc);
- m_SmoothFramebuffers[0] = backendDevice->CreateFramebuffer("LOSSmoothFramebuffer0",
- m_SmoothTextures[0].get(), nullptr);
- m_SmoothFramebuffers[1] = backendDevice->CreateFramebuffer("LOSSmoothFramebuffer1",
- m_SmoothTextures[1].get(), nullptr);
+ m_SmoothFramebuffers[0] = backendDevice->CreateFramebuffer(
+ "LOSSmoothFramebuffer0", m_SmoothTextures[0].get(), nullptr);
+ m_SmoothFramebuffers[1] = backendDevice->CreateFramebuffer(
+ "LOSSmoothFramebuffer1", m_SmoothTextures[1].get(), nullptr);
if (!m_SmoothFramebuffers[0] || !m_SmoothFramebuffers[1])
{
LOGERROR("Failed to create LOS framebuffers");
@@ -274,16 +286,13 @@ void CLOSTexture::ConstructTexture(Renderer::Backend::IDeviceCommandContext* dev
}
deviceCommandContext->UploadTexture(
- m_SmoothTextures[0].get(), Renderer::Backend::Format::A8_UNORM,
- texData.get(), textureSize * textureSize);
+ m_SmoothTextures[0].get(), m_TextureFormat, texData.get(), textureDataSize);
deviceCommandContext->UploadTexture(
- m_SmoothTextures[1].get(), Renderer::Backend::Format::A8_UNORM,
- texData.get(), textureSize * textureSize);
+ m_SmoothTextures[1].get(), m_TextureFormat, texData.get(), textureDataSize);
}
deviceCommandContext->UploadTexture(
- m_Texture.get(), Renderer::Backend::Format::A8_UNORM,
- texData.get(), textureSize * textureSize);
+ m_Texture.get(), m_TextureFormat, texData.get(), textureDataSize);
texData.reset();
@@ -334,32 +343,49 @@ void CLOSTexture::RecomputeTexture(Renderer::Backend::IDeviceCommandContext* dev
PROFILE("recompute LOS texture");
- size_t pitch;
- const size_t dataSize = GetBitmapSize(m_MapSize, m_MapSize, &pitch);
- ENSURE(pitch * m_MapSize <= dataSize);
- std::unique_ptr losData = std::make_unique(dataSize);
-
CmpPtr cmpRangeManager(m_Simulation, SYSTEM_ENTITY);
if (!cmpRangeManager)
return;
+ size_t pitch;
+ const size_t dataSize = GetBitmapSize(m_MapSize, m_MapSize, &pitch);
+ ENSURE(pitch * m_MapSize <= dataSize);
+ std::unique_ptr losData = std::make_unique(
+ dataSize * m_TextureFormatStride);
+
CLosQuerier los(cmpRangeManager->GetLosQuerier(g_Game->GetSimulation2()->GetSimContext().GetCurrentDisplayedPlayer()));
GenerateBitmap(los, &losData[0], m_MapSize, m_MapSize, pitch);
+ // GenerateBitmap writes data tightly packed and we need to offset it to fit
+ // into the texture format properly.
+ const size_t textureDataPitch = pitch * m_TextureFormatStride;
+ if (m_TextureFormatStride > 1)
+ {
+ // We skip the last byte because it will be first in our order and we
+ // don't need to move it.
+ for (size_t index = 0; index + 1 < dataSize; ++index)
+ {
+ const size_t oldAddress = dataSize - 1 - index;
+ const size_t newAddress = oldAddress * m_TextureFormatStride;
+ losData[newAddress] = losData[oldAddress];
+ losData[oldAddress] = 0;
+ }
+ }
+
if (CRenderer::IsInitialised() && g_RenderingOptions.GetSmoothLOS() && recreated)
{
deviceCommandContext->UploadTextureRegion(
- m_SmoothTextures[0].get(), Renderer::Backend::Format::A8_UNORM, losData.get(),
- pitch * m_MapSize, 0, 0, pitch, m_MapSize);
+ m_SmoothTextures[0].get(), m_TextureFormat, losData.get(),
+ textureDataPitch * m_MapSize, 0, 0, pitch, m_MapSize);
deviceCommandContext->UploadTextureRegion(
- m_SmoothTextures[1].get(), Renderer::Backend::Format::A8_UNORM, losData.get(),
- pitch * m_MapSize, 0, 0, pitch, m_MapSize);
+ m_SmoothTextures[1].get(), m_TextureFormat, losData.get(),
+ textureDataPitch * m_MapSize, 0, 0, pitch, m_MapSize);
}
deviceCommandContext->UploadTextureRegion(
- m_Texture.get(), Renderer::Backend::Format::A8_UNORM, losData.get(),
- pitch * m_MapSize, 0, 0, pitch, m_MapSize);
+ m_Texture.get(), m_TextureFormat, losData.get(),
+ textureDataPitch * m_MapSize, 0, 0, pitch, m_MapSize);
}
size_t CLOSTexture::GetBitmapSize(size_t w, size_t h, size_t* pitch)
diff --git a/source/graphics/LOSTexture.h b/source/graphics/LOSTexture.h
index 30ea4253a4..e090503e09 100644
--- a/source/graphics/LOSTexture.h
+++ b/source/graphics/LOSTexture.h
@@ -20,6 +20,7 @@
#include "graphics/ShaderTechniquePtr.h"
#include "maths/Matrix3D.h"
+#include "renderer/backend/Format.h"
#include "renderer/backend/IDeviceCommandContext.h"
#include "renderer/backend/IFramebuffer.h"
#include "renderer/backend/ITexture.h"
@@ -87,6 +88,12 @@ private:
bool m_ShaderInitialized = false;
+ // We need to choose the smallest format. We always use the red channel but
+ // R8_UNORM might be unavailable on some platforms. So we fallback to
+ // R8G8B8A8_UNORM.
+ Renderer::Backend::Format m_TextureFormat =
+ Renderer::Backend::Format::UNDEFINED;
+ size_t m_TextureFormatStride = 0;
std::unique_ptr
m_Texture, m_SmoothTextures[2];
diff --git a/source/graphics/MiniMapTexture.cpp b/source/graphics/MiniMapTexture.cpp
index 50133cbbb8..832c002725 100644
--- a/source/graphics/MiniMapTexture.cpp
+++ b/source/graphics/MiniMapTexture.cpp
@@ -490,11 +490,11 @@ void CMiniMapTexture::RenderFinalTexture(
DrawTexture(deviceCommandContext);
deviceCommandContext->EndPass();
- pipelineStateDesc.blendState.enabled = false;
- pipelineStateDesc.blendState.colorWriteMask =
- Renderer::Backend::ColorWriteMask::ALPHA;
- deviceCommandContext->SetGraphicsPipelineState(pipelineStateDesc);
+ tech = g_Renderer.GetShaderManager().LoadEffect(str_minimap_los, CShaderDefines());
+ deviceCommandContext->SetGraphicsPipelineState(
+ tech->GetGraphicsPipelineStateDesc());
deviceCommandContext->BeginPass();
+ shader = tech->GetShader();
deviceCommandContext->SetTexture(
shader->GetBindingSlot(str_baseTex), losTexture.GetTexture());
diff --git a/source/gui/ObjectTypes/CMiniMap.cpp b/source/gui/ObjectTypes/CMiniMap.cpp
index efa89dabdf..60fe50cf3e 100644
--- a/source/gui/ObjectTypes/CMiniMap.cpp
+++ b/source/gui/ObjectTypes/CMiniMap.cpp
@@ -21,7 +21,6 @@
#include "graphics/Canvas2D.h"
#include "graphics/GameView.h"
-#include "graphics/LOSTexture.h"
#include "graphics/MiniMapTexture.h"
#include "graphics/MiniPatch.h"
#include "graphics/ShaderManager.h"
diff --git a/source/ps/CStrInternStatic.h b/source/ps/CStrInternStatic.h
index 7e106ea24b..e4cac6803e 100644
--- a/source/ps/CStrInternStatic.h
+++ b/source/ps/CStrInternStatic.h
@@ -127,6 +127,7 @@ X(mapSize)
X(maskTex)
X(maskTextureTransform)
X(minimap)
+X(minimap_los)
X(modelViewMatrix)
X(murkiness)
X(normalMap)
diff --git a/source/renderer/backend/Format.h b/source/renderer/backend/Format.h
index 7f42966b57..062cc6d6fc 100644
--- a/source/renderer/backend/Format.h
+++ b/source/renderer/backend/Format.h
@@ -27,12 +27,15 @@ namespace Backend
enum class Format
{
UNDEFINED,
+ R8_UNORM,
R8G8_UNORM,
R8G8_UINT,
R8G8B8_UNORM,
R8G8B8A8_UNORM,
R8G8B8A8_UINT,
+ // TODO: we need to drop legacy A8 and L8 formats as soon as we have proper
+ // channel swizzling.
A8_UNORM,
L8_UNORM,
diff --git a/source/renderer/backend/IDevice.h b/source/renderer/backend/IDevice.h
index fd621e66b7..a08c180e4d 100644
--- a/source/renderer/backend/IDevice.h
+++ b/source/renderer/backend/IDevice.h
@@ -99,6 +99,8 @@ public:
virtual bool IsTextureFormatSupported(const Format format) const = 0;
+ virtual bool IsFramebufferFormatSupported(const Format format) const = 0;
+
virtual const Capabilities& GetCapabilities() const = 0;
};
diff --git a/source/renderer/backend/dummy/Device.cpp b/source/renderer/backend/dummy/Device.cpp
index fae6c8870a..acabf6b711 100644
--- a/source/renderer/backend/dummy/Device.cpp
+++ b/source/renderer/backend/dummy/Device.cpp
@@ -122,6 +122,11 @@ bool CDevice::IsTextureFormatSupported(const Format UNUSED(format)) const
return true;
}
+bool CDevice::IsFramebufferFormatSupported(const Format UNUSED(format)) const
+{
+ return true;
+}
+
} // namespace Dummy
} // namespace Backend
diff --git a/source/renderer/backend/dummy/Device.h b/source/renderer/backend/dummy/Device.h
index f2918bf823..972378bb66 100644
--- a/source/renderer/backend/dummy/Device.h
+++ b/source/renderer/backend/dummy/Device.h
@@ -76,6 +76,8 @@ public:
bool IsTextureFormatSupported(const Format format) const override;
+ bool IsFramebufferFormatSupported(const Format format) const override;
+
const Capabilities& GetCapabilities() const override { return m_Capabilities; }
protected:
diff --git a/source/renderer/backend/gl/Device.cpp b/source/renderer/backend/gl/Device.cpp
index bd2c59a1f5..2b1d0013ae 100644
--- a/source/renderer/backend/gl/Device.cpp
+++ b/source/renderer/backend/gl/Device.cpp
@@ -912,6 +912,27 @@ bool CDevice::IsTextureFormatSupported(const Format format) const
return supported;
}
+bool CDevice::IsFramebufferFormatSupported(const Format format) const
+{
+ bool supported = false;
+ switch (format)
+ {
+ case Format::UNDEFINED:
+ break;
+#if !CONFIG2_GLES
+ case Format::R8_UNORM:
+ supported = ogl_HaveVersion(3, 0);
+ break;
+#endif
+ case Format::R8G8B8A8_UNORM:
+ supported = true;
+ break;
+ default:
+ break;
+ }
+ return supported;
+}
+
} // namespace GL
} // namespace Backend
diff --git a/source/renderer/backend/gl/Device.h b/source/renderer/backend/gl/Device.h
index 74965c2dfa..9c30c7ed1b 100644
--- a/source/renderer/backend/gl/Device.h
+++ b/source/renderer/backend/gl/Device.h
@@ -93,6 +93,8 @@ public:
bool IsTextureFormatSupported(const Format format) const override;
+ bool IsFramebufferFormatSupported(const Format format) const override;
+
const Capabilities& GetCapabilities() const override { return m_Capabilities; }
private:
diff --git a/source/renderer/backend/gl/DeviceCommandContext.cpp b/source/renderer/backend/gl/DeviceCommandContext.cpp
index d11b34fd9e..286bf60021 100644
--- a/source/renderer/backend/gl/DeviceCommandContext.cpp
+++ b/source/renderer/backend/gl/DeviceCommandContext.cpp
@@ -228,6 +228,9 @@ void CDeviceCommandContext::UploadTextureRegion(
ENSURE(layer == 0);
if (texture->GetFormat() == Format::R8G8B8A8_UNORM ||
texture->GetFormat() == Format::R8G8B8_UNORM ||
+#if !CONFIG2_GLES
+ texture->GetFormat() == Format::R8_UNORM ||
+#endif
texture->GetFormat() == Format::A8_UNORM)
{
ENSURE(texture->GetFormat() == dataFormat);
@@ -241,6 +244,12 @@ void CDeviceCommandContext::UploadTextureRegion(
pixelFormat = GL_RGB;
bytesPerPixel = 3;
break;
+#if !CONFIG2_GLES
+ case Format::R8_UNORM:
+ pixelFormat = GL_RED;
+ bytesPerPixel = 1;
+ break;
+#endif
case Format::A8_UNORM:
pixelFormat = GL_ALPHA;
bytesPerPixel = 1;
@@ -980,7 +989,14 @@ void CDeviceCommandContext::DrawInstanced(
return;
ENSURE(firstInstance == 0);
m_ShaderProgram->AssertPointersBound();
+#if CONFIG2_GLES
+ ENSURE(!m_Device->GetCapabilities().instancing);
+ UNUSED2(firstVertex);
+ UNUSED2(vertexCount);
+ UNUSED2(instanceCount);
+#else
glDrawArraysInstancedARB(GL_TRIANGLES, firstVertex, vertexCount, instanceCount);
+#endif
ogl_WarnIfError();
}
@@ -1004,9 +1020,16 @@ void CDeviceCommandContext::DrawIndexedInstanced(
// Don't use glMultiDrawElements here since it doesn't have a significant
// performance impact and it suffers from various driver bugs (e.g. it breaks
// in Mesa 7.10 swrast with index VBOs).
+#if CONFIG2_GLES
+ ENSURE(!m_Device->GetCapabilities().instancing);
+ UNUSED2(indexCount);
+ UNUSED2(firstIndex);
+ UNUSED2(instanceCount);
+#else
glDrawElementsInstancedARB(GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT,
static_cast((static_cast(m_IndexBufferData) + sizeof(uint16_t) * firstIndex)),
instanceCount);
+#endif
ogl_WarnIfError();
}
diff --git a/source/renderer/backend/gl/Framebuffer.cpp b/source/renderer/backend/gl/Framebuffer.cpp
index 96fd785637..942b77b1bd 100644
--- a/source/renderer/backend/gl/Framebuffer.cpp
+++ b/source/renderer/backend/gl/Framebuffer.cpp
@@ -57,6 +57,8 @@ std::unique_ptr CFramebuffer::Create(
if (colorAttachment)
{
+ ENSURE(device->IsFramebufferFormatSupported(colorAttachment->GetFormat()));
+
framebuffer->m_AttachmentMask |= GL_COLOR_BUFFER_BIT;
#if CONFIG2_GLES
diff --git a/source/renderer/backend/gl/ShaderProgram.cpp b/source/renderer/backend/gl/ShaderProgram.cpp
index 70774ed56d..94d3a8faf2 100644
--- a/source/renderer/backend/gl/ShaderProgram.cpp
+++ b/source/renderer/backend/gl/ShaderProgram.cpp
@@ -1101,12 +1101,17 @@ public:
const GLboolean normalized = NormalizedFromFormat(format);
glVertexAttribPointer(
attributeLocation, size, type, normalized, stride, static_cast(data) + offset);
+#if CONFIG2_GLES
+ ENSURE(!m_Device->GetCapabilities().instancing);
+ UNUSED2(rate);
+#else
if (rate == VertexAttributeRate::PER_INSTANCE)
ENSURE(m_Device->GetCapabilities().instancing);
if (m_Device->GetCapabilities().instancing)
{
glVertexAttribDivisorARB(attributeLocation, rate == VertexAttributeRate::PER_INSTANCE ? 1 : 0);
}
+#endif
m_ValidStreams |= GetStreamMask(stream);
}
diff --git a/source/renderer/backend/gl/Texture.cpp b/source/renderer/backend/gl/Texture.cpp
index 23e48fc8b5..c71a39c6ca 100644
--- a/source/renderer/backend/gl/Texture.cpp
+++ b/source/renderer/backend/gl/Texture.cpp
@@ -178,6 +178,13 @@ std::unique_ptr CTexture::Create(CDevice* device, const char* name,
pixelFormat = GL_RGB;
pixelType = GL_UNSIGNED_BYTE;
break;
+#if !CONFIG2_GLES
+ case Format::R8_UNORM:
+ internalFormat = GL_RED;
+ pixelFormat = GL_RED;
+ pixelType = GL_UNSIGNED_BYTE;
+ break;
+#endif
case Format::A8_UNORM:
internalFormat = GL_ALPHA;
pixelFormat = GL_ALPHA;
diff --git a/source/renderer/backend/vulkan/Device.cpp b/source/renderer/backend/vulkan/Device.cpp
index e52f9d75d1..f39311ad94 100644
--- a/source/renderer/backend/vulkan/Device.cpp
+++ b/source/renderer/backend/vulkan/Device.cpp
@@ -162,6 +162,12 @@ bool CDevice::IsTextureFormatSupported(const Format format) const
return false;
}
+bool CDevice::IsFramebufferFormatSupported(const Format format) const
+{
+ UNUSED2(format);
+ return false;
+}
+
} // namespace Vulkan
} // namespace Backend
diff --git a/source/renderer/backend/vulkan/Device.h b/source/renderer/backend/vulkan/Device.h
index d89d3af778..bedd225476 100644
--- a/source/renderer/backend/vulkan/Device.h
+++ b/source/renderer/backend/vulkan/Device.h
@@ -81,6 +81,8 @@ public:
bool IsTextureFormatSupported(const Format format) const override;
+ bool IsFramebufferFormatSupported(const Format format) const override;
+
const Capabilities& GetCapabilities() const override { return m_Capabilities; }
private: