shadows basically works
This commit is contained in:
@@ -61,6 +61,8 @@ Renderer::Renderer(QGLView * view_)
|
||||
shader_files[srFinalPass] = "ds_final.glsl";
|
||||
shader_files[srTonemapPass] = "ds_tonemap.glsl";
|
||||
|
||||
shader_files[srShadowPass] = "shadow.glsl";
|
||||
|
||||
shader_defines[srGeometrySolidPass] << "SOLID";
|
||||
shader_defines[srLightSpotPass] << "SPOT";
|
||||
|
||||
@@ -161,15 +163,16 @@ 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");
|
||||
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}) {
|
||||
initUniformBuffer(shaders.value(role), &buffer_materials, bpMaterials, "QGLMaterialData");
|
||||
initUniformBuffer(shaders.value(role), &buffer_lights, bpLightParameters, "QGLLightParameterData");
|
||||
initUniformBuffer(shaders.value(role), &buffer_lights_pos, bpLightPositions, "QGLLightPositionData");
|
||||
if (!bindShader(role, &prog)) continue;
|
||||
initUniformBuffer(prog, &buffer_materials, bpMaterials, "QGLMaterialData");
|
||||
initUniformBuffer(prog, &buffer_lights, bpLightParameters, "QGLLightParameterData");
|
||||
initUniformBuffer(prog, &buffer_lights_pos, bpLightPositions, "QGLLightPositionData");
|
||||
for (int i = 0; i < 5; ++i)
|
||||
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
|
||||
prog->setUniformValue("tex_coeffs[0]", (int)Renderer::dbrBuffersCount);
|
||||
@@ -182,10 +185,9 @@ void Renderer::initShaders() {
|
||||
prog->setUniformValue("tex_t_0", 3);
|
||||
prog->setUniformValue("tex_t_1", 4);
|
||||
}
|
||||
if (bindShader(srGeometrySolidPass, &prog)) {
|
||||
setUniformMaps(prog);
|
||||
}
|
||||
if (bindShader(srGeometryTransparentPass, &prog)) {
|
||||
for (ShaderRole role: {srGeometrySolidPass, srGeometryTransparentPass, srShadowPass}) {
|
||||
if (!bindShader(role, &prog)) continue;
|
||||
initUniformBuffer(prog, &buffer_materials, bpMaterials, "QGLMaterialData");
|
||||
setUniformMaps(prog);
|
||||
}
|
||||
if (bindShader(srTonemapPass, &prog)) {
|
||||
@@ -286,6 +288,18 @@ 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);
|
||||
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;
|
||||
}
|
||||
prog->setUniformValueArray("tex_shadow", samplers.data(), samplers.size());
|
||||
}
|
||||
fbo_out.setWriteBuffer(first_wr_buff + pass.second);
|
||||
glClearFramebuffer(back, false);
|
||||
if (clear_only) continue;
|
||||
@@ -303,6 +317,26 @@ void Renderer::renderLight(int first_wr_buff, bool clear_only) {
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderShadow(Light * light) {
|
||||
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);
|
||||
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();
|
||||
glClearFramebuffer();
|
||||
renderObjects(scene, rpSolid);
|
||||
light->shadow_map.release();
|
||||
}
|
||||
|
||||
|
||||
void Renderer::renderScene() {
|
||||
timings.clear();
|
||||
Measurer phase(&timings);
|
||||
@@ -315,6 +349,7 @@ void Renderer::renderScene() {
|
||||
Camera * cam = view->camera();
|
||||
QOpenGLShaderProgram * prog = 0;
|
||||
bool scene_changed = scene.prepare();
|
||||
cur_lights = scene.lights_used;
|
||||
scene.destroyUnused(f);
|
||||
phase.end();
|
||||
|
||||
@@ -335,9 +370,36 @@ void Renderer::renderScene() {
|
||||
}
|
||||
phase.end();
|
||||
|
||||
/// shadows
|
||||
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);
|
||||
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);
|
||||
prog->setUniformValue("qgl_ViewProjMatrix", vpm);
|
||||
renderShadow(l);
|
||||
l->shadow_matrix = mat_vp * vpm * cam_ivm;
|
||||
}
|
||||
}
|
||||
phase.end();
|
||||
|
||||
/// lights
|
||||
phase.begin("lights prepare");
|
||||
cur_lights = scene.lights_used;
|
||||
bool use_camlight = (camera_light_mode == QGLView::clmOn);
|
||||
if ((camera_light_mode == QGLView::clmAuto) && cur_lights.isEmpty()) {
|
||||
use_camlight = true;
|
||||
@@ -360,6 +422,7 @@ void Renderer::renderScene() {
|
||||
}
|
||||
phase.end();
|
||||
|
||||
|
||||
/// solid geometry pass
|
||||
phase.begin("geometry solid");
|
||||
fbo_ds.bind();
|
||||
@@ -369,7 +432,9 @@ void Renderer::renderScene() {
|
||||
setUniformCamera(prog, cam);
|
||||
textures_empty.bind(f, tarEmpty);
|
||||
textures_maps.bind(f, tarMaps);
|
||||
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());
|
||||
@@ -392,7 +457,9 @@ void Renderer::renderScene() {
|
||||
setUniformCamera(prog, cam);
|
||||
textures_empty.bind(f, tarEmpty);
|
||||
textures_maps.bind(f, tarMaps);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, view->renderMode());
|
||||
renderObjects(scene, rpTransparent);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
fbo_ds.release();
|
||||
phase.end();
|
||||
@@ -434,7 +501,7 @@ void Renderer::renderScene() {
|
||||
|
||||
/// FXAA
|
||||
phase.begin("fxaa");
|
||||
if (view->isFeatureEnabled(QGLView::qglFXAA)) {
|
||||
if (view->FXAA_) {
|
||||
prog = shader_fxaa;
|
||||
if (bindShader(prog)) {
|
||||
auto free = getFreePlanes(0);
|
||||
@@ -462,7 +529,7 @@ void Renderer::renderScene() {
|
||||
rend_selection.drawSelection(fbo_out, cur_write_plane);
|
||||
rend_service.renderService();
|
||||
} else {
|
||||
fbo_out.blit(cur_write_plane, 0, 0, fbo_out.rect(), QRect(QPoint(), view->size() * view->devicePixelRatio()));
|
||||
fbo_out.blit(cur_write_plane, 0, 0, fbo_out.rect(), QRect(QPoint(), view->pixelSize()));
|
||||
}
|
||||
phase.end();
|
||||
|
||||
@@ -474,6 +541,12 @@ 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());
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user