|
|
|
|
@@ -88,6 +88,7 @@ void Renderer::init(int width, int height) {
|
|
|
|
|
buffer_lights_pos.reinit();
|
|
|
|
|
textures_maps.reinit();
|
|
|
|
|
textures_empty.reinit();
|
|
|
|
|
shadow_maps_cone.reinit();
|
|
|
|
|
resize(width, height);
|
|
|
|
|
rend_mat.init(width, height);
|
|
|
|
|
rend_service.init(width, height);
|
|
|
|
|
@@ -163,10 +164,14 @@ bool Renderer::bindShader(QOpenGLShaderProgram * sp) {
|
|
|
|
|
|
|
|
|
|
void Renderer::initShaders() {
|
|
|
|
|
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");
|
|
|
|
|
QVector<GLuint> samplers;
|
|
|
|
|
samplers.resize(16);
|
|
|
|
|
for (int i = 0; i < samplers.size(); ++i)
|
|
|
|
|
samplers[i] = mtShadowCone + i;
|
|
|
|
|
QOpenGLShaderProgram * prog = 0;
|
|
|
|
|
for (ShaderRole role: {srLightOmniPass, srLightSpotPass}) {
|
|
|
|
|
if (!bindShader(role, &prog)) continue;
|
|
|
|
|
@@ -177,6 +182,7 @@ void Renderer::initShaders() {
|
|
|
|
|
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
|
|
|
|
|
prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount);
|
|
|
|
|
prog->setUniformValue("tex_env", (int)Renderer::dbrBuffersCount + 1);
|
|
|
|
|
prog->setUniformValue("tex_shadows_cone", (int)tarShadowsCone);
|
|
|
|
|
}
|
|
|
|
|
if (bindShader(srFinalPass, &prog)) {
|
|
|
|
|
prog->setUniformValue("tex_g1", 0);
|
|
|
|
|
@@ -288,18 +294,14 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
|
|
|
|
|
back.setAlpha(0);
|
|
|
|
|
foreach(PassPair pass, passes) {
|
|
|
|
|
if (bindShader(pass.first, &prog)) {
|
|
|
|
|
if (pass.second == Light::Cone) {
|
|
|
|
|
QVector<GLint> samplers;
|
|
|
|
|
samplers.resize(16);
|
|
|
|
|
/*if (pass.second == Light::Cone) {
|
|
|
|
|
auto & cone_ll(cur_lights[pass.second]);
|
|
|
|
|
for (int i = 0; i < cone_ll.size(); ++i) {
|
|
|
|
|
Light * l = cone_ll[i];
|
|
|
|
|
l->shadow_map.bindDepthTexture(mtShadowCone + i);
|
|
|
|
|
// l->shadow_map.bindColorTexture(0, 10);
|
|
|
|
|
samplers[i] = mtShadowCone + i;
|
|
|
|
|
// l->shadow_map.bindDepthTexture(mtShadowCone + i);
|
|
|
|
|
l->shadow_map.bindColorTexture(0, mtShadowCone + i);
|
|
|
|
|
}
|
|
|
|
|
prog->setUniformValueArray("tex_shadow", samplers.data(), samplers.size());
|
|
|
|
|
}
|
|
|
|
|
}*/
|
|
|
|
|
fbo_out.setWriteBuffer(first_wr_buff + pass.second);
|
|
|
|
|
glClearFramebuffer(back, false);
|
|
|
|
|
if (clear_only) continue;
|
|
|
|
|
@@ -311,13 +313,14 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
|
|
|
|
|
prog->setUniformValue("fog_decay", qMax(view->fogDecay(), 0.001f));
|
|
|
|
|
prog->setUniformValue("fog_density", view->fogDensity());
|
|
|
|
|
prog->setUniformValue("view_mat", cam->viewMatrix().inverted().toGenericMatrix<3, 3>());
|
|
|
|
|
prog->setUniformValue("shadow_size", view->shadow_map_size);
|
|
|
|
|
renderQuad(prog, quad, cam);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Renderer::renderShadow(Light * light) {
|
|
|
|
|
void Renderer::renderShadow(int index, Light * light) {
|
|
|
|
|
Scene & scene(*(view->scene()));
|
|
|
|
|
bool force_resize = false;
|
|
|
|
|
if (!light->shadow_map.isInit()) {
|
|
|
|
|
@@ -325,12 +328,16 @@ void Renderer::renderShadow(Light * light) {
|
|
|
|
|
force_resize = true;
|
|
|
|
|
}
|
|
|
|
|
light->shadow_map.resize(view->shadow_map_size, force_resize);
|
|
|
|
|
if (force_resize) {
|
|
|
|
|
light->shadow_map.bindDepthTexture(mtShadowCone);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
|
|
|
}
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
glDrawBuffer(GL_COLOR_ATTACHMENT0);
|
|
|
|
|
glClearFramebuffer();
|
|
|
|
|
renderObjects(scene, rpSolid);
|
|
|
|
|
light->shadow_map.release();
|
|
|
|
|
@@ -378,11 +385,13 @@ void Renderer::renderScene() {
|
|
|
|
|
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];
|
|
|
|
|
Light * l = cone_ll[i];
|
|
|
|
|
if (!l->isCastShadows()) continue;
|
|
|
|
|
QMatrix4x4 pm = glMatrixPerspective(l->angle_end, 1., 0.1), om, vm;
|
|
|
|
|
om.translate(-l->worldAim());
|
|
|
|
|
vm.translate(0., 0., -l->distance());
|
|
|
|
|
@@ -392,7 +401,7 @@ void Renderer::renderScene() {
|
|
|
|
|
vm *= pmat.inverted();
|
|
|
|
|
auto vpm = pm * (vm * om);
|
|
|
|
|
prog->setUniformValue("qgl_ViewProjMatrix", vpm);
|
|
|
|
|
renderShadow(l);
|
|
|
|
|
renderShadow(i, l);
|
|
|
|
|
l->shadow_matrix = mat_vp * vpm * cam_ivm;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -432,12 +441,13 @@ void Renderer::renderScene() {
|
|
|
|
|
setUniformCamera(prog, cam);
|
|
|
|
|
textures_empty.bind(f, tarEmpty);
|
|
|
|
|
textures_maps.bind(f, tarMaps);
|
|
|
|
|
shadow_maps_cone.bind(f, tarShadowsCone);
|
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, view->renderMode());
|
|
|
|
|
renderObjects(scene, rpSolid);
|
|
|
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
|
|
|
}
|
|
|
|
|
fbo_ds.blit(dbrNormalZ, fbo_ds.id(), dbrNormalZSolid, fbo_ds.rect(), fbo_ds.rect());
|
|
|
|
|
fbo_ds.blit(dbrSpecularReflect, fbo_ds.id(), dbrSpecularReflectSolid, fbo_ds.rect(), fbo_ds.rect());
|
|
|
|
|
fbo_ds.blit(dbrMetalRoughReflectFlags, fbo_ds.id(), dbrMetalRoughReflectFlagsSolid, fbo_ds.rect(), fbo_ds.rect());
|
|
|
|
|
fbo_ds.release();
|
|
|
|
|
phase.end();
|
|
|
|
|
|
|
|
|
|
|