diff --git a/src/core/core/glcubemaparray.cpp b/src/core/core/glcubemaparray.cpp
new file mode 100644
index 0000000..1736091
--- /dev/null
+++ b/src/core/core/glcubemaparray.cpp
@@ -0,0 +1,108 @@
+/*
+ QGL CubeMapArray
+ Ivan Pelipenko peri4ko@yandex.ru
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+#define GL_GLEXT_PROTOTYPES
+#include "glcubemaparray.h"
+
+#include
+
+
+CubeMapArray::CubeMapArray(GLenum format, bool filter) {
+ target_ = GL_TEXTURE_CUBE_MAP_ARRAY;
+ format_ = format;
+ texture_ = 0;
+ layers_ = 0;
+ filtering_ = filter;
+}
+
+
+CubeMapArray::~CubeMapArray() {}
+
+
+void CubeMapArray::init(QOpenGLExtraFunctions * f) {
+ if (!isInit()) {
+ f->glGenTextures(1, &texture_);
+ }
+}
+
+
+void CubeMapArray::destroy(QOpenGLExtraFunctions * f) {
+ if (texture_ != 0) {
+ f->glDeleteTextures(1, &texture_);
+ }
+ texture_ = 0;
+}
+
+
+void CubeMapArray::reinit() {
+ texture_ = 0;
+ layers_ = 0;
+}
+
+
+void CubeMapArray::bind(QOpenGLExtraFunctions * f, int channel) {
+ f->glActiveTexture(GL_TEXTURE0 + channel);
+ f->glBindTexture(target_, texture_);
+}
+
+
+void CubeMapArray::release(QOpenGLExtraFunctions * f) {
+ f->glBindTexture(target_, 0);
+}
+
+
+bool CubeMapArray::resize(QOpenGLExtraFunctions * f, QSize new_size, int layers_count) {
+ if (new_size.isNull() || layers_count <= 0) return false;
+ if ((size_ == new_size) && (layers_ >= layers_count)) return false;
+ size_ = new_size;
+ layers_ = layers_count;
+ f->glBindTexture(target_, texture_);
+ f->glTexParameteri(target_, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ f->glTexParameteri(target_, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ if (filtering_) {
+ f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ f->glTexParameteri(target_, GL_TEXTURE_MAX_ANISOTROPY_EXT, 8);
+ } else {
+ f->glTexParameteri(target_, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ f->glTexParameteri(target_, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ }
+ GLenum bformat = format_;
+ GLenum btype = GL_UNSIGNED_BYTE;
+ if (format_ == GL_R16F || format_ == GL_R32F) {
+ bformat = GL_RED;
+ btype = GL_FLOAT;
+ }
+ f->glTexImage3D(target_, 0, format_, size_.width(), size_.height(), layers_ * 6, 0, bformat, btype, nullptr);
+ return true;
+}
+
+
+void CubeMapArray::load(QOpenGLExtraFunctions * f, const QImage & image, int layer) {
+ if (image.isNull() || size_.isNull() || layer < 0 || layer >= layers_) return;
+ QImage im =
+ image.mirrored(false, true).scaled(size_, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).convertToFormat(QImage::Format_RGBA8888);
+ // qDebug() << "CubeMapArray::load image" << image.size() << "to layer" << layer;
+ // f->glTexSubImage3D(target_, 0, 0, 0, layer, size_.width(), size_.height(), 1, GL_RGBA, GL_UNSIGNED_BYTE, im.constBits());
+}
+
+
+void CubeMapArray::mipmaps(QOpenGLExtraFunctions * f) {
+ f->glBindTexture(target_, texture_);
+ f->glGenerateMipmap(target_);
+}
diff --git a/src/core/core/glcubemaparray.h b/src/core/core/glcubemaparray.h
new file mode 100644
index 0000000..392b8b1
--- /dev/null
+++ b/src/core/core/glcubemaparray.h
@@ -0,0 +1,55 @@
+/*
+ QGL Texture2DArray
+ Ivan Pelipenko peri4ko@yandex.ru
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with this program. If not, see .
+*/
+
+#ifndef GLCUBEMAPARRAY_H
+#define GLCUBEMAPARRAY_H
+
+#include "gltypes.h"
+
+
+class QGLENGINE_CORE_EXPORT CubeMapArray {
+public:
+ CubeMapArray(GLenum format, bool filter);
+ ~CubeMapArray();
+
+ void init(QOpenGLExtraFunctions * f);
+ void destroy(QOpenGLExtraFunctions * f);
+ void reinit();
+
+ void bind(QOpenGLExtraFunctions * f, int channel = 0);
+ void release(QOpenGLExtraFunctions * f);
+
+ // returns true if size changed
+ bool resize(QOpenGLExtraFunctions * f, QSize new_size, int layers_count);
+ void load(QOpenGLExtraFunctions * f, const QImage & image, int layer);
+ void mipmaps(QOpenGLExtraFunctions * f);
+
+ GLuint ID() const { return texture_; }
+ bool isInit() const { return texture_ != 0; }
+ int layersCount() const { return layers_; }
+
+private:
+ GLenum target_, format_;
+ GLuint texture_;
+ QSize size_;
+ int layers_;
+ bool filtering_;
+};
+
+
+#endif // GLCUBEMAPARRAY_H
diff --git a/src/core/core/glshaders_types.h b/src/core/core/glshaders_types.h
index 1579692..8452c17 100644
--- a/src/core/core/glshaders_types.h
+++ b/src/core/core/glshaders_types.h
@@ -108,6 +108,7 @@ enum TextureArrayRole {
tarEmpty = 10,
tarMaps = 11,
tarShadowsCone = 12,
+ tarShadowsOmni = 13,
};
enum EmptyMapRole {
emrWhite = 0,
diff --git a/src/core/render/renderer.cpp b/src/core/render/renderer.cpp
index 1d5395a..abc349d 100644
--- a/src/core/render/renderer.cpp
+++ b/src/core/render/renderer.cpp
@@ -40,6 +40,31 @@ Renderer::Renderer(QGLView * view_)
, rend_selection(this)
, tone_proc(this)
, tex_env(view_, 512) {
+ mat_norm_to_tex_coord.scale(0.5, 0.5);
+ mat_norm_to_tex_coord.translate(1, 1);
+ mat_proj_90 = glMatrixPerspective(90., 1., 0.1);
+ for (int i = 0; i < 6; ++i) {
+ QMatrix4x4 fvm;
+ switch (i) {
+ case 0:
+ fvm.rotate(-90., QVector3D(0, 1, 0));
+ fvm.rotate(180., QVector3D(0, 0, 1));
+ break;
+ case 1:
+ fvm.rotate(90., QVector3D(0, 1, 0));
+ fvm.rotate(180., QVector3D(0, 0, 1));
+ break;
+ case 2: fvm.rotate(-90., QVector3D(1, 0, 0)); break;
+ case 3: fvm.rotate(90., QVector3D(1, 0, 0)); break;
+ case 4:
+ fvm.rotate(180., QVector3D(0, 0, 1));
+ fvm.rotate(180., QVector3D(0, 1, 0));
+ break;
+ case 5: fvm.rotate(180., QVector3D(0, 0, 1)); break;
+ }
+ mat_faces[i] = fvm;
+ }
+
quad = Primitive::plane(2., 2.);
cam_light = new Light();
cam_light->intensity = 0.75;
@@ -61,10 +86,12 @@ Renderer::Renderer(QGLView * view_)
shader_files[srFinalPass] = "ds_final.glsl";
shader_files[srTonemapPass] = "ds_tonemap.glsl";
- shader_files[srShadowPass] = "shadow.glsl";
+ shader_files[srShadowConePass] = "shadow.glsl";
+ shader_files[srShadowOmniPass] = "shadow.glsl";
shader_defines[srGeometrySolidPass] << "SOLID";
shader_defines[srLightSpotPass] << "SPOT";
+ shader_defines[srShadowOmniPass] << "OMNI";
edit_mode = need_init_shaders = true;
camera_light_mode = QGLView::clmAuto;
@@ -89,6 +116,7 @@ void Renderer::init(int width, int height) {
textures_maps.reinit();
textures_empty.reinit();
shadow_maps_cone.reinit();
+ shadow_maps_omni.reinit();
resize(width, height);
rend_mat.init(width, height);
rend_service.init(width, height);
@@ -115,6 +143,7 @@ void Renderer::resize(int width, int height) {
void Renderer::reloadShaders() {
+ __reinit_debug = true;
QMapIterator it(shader_files);
qDeleteAll(shaders.values());
shaders.clear();
@@ -122,7 +151,7 @@ void Renderer::reloadShaders() {
shader_fxaa = nullptr;
if (tone_proc.shader_sum) delete tone_proc.shader_sum;
tone_proc.shader_sum = nullptr;
- QString dir = ":/shaders/";
+ QString dir = "./shaders/";
while (it.hasNext()) {
it.next();
loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key()));
@@ -165,9 +194,6 @@ bool Renderer::bindShader(QOpenGLShaderProgram * sp) {
void Renderer::initShaders() {
if (!need_init_shaders) return;
need_init_shaders = false;
- // initUniformBuffer(shaders.value(srGeometrySolidPass), &buffer_materials, bpMaterials, "QGLMaterialData");
- // initUniformBuffer(shaders.value(srGeometryTransparentPass), &buffer_materials, bpMaterials, "QGLMaterialData");
- // initUniformBuffer(shaders.value(srShadowPass), &buffer_materials, bpMaterials, "QGLMaterialData");
QOpenGLShaderProgram * prog = 0;
for (ShaderRole role: {srLightOmniPass, srLightSpotPass}) {
if (!bindShader(role, &prog)) continue;
@@ -188,7 +214,7 @@ void Renderer::initShaders() {
prog->setUniformValue("tex_t_0", 3);
prog->setUniformValue("tex_t_1", 4);
}
- for (ShaderRole role: {srGeometrySolidPass, srGeometryTransparentPass, srShadowPass}) {
+ for (ShaderRole role: {srGeometrySolidPass, srGeometryTransparentPass, srShadowConePass, srShadowOmniPass}) {
if (!bindShader(role, &prog)) continue;
initUniformBuffer(prog, &buffer_materials, bpMaterials, "QGLMaterialData");
setUniformMaps(prog);
@@ -317,16 +343,71 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
prog->setUniformValue("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3, 3>());
prog->setUniformValue("shadow_size", view->shadow_map_size);
prog->setUniformValue("tex_shadows_cone", (int)tarShadowsCone);
+ prog->setUniformValue("tex_shadows_omni", (int)tarShadowsOmni);
prog->setUniformValue("soft_shadows_enabled", view->soft_shadows);
prog->setUniformValue("soft_shadows_samples", view->soft_shadows_samples);
shadow_maps_cone.bind(view, tarShadowsCone);
+ shadow_maps_omni.bind(view, tarShadowsOmni);
renderQuad(prog, quad, cam);
}
}
}
-void Renderer::renderShadow(int index, Light * light) {
+void Renderer::renderConeShadows() {
+ QOpenGLExtraFunctions * f = view;
+ QOpenGLShaderProgram * prog = 0;
+ if (bindShader(srShadowConePass, &prog)) {
+ glEnableDepth();
+ textures_empty.bind(f, tarEmpty);
+ textures_maps.bind(f, tarMaps);
+ auto cone_ll = cur_lights.value(Light::Cone);
+ shadow_maps_cone.resize(f, view->shadow_map_size, cone_ll.size());
+ for (int i = 0; i < cone_ll.size(); ++i) {
+ Light * l = cone_ll[i];
+ QMatrix4x4 pm = glMatrixPerspective(l->angle_end, 1., 0.1), om, vm;
+ om.translate(-l->worldAim());
+ vm.translate(0., 0., -l->distance());
+ // vm.rotate(-roll_, 0., 0., 1.);
+ QMatrix4x4 pmat = l->worldTransform();
+ pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
+ vm *= pmat.inverted();
+ auto vpm = pm * (vm * om);
+ if (l->isCastShadows()) {
+ prog->setUniformValue("qgl_ViewProjMatrix", vpm);
+ renderConeShadow(i, l);
+ }
+ l->shadow_matrix = mat_norm_to_tex_coord * vpm * mat_camera_fullview_inv;
+ }
+ }
+}
+
+
+void Renderer::renderOmniShadows() {
+ QOpenGLExtraFunctions * f = view;
+ QOpenGLShaderProgram * prog = 0;
+ if (bindShader(srShadowOmniPass, &prog)) {
+ glEnableDepth();
+ textures_empty.bind(f, tarEmpty);
+ textures_maps.bind(f, tarMaps);
+ auto omni_ll = cur_lights.value(Light::Omni);
+ shadow_maps_omni.resize(f, view->shadow_map_size, omni_ll.size());
+ for (int i = 0; i < omni_ll.size(); ++i) {
+ Light * l = omni_ll[i];
+ QMatrix4x4 om;
+ om.translate(-l->worldPos());
+ // vm.translate(0., 0., -l->distance());
+ // vm.rotate(-roll_, 0., 0., 1.);
+ if (l->isCastShadows()) {
+ renderOmniShadow(i, l, prog, om);
+ }
+ // l->shadow_matrix = mat_norm_to_tex_coord * vpm * mat_camera_fullview_inv;
+ }
+ }
+}
+
+
+void Renderer::renderConeShadow(int index, Light * light) {
Scene & scene(*(view->scene()));
bool force_resize = false;
if (!light->shadow_map.isInit()) {
@@ -336,13 +417,7 @@ void Renderer::renderShadow(int index, Light * light) {
light->shadow_map.resize(view->shadow_map_size, force_resize);
light->shadow_map.bind();
- if (!framebufferTextureLayer) {
- framebufferTextureLayer = view->context()->getProcAddress("glFramebufferTextureLayer");
- }
- if (framebufferTextureLayer) {
- ((PFNGLFRAMEBUFFERTEXTURELAYERPROC)framebufferTextureLayer)(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadow_maps_cone.ID(), 0, index);
- // glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, shadow_maps_cone.ID(), 0, index);
- }
+ view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadow_maps_cone.ID(), 0, index);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glClearFramebuffer();
renderObjects(scene, rpSolid);
@@ -350,6 +425,36 @@ void Renderer::renderShadow(int index, Light * light) {
}
+void Renderer::renderOmniShadow(int index, Light * light, QOpenGLShaderProgram * prog, QMatrix4x4 om) {
+ Scene & scene(*(view->scene()));
+ bool force_resize = false;
+ if (!light->shadow_map.isInit()) {
+ light->shadow_map.reinit(view);
+ force_resize = true;
+ }
+ light->shadow_map.resize(view->shadow_map_size, force_resize);
+ light->shadow_map.bind();
+
+ for (int i = 0; i < 6; ++i) {
+ QMatrix4x4 vm = mat_proj_90 * mat_faces[i] * om;
+ prog->setUniformValue("qgl_ViewProjMatrix", vm);
+ int buff_ind = GL_COLOR_ATTACHMENT0 + i;
+ view->glFramebufferTextureLayer(GL_FRAMEBUFFER, buff_ind, shadow_maps_omni.ID(), 0, index * 6 + i);
+ // static GLenum faces[6] = {GL_COLOR_ATTACHMENT0,
+ // GL_COLOR_ATTACHMENT1,
+ // GL_COLOR_ATTACHMENT2,
+ // GL_COLOR_ATTACHMENT3,
+ // GL_COLOR_ATTACHMENT4,
+ // GL_COLOR_ATTACHMENT5};
+ // view->glDrawBuffers(6, faces);
+ glDrawBuffer(buff_ind);
+ glClearFramebuffer();
+ renderObjects(scene, rpSolid);
+ }
+ light->shadow_map.release();
+}
+
+
void Renderer::renderScene() {
timings.clear();
Measurer phase(&timings);
@@ -363,6 +468,7 @@ void Renderer::renderScene() {
QOpenGLShaderProgram * prog = 0;
bool scene_changed = scene.prepare();
cur_lights = scene.lights_used;
+ mat_camera_fullview_inv = cam->fullViewMatrix().inverted();
scene.destroyUnused(f);
phase.end();
@@ -383,35 +489,14 @@ void Renderer::renderScene() {
}
phase.end();
- /// shadows and shadow matrix
- phase.begin("shadows");
- if (bindShader(srShadowPass, &prog)) {
- glEnableDepth();
- textures_empty.bind(f, tarEmpty);
- textures_maps.bind(f, tarMaps);
- auto cam_ivm = cam->fullViewMatrix().inverted();
- auto cone_ll = cur_lights.value(Light::Cone);
- shadow_maps_cone.resize(f, view->shadow_map_size, cone_ll.size());
- QMatrix4x4 mat_vp;
- mat_vp.scale(0.5, 0.5);
- mat_vp.translate(1, 1);
- for (int i = 0; i < cone_ll.size(); ++i) {
- Light * l = cone_ll[i];
- QMatrix4x4 pm = glMatrixPerspective(l->angle_end, 1., 0.1), om, vm;
- om.translate(-l->worldAim());
- vm.translate(0., 0., -l->distance());
- // vm.rotate(-roll_, 0., 0., 1.);
- QMatrix4x4 pmat = l->worldTransform();
- pmat(0, 3) = pmat(1, 3) = pmat(2, 3) = 0.;
- vm *= pmat.inverted();
- auto vpm = pm * (vm * om);
- if (l->isCastShadows()) {
- prog->setUniformValue("qgl_ViewProjMatrix", vpm);
- renderShadow(i, l);
- }
- l->shadow_matrix = mat_vp * vpm * cam_ivm;
- }
- }
+ /// cone shadows and shadow matrix
+ phase.begin("shadows cone");
+ renderConeShadows();
+ phase.end();
+
+ /// omni shadows and shadow matrix
+ phase.begin("shadows omni");
+ renderOmniShadows();
phase.end();
/// lights
@@ -558,13 +643,29 @@ void Renderer::renderScene() {
// qDebug() << last_img.size();
}
phase.end();
+
/*
- auto cone_ll = cur_lights.value(Light::Cone);
- if (!cone_ll.isEmpty()) {
- Light * l = cone_ll[0];
- l->shadow_map.blit(0, 0, 0, l->shadow_map.rect(), l->shadow_map.rect());
+ static QOpenGLShaderProgram * tprog = nullptr;
+ if (tprog && __reinit_debug) {
+ delete tprog;
+ tprog = nullptr;
}
- */
+ if (!tprog) {
+ loadShadersMulti(tprog, "./shaders/debug.glsl");
+ tprog->bind();
+ tprog->setUniformValue("tex_cone", (int)tarShadowsCone);
+ tprog->setUniformValue("tex_omni", (int)tarShadowsOmni);
+ QMatrix4x4 mat;
+ double sz = 0.33;
+ mat.translate(sz - 1, sz - 1);
+ mat.scale(sz, sz);
+ tprog->setUniformValue("qgl_ViewProjMatrix", mat);
+ }
+ __reinit_debug = false;
+ tprog->bind();
+ shadow_maps_cone.bind(f, tarShadowsCone);
+ shadow_maps_omni.bind(f, tarShadowsOmni);
+ quad->draw(f, 1);*/
}
diff --git a/src/core/render/renderer.h b/src/core/render/renderer.h
index e7d56b2..a55ceda 100644
--- a/src/core/render/renderer.h
+++ b/src/core/render/renderer.h
@@ -57,7 +57,8 @@ class QGLENGINE_CORE_EXPORT Renderer: public RendererBase {
srLightSpotPass,
srFinalPass,
srTonemapPass,
- srShadowPass,
+ srShadowConePass,
+ srShadowOmniPass,
};
enum OutBufferRole {
obrSolidOmni,
@@ -112,7 +113,10 @@ protected:
void fillObjectsBuffer(const ObjectBaseList & ol, RenderPass pass);
void renderObjects(Scene & scene, RenderPass pass);
void renderLight(int first_wr_buff, bool clear_only);
- void renderShadow(int index, Light * light);
+ void renderConeShadows();
+ void renderOmniShadows();
+ void renderConeShadow(int index, Light * light);
+ void renderOmniShadow(int index, Light * light, QOpenGLShaderProgram * prog, QMatrix4x4 om);
bool bindShader(ShaderRole role, QOpenGLShaderProgram ** ret = 0);
bool bindShader(QOpenGLShaderProgram * sp);
@@ -124,7 +128,7 @@ protected:
private:
float gamma_ = 1.f;
int camera_light_mode, cur_write_plane = 0, prev_write_plane = 0;
- bool edit_mode, need_init_shaders, need_render_sum;
+ bool edit_mode, need_init_shaders, need_render_sum, __reinit_debug;
Framebuffer fbo_ds, fbo_out;
QMap shader_files;
QMap shader_defines;
@@ -143,6 +147,8 @@ private:
QPoint mouse_pos;
QRect mouse_rect;
QMatrix4x4 prev_view, prev_proj;
+ QMatrix4x4 mat_norm_to_tex_coord, mat_camera_fullview_inv, mat_proj_90;
+ QMatrix4x4 mat_faces[6];
QMatrix3x3 nm;
QVector4D corner_dirs[4];
QVector hcontent;
@@ -150,8 +156,7 @@ private:
QVector fb_effects;
QImage last_img;
QString timings;
- bool is_grabbing = false;
- QFunctionPointer framebufferTextureLayer = nullptr;
+ bool is_grabbing = false;
};
#endif // RENDERER_H
diff --git a/src/core/render/renderer_base.cpp b/src/core/render/renderer_base.cpp
index 40c3c7a..ded4ac2 100644
--- a/src/core/render/renderer_base.cpp
+++ b/src/core/render/renderer_base.cpp
@@ -37,7 +37,8 @@ RendererBase::RendererBase(QGLView * view_)
, buffer_lights_pos(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
, textures_empty(GL_RGBA, false)
, textures_maps(GL_RGBA, true)
- , shadow_maps_cone(GL_R32F, false) {
+ , shadow_maps_cone(GL_R32F, false)
+ , shadow_maps_omni(GL_R32F, false) {
textures_manager = new TextureManager(view);
maps_size = QSize(1024, 1024);
maps_hash = 0;
@@ -62,6 +63,7 @@ void RendererBase::initTextureArrays() {
im.fill(0xFF8080);
textures_empty.load(f, im, emrBlue);
shadow_maps_cone.init(f);
+ shadow_maps_omni.init(f);
}
diff --git a/src/core/render/renderer_base.h b/src/core/render/renderer_base.h
index 421aa87..5411d90 100644
--- a/src/core/render/renderer_base.h
+++ b/src/core/render/renderer_base.h
@@ -20,6 +20,7 @@
#define RENDERER_BASE_H
#include "glbuffer.h"
+#include "glcubemaparray.h"
#include "glshaders_types.h"
#include "gltexturearray.h"
#include "measurer.h"
@@ -59,6 +60,7 @@ protected:
Buffer buffer_materials;
Buffer buffer_lights, buffer_lights_pos;
Texture2DArray textures_empty, textures_maps, shadow_maps_cone;
+ CubeMapArray shadow_maps_omni;
QSize maps_size;
uint maps_hash;
GLuint tex_coeff[2];