Updates to cmodview:
- Use better values for near and far camera planes to prevent clipping - Added selection capability - Improved zoom functionsensor-dev
parent
f9260386b2
commit
c83622222c
|
@ -11,14 +11,16 @@ HEADERS = \
|
|||
mainwindow.h \
|
||||
modelviewwidget.h \
|
||||
convert3ds.h \
|
||||
cmodops.h
|
||||
cmodops.h \
|
||||
materialwidget.h
|
||||
|
||||
SOURCES = \
|
||||
mainwindow.cpp \
|
||||
cmodview.cpp \
|
||||
modelviewwidget.cpp \
|
||||
convert3ds.cpp \
|
||||
cmodops.cpp
|
||||
cmodops.cpp \
|
||||
materialwidget.cpp
|
||||
|
||||
|
||||
#### CMOD Mesh library ####
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <QtGui>
|
||||
#include "mainwindow.h"
|
||||
#include "materialwidget.h"
|
||||
#include "convert3ds.h"
|
||||
#include "cmodops.h"
|
||||
#include <cel3ds/3dsread.h>
|
||||
|
@ -68,11 +69,13 @@ MainWindow::MainWindow() :
|
|||
QAction* generateTangentsAction = new QAction(tr("Generate &Tangents..."), this);
|
||||
QAction* uniquifyVerticesAction = new QAction(tr("&Uniquify Vertices"), this);
|
||||
QAction* mergeMeshesAction = new QAction(tr("&Merge Meshes"), this);
|
||||
QAction* editMaterialAction = new QAction(tr("&Edit Material"), this);
|
||||
|
||||
operationsMenu->addAction(generateNormalsAction);
|
||||
operationsMenu->addAction(generateTangentsAction);
|
||||
operationsMenu->addAction(uniquifyVerticesAction);
|
||||
operationsMenu->addAction(mergeMeshesAction);
|
||||
operationsMenu->addAction(editMaterialAction);
|
||||
menuBar->addMenu(operationsMenu);
|
||||
|
||||
setMenuBar(menuBar);
|
||||
|
@ -100,6 +103,7 @@ MainWindow::MainWindow() :
|
|||
connect(generateTangentsAction, SIGNAL(triggered()), this, SLOT(generateTangents()));
|
||||
connect(uniquifyVerticesAction, SIGNAL(triggered()), this, SLOT(uniquifyVertices()));
|
||||
connect(mergeMeshesAction, SIGNAL(triggered()), this, SLOT(mergeMeshes()));
|
||||
connect(editMaterialAction, SIGNAL(triggered()), this, SLOT(editMaterial()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -564,3 +568,30 @@ MainWindow::mergeMeshes()
|
|||
setModel(modelFileName(), newModel);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::editMaterial()
|
||||
{
|
||||
QDialog dialog(this);
|
||||
|
||||
MaterialWidget* materialWidget = new MaterialWidget(&dialog);
|
||||
QVBoxLayout* layout = new QVBoxLayout;
|
||||
layout->addWidget(materialWidget);
|
||||
|
||||
if (!m_modelView->selection().isEmpty())
|
||||
{
|
||||
QSetIterator<Mesh::PrimitiveGroup*> iter(m_modelView->selection());
|
||||
Mesh::PrimitiveGroup* selectedGroup = iter.next();
|
||||
const Material* material = m_modelView->model()->getMaterial(selectedGroup->materialIndex);
|
||||
if (material)
|
||||
{
|
||||
materialWidget->setMaterial(*material);
|
||||
}
|
||||
}
|
||||
|
||||
dialog.setLayout(layout);
|
||||
dialog.resize(350, 250);
|
||||
|
||||
dialog.show();
|
||||
dialog.exec();
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ public slots:
|
|||
void generateTangents();
|
||||
void uniquifyVertices();
|
||||
void mergeMeshes();
|
||||
void editMaterial();
|
||||
|
||||
private:
|
||||
ModelViewWidget* m_modelView;
|
||||
|
|
|
@ -0,0 +1,187 @@
|
|||
// materialwidget.cpp
|
||||
//
|
||||
// Copyright (C) 2010, Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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 2
|
||||
// of the License, or (at your option) any later version.
|
||||
|
||||
#include "materialwidget.h"
|
||||
#include <celmodel/material.h>
|
||||
#include <QFormLayout>
|
||||
#include <QPushButton>
|
||||
#include <QColorDialog>
|
||||
|
||||
using namespace cmod;
|
||||
|
||||
|
||||
static QColor toQtColor(const Material::Color& color)
|
||||
{
|
||||
return QColor((int) (color.red()) * 255.99f, (int) (color.green() * 255.99f), (int) (color.blue() * 255.99f));
|
||||
}
|
||||
|
||||
static Material::Color fromQtColor(const QColor& color)
|
||||
{
|
||||
return Material::Color(color.redF(), color.greenF(), color.blueF());
|
||||
}
|
||||
|
||||
static void setWidgetColor(QLabel* widget, const Material::Color& color)
|
||||
{
|
||||
widget->setPalette(QPalette(toQtColor(color)));
|
||||
widget->setAutoFillBackground(true);
|
||||
widget->setText(QString("%1, %2, %3").arg(color.red(), 0, 'g', 3).arg(color.green(), 0, 'g', 3).arg(color.blue(), 0, 'g', 3));
|
||||
}
|
||||
|
||||
|
||||
MaterialWidget::MaterialWidget(QWidget* parent) :
|
||||
QWidget(parent)
|
||||
|
||||
{
|
||||
QGridLayout *layout = new QGridLayout;
|
||||
layout->setColumnStretch(1, 1);
|
||||
|
||||
int frameStyle = QFrame::Sunken | QFrame::Panel;
|
||||
|
||||
m_diffuseColor = new QLabel(this);
|
||||
m_specularColor = new QLabel(this);
|
||||
m_emissiveColor = new QLabel(this);
|
||||
m_opacity = new QLineEdit(this);
|
||||
m_specularPower = new QLineEdit(this);
|
||||
m_baseTexture = new QLabel(this);
|
||||
m_specularMap = new QLabel(this);
|
||||
m_emissiveMap = new QLabel(this);
|
||||
m_normalMap = new QLabel(this);
|
||||
|
||||
m_diffuseColor->setFrameStyle(frameStyle);
|
||||
m_specularColor->setFrameStyle(frameStyle);
|
||||
m_emissiveColor->setFrameStyle(frameStyle);
|
||||
m_baseTexture->setFrameStyle(frameStyle);
|
||||
m_specularMap->setFrameStyle(frameStyle);
|
||||
m_emissiveMap->setFrameStyle(frameStyle);
|
||||
m_normalMap->setFrameStyle(frameStyle);
|
||||
|
||||
QPushButton* changeDiffuse = new QPushButton(tr("Change..."), this);
|
||||
QPushButton* changeSpecular = new QPushButton(tr("Change..."), this);
|
||||
QPushButton* changeEmissive = new QPushButton(tr("Change..."), this);
|
||||
QPushButton* changeBaseTexture = new QPushButton(tr("Change..."), this);
|
||||
QPushButton* changeSpecularMap = new QPushButton(tr("Change..."), this);
|
||||
QPushButton* changeEmissiveMap = new QPushButton(tr("Change..."), this);
|
||||
QPushButton* changeNormalMap = new QPushButton(tr("Change..."), this);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Diffuse")), 0, 0);
|
||||
layout->addWidget(m_diffuseColor, 0, 1);
|
||||
layout->addWidget(changeDiffuse, 0, 2);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Specular")), 1, 0);
|
||||
layout->addWidget(m_specularColor, 1, 1);
|
||||
layout->addWidget(changeSpecular, 1, 2);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Emissive")), 2, 0);
|
||||
layout->addWidget(m_emissiveColor, 2, 1);
|
||||
layout->addWidget(changeEmissive, 2, 2);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Opacity")), 3, 0);
|
||||
layout->addWidget(m_opacity, 3, 1);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Shininess")), 4, 0);
|
||||
layout->addWidget(m_specularPower, 4, 1);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Base Texture")), 5, 0);
|
||||
layout->addWidget(m_baseTexture, 5, 1);
|
||||
layout->addWidget(changeBaseTexture, 5, 2);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Specular Map")), 6, 0);
|
||||
layout->addWidget(m_specularMap, 6, 1);
|
||||
layout->addWidget(changeSpecularMap, 6, 2);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Emissive Map")), 7, 0);
|
||||
layout->addWidget(m_emissiveMap, 7, 1);
|
||||
layout->addWidget(changeEmissiveMap, 7, 2);
|
||||
|
||||
layout->addWidget(new QLabel(tr("Normal Map")), 8, 0);
|
||||
layout->addWidget(m_normalMap, 8, 1);
|
||||
layout->addWidget(changeNormalMap, 8, 2);
|
||||
|
||||
connect(changeDiffuse, SIGNAL(clicked()), this, SLOT(editDiffuse()));
|
||||
connect(changeSpecular, SIGNAL(clicked()), this, SLOT(editSpecular()));
|
||||
connect(changeEmissive, SIGNAL(clicked()), this, SLOT(editEmissive()));
|
||||
|
||||
setMaterial(Material());
|
||||
|
||||
this->setLayout(layout);
|
||||
}
|
||||
|
||||
|
||||
MaterialWidget::~MaterialWidget()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MaterialWidget::setMaterial(const Material& material)
|
||||
{
|
||||
m_material = material;
|
||||
|
||||
setWidgetColor(m_diffuseColor, m_material.diffuse);
|
||||
setWidgetColor(m_specularColor, m_material.specular);
|
||||
setWidgetColor(m_emissiveColor, m_material.emissive);
|
||||
m_opacity->setText(QString::number(m_material.opacity));
|
||||
m_specularPower->setText(QString::number(m_material.specularPower));
|
||||
|
||||
emit materialChanged();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MaterialWidget::editDiffuse()
|
||||
{
|
||||
QColor color = QColorDialog::getColor(toQtColor(m_material.diffuse), this);
|
||||
m_material.diffuse = fromQtColor(color);
|
||||
setWidgetColor(m_diffuseColor, m_material.diffuse);
|
||||
emit materialChanged();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MaterialWidget::editSpecular()
|
||||
{
|
||||
QColor color = QColorDialog::getColor(toQtColor(m_material.specular), this);
|
||||
m_material.specular = fromQtColor(color);
|
||||
setWidgetColor(m_specularColor, m_material.specular);
|
||||
emit materialChanged();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MaterialWidget::editEmissive()
|
||||
{
|
||||
QColor color = QColorDialog::getColor(toQtColor(m_material.emissive), this);
|
||||
m_material.emissive = fromQtColor(color);
|
||||
setWidgetColor(m_emissiveColor, m_material.emissive);
|
||||
emit materialChanged();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MaterialWidget::editBaseTexture()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MaterialWidget::editSpecularMap()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MaterialWidget::editEmissiveMap()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MaterialWidget::editNormalMap()
|
||||
{
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// materialwidget.h
|
||||
//
|
||||
// Copyright (C) 2010, Chris Laurel <claurel@gmail.com>
|
||||
//
|
||||
// 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 2
|
||||
// of the License, or (at your option) any later version.
|
||||
|
||||
#ifndef _CMODVIEW_MATERIAL_WIDGET_H_
|
||||
#define _CMODVIEW_MATERIAL_WIDGET_H_
|
||||
|
||||
#include <celmodel/material.h>
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
|
||||
|
||||
class MaterialWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MaterialWidget(QWidget* parent);
|
||||
~MaterialWidget();
|
||||
|
||||
const cmod::Material& material() const
|
||||
{
|
||||
return m_material;
|
||||
}
|
||||
|
||||
void setMaterial(const cmod::Material& material);
|
||||
|
||||
public slots:
|
||||
void editDiffuse();
|
||||
void editSpecular();
|
||||
void editEmissive();
|
||||
void editBaseTexture();
|
||||
void editSpecularMap();
|
||||
void editEmissiveMap();
|
||||
void editNormalMap();
|
||||
|
||||
signals:
|
||||
void materialChanged();
|
||||
|
||||
private:
|
||||
QLabel* m_diffuseColor;
|
||||
QLabel* m_specularColor;
|
||||
QLabel* m_emissiveColor;
|
||||
QLineEdit* m_opacity;
|
||||
QLineEdit* m_specularPower;
|
||||
QLabel* m_baseTexture;
|
||||
QLabel* m_specularMap;
|
||||
QLabel* m_emissiveMap;
|
||||
QLabel* m_normalMap;
|
||||
|
||||
cmod::Material m_material;
|
||||
};
|
||||
|
||||
#endif // _CMODVIEW_MATERIAL_WIDGET_H_
|
|
@ -11,10 +11,13 @@
|
|||
#include <GL/glew.h>
|
||||
#include "modelviewwidget.h"
|
||||
#include <QtOpenGL>
|
||||
#include <Eigen/LU>
|
||||
|
||||
using namespace cmod;
|
||||
using namespace Eigen;
|
||||
|
||||
static const float VIEWPORT_FOV = 45.0;
|
||||
static const double PI = 3.1415926535897932;
|
||||
|
||||
class MaterialLibrary
|
||||
{
|
||||
|
@ -36,7 +39,12 @@ public:
|
|||
QString ext = QFileInfo(fileName).suffix().toLower();
|
||||
if (ext == "dds")
|
||||
{
|
||||
return m_glWidget->bindTexture(fileName);
|
||||
GLuint texId = m_glWidget->bindTexture(fileName);
|
||||
// Qt doesn't seem to enable mipmap filtering automatically
|
||||
// TODO: Check whether the texture has mipmaps:
|
||||
// glGetTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, &maxLevel);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||
return texId;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -125,6 +133,8 @@ ModelViewWidget::setModel(cmod::Model* model, const QString& modelDirPath)
|
|||
}
|
||||
m_materialLibrary = new MaterialLibrary(this, modelDirPath);
|
||||
|
||||
m_selection.clear();
|
||||
|
||||
// Load materials
|
||||
if (m_model != NULL)
|
||||
{
|
||||
|
@ -154,7 +164,7 @@ ModelViewWidget::resetCamera()
|
|||
}
|
||||
}
|
||||
|
||||
m_modelBoundingRadius = bbox.max().norm();
|
||||
m_modelBoundingRadius = std::max(bbox.max().norm(), bbox.min().norm());
|
||||
m_cameraPosition = m_modelBoundingRadius * Vector3d::UnitZ() * 2.0;
|
||||
m_cameraOrientation = Quaterniond::Identity();
|
||||
}
|
||||
|
@ -174,6 +184,20 @@ void
|
|||
ModelViewWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
m_lastMousePosition = event->pos();
|
||||
m_mouseDownPosition = event->pos();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelViewWidget::mouseReleaseEvent(QMouseEvent* event)
|
||||
{
|
||||
int moveDistance = (event->pos() - m_mouseDownPosition).manhattanLength();
|
||||
if (moveDistance < 3)
|
||||
{
|
||||
float x = (float) event->pos().x() / (float) size().width() * 2.0f - 1.0f;
|
||||
float y = (float) event->pos().y() / (float) size().height() * -2.0f + 1.0f;
|
||||
select(Vector2f(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,14 +236,60 @@ ModelViewWidget::wheelEvent(QWheelEvent* event)
|
|||
}
|
||||
|
||||
// Mouse wheel controls camera dolly
|
||||
#if LINEAR_DOLLY
|
||||
double adjust = m_modelBoundingRadius * event->delta() / 1000.0;
|
||||
double newDistance = m_cameraPosition.norm() + adjust;
|
||||
m_cameraPosition = m_cameraPosition.normalized() * newDistance;
|
||||
#else
|
||||
double adjust = std::pow(2.0, event->delta() / 1000.0);
|
||||
double newDistance = m_cameraPosition.norm() * adjust;
|
||||
m_cameraPosition = m_cameraPosition.normalized() * newDistance;
|
||||
#endif
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelViewWidget::select(const Vector2f& viewportPoint)
|
||||
{
|
||||
if (!m_model)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float aspectRatio = (float) size().width() / (float) size().height();
|
||||
float fovRad = float(VIEWPORT_FOV * PI / 180.0f);
|
||||
float h = (float) tan(fovRad / 2.0f);
|
||||
Vector3d direction(h * aspectRatio * viewportPoint.x(), h * viewportPoint.y(), -1.0f);
|
||||
direction.normalize();
|
||||
Vector3d origin = Vector3d::Zero();
|
||||
Transform3d camera(cameraTransform().inverse());
|
||||
|
||||
Mesh::PickResult pickResult;
|
||||
bool hit = m_model->pick(camera * origin, camera.linear() * direction, &pickResult);
|
||||
if (hit)
|
||||
{
|
||||
m_selection.clear();
|
||||
m_selection.insert(pickResult.group);
|
||||
update();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_selection.clear();
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Transform3d
|
||||
ModelViewWidget::cameraTransform() const
|
||||
{
|
||||
Transform3d t(m_cameraOrientation.conjugate());
|
||||
t.translate(-m_cameraPosition);
|
||||
return t;
|
||||
}
|
||||
|
||||
void
|
||||
ModelViewWidget::initializeGL()
|
||||
{
|
||||
|
@ -233,12 +303,14 @@ ModelViewWidget::paintGL()
|
|||
glDepthMask(GL_TRUE);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||
|
||||
double distanceToOrigin = m_cameraPosition.norm();
|
||||
double nearDistance = std::max(m_modelBoundingRadius * 0.001, distanceToOrigin - m_modelBoundingRadius);
|
||||
double farDistance = m_modelBoundingRadius + distanceToOrigin;
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
double aspectRatio = (double) size().width() / (double) size().height();
|
||||
double nearDistance = m_modelBoundingRadius * 0.05;
|
||||
double farDistance = m_modelBoundingRadius * 20.0;
|
||||
gluPerspective(45.0, aspectRatio, nearDistance, farDistance);
|
||||
gluPerspective(VIEWPORT_FOV, aspectRatio, nearDistance, farDistance);
|
||||
|
||||
glEnable(GL_LIGHTING);
|
||||
|
||||
|
@ -263,10 +335,7 @@ ModelViewWidget::paintGL()
|
|||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
Transform3d cameraRotation(m_cameraOrientation.conjugate());
|
||||
glMultMatrixd(cameraRotation.data());
|
||||
glTranslated(-m_cameraPosition.x(), -m_cameraPosition.y(), -m_cameraPosition.z());
|
||||
|
||||
glMultMatrixd(cameraTransform().data());
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
@ -274,6 +343,12 @@ ModelViewWidget::paintGL()
|
|||
if (m_model)
|
||||
{
|
||||
renderModel(m_model);
|
||||
if (!m_selection.isEmpty())
|
||||
{
|
||||
glEnable(GL_POLYGON_OFFSET_FILL);
|
||||
glPolygonOffset(-0.0f, -1.0f);
|
||||
renderSelection(m_model);
|
||||
}
|
||||
}
|
||||
|
||||
GLenum errorCode = glGetError();
|
||||
|
@ -309,6 +384,7 @@ static int GLComponentCounts[Mesh::FormatMax] =
|
|||
4, // UByte4
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
setVertexArrays(const Mesh::VertexDescription& desc, const void* vertexData)
|
||||
{
|
||||
|
@ -377,6 +453,50 @@ setVertexArrays(const Mesh::VertexDescription& desc, const void* vertexData)
|
|||
}
|
||||
|
||||
|
||||
// Set just the vertex pointer
|
||||
void
|
||||
setVertexPointer(const Mesh::VertexDescription& desc, const void* vertexData)
|
||||
{
|
||||
const Mesh::VertexAttribute& position = desc.getAttribute(Mesh::Position);
|
||||
|
||||
// Can't render anything unless we have positions
|
||||
if (position.format != Mesh::Float3)
|
||||
return;
|
||||
|
||||
// Set up the vertex arrays
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glVertexPointer(3, GL_FLOAT, desc.stride,
|
||||
reinterpret_cast<const char*>(vertexData) + position.offset);
|
||||
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_COLOR_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
static GLenum
|
||||
getGLMode(Mesh::PrimitiveGroupType primitive)
|
||||
{
|
||||
switch (primitive)
|
||||
{
|
||||
case Mesh::TriList:
|
||||
return GL_TRIANGLES;
|
||||
case Mesh::TriStrip:
|
||||
return GL_TRIANGLE_STRIP;
|
||||
case Mesh::TriFan:
|
||||
return GL_TRIANGLE_FAN;
|
||||
case Mesh::LineList:
|
||||
return GL_LINES;
|
||||
case Mesh::LineStrip:
|
||||
return GL_LINE_STRIP;
|
||||
case Mesh::PointList:
|
||||
return GL_POINTS;
|
||||
default:
|
||||
return GL_POINTS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ModelViewWidget::bindMaterial(const Material* material)
|
||||
{
|
||||
|
@ -460,37 +580,42 @@ ModelViewWidget::renderModel(Model* model)
|
|||
}
|
||||
bindMaterial(material);
|
||||
|
||||
GLenum primitiveMode = 0;
|
||||
bool validMode = true;
|
||||
switch (group->prim)
|
||||
{
|
||||
case Mesh::TriList:
|
||||
primitiveMode = GL_TRIANGLES;
|
||||
break;
|
||||
case Mesh::TriStrip:
|
||||
primitiveMode = GL_TRIANGLE_STRIP;
|
||||
break;
|
||||
case Mesh::TriFan:
|
||||
primitiveMode = GL_TRIANGLE_FAN;
|
||||
break;
|
||||
case Mesh::LineList:
|
||||
primitiveMode = GL_LINES;
|
||||
break;
|
||||
case Mesh::LineStrip:
|
||||
primitiveMode = GL_LINE_STRIP;
|
||||
break;
|
||||
case Mesh::PointList:
|
||||
primitiveMode = GL_POINTS;
|
||||
break;
|
||||
default:
|
||||
validMode = false;
|
||||
break;
|
||||
}
|
||||
GLenum primitiveMode = getGLMode(group->prim);
|
||||
glDrawElements(primitiveMode, group->nIndices, GL_UNSIGNED_INT, group->indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (validMode)
|
||||
|
||||
void
|
||||
ModelViewWidget::renderSelection(Model* model)
|
||||
{
|
||||
glEnable(GL_CULL_FACE);
|
||||
glPolygonMode(GL_FRONT, GL_LINE);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glColor4f(0.0f, 1.0f, 0.0f, 0.5f);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
for (unsigned int meshIndex = 0; meshIndex < model->getMeshCount(); ++meshIndex)
|
||||
{
|
||||
Mesh* mesh = model->getMesh(meshIndex);
|
||||
setVertexPointer(mesh->getVertexDescription(), mesh->getVertexData());
|
||||
|
||||
for (unsigned int groupIndex = 0; groupIndex < mesh->getGroupCount(); ++groupIndex)
|
||||
{
|
||||
Mesh::PrimitiveGroup* group = mesh->getGroup(groupIndex);
|
||||
if (m_selection.contains(group))
|
||||
{
|
||||
GLenum primitiveMode = getGLMode(group->prim);
|
||||
glDrawElements(primitiveMode, group->nIndices, GL_UNSIGNED_INT, group->indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glPolygonMode(GL_FRONT, GL_FILL);
|
||||
glDisable(GL_BLEND);
|
||||
glDepthMask(GL_TRUE);
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define _CMODVIEW_MODEL_VIEW_WIDGET_H_
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QSet>
|
||||
#include <celmodel/model.h>
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Geometry>
|
||||
|
@ -43,15 +44,24 @@ public:
|
|||
};
|
||||
|
||||
void mousePressEvent(QMouseEvent *event);
|
||||
void mouseReleaseEvent(QMouseEvent *event);
|
||||
void mouseMoveEvent(QMouseEvent *event);
|
||||
void wheelEvent(QWheelEvent* event);
|
||||
|
||||
void select(const Eigen::Vector2f& point);
|
||||
QSet<cmod::Mesh::PrimitiveGroup*> selection()
|
||||
{
|
||||
return m_selection;
|
||||
}
|
||||
|
||||
void setRenderStyle(RenderStyle style);
|
||||
RenderStyle renderStyle() const
|
||||
{
|
||||
return m_renderStyle;
|
||||
}
|
||||
|
||||
Eigen::Transform3d cameraTransform() const;
|
||||
|
||||
protected:
|
||||
void initializeGL();
|
||||
void paintGL();
|
||||
|
@ -59,6 +69,7 @@ protected:
|
|||
|
||||
private:
|
||||
void renderModel(cmod::Model* model);
|
||||
void renderSelection(cmod::Model* model);
|
||||
void bindMaterial(const cmod::Material* material);
|
||||
|
||||
private:
|
||||
|
@ -67,9 +78,12 @@ private:
|
|||
Eigen::Vector3d m_cameraPosition;
|
||||
Eigen::Quaterniond m_cameraOrientation;
|
||||
QPoint m_lastMousePosition;
|
||||
QPoint m_mouseDownPosition;
|
||||
RenderStyle m_renderStyle;
|
||||
|
||||
MaterialLibrary* m_materialLibrary;
|
||||
|
||||
QSet<cmod::Mesh::PrimitiveGroup*> m_selection;
|
||||
};
|
||||
|
||||
#endif // _CMODVIEW_MODEL_VIEW_WIDGET_H_
|
||||
|
|
Loading…
Reference in New Issue