/* 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 . */ #define GL_GLEXT_PROTOTYPES #include #include "renderer_material.h" #include "renderer.h" #include "qglview.h" #include "glmesh.h" #include "gltexture_manager.h" #include 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> 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); } }