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());
|
||||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -57,6 +57,7 @@ class QGLENGINE_CORE_EXPORT Renderer: public RendererBase {
|
||||
srLightSpotPass,
|
||||
srFinalPass,
|
||||
srTonemapPass,
|
||||
srShadowPass,
|
||||
};
|
||||
enum OutBufferRole {
|
||||
obrSolidOmni,
|
||||
@@ -112,6 +113,7 @@ protected:
|
||||
void reloadObjects();
|
||||
void renderObjects(Scene & scene, RenderPass pass);
|
||||
void renderLight(int first_wr_buff, bool clear_only);
|
||||
void renderShadow(Light * light);
|
||||
|
||||
bool bindShader(ShaderRole role, QOpenGLShaderProgram ** ret = 0);
|
||||
bool bindShader(QOpenGLShaderProgram * sp);
|
||||
|
||||
@@ -35,8 +35,8 @@ RendererBase::RendererBase(QGLView * view_)
|
||||
, buffer_materials(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
|
||||
, buffer_lights(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
|
||||
, buffer_lights_pos(GL_UNIFORM_BUFFER, GL_STREAM_DRAW)
|
||||
, textures_empty(false)
|
||||
, textures_maps(true) {
|
||||
, textures_empty(GL_RGBA, false)
|
||||
, textures_maps(GL_RGBA, true) {
|
||||
textures_manager = new TextureManager(view);
|
||||
maps_size = QSize(1024, 1024);
|
||||
maps_hash = 0;
|
||||
@@ -237,11 +237,12 @@ void RendererBase::reloadLightsPositions(Camera * cam) {
|
||||
QGLLightPosition & so(cur_lights_pos_[i]);
|
||||
Light * l = current_lights[i];
|
||||
QMatrix4x4 m = mat * l->worldTransform();
|
||||
QVector4D pos(0, 0, 0, 1.), dir(QVector3D(0, 0, -1), 1);
|
||||
QVector4D pos(0, 0, 0, 1.), dir(0, 0, -1, 1);
|
||||
pos = m * pos;
|
||||
dir = (m * QVector4D(QVector3D(0, 0, -1), 0)).normalized();
|
||||
dir = (m * QVector4D(0, 0, -1, 0)).normalized();
|
||||
so.position = pos;
|
||||
so.direction = dir;
|
||||
l->shadow_matrix.transposed().copyDataTo(so.shadowmatrix);
|
||||
}
|
||||
buffer_lights_pos.bind(view);
|
||||
buffer_lights_pos.resize(view, cur_lights_pos_.size() * sizeof(QGLLightPosition));
|
||||
|
||||
Reference in New Issue
Block a user