first works of omni shadows
This commit is contained in:
108
src/core/core/glcubemaparray.cpp
Normal file
108
src/core/core/glcubemaparray.cpp
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GL_GLEXT_PROTOTYPES
|
||||||
|
#include "glcubemaparray.h"
|
||||||
|
|
||||||
|
#include <QOpenGLExtraFunctions>
|
||||||
|
|
||||||
|
|
||||||
|
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_);
|
||||||
|
}
|
||||||
55
src/core/core/glcubemaparray.h
Normal file
55
src/core/core/glcubemaparray.h
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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
|
||||||
@@ -108,6 +108,7 @@ enum TextureArrayRole {
|
|||||||
tarEmpty = 10,
|
tarEmpty = 10,
|
||||||
tarMaps = 11,
|
tarMaps = 11,
|
||||||
tarShadowsCone = 12,
|
tarShadowsCone = 12,
|
||||||
|
tarShadowsOmni = 13,
|
||||||
};
|
};
|
||||||
enum EmptyMapRole {
|
enum EmptyMapRole {
|
||||||
emrWhite = 0,
|
emrWhite = 0,
|
||||||
|
|||||||
@@ -40,6 +40,31 @@ Renderer::Renderer(QGLView * view_)
|
|||||||
, rend_selection(this)
|
, rend_selection(this)
|
||||||
, tone_proc(this)
|
, tone_proc(this)
|
||||||
, tex_env(view_, 512) {
|
, 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.);
|
quad = Primitive::plane(2., 2.);
|
||||||
cam_light = new Light();
|
cam_light = new Light();
|
||||||
cam_light->intensity = 0.75;
|
cam_light->intensity = 0.75;
|
||||||
@@ -61,10 +86,12 @@ Renderer::Renderer(QGLView * view_)
|
|||||||
shader_files[srFinalPass] = "ds_final.glsl";
|
shader_files[srFinalPass] = "ds_final.glsl";
|
||||||
shader_files[srTonemapPass] = "ds_tonemap.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[srGeometrySolidPass] << "SOLID";
|
||||||
shader_defines[srLightSpotPass] << "SPOT";
|
shader_defines[srLightSpotPass] << "SPOT";
|
||||||
|
shader_defines[srShadowOmniPass] << "OMNI";
|
||||||
|
|
||||||
edit_mode = need_init_shaders = true;
|
edit_mode = need_init_shaders = true;
|
||||||
camera_light_mode = QGLView::clmAuto;
|
camera_light_mode = QGLView::clmAuto;
|
||||||
@@ -89,6 +116,7 @@ void Renderer::init(int width, int height) {
|
|||||||
textures_maps.reinit();
|
textures_maps.reinit();
|
||||||
textures_empty.reinit();
|
textures_empty.reinit();
|
||||||
shadow_maps_cone.reinit();
|
shadow_maps_cone.reinit();
|
||||||
|
shadow_maps_omni.reinit();
|
||||||
resize(width, height);
|
resize(width, height);
|
||||||
rend_mat.init(width, height);
|
rend_mat.init(width, height);
|
||||||
rend_service.init(width, height);
|
rend_service.init(width, height);
|
||||||
@@ -115,6 +143,7 @@ void Renderer::resize(int width, int height) {
|
|||||||
|
|
||||||
|
|
||||||
void Renderer::reloadShaders() {
|
void Renderer::reloadShaders() {
|
||||||
|
__reinit_debug = true;
|
||||||
QMapIterator<ShaderRole, QString> it(shader_files);
|
QMapIterator<ShaderRole, QString> it(shader_files);
|
||||||
qDeleteAll(shaders.values());
|
qDeleteAll(shaders.values());
|
||||||
shaders.clear();
|
shaders.clear();
|
||||||
@@ -122,7 +151,7 @@ void Renderer::reloadShaders() {
|
|||||||
shader_fxaa = nullptr;
|
shader_fxaa = nullptr;
|
||||||
if (tone_proc.shader_sum) delete tone_proc.shader_sum;
|
if (tone_proc.shader_sum) delete tone_proc.shader_sum;
|
||||||
tone_proc.shader_sum = nullptr;
|
tone_proc.shader_sum = nullptr;
|
||||||
QString dir = ":/shaders/";
|
QString dir = "./shaders/";
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
it.next();
|
it.next();
|
||||||
loadShadersMulti(shaders[it.key()], dir + it.value(), true, shader_defines.value(it.key()));
|
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() {
|
void Renderer::initShaders() {
|
||||||
if (!need_init_shaders) return;
|
if (!need_init_shaders) return;
|
||||||
need_init_shaders = false;
|
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;
|
QOpenGLShaderProgram * prog = 0;
|
||||||
for (ShaderRole role: {srLightOmniPass, srLightSpotPass}) {
|
for (ShaderRole role: {srLightOmniPass, srLightSpotPass}) {
|
||||||
if (!bindShader(role, &prog)) continue;
|
if (!bindShader(role, &prog)) continue;
|
||||||
@@ -188,7 +214,7 @@ void Renderer::initShaders() {
|
|||||||
prog->setUniformValue("tex_t_0", 3);
|
prog->setUniformValue("tex_t_0", 3);
|
||||||
prog->setUniformValue("tex_t_1", 4);
|
prog->setUniformValue("tex_t_1", 4);
|
||||||
}
|
}
|
||||||
for (ShaderRole role: {srGeometrySolidPass, srGeometryTransparentPass, srShadowPass}) {
|
for (ShaderRole role: {srGeometrySolidPass, srGeometryTransparentPass, srShadowConePass, srShadowOmniPass}) {
|
||||||
if (!bindShader(role, &prog)) continue;
|
if (!bindShader(role, &prog)) continue;
|
||||||
initUniformBuffer(prog, &buffer_materials, bpMaterials, "QGLMaterialData");
|
initUniformBuffer(prog, &buffer_materials, bpMaterials, "QGLMaterialData");
|
||||||
setUniformMaps(prog);
|
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("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3, 3>());
|
||||||
prog->setUniformValue("shadow_size", view->shadow_map_size);
|
prog->setUniformValue("shadow_size", view->shadow_map_size);
|
||||||
prog->setUniformValue("tex_shadows_cone", (int)tarShadowsCone);
|
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_enabled", view->soft_shadows);
|
||||||
prog->setUniformValue("soft_shadows_samples", view->soft_shadows_samples);
|
prog->setUniformValue("soft_shadows_samples", view->soft_shadows_samples);
|
||||||
shadow_maps_cone.bind(view, tarShadowsCone);
|
shadow_maps_cone.bind(view, tarShadowsCone);
|
||||||
|
shadow_maps_omni.bind(view, tarShadowsOmni);
|
||||||
renderQuad(prog, quad, cam);
|
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()));
|
Scene & scene(*(view->scene()));
|
||||||
bool force_resize = false;
|
bool force_resize = false;
|
||||||
if (!light->shadow_map.isInit()) {
|
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.resize(view->shadow_map_size, force_resize);
|
||||||
light->shadow_map.bind();
|
light->shadow_map.bind();
|
||||||
|
|
||||||
if (!framebufferTextureLayer) {
|
view->glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, shadow_maps_cone.ID(), 0, index);
|
||||||
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);
|
|
||||||
}
|
|
||||||
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
||||||
glClearFramebuffer();
|
glClearFramebuffer();
|
||||||
renderObjects(scene, rpSolid);
|
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() {
|
void Renderer::renderScene() {
|
||||||
timings.clear();
|
timings.clear();
|
||||||
Measurer phase(&timings);
|
Measurer phase(&timings);
|
||||||
@@ -363,6 +468,7 @@ void Renderer::renderScene() {
|
|||||||
QOpenGLShaderProgram * prog = 0;
|
QOpenGLShaderProgram * prog = 0;
|
||||||
bool scene_changed = scene.prepare();
|
bool scene_changed = scene.prepare();
|
||||||
cur_lights = scene.lights_used;
|
cur_lights = scene.lights_used;
|
||||||
|
mat_camera_fullview_inv = cam->fullViewMatrix().inverted();
|
||||||
scene.destroyUnused(f);
|
scene.destroyUnused(f);
|
||||||
phase.end();
|
phase.end();
|
||||||
|
|
||||||
@@ -383,35 +489,14 @@ void Renderer::renderScene() {
|
|||||||
}
|
}
|
||||||
phase.end();
|
phase.end();
|
||||||
|
|
||||||
/// shadows and shadow matrix
|
/// cone shadows and shadow matrix
|
||||||
phase.begin("shadows");
|
phase.begin("shadows cone");
|
||||||
if (bindShader(srShadowPass, &prog)) {
|
renderConeShadows();
|
||||||
glEnableDepth();
|
phase.end();
|
||||||
textures_empty.bind(f, tarEmpty);
|
|
||||||
textures_maps.bind(f, tarMaps);
|
/// omni shadows and shadow matrix
|
||||||
auto cam_ivm = cam->fullViewMatrix().inverted();
|
phase.begin("shadows omni");
|
||||||
auto cone_ll = cur_lights.value(Light::Cone);
|
renderOmniShadows();
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
phase.end();
|
phase.end();
|
||||||
|
|
||||||
/// lights
|
/// lights
|
||||||
@@ -558,13 +643,29 @@ void Renderer::renderScene() {
|
|||||||
// qDebug() << last_img.size();
|
// qDebug() << last_img.size();
|
||||||
}
|
}
|
||||||
phase.end();
|
phase.end();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
auto cone_ll = cur_lights.value(Light::Cone);
|
static QOpenGLShaderProgram * tprog = nullptr;
|
||||||
if (!cone_ll.isEmpty()) {
|
if (tprog && __reinit_debug) {
|
||||||
Light * l = cone_ll[0];
|
delete tprog;
|
||||||
l->shadow_map.blit(0, 0, 0, l->shadow_map.rect(), l->shadow_map.rect());
|
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);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ class QGLENGINE_CORE_EXPORT Renderer: public RendererBase {
|
|||||||
srLightSpotPass,
|
srLightSpotPass,
|
||||||
srFinalPass,
|
srFinalPass,
|
||||||
srTonemapPass,
|
srTonemapPass,
|
||||||
srShadowPass,
|
srShadowConePass,
|
||||||
|
srShadowOmniPass,
|
||||||
};
|
};
|
||||||
enum OutBufferRole {
|
enum OutBufferRole {
|
||||||
obrSolidOmni,
|
obrSolidOmni,
|
||||||
@@ -112,7 +113,10 @@ protected:
|
|||||||
void fillObjectsBuffer(const ObjectBaseList & ol, RenderPass pass);
|
void fillObjectsBuffer(const ObjectBaseList & ol, RenderPass pass);
|
||||||
void renderObjects(Scene & scene, RenderPass pass);
|
void renderObjects(Scene & scene, RenderPass pass);
|
||||||
void renderLight(int first_wr_buff, bool clear_only);
|
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(ShaderRole role, QOpenGLShaderProgram ** ret = 0);
|
||||||
bool bindShader(QOpenGLShaderProgram * sp);
|
bool bindShader(QOpenGLShaderProgram * sp);
|
||||||
@@ -124,7 +128,7 @@ protected:
|
|||||||
private:
|
private:
|
||||||
float gamma_ = 1.f;
|
float gamma_ = 1.f;
|
||||||
int camera_light_mode, cur_write_plane = 0, prev_write_plane = 0;
|
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;
|
Framebuffer fbo_ds, fbo_out;
|
||||||
QMap<ShaderRole, QString> shader_files;
|
QMap<ShaderRole, QString> shader_files;
|
||||||
QMap<ShaderRole, QStringList> shader_defines;
|
QMap<ShaderRole, QStringList> shader_defines;
|
||||||
@@ -143,6 +147,8 @@ private:
|
|||||||
QPoint mouse_pos;
|
QPoint mouse_pos;
|
||||||
QRect mouse_rect;
|
QRect mouse_rect;
|
||||||
QMatrix4x4 prev_view, prev_proj;
|
QMatrix4x4 prev_view, prev_proj;
|
||||||
|
QMatrix4x4 mat_norm_to_tex_coord, mat_camera_fullview_inv, mat_proj_90;
|
||||||
|
QMatrix4x4 mat_faces[6];
|
||||||
QMatrix3x3 nm;
|
QMatrix3x3 nm;
|
||||||
QVector4D corner_dirs[4];
|
QVector4D corner_dirs[4];
|
||||||
QVector<QVector3D> hcontent;
|
QVector<QVector3D> hcontent;
|
||||||
@@ -150,8 +156,7 @@ private:
|
|||||||
QVector<FramebufferEffectBase *> fb_effects;
|
QVector<FramebufferEffectBase *> fb_effects;
|
||||||
QImage last_img;
|
QImage last_img;
|
||||||
QString timings;
|
QString timings;
|
||||||
bool is_grabbing = false;
|
bool is_grabbing = false;
|
||||||
QFunctionPointer framebufferTextureLayer = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // RENDERER_H
|
#endif // RENDERER_H
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ RendererBase::RendererBase(QGLView * view_)
|
|||||||
, buffer_lights_pos(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
|
, buffer_lights_pos(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
|
||||||
, textures_empty(GL_RGBA, false)
|
, textures_empty(GL_RGBA, false)
|
||||||
, textures_maps(GL_RGBA, true)
|
, 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);
|
textures_manager = new TextureManager(view);
|
||||||
maps_size = QSize(1024, 1024);
|
maps_size = QSize(1024, 1024);
|
||||||
maps_hash = 0;
|
maps_hash = 0;
|
||||||
@@ -62,6 +63,7 @@ void RendererBase::initTextureArrays() {
|
|||||||
im.fill(0xFF8080);
|
im.fill(0xFF8080);
|
||||||
textures_empty.load(f, im, emrBlue);
|
textures_empty.load(f, im, emrBlue);
|
||||||
shadow_maps_cone.init(f);
|
shadow_maps_cone.init(f);
|
||||||
|
shadow_maps_omni.init(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
#define RENDERER_BASE_H
|
#define RENDERER_BASE_H
|
||||||
|
|
||||||
#include "glbuffer.h"
|
#include "glbuffer.h"
|
||||||
|
#include "glcubemaparray.h"
|
||||||
#include "glshaders_types.h"
|
#include "glshaders_types.h"
|
||||||
#include "gltexturearray.h"
|
#include "gltexturearray.h"
|
||||||
#include "measurer.h"
|
#include "measurer.h"
|
||||||
@@ -59,6 +60,7 @@ protected:
|
|||||||
Buffer buffer_materials;
|
Buffer buffer_materials;
|
||||||
Buffer buffer_lights, buffer_lights_pos;
|
Buffer buffer_lights, buffer_lights_pos;
|
||||||
Texture2DArray textures_empty, textures_maps, shadow_maps_cone;
|
Texture2DArray textures_empty, textures_maps, shadow_maps_cone;
|
||||||
|
CubeMapArray shadow_maps_omni;
|
||||||
QSize maps_size;
|
QSize maps_size;
|
||||||
uint maps_hash;
|
uint maps_hash;
|
||||||
GLuint tex_coeff[2];
|
GLuint tex_coeff[2];
|
||||||
|
|||||||
Reference in New Issue
Block a user