diff --git a/scwx-qt/gl/texture2d_array.frag b/scwx-qt/gl/texture2d_array.frag
new file mode 100644
index 00000000..c345769a
--- /dev/null
+++ b/scwx-qt/gl/texture2d_array.frag
@@ -0,0 +1,16 @@
+#version 330 core
+
+// Lower the default precision to medium
+precision mediump float;
+
+uniform sampler2DArray uTexture;
+
+smooth in vec2 texCoord;
+smooth in vec4 color;
+
+layout (location = 0) out vec4 fragColor;
+
+void main()
+{
+ fragColor = texture(uTexture, vec3(texCoord, 0.0)) * color;
+}
diff --git a/scwx-qt/scwx-qt.cmake b/scwx-qt/scwx-qt.cmake
index 6f3513dd..6557e6ca 100644
--- a/scwx-qt/scwx-qt.cmake
+++ b/scwx-qt/scwx-qt.cmake
@@ -265,6 +265,7 @@ set(SHADER_FILES gl/color.frag
gl/texture1d.frag
gl/texture1d.vert
gl/texture2d.frag
+ gl/texture2d_array.frag
gl/threshold.geom)
set(CMAKE_FILES scwx-qt.cmake)
diff --git a/scwx-qt/scwx-qt.qrc b/scwx-qt/scwx-qt.qrc
index 5453b19d..47e49c4c 100644
--- a/scwx-qt/scwx-qt.qrc
+++ b/scwx-qt/scwx-qt.qrc
@@ -12,6 +12,7 @@
gl/texture1d.frag
gl/texture1d.vert
gl/texture2d.frag
+ gl/texture2d_array.frag
gl/threshold.geom
res/config/radar_sites.json
res/fonts/din1451alt.ttf
diff --git a/scwx-qt/source/scwx/qt/gl/draw/geo_line.cpp b/scwx-qt/source/scwx/qt/gl/draw/geo_line.cpp
index 2b939293..912a5022 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/geo_line.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/geo_line.cpp
@@ -92,8 +92,8 @@ void GeoLine::Initialize()
{
gl::OpenGLFunctions& gl = p->context_->gl();
- p->shaderProgram_ = p->context_->GetShaderProgram(":/gl/geo_line.vert",
- ":/gl/texture2d.frag");
+ p->shaderProgram_ = p->context_->GetShaderProgram(
+ ":/gl/geo_line.vert", ":/gl/texture2d_array.frag");
p->uMVPMatrixLocation_ =
gl.glGetUniformLocation(p->shaderProgram_->id(), "uMVPMatrix");
diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp
index fce5495d..22e94bb8 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_icons.cpp
@@ -151,7 +151,7 @@ void PlacefileIcons::Initialize()
p->shaderProgram_ = p->context_->GetShaderProgram(
{{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
- {GL_FRAGMENT_SHADER, ":/gl/texture2d.frag"}});
+ {GL_FRAGMENT_SHADER, ":/gl/texture2d_array.frag"}});
p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix");
p->uMapMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMapMatrix");
@@ -261,8 +261,8 @@ void PlacefileIcons::Render(
}
// Interpolate texture coordinates
- gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Draw icons
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
diff --git a/scwx-qt/source/scwx/qt/gl/draw/placefile_images.cpp b/scwx-qt/source/scwx/qt/gl/draw/placefile_images.cpp
index 092fdbf3..e796ed04 100644
--- a/scwx-qt/source/scwx/qt/gl/draw/placefile_images.cpp
+++ b/scwx-qt/source/scwx/qt/gl/draw/placefile_images.cpp
@@ -129,7 +129,7 @@ void PlacefileImages::Initialize()
p->shaderProgram_ = p->context_->GetShaderProgram(
{{GL_VERTEX_SHADER, ":/gl/geo_texture2d.vert"},
{GL_GEOMETRY_SHADER, ":/gl/threshold.geom"},
- {GL_FRAGMENT_SHADER, ":/gl/texture2d.frag"}});
+ {GL_FRAGMENT_SHADER, ":/gl/texture2d_array.frag"}});
p->uMVPMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMVPMatrix");
p->uMapMatrixLocation_ = p->shaderProgram_->GetUniformLocation("uMapMatrix");
@@ -230,8 +230,8 @@ void PlacefileImages::Render(
}
// Interpolate texture coordinates
- gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
// Draw images
gl.glDrawArrays(GL_TRIANGLES, 0, p->numVertices_);
diff --git a/scwx-qt/source/scwx/qt/map/draw_layer.cpp b/scwx-qt/source/scwx/qt/map/draw_layer.cpp
index 6a6895e7..4ecf2fb3 100644
--- a/scwx-qt/source/scwx/qt/map/draw_layer.cpp
+++ b/scwx-qt/source/scwx/qt/map/draw_layer.cpp
@@ -56,7 +56,7 @@ void DrawLayer::Render(const QMapLibreGL::CustomLayerRenderParameters& params)
newTextureAtlasBuildCount != p->textureAtlasBuildCount_;
gl.glActiveTexture(GL_TEXTURE0);
- gl.glBindTexture(GL_TEXTURE_2D, p->textureAtlas_);
+ gl.glBindTexture(GL_TEXTURE_2D_ARRAY, p->textureAtlas_);
for (auto& item : p->drawList_)
{
diff --git a/scwx-qt/source/scwx/qt/util/texture_atlas.cpp b/scwx-qt/source/scwx/qt/util/texture_atlas.cpp
index 274ea8fb..7cb4d067 100644
--- a/scwx-qt/source/scwx/qt/util/texture_atlas.cpp
+++ b/scwx-qt/source/scwx/qt/util/texture_atlas.cpp
@@ -296,18 +296,21 @@ GLuint TextureAtlas::BufferAtlas(gl::OpenGLFunctions& gl)
lock.unlock();
gl.glGenTextures(1, &texture);
- gl.glBindTexture(GL_TEXTURE_2D, texture);
+ gl.glBindTexture(GL_TEXTURE_2D_ARRAY, texture);
- gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ gl.glTexParameteri(
+ GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(
+ GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ gl.glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- gl.glTexImage2D(GL_TEXTURE_2D,
+ gl.glTexImage3D(GL_TEXTURE_2D_ARRAY,
0,
GL_RGBA,
view.width(),
view.height(),
+ 1u,
0,
GL_RGBA,
GL_UNSIGNED_BYTE,