git-svn-id: svn://db.shs.com.ru/libs@46 a8b55f48-bf90-11e4-a774-851b48703e85

This commit is contained in:
2015-11-24 14:45:54 +00:00
parent 48addec20f
commit 2ace72ff47
20 changed files with 216 additions and 167 deletions

View File

@@ -25,8 +25,9 @@ QMatrix4x4 globCameraMatrix;
Camera::Camera() {
fov_ = 60.;
angle_limit_lower_xy = -180.;
angle_limit_upper_xy = 180.;
angle_limit_lower_xy = 0.;
angle_limit_upper_xy = 360.;
angles_.setY(270.);
depth_start = 0.1;
depth_end = 1000.;
mirror_x = mirror_y = false;
@@ -37,7 +38,7 @@ void Camera::anglesFromPoints() {
QVector3D dv = aim_ - pos_, tv;
tv = QVector3D(dv.x(), dv.y(), 0.);
angles_.setZ(atan2(tv.x(), tv.y()) * rad2deg);
angles_.setY(piClamp<GLdouble>(atan2(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy));
angles_.setY(piClamp<GLdouble>(atan2(tv.length(), dv.z()) * rad2deg, angle_limit_lower_xy, angle_limit_upper_xy) + 180.);
}
@@ -60,6 +61,7 @@ void Camera::apply(const GLdouble & aspect) {
if (parent_)
pm *= parent_->worldTransform().inverted();
setGLMatrix(pm);
//qDebug() << angles_;
}
/*

View File

@@ -103,6 +103,13 @@ void GLFramebuffer::release() {
}
void GLFramebuffer::setWriteBuffer(int index) {
//QVector<GLenum> buffers; buffers << GL_COLOR_ATTACHMENT0 + index;
glDrawBuffer(GL_COLOR_ATTACHMENT0 + index);
//glDrawBuffers(buffers.size(), buffers.constData());
}
void GLFramebuffer::setWriteBuffers(int indeces[]) {
QVector<GLenum> buffers;
for (uint i = 0; i < sizeof(indeces); ++i) {

View File

@@ -40,7 +40,7 @@ public:
void bind();
void release();
void setReadBuffer(int index) {glReadBuffer(GL_COLOR_ATTACHMENT0 + index);}
void setWriteBuffer(int index) {glDrawBuffer(GL_COLOR_ATTACHMENT0 + index);}
void setWriteBuffer(int index);
void setWriteBuffers(int indeces[]);
void setWriteBuffers(int * indeces, int count);
void setColorFormat(GLenum format) {color_format = format; is_changed = true;}

View File

@@ -197,20 +197,21 @@ void Material::apply(QGLShaderProgram * prog) {
GLfloat mat_diffuse[4] = {1.0f, 1.0f, 1.0f, 1.0f};
GLfloat mat_specular[4] = {0.9f, 0.9f, 0.9f, 1.0f};
GLfloat mat_emission[4] = {0.f, 0.f, 0.f, 1.0f};
mat_diffuse[0] = color_diffuse.redF();
mat_diffuse[1] = color_diffuse.greenF();
mat_diffuse[2] = color_diffuse.blueF();
mat_diffuse[3] = color_diffuse.alphaF() * (1.f - transparency);
mat_diffuse[0] = map_diffuse.color_amount * color_diffuse.redF();
mat_diffuse[1] = map_diffuse.color_amount * color_diffuse.greenF();
mat_diffuse[2] = map_diffuse.color_amount * color_diffuse.blueF();
mat_diffuse[3] = map_diffuse.color_amount * color_diffuse.alphaF() * (1.f - transparency);
mat_specular[0] = map_specular.color_amount * color_specular.redF();
mat_specular[1] = map_specular.color_amount * color_specular.greenF();
mat_specular[2] = map_specular.color_amount * color_specular.blueF();
mat_emission[0] = color_self_illumination.redF();
mat_emission[1] = color_self_illumination.greenF();
mat_emission[2] = color_self_illumination.blueF();
mat_emission[0] = map_self_illumination.color_amount * color_self_illumination.redF();
mat_emission[1] = map_self_illumination.color_amount * color_self_illumination.greenF();
mat_emission[2] = map_self_illumination.color_amount * color_self_illumination.blueF();
glColor4f(mat_diffuse[0], mat_diffuse[1], mat_diffuse[2], mat_diffuse[3]);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
glMaterialf(GL_FRONT, GL_SHININESS, (1. - map_specularity.color_amount)*100.);
//qDebug() << (map_specularity.color_amount)*128.;
glMaterialf(GL_FRONT, GL_SHININESS, (map_specularity.color_amount)*128.);
glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_diffuse);
}

View File

@@ -153,41 +153,41 @@ void GLRendererBase::applyFilteringParameters() {
void GLRendererBase::renderObjects(int pass, int light_pass, void * shaders, bool textures, bool light, bool fog) {
RenderingParameters rp;
rp.pass = pass;
rp.light_pass = light_pass;
rp.shaders = shaders;
rp.textures = textures;
rp.light = rp.prev_light = light;
rp.fog = rp.prev_fog = fog;
rp.view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
rp.proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
RenderingParameters rpl;
rpl.pass = pass;
rpl.light_pass = light_pass;
rpl.shaders = shaders;
rpl.textures = textures;
rpl.light = rpl.prev_light = light;
rpl.fog = rpl.prev_fog = fog;
rpl.view_matrix = rp.view_matrix;
rpl.proj_matrix = rp.proj_matrix;
//qDebug() << "view:" << rp.view_matrix;
for (int i = 0; i < 32; ++i) rp.prev_tex[i] = 0;
setupTextures(view.objects_, rp, true);
glSetLightEnabled(rp.prev_light);
glSetFogEnabled(rp.prev_fog);
glSetCapEnabled(GL_TEXTURE_2D, rp.textures);
for (int i = 0; i < 32; ++i) rpl.prev_tex[i] = 0;
setupTextures(view.objects_, rpl, true);
glSetLightEnabled(rpl.prev_light);
glSetFogEnabled(rpl.prev_fog);
glSetCapEnabled(GL_TEXTURE_2D, rpl.textures);
glSetCapEnabled(GL_BLEND, pass == GLObjectBase::Transparent);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDisable(GL_TEXTURE_CUBE_MAP);
glPushMatrix();
renderSingleObject(view.objects_, rp);
renderSingleObject(view.objects_, rpl);
glPopMatrix();
}
void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rp) {
void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters & rpl) {
if (!o.isInit())
o.init();
if (!o.isTexturesLoaded())
o.loadTextures();
if (!o.visible_) return;
if (rp.pass == o.pass_) {
if (rpl.pass == o.pass_) {
Material & mat(o.material_);
QMatrix4x4 curview = rp.view_matrix * o.itransform_;
setupTextures(o, rp, false);
mat.apply((QGLShaderProgram*)rp.shaders);
QMatrix4x4 curview = rpl.view_matrix * o.itransform_;
setupTextures(o, rpl, false);
mat.apply((QGLShaderProgram*)rpl.shaders);
glSetPolygonMode(o.render_mode != GLObjectBase::View ? o.render_mode : (view.rmode != GLObjectBase::View ? view.rmode : GL_FILL));
glLineWidth(o.line_width > 0. ? o.line_width : view.lineWidth_);
glPointSize(o.line_width > 0. ? o.line_width : view.lineWidth_);
@@ -199,7 +199,7 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters &
if (!mat.map_reflection.isEmpty()) mat.map_reflection.bind();
else glDisable(GL_TEXTURE_CUBE_MAP);
} else glDisable(GL_TEXTURE_CUBE_MAP);
if (rp.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP);
if (rpl.light_pass > 0) glDisable(GL_TEXTURE_CUBE_MAP);
GLfloat gm[16], bc[4] = {mat.reflectivity, mat.reflectivity, mat.reflectivity, mat.reflectivity};
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
@@ -213,15 +213,46 @@ void GLRendererBase::renderSingleObject(GLObjectBase & o, RenderingParameters &
glMatrixMode(GL_MODELVIEW);
glActiveTextureChannel(0);
}
if (rp.shaders) {
if (rpl.shaders) {
//qDebug() << o.name() << curview << curview.determinant();
setUniformMatrices((QGLShaderProgram*)rp.shaders, rp.proj_matrix, curview);
setUniformMatrices((QGLShaderProgram*)rpl.shaders, rpl.proj_matrix, curview);
} else {
glMatrixMode(GL_MODELVIEW);
setGLMatrix(curview);
}
o.draw((QGLShaderProgram*)rp.shaders);
o.draw((QGLShaderProgram*)rpl.shaders);
}
foreach (GLObjectBase * i, o.children_)
renderSingleObject(*i, rp);
renderSingleObject(*i, rpl);
}
void GLRendererBase::RenderingParameters::prepare() {
proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
viewproj_matrix = proj_matrix * view_matrix;
normal_matrix = view_matrix.normalMatrix();
proj_matrix_i = proj_matrix.inverted();
view_matrix_i = view_matrix.inverted();
viewproj_matrix_i = viewproj_matrix.inverted();
}
void GLRendererBase::RenderingParameters::setUniform(QGLShaderProgram * prog) {
if (!prog) return;
prog->setUniformValue("qgl_ModelViewMatrix", view_matrix);
prog->setUniformValue("qgl_ProjectionMatrix", proj_matrix);
prog->setUniformValue("qgl_ModelViewProjectionMatrix", viewproj_matrix);
prog->setUniformValue("qgl_NormalMatrix", normal_matrix);
prog->setUniformValue("qgl_ModelViewMatrixInverse", view_matrix_i);
prog->setUniformValue("qgl_ProjectionMatrixInverse", proj_matrix_i);
prog->setUniformValue("qgl_ModelViewProjectionMatrixInverse", viewproj_matrix_i);
prog->setUniformValue("qgl_ModelViewMatrixTranspose", view_matrix.transposed());
prog->setUniformValue("qgl_ProjectionMatrixTranspose", proj_matrix.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", viewproj_matrix.transposed());
prog->setUniformValue("qgl_ModelViewMatrixInverseTranspose", view_matrix_i.transposed());
prog->setUniformValue("qgl_ProjectionMatrixInverseTranspose", proj_matrix_i.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixInverseTranspose", viewproj_matrix_i.transposed());
}

View File

@@ -28,10 +28,13 @@ class GLRendererBase: public QObject
Q_OBJECT
public:
GLRendererBase(QGLView * view_);
virtual void prepareScene() {;}
virtual void renderScene() = 0;
protected:
struct RenderingParameters {
void prepare();
void setUniform(QGLShaderProgram * prog);
int pass;
int light_pass;
bool light;
@@ -41,8 +44,10 @@ protected:
bool prev_fog;
GLuint prev_tex[32];
void * shaders;
QMatrix4x4 view_matrix;
QMatrix4x4 proj_matrix;
QMatrix4x4 view_matrix, view_matrix_i;
QMatrix4x4 proj_matrix, proj_matrix_i;
QMatrix4x4 viewproj_matrix, viewproj_matrix_i;
QMatrix3x3 normal_matrix;
QGLShaderProgram * cur_shader;
};
@@ -58,8 +63,9 @@ protected:
void setupLights(int pass, int lights_per_pass);
inline void applyFilteringParameters();
void renderObjects(int pass, int light_pass, void * shaders = 0, bool textures = true, bool light = true, bool fog = true);
void renderSingleObject(GLObjectBase & o, RenderingParameters & rp);
void renderSingleObject(GLObjectBase & o, RenderingParameters & rpl);
RenderingParameters rp;
QGLView & view;
QImage white_image, violent_image;
GLuint white_image_id, violent_image_id;

View File

@@ -133,7 +133,7 @@ bool loadShaders(QGLShaderProgram * prog, const QString & name, const QString &
loadShaderFile(prog, QGLShader::Fragment, i.absoluteFilePath());
}
if (!prog->link()) {
//qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log();
qDebug() << "[QGLView] Shader \"" + name + "\" link error: " + prog->log();
return false;
}
return true;

View File

@@ -51,15 +51,19 @@ QString findFile(const QString & file, const QStringList & pathes) {
}
void glDrawQuad(GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
void glDrawQuad(QGLShaderProgram * prog, GLfloat x, GLfloat y, GLfloat w, GLfloat h) {
glResetAllTransforms();
glSetPolygonMode(GL_FILL);
int loc = prog ? prog->attributeLocation("qgl_Color") : 0,
locv = prog ? prog->attributeLocation("qgl_Vertex") : 0,
loct = prog ? prog->attributeLocation("qgl_Texture") : 0;
//locc = prog ? prog->attributeLocation("view_corner") : 0;
glBegin(GL_QUADS);
glColor3f(1.f, 1.f, 1.f);
glTexCoord2f(0.f, 0.f); glVertex2f(x, y);
glTexCoord2f(1.f, 0.f); glVertex2f(x + w, y);
glTexCoord2f(1.f, 1.f); glVertex2f(x + w, y + h);
glTexCoord2f(0.f, 1.f); glVertex2f(x, y + h);
if (prog) glVertexAttrib3f(loc, 1.f, 1.f, 1.f); glColor3f(1.f, 1.f, 1.f);
if (prog) {/*prog->setAttributeValue(locc, corner_dirs[0]);*/ glVertexAttrib2f(loct, 0.f, 0.f); glVertexAttrib2f(locv, x, y);} glTexCoord2f(0.f, 0.f); glVertex2f(x, y);
if (prog) {/*prog->setAttributeValue(locc, corner_dirs[1]);*/ glVertexAttrib2f(loct, 1.f, 0.f); glVertexAttrib2f(locv, x + w, y);} glTexCoord2f(1.f, 0.f); glVertex2f(x + w, y);
if (prog) {/*prog->setAttributeValue(locc, corner_dirs[2]);*/ glVertexAttrib2f(loct, 1.f, 1.f); glVertexAttrib2f(locv, x + w, y + h);} glTexCoord2f(1.f, 1.f); glVertex2f(x + w, y + h);
if (prog) {/*prog->setAttributeValue(locc, corner_dirs[3]);*/ glVertexAttrib2f(loct, 0.f, 1.f); glVertexAttrib2f(locv, x, y + h);} glTexCoord2f(0.f, 1.f); glVertex2f(x, y + h);
glEnd();
}

View File

@@ -155,7 +155,7 @@ inline void glSetCapEnabled(GLenum cap, bool on = true) {if (on) glEnable(cap);
inline void glSetLightEnabled(bool on) {if (on) glEnable(GL_LIGHTING); else glDisable(GL_LIGHTING);}
inline void glSetFogEnabled(bool on) {if (on) glEnable(GL_FOG); else glDisable(GL_FOG);}
inline void glSetPolygonMode(GLenum mode) {glPolygonMode(GL_FRONT_AND_BACK, mode);}
void glDrawQuad(GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f);
void glDrawQuad(QGLShaderProgram * prog = 0, GLfloat x = -1.f, GLfloat y = -1.f, GLfloat w = 2.f, GLfloat h = 2.f);
QMatrix4x4 getGLMatrix(GLenum matrix);
void setGLMatrix(QMatrix4x4 matrix);
inline void deleteGLTexture(GLuint & tex) {if (tex != 0) glDeleteTextures(1, &tex); tex = 0;}

View File

@@ -184,17 +184,15 @@ void GLVBO::draw(GLenum type, QGLShaderProgram * prog, bool simplest) {
if (!simplest) {
if (has_normals) {
glEnableClientState(GL_NORMAL_ARRAY);
glNormalPointer(GL_FLOAT, 0, offset);
offset = (void*)(llong(offset) + vert_count * 3 * sizeof(GLfloat));
glNormalPointer(GL_FLOAT, 0, offsets[0]);
} else glDisableClientState(GL_NORMAL_ARRAY);
if (has_texcoords) {
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glTexCoordPointer(2, GL_FLOAT, 0, offset);
offset = (void*)(llong(offset) + vert_count * 2 * sizeof(GLfloat));
glTexCoordPointer(2, GL_FLOAT, 0, offsets[1]);
} else glDisableClientState(GL_TEXTURE_COORD_ARRAY);
if (has_colors) {
glEnableClientState(GL_COLOR_ARRAY);
glColorPointer(4, GL_FLOAT, 0, offset);
glColorPointer(4, GL_FLOAT, 0, offsets[2]);
} else glDisableClientState(GL_COLOR_ARRAY);
}
}

View File

@@ -30,14 +30,19 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
colorHalo->setColor(view->selectionHaloColor());
sel_obj = 0;
treeProperties->assignObject(view);
//spinSliderShine->setDecimals(2);
view->setFrameShape(QFrame::NoFrame);
//view->setRenderer(new RendererDeferredShading(view));
view->setRenderer(new RendererDeferredShading(view));
view->setMouseSelectionEnabled(false);
view->setRenderer(new RendererSimple(view));
view->setMouseRotateEnabled(true);
view->setMouseSelectionEnabled(true);
view->setSelectionHaloEnabled(true);
view->setHoverHaloEnabled(true);
view->setHoverHaloFillAlpha(0.);
view->setSelectionHaloFillAlpha(0.);
view->setBackColor(Qt::lightGray);
view->setDepthStart(1.);
view->setDepthEnd(10000.);
//view->setLightingMode(QGLView::PerPixel);
/*MaterialEditor * o = new MaterialEditor();
o->setWindowOpacity(.666);
@@ -65,12 +70,15 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
GLTextureManager::addSearchPath("data");
GLTextureManager::addSearchPath("data/images");
GLTextureManager::addSearchPath("data/SU-33_maps");
obj = loadFromDAEFile("data/earth.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
obj = loadFromDAEFile("data/lights_r.dae");//new GLPrimitiveEllipsoid(EARTH_WL / 1E+6, EARTH_WL / 1E+6, EARTH_H / 1E+6, 500, 500);//GLPrimitiveCube();
obj->setScale(0.1);
//obj->child("Plane001")->material().map_specularity.color_amount = 0.95;
//obj = new GLPrimitiveEllipsoid(100, 100, 100, 100, 100);//GLPrimitiveCube();
for (int i = 0; i < obj->childCount(); ++i)
if (obj->child(i)->type() == GLObjectBase::Light)
((Light*)obj->child(i))->intensity = 0.;
if (obj->child(i)->type() == GLObjectBase::Light) {
((Light*)obj->child(i))->intensity = 1.5;
((Light*)obj->child(i))->decay_linear = .5;
}
view->addObject(obj);
//obj->child("Box001")->addChild(&(view->camera()));
//view->camera().flyToDistance(30);
@@ -94,11 +102,9 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
view->camera().setAim(QVector3D());
view->camera().flyToDistance(100);
//view->camera().setMode(Camera::AimMatrix);
view->setMouseSelectionEnabled(false);
view->setSelectionHaloEnabled(false);
view->setHoverHaloEnabled(false);
Light * l = new Light(view->camera().pos());
l->intensity = 0.5;
l->decay_linear = 0.2;
l->setName("camera");
view->addObject(l);
view->start(-1);
@@ -147,6 +153,7 @@ MainWindow::MainWindow(QWidget * parent): QMainWindow(parent), Ui::MainWindow()
startTimer(1000/60);
//connect(view, SIGNAL(hoverChanged(GLObjectBase*,GLObjectBase*)), this, SLOT(hoverChanged(GLObjectBase*,GLObjectBase*)));
treeProperties->assignObject(view);
connect(view, SIGNAL(selectionChanged(GLObjectBase*,GLObjectBase*)), this, SLOT(selectionChanged(GLObjectBase*,GLObjectBase*)));
connect(view, SIGNAL(glInitializeDone()), this, SLOT(glInit()));
connect(matEditor, SIGNAL(changed()), this, SLOT(materialChanged()));

View File

@@ -12,7 +12,7 @@ QWidget * Delegate::widgetForProperty(QWidget * parent, const QModelIndex & inde
//QMetaProperty prop = index.parent().data(Qt::UserRole + 1).value<QMetaProperty>();
w = new QCheckBox(parent); type = 14; ((QCheckBox*)w)->setChecked(((value.toULongLong() & key) == key && key != 0) || (value.toULongLong() == 0 && key == 0));
((QCheckBox*)w)->setText("0x" + QString::number(key, 16).toUpper());
connect((QCheckBox*)w, SIGNAL(toggled(bool)), this, SLOT(changedFlag()));
connect((QCheckBox*)w, SIGNAL(clicked(bool)), this, SLOT(changedFlag()));
//qDebug() << prop.enumerator().name();
} else {
if (value.canConvert<PropertyValuePair>()) {
@@ -273,6 +273,7 @@ void Delegate::changedFlag() {
PropertyEditor::PropertyEditor(QWidget * parent): QTreeWidget(parent) {
object = 0;
active_ = false;
configTree();
connect(this, SIGNAL(itemClicked(QTreeWidgetItem * , int)), this, SLOT(itemClicked(QTreeWidgetItem * , int)));
connect(this, SIGNAL(itemChanged(QTreeWidgetItem * , int)), this, SLOT(itemChanged(QTreeWidgetItem * , int)));
@@ -319,6 +320,7 @@ void PropertyEditor::itemClicked(QTreeWidgetItem * item, int column) {
void PropertyEditor::itemChanged(QTreeWidgetItem * item, int column) {
if (!active_) return;
if (column != 1) return;
QVariant value = item->data(1, Qt::UserRole);
if (value.canConvert<PropertyValuePair>()) {
@@ -332,6 +334,7 @@ void PropertyEditor::rebuild() {
clear();
configTree();
if (object == 0) return;
active_ = false;
const QMetaObject * mo = object->metaObject();
QList<const QMetaObject * > mol;
while (mo != 0) {
@@ -396,6 +399,7 @@ void PropertyEditor::rebuild() {
chue += 60;
chue %= 360;
}
active_ = true;
}

View File

@@ -66,6 +66,7 @@ private:
QObject * object;
QFont font_b;
QList<QMetaProperty> props;
bool active_;
private slots:
void itemClicked(QTreeWidgetItem * item, int column);

View File

@@ -242,14 +242,14 @@ void QGLView::paintGL() {
}
//if (so != 0) qDebug() << sel_obj->name() << cgid[3];
}
if (hoverHalo_) {
fbo_selection.setWriteBuffer(1);
renderHalo(so, iid, hoverHaloColor_, hoverHaloFill_);
}
if (selectionHalo_) {
if (selectionHalo_ && sel_obj) {
fbo_selection.setWriteBuffer(2);
renderHalo(sel_obj, ids.key(sel_obj), selectionHaloColor_, selectionHaloFill_);
}
if (hoverHalo_ && hov_obj) {
fbo_selection.setWriteBuffer(1);
renderHalo(hov_obj, iid, hoverHaloColor_, hoverHaloFill_);
}
fbo_selection.release();
glEnableDepth();
glEnableClientState(GL_NORMAL_ARRAY);
@@ -269,7 +269,11 @@ void QGLView::paintGL() {
}
}
emit glBeginPaint();
if (renderer_ != 0) renderer_->renderScene();
if (renderer_ != 0) {
renderer_->rp.prepare();
renderer_->prepareScene();
renderer_->renderScene();
}
if (selectionHalo_ || hoverHalo_) {
glReleaseTextures();
glReleaseShaders();
@@ -281,12 +285,14 @@ void QGLView::paintGL() {
glDisable(GL_LIGHTING);
glDisableDepth();
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
if (selectionHalo_) {
if (selectionHalo_ && sel_obj) {
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(2));
//qDebug() << "draw sel";
glDrawQuad();
}
if (hoverHalo_) {
if (hoverHalo_ && hov_obj) {
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture(1));
//qDebug() << "draw hover";
glDrawQuad();
}
}
@@ -346,12 +352,11 @@ void QGLView::paintGL() {
void QGLView::renderHalo(const GLObjectBase * obj, const int iid, const QColor & color, const double & fill) {
if (!shaders_supported) return;
if (obj == 0) {
glClearFramebuffer(Qt::black, false);
} else {
if (obj) {
shader_halo->bind();
shader_halo->setUniformValue("qgl_ModelViewProjectionMatrix", QMatrix4x4());
glActiveTextureChannel(0);
glBindTexture(GL_TEXTURE_2D, fbo_selection.colorTexture());
shader_halo->bind();
shader_halo->setUniformValue("t0", 0);
shader_halo->setUniformValue("dt", QVector2D(1. / viewport()->width(), 1. / viewport()->height()));
shader_halo->setUniformValue("selected", QVector4D(float((iid >> 24) & 0xFF) / 255.f,
@@ -360,11 +365,14 @@ void QGLView::renderHalo(const GLObjectBase * obj, const int iid, const QColor &
float(iid & 0xFF) / 255.f));
shader_halo->setUniformValue("color", color);
shader_halo->setUniformValue("fill", GLfloat(fill));
glDisable(GL_DEPTH_TEST);
glDepthMask(GL_FALSE);
glDrawQuad();
//qDebug() << "render halo" << iid << shader_halo->log() << shader_halo->programId();
glDisableDepth();
glDrawQuad(shader_halo);
glDepthMask(GL_TRUE);
//glFlush();
shader_halo->release();
} else {
glClearFramebuffer(Qt::black, false);
}
}
@@ -609,6 +617,12 @@ void QGLView::wheelEvent(QWheelEvent * e) {
}
void QGLView::leaveEvent(QEvent * ) {
lastPos = QPoint(-1, -1);
//qDebug() << lastPos;
}
void QGLView::processKeys() {
if (ktm_.elapsed() < QApplication::keyboardInputInterval()) return;
Qt::KeyboardModifiers km = QApplication::keyboardModifiers();

View File

@@ -205,6 +205,7 @@ protected:
virtual void mouseMoveEvent(QMouseEvent * e);
virtual void mouseReleaseEvent(QMouseEvent * e);
virtual void wheelEvent(QWheelEvent * e);
virtual void leaveEvent(QEvent * );
virtual void keyPressEvent(QKeyEvent * e) {emit glKeyPressEvent(e); if (e->key() > 0) keys_.insert(e->key());}
virtual void keyReleaseEvent(QKeyEvent * e) {emit glKeyReleaseEvent(e); keys_.remove(e->key());}
virtual void focusOutEvent(QFocusEvent *) {keys_.clear();}

View File

@@ -19,26 +19,22 @@
#include "renderer_deferred_shading.h"
RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo(6, true, GL_RGBA16F) {
RendererDeferredShading::RendererDeferredShading(QGLView * view_): GLRendererBase(view_), fbo_g(4, true, GL_RGBA16F), fbo_out(2, GL_RGBA16F) {
shader_fxaa = shader_ds_0 = shader_ds_1 = 0;
}
void RendererDeferredShading::renderScene() {
prepareUniform();
QMatrix4x4 view_matrix = getGLMatrix(GL_MODELVIEW_MATRIX);
QMatrix4x4 proj_matrix = getGLMatrix(GL_PROJECTION_MATRIX);
QMatrix4x4 viewprojinv = (proj_matrix * view_matrix).inverted();
corner_dirs[0] = (QVector4D(-1, -1, 1, 1) * viewprojinv).normalized();
corner_dirs[1] = (QVector4D( 1, -1, 1, 1) * viewprojinv).normalized();
corner_dirs[2] = (QVector4D( 1, 1, 1, 1) * viewprojinv).normalized();
corner_dirs[3] = (QVector4D(-1, 1, 1, 1) * viewprojinv).normalized();
QMatrix4x4 mproji = rp.proj_matrix_i;
QMatrix4x4 mview = rp.view_matrix;
corner_dirs[0] = (QVector4D(-1, -1, 1, 1) * rp.viewproj_matrix).normalized();
corner_dirs[1] = (QVector4D( 1, -1, 1, 1) * rp.viewproj_matrix).normalized();
corner_dirs[2] = (QVector4D( 1, 1, 1, 1) * rp.viewproj_matrix).normalized();
corner_dirs[3] = (QVector4D(-1, 1, 1, 1) * rp.viewproj_matrix).normalized();
//qDebug() << corner_dirs[0] << corner_dirs[1] << corner_dirs[2] << corner_dirs[3];
int passes = (view.lightsCount() - 1) / 8 + 1;
if (passes < 1) passes = 1;
fbo.bind();
fbo_g.bind();
int buffs[] = {0, 1, 2, 3};
fbo.setWriteBuffers(buffs);
fbo_g.setWriteBuffers(buffs);
if (white_image_id == 0) {
glActiveTextureChannel(6);
white_image_id = ((GLTextureManagerBase*)currentGLTextureManager)->loadTexture(white_image, false);
@@ -55,7 +51,7 @@ void RendererDeferredShading::renderScene() {
//glEnable(GL_TEXTURE_2D);
glEnableDepth();
shader_ds_0->bind();
setUniform(shader_ds_0);
rp.setUniform(shader_ds_0);
shader_ds_0->setUniformValue("z_far", GLfloat(view.depthEnd()));
shader_ds_0->setUniformValue("z_near", GLfloat(view.depthStart()));
shader_ds_0->setUniformValue("t0", 0);
@@ -68,13 +64,14 @@ void RendererDeferredShading::renderScene() {
//fbo.release();
glResetAllTransforms();
prepareUniform();
rp.prepare();
glSetLightEnabled(false);
glDisable(GL_BLEND);
//glBlendFunc(GL_ONE, GL_ONE);
glDisableDepth();
shader_ds_1->bind();
setUniform(shader_ds_1);
rp.setUniform(shader_ds_1);
//qDebug() << rp.view_matrix;
shader_ds_1->setUniformValue("z_far", GLfloat(view.depthEnd()));
shader_ds_1->setUniformValue("z_near", GLfloat(view.depthStart()));
shader_ds_1->setUniformValue("t0", 0);
@@ -83,28 +80,37 @@ void RendererDeferredShading::renderScene() {
shader_ds_1->setUniformValue("t3", 3);
shader_ds_1->setUniformValue("td", 4);
shader_ds_1->setUniformValue("back_color", view.backColor());
shader_ds_1->setUniformValue("mat_proji", proj_matrix.inverted());
shader_ds_1->setUniformValue("mat_proji", mproji);
shader_ds_1->setUniformValue("dt", QVector2D(1. / view.viewport()->width(), 1. / view.viewport()->height()));
fbo.setWriteBuffer(4);
fbo.bindColorTextures();
fbo.bindDepthTexture(4);
fbo_g.bindColorTextures();
fbo_g.bindDepthTexture(4);
fbo_out.bind();
fbo_out.setWriteBuffer(0);
glClearFramebuffer(Qt::black, false);
//QVector<QVector4D> lpos;
//qDebug() << view_matrix;
int passes = (view.lightsCount() - 1) / 16 + 1;
if (passes < 1) passes = 1;
shader_ds_1->setUniformValue("t_pp", 5);
//qDebug() << "render in" << passes << "passes";
for (int l = 0; l < passes; ++l) {
fbo.setWriteBuffer(5 - l % 2);
shader_ds_1->setUniformValue("tb", 4 + l % 2);
setupDSLights(l, 16, view_matrix);
int wi = 1 - l % 2, ri = l % 2;
//qDebug() << " pass" << l << "read from" << ri << "write to" << wi;
glActiveTextureChannel(5);
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(ri));
fbo_out.setWriteBuffer(wi);
setupDSLights(l, 16, mview);
//shader_ds_1->setUniformValue("lightsCount", cplc);
drawFB(shader_ds_1);
glDrawQuad(shader_ds_1);
//renderObjects(GLObjectBase::Solid, l, 0, true, true, view.isFogEnabled());
//renderObjects(GLObjectBase::Transparent, l, 0, true, true, view.isFogEnabled());
glFlush();
glFinish();
//break;
}
fbo.release();
fbo_out.release();
glReleaseShaders();
glActiveTextureChannel(0);
glBindTexture(GL_TEXTURE_2D, fbo.colorTexture(4 + passes % 2));
glBindTexture(GL_TEXTURE_2D, fbo_out.colorTexture(passes % 2));
if (view.isFXAAEnabled()) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -120,6 +126,18 @@ void RendererDeferredShading::renderScene() {
}
void RendererDeferredShading::init(int width, int height) {
fbo_g.resize(width, height);
fbo_out.resize(width, height);
}
void RendererDeferredShading::resize(int width, int height) {
fbo_g.resize(width, height);
fbo_out.resize(width, height);
}
void RendererDeferredShading::reloadShaders() {
if (shader_fxaa == 0) shader_fxaa = new QGLShaderProgram(view.context());
if (shader_ds_0 == 0) shader_ds_0 = new QGLShaderProgram(view.context());
@@ -148,7 +166,7 @@ void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const
int light_start, light_end, lmax;
light_start = pass * lights_per_pass;
light_end = qMin<int>((pass + 1) * lights_per_pass, view.lights().size());
lmax = light_start + 8;
lmax = light_start + lights_per_pass;
amb_light.intensity = (pass == 0 ? 1. : 0.);
amb_light.setColor(pass == 0 ? view.ambientColor() : Qt::black);
amb_light.setName("ambient");
@@ -160,6 +178,8 @@ void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const
amb_light.setName("null");
for (int i = light_end; i < lmax; ++i)
lv << &amb_light;
//QStringList lnl; foreach (Light * l, lv) lnl << l->name();
//qDebug() << " lights" << light_start << "->" << light_end << ", inactive" << (lmax - light_end) << lnl;
setUniformLights(shader_ds_1, lv, view_matrix, view.camera().pos());
}
@@ -167,49 +187,3 @@ void RendererDeferredShading::setupDSLights(int pass, int lights_per_pass, const
void RendererDeferredShading::setupAmbientLight(const QColor & a, bool first_pass) {
}
void RendererDeferredShading::prepareUniform() {
pm = getGLMatrix(GL_PROJECTION_MATRIX);
mvm = getGLMatrix(GL_MODELVIEW_MATRIX);
mvpm = pm * mvm;
pim = pm.inverted();
mvim = mvm.inverted();
mvpim = mvpm.inverted();
nm = mvm.normalMatrix();
}
void RendererDeferredShading::setUniform(QGLShaderProgram * prog) {
//qDebug() << mvm;
prog->setUniformValue("qgl_ModelViewMatrix", mvm);
prog->setUniformValue("qgl_ProjectionMatrix", pm);
prog->setUniformValue("qgl_ModelViewProjectionMatrix", mvpm);
prog->setUniformValue("qgl_NormalMatrix", nm);
prog->setUniformValue("qgl_ModelViewMatrixInverse", mvim);
prog->setUniformValue("qgl_ProjectionMatrixInverse", pim);
prog->setUniformValue("qgl_ModelViewProjectionMatrixInverse", mvpim);
prog->setUniformValue("qgl_ModelViewMatrixTranspose", mvm.transposed());
prog->setUniformValue("qgl_ProjectionMatrixTranspose", pm.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixTranspose", mvpm.transposed());
prog->setUniformValue("qgl_ModelViewMatrixInverseTranspose", mvim.transposed());
prog->setUniformValue("qgl_ProjectionMatrixInverseTranspose", pim.transposed());
prog->setUniformValue("qgl_ModelViewProjectionMatrixInverseTranspose", mvpim.transposed());
}
void RendererDeferredShading::drawFB(QGLShaderProgram * prog) {
glSetPolygonMode(GL_FILL);
int loc = prog->attributeLocation("qgl_Color");
glVertexAttrib3f(loc, 1.f, 1.f, 1.f);
int locv = prog->attributeLocation("qgl_Vertex"),
loct = prog->attributeLocation("qgl_Texture"),
locc = prog->attributeLocation("view_corner");
glBegin(GL_QUADS);
glColor3f(1.f, 1.f, 1.f);
prog->setAttributeValue(locc, corner_dirs[0]); glVertexAttrib2f(loct, 0.f, 0.f); glTexCoord2f(0.f, 0.f); glVertexAttrib2f(locv, -1.f, -1.f); glVertex2f(-1.f, -1.f);
prog->setAttributeValue(locc, corner_dirs[1]); glVertexAttrib2f(loct, 1.f, 0.f); glTexCoord2f(1.f, 0.f); glVertexAttrib2f(locv, 1.f, -1.f); glVertex2f(1.f, -1.f);
prog->setAttributeValue(locc, corner_dirs[2]); glVertexAttrib2f(loct, 1.f, 1.f); glTexCoord2f(1.f, 1.f); glVertexAttrib2f(locv, 1.f, 1.f); glVertex2f(1.f, 1.f);
prog->setAttributeValue(locc, corner_dirs[3]); glVertexAttrib2f(loct, 0.f, 1.f); glTexCoord2f(0.f, 1.f); glVertexAttrib2f(locv, -1.f, 1.f); glVertex2f(-1.f, 1.f);
glEnd();
}

View File

@@ -30,21 +30,17 @@ public:
virtual void renderScene();
protected:
void init(int width, int height) {fbo.resize(width, height);}
void resize(int width, int height) {fbo.resize(width, height);}
void init(int width, int height);
void resize(int width, int height);
void reloadShaders();
void setupShadersTextures(GLObjectBase & object, RenderingParameters & rp);
void setupShadersLights(int lights_count) {cplc = lights_count;}
void setupDSLights(int pass, int lights_per_pass, const QMatrix4x4 & view_matrix);
void setupAmbientLight(const QColor & a, bool first_pass);
void prepareUniform();
void setUniform(QGLShaderProgram * prog);
void drawFB(QGLShaderProgram * prog);
private:
int cplc;
GLFramebuffer fbo;
GLFramebuffer fbo_g, fbo_out;
QGLShaderProgram * shader_fxaa, * shader_ds_0, * shader_ds_1;
QMatrix4x4 pm, mvm, mvpm, pim, mvim, mvpim;

View File

@@ -70,10 +70,11 @@ void RendererSimple::renderScene() {
glDepthFunc(GL_EQUAL);
}
view.camera().apply(view.aspect);
rp.prepare();
setupLights(l, 8);
fbo_c.bind();
/*fbo_c.bind();
glClearFramebuffer();
//shader->bind(); /// WARNING
renderObjects(GLObjectBase::Solid, l, 0, true, view.isLightEnabled(), view.isFogEnabled());
@@ -84,7 +85,8 @@ void RendererSimple::renderScene() {
glReadPixels(mpos.x(), fbo_c.height() - mpos.y(), 1, 1, GL_RGBA, GL_FLOAT, data);
//qDebug() << QVector3D(data[0], data[1], data[2]);
}
fbo_c.release();
fbo_c.release();*/
//qDebug() << rp.viewproj_matrix << (getGLMatrix(GL_PROJECTION_MATRIX)*getGLMatrix(GL_MODELVIEW_MATRIX));
renderObjects(GLObjectBase::Solid, l, 0, true, view.isLightEnabled(), view.isFogEnabled());

View File

@@ -4,7 +4,7 @@
in vec4 view_dir, view_pos;
uniform vec3 ambient;
uniform sampler2D t0, t1, t2, t3, tb;
uniform sampler2D t0, t1, t2, t3, t_pp;
uniform sampler2D td;
uniform int gid, lightsCount;
uniform float z_near, z_far;
@@ -81,8 +81,8 @@ void main(void) {
vec3 v = normalize(-pos.xyz);
sh_pow = 1. / max((1. - v1.w), 0.0001);
sh_mul = max(1. - v1.w, 0.0001);
for (int i = 0; i < 16; ++i)
calcLight(i, n, v, v2);
//for (int i = 0; i < 16; ++i)
calcLight(7, n, v, v2);
/*if (lightsCount > 0) {
calcLight(0, n, v, v2);
if (lightsCount > 1) {
@@ -107,9 +107,9 @@ void main(void) {
}
}
}*/
qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb;// + texture2D(tb, tc).rgb;
qgl_FragData[0].rgb = li * dc + si * v2.rgb + v3.rgb + texture2D(t_pp, tc).rgb;
//qgl_FragData[0].rgb = vec3(abs(lpos.xyz - pos.xyz)/10);
//qgl_FragData[0].rgb = vec3(li.xyz);
//qgl_FragData[0].rgb = vec3(v1.xyz);
//qgl_FragData[0].rgb = texture2D(t_pp, tc).rgb;
//qgl_FragData[0].rgb = vec3(pow(NdotH,100)*2);
//qgl_FragData[0].a = 0.;
}

View File

@@ -15,5 +15,6 @@ void main(void) {
float vs = step(1e-6, d0 + d1 + d2 + d3);
float vm = step(1e-3, (d0 * 255.) * (d1 * 255.) * (d2 * 255.) * (d3 * 255.));
float v = mix(vs - vm, vs - vm - vm + 1, fill);
//qgl_FragData[0] = vec4(1,0,0,0.5);//vec4(color.rgb, v * color.a);
qgl_FragData[0] = vec4(color.rgb, v * color.a);
}