133 lines
3.9 KiB
C++
133 lines
3.9 KiB
C++
/*
|
|
QGLView
|
|
Copyright (C) 2019 Ivan Pelipenko peri4ko@yandex.ru
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
it under the terms of the GNU 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 General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#define GL_GLEXT_PROTOTYPES
|
|
#include <QOpenGLExtraFunctions>
|
|
#include "renderer_material.h"
|
|
#include "renderer.h"
|
|
#include "qglview.h"
|
|
#include "glmesh.h"
|
|
#include "gltexture_manager.h"
|
|
#include <qad_types.h>
|
|
|
|
using namespace QGLEngineShaders;
|
|
|
|
|
|
RendererMaterial::RendererMaterial(Renderer * r_): r(r_),
|
|
fbo_mat_thumb(r->view, 6, true , GL_RGBA16F) {
|
|
mat_sphere = Primitive::ellipsoid(16, 16);
|
|
mat_camera = new Camera();
|
|
mat_camera->setPos(QVector3D(1, 1, 1));
|
|
mat_camera->setAim(QVector3D());
|
|
mat_camera->setFOV(45.);
|
|
mat_light = new Light();
|
|
mat_light->setPos(QVector3D(50, 100, 25));
|
|
last_thumb_material = 0;
|
|
}
|
|
|
|
|
|
RendererMaterial::~RendererMaterial() {
|
|
delete mat_sphere;
|
|
delete mat_camera;
|
|
delete mat_light;
|
|
}
|
|
|
|
|
|
void RendererMaterial::init(int width, int height) {
|
|
resize(width, height);
|
|
}
|
|
|
|
|
|
void RendererMaterial::resize(int width, int height) {
|
|
fbo_mat_thumb.enablePixelBuffer();
|
|
fbo_mat_thumb.resize(256, 256);
|
|
}
|
|
|
|
|
|
void RendererMaterial::renderMaterial(Material * m) {
|
|
//qDebug() << "renderMaterial" << m;
|
|
last_thumb_material = m;
|
|
QOpenGLShaderProgram * prog = 0;
|
|
QOpenGLExtraFunctions * f = r->view;
|
|
fbo_mat_thumb.bind();
|
|
glEnableDepth();
|
|
glClearFramebuffer();
|
|
if (r->bindShader(Renderer::srGeometryPass, &prog)) {
|
|
r->setUniformMaps(prog);
|
|
r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size());
|
|
//qDebug() << mat_camera->viewMatrix();
|
|
r->textures_empty.bind(f, tarEmpty);
|
|
r->textures_maps .bind(f, tarMaps );
|
|
Object o;
|
|
o.material = m->_index;
|
|
mat_sphere->loadObject(f, o);
|
|
mat_sphere->draw(f, 1);
|
|
}
|
|
fbo_mat_thumb.bindColorTextures();
|
|
fbo_mat_thumb.bindDepthTexture(5);
|
|
fbo_mat_thumb.setWriteBuffer(5);
|
|
if (r->bindShader(Renderer::srLightOmniPass, &prog)) {
|
|
r->setUniformCamera(prog, mat_camera, true, fbo_mat_thumb.size());
|
|
r->setUniformViewCorners(prog, mat_camera, fbo_mat_thumb.size());
|
|
for (int i = 0; i < 5; ++i)
|
|
prog->setUniformValue(QString("tex_%1").arg(i).toLatin1().constData(), i);
|
|
prog->setUniformValue("tex_d", 5);
|
|
prog->setUniformValue("lights_start", 0);
|
|
prog->setUniformValue("lights_count", 1);
|
|
QMap<int, QList<Light*>> mat_l;
|
|
mat_l[Light::Omni] << mat_light;
|
|
r->reloadLightsParameters(mat_l);
|
|
r->reloadLightsPositions(mat_camera);
|
|
glClearFramebuffer(r->view->backColor(), false);
|
|
r->renderQuad(prog, r->quad, mat_camera);
|
|
r->view->scene()->setLightsChanged();
|
|
}
|
|
fbo_mat_thumb.queryImage(5);
|
|
fbo_mat_thumb.release();
|
|
}
|
|
|
|
|
|
void RendererMaterial::procQueue() {
|
|
if (last_thumb_material) {
|
|
mat_thumbnails[last_thumb_material] = fbo_mat_thumb.getImage();
|
|
emit r->view->materialThumbnailCreated(last_thumb_material);
|
|
last_thumb_material = 0;
|
|
}
|
|
if (!mat_thumb_queue.isEmpty())
|
|
renderMaterial(mat_thumb_queue.dequeue());
|
|
}
|
|
|
|
|
|
QImage RendererMaterial::materialThumbnail(Material * m) {
|
|
return mat_thumbnails.value(m);
|
|
}
|
|
|
|
|
|
void RendererMaterial::recreateMaterialThumbnails(bool force_all) {
|
|
if (force_all) {
|
|
mat_thumb_queue.clear();
|
|
//qDebug() << "recreateMaterialThumbnails" << view->scene_->materials;
|
|
foreach (Material * m, r->view->scene_->materials)
|
|
mat_thumb_queue.enqueue(m);
|
|
} else {
|
|
foreach (Material * m, r->view->scene_->changed_materials)
|
|
if (!mat_thumb_queue.contains(m))
|
|
mat_thumb_queue.enqueue(m);
|
|
}
|
|
}
|