19#include <QtCore/QTimer>
20#include <QtGui/QWheelEvent>
21#include <QtWidgets/QMessageBox>
48 : QOpenGLWidget(parent),
51 right_key_is_moved_(false),
53 refreshTimer_(nullptr),
56 camera_dialog_(nullptr),
57 current_cameraPtr_(nullptr),
60 managed_shader_prog_(),
61 tmp_renderable_obj_list_(),
62 permanent_renderable_obj_list_() {
63 current_cameraPtr_ = &target_camera_;
70 refreshTimer_->stop();
75 auto iter = managed_shader_prog_.begin();
76 for (; iter != managed_shader_prog_.end(); ++iter) {
77 iter->second->destroyed();
81 managed_shader_prog_.clear();
83 for (
auto &iter : tmp_renderable_obj_list_) {
87 tmp_renderable_obj_list_.clear();
89 while (!permanent_renderable_obj_list_.isEmpty()) {
90 delete permanent_renderable_obj_list_.takeFirst();
99 auto iter = tmp_renderable_obj_list_.find(tmpObjGroupName);
100 if (iter != tmp_renderable_obj_list_.cend()) {
101 iter->second->isEnabled_ = b;
109 auto iter = tmp_renderable_obj_list_.find(tmpObjGroupName);
110 if (iter == tmp_renderable_obj_list_.cend()) {
113 objGroup->
append(renderObj);
114 tmp_renderable_obj_list_.insert(
115 std::make_pair(tmpObjGroupName, objGroup));
119 iter->second->objGroupList_.append(renderObj);
128 const std::string &shaderProgName,
129 const std::shared_ptr<QOpenGLShaderProgram> &newShaderProg) {
130 if (newShaderProg ==
nullptr) {
134 auto iter = managed_shader_prog_.find(shaderProgName);
135 if (iter != managed_shader_prog_.end()) {
136 iter->second.reset();
142 newShaderProg->bind();
143 newShaderProg->setUniformValue(
"mvp", mvp);
144 newShaderProg->release();
146 managed_shader_prog_[shaderProgName] = newShaderProg;
150 initializeOpenGLFunctions();
153 glEnable(GL_PROGRAM_POINT_SIZE);
154 glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
156 refreshTimer_ =
new QTimer(
this);
157 if (!refreshTimer_) {
161 refreshTimer_->setObjectName(tr(
"_refreshTimer"));
162 refreshTimer_->setInterval(40);
163 refreshTimer_->start();
164 connect(refreshTimer_, SIGNAL(timeout()),
this, SLOT(repaint()));
166 free_camera_.
SetUpProjection(45.0f, GLfloat(width()), GLfloat(height()));
167 target_camera_.
SetUpProjection(45.0f, GLfloat(width()), GLfloat(height()));
174 glViewport(0, 0, (GLsizei)width, (GLsizei)height);
188 UpdateAllShaderProgMVP(mvp);
200 for (
auto &iter : tmp_renderable_obj_list_) {
201 if (!iter.second->isEmpty()) {
204 if (iter.second->isEnabled()) {
205 lastItem = iter.second->takeLast();
206 if (lastItem->
Init()) {
211 while (!iter.second->isEmpty()) {
212 delete iter.second->takeFirst();
216 iter.second->append(lastItem);
224 if (index < TARGET || index >
FREE) {
228 current_cameraPtr_ = &free_camera_;
230 current_cameraPtr_ = &target_camera_;
240 target_camera_.
Rotate(-45.0f, -90.0f, 0.0f);
250 free_camera_.
set_x(
static_cast<float>(x));
251 target_camera_.
set_x(
static_cast<float>(x));
256 free_camera_.
set_y(
static_cast<float>(y));
257 target_camera_.
set_y(
static_cast<float>(y));
262 free_camera_.
set_z(
static_cast<float>(z));
263 target_camera_.
set_y(
static_cast<float>(z));
268 if (yawInDegrees > 360.0) {
269 yawInDegrees -= 360.0;
271 if (yawInDegrees < -360.0) {
272 yawInDegrees += 360.0;
275 free_camera_.
set_yaw(
static_cast<float>(yawInDegrees));
276 target_camera_.
set_yaw(
static_cast<float>(yawInDegrees));
281 if (pitchInDegrees > 90.0) {
282 pitchInDegrees = 90.0;
284 if (pitchInDegrees < -90.0) {
285 pitchInDegrees = -90.0;
288 free_camera_.
set_pitch(
static_cast<float>(pitchInDegrees));
289 target_camera_.
set_pitch(
static_cast<float>(pitchInDegrees));
293 if (rollInDegrees > 360.0) {
294 rollInDegrees -= 360.0;
296 if (rollInDegrees < -360.0) {
297 rollInDegrees += 360.0;
300 free_camera_.
set_roll(
static_cast<float>(rollInDegrees));
301 free_camera_.
set_roll(
static_cast<float>(rollInDegrees));
305void SceneViewer::UpdateCameraWorld(
void) {
312 UpdateAllShaderProgMVP(mvp);
317void SceneViewer::UpdateAllShaderProgMVP(
const QMatrix4x4 &mvp) {
318 for (
auto iter = managed_shader_prog_.begin();
319 iter != managed_shader_prog_.end(); ++iter) {
320 iter->second->bind();
321 iter->second->setUniformValue(
"mvp", mvp);
322 iter->second->release();
327 setCursor(Qt::SizeAllCursor);
328 QOpenGLWidget::enterEvent(event);
333 QOpenGLWidget::leaveEvent(event);
337 if (event->button() == Qt::LeftButton) {
338 left_key_last_pos_ = QCursor::pos();
339 }
else if (event->button() == Qt::RightButton) {
340 right_key_is_moved_ =
false;
341 right_key_last_y_ =
static_cast<float>(QCursor::pos().y());
344 QOpenGLWidget::mousePressEvent(event);
348 if (mouseEvent->buttons() == Qt::LeftButton) {
349 QPoint tmp = QCursor::pos();
350 QPoint dd = tmp - left_key_last_pos_;
351 left_key_last_pos_ = tmp;
353 float x =
static_cast<float>(dd.x()) *
sensitivity();
354 float y =
static_cast<float>(dd.y()) *
sensitivity();
358 free_camera_.
Lift(y);
362 x = target_camera_.
yaw() - x;
363 y = target_camera_.
pitch() - y;
386 }
else if (mouseEvent->buttons() == Qt::RightButton) {
387 right_key_is_moved_ =
true;
390 float tmp =
static_cast<float>(QCursor::pos().y());
391 float dd = right_key_last_y_ - tmp;
392 right_key_last_y_ = tmp;
396 free_camera_.
Walk(z);
406 QOpenGLWidget::mousePressEvent(mouseEvent);
410 float delta =
static_cast<float>(
event->angleDelta().y());
415 delta += free_camera_.
pitch();
419 if (delta < -90.0f) {
432 QOpenGLWidget::wheelEvent(event);
436 if (!right_key_is_moved_ && event->button() == Qt::RightButton) {
437 if (camera_dialog_ ==
nullptr) {
439 if (!camera_dialog_) {
440 QMessageBox::warning(
this, tr(
"Error"),
441 tr(
"No Enough for creating Camera Dialog!!!"),
445 connect(camera_dialog_, SIGNAL(resetcamera()),
this,
447 connect(camera_dialog_, SIGNAL(xValueChanged(
double)),
this,
449 connect(camera_dialog_, SIGNAL(yValueChanged(
double)),
this,
451 connect(camera_dialog_, SIGNAL(zValueChanged(
double)),
this,
453 connect(camera_dialog_, SIGNAL(yawValueChanged(
double)),
this,
455 connect(camera_dialog_, SIGNAL(pitchValueChanged(
double)),
this,
457 connect(camera_dialog_, SIGNAL(rollValueChanged(
double)),
this,
459 connect(camera_dialog_, SIGNAL(cameraTypeChanged(
int)),
this,
461 connect(camera_dialog_, SIGNAL(sensitivityChanged(
float)),
this,
465 SLOT(updateCameraAttitude(QVector3D)));
467 SLOT(updateCameraPos(QVector3D)));
473 camera_dialog_->move(event->globalPos());
474 camera_dialog_->show();
478 QOpenGLWidget::mouseReleaseEvent(event);
void set_near_plane_width(const float npWidth)
void SetUpProjection(float fovInDegrees, float nearPlaneWidth, float nearPlaneHeight, float near=0.1f, float far=1000.f)
void set_roll(float rInDegrees)
const QVector3D & position(void) const
void set_yaw(float yInDegrees)
void set_position(const QVector3D &pos)
const QMatrix4x4 & model_view_matrix(void) const
void UpdateProjection(void)
void set_pitch(float pInDegrees)
void SetAttitude(float yawInDegrees, float pitchInDegrees, float rollInDegrees)
const QMatrix4x4 & projection_matrix(void) const
void set_near_plane_height(const float npHeight)
const QVector3D & attitude(void) const
virtual void UpdateWorld(void)
void Starfe(const float dt)
void Lift(const float dt)
void Walk(const float dt)
bool Init(std::shared_ptr< QOpenGLShaderProgram > &shaderProgram=NullRenderableObj)
void Render(const QMatrix4x4 *mvp=nullptr)
bool haveShaderProgram(void)
void updateCameraPos(const QVector3D &)
void updateCameraAttitude(const QVector3D &)
bool IsFreeCamera(void) const
void resizeGL(int w, int h) override
void mouseMoveEvent(QMouseEvent *mouseEvent) override
void enterEvent(QEvent *event) override
void mouseReleaseEvent(QMouseEvent *event) override
void leaveEvent(QEvent *event) override
void CameraAttitudeChanged(const QVector3D &attitude)
void mousePressEvent(QMouseEvent *mouseEvent) override
void ChangeCameraType(int index)
void UpdateCameraY(double Y)
void UpdateCameraRoll(double rollInDegrees)
void AddNewShaderProg(const std::string &shaderProgName, const std::shared_ptr< QOpenGLShaderProgram > &newShaderProg)
void initializeGL() override
void UpdateCameraPitch(double pitchInDegrees)
bool AddTempRenderableObj(const std::string &tmpObjGroupName, RenderableObject *renderObj)
void ResetCameraPosAttitude(void)
void set_sensitivity(float s)
float sensitivity(void) const
SceneViewer(QWidget *parent=nullptr)
void setTempObjGroupEnabled(const std::string &tmpObjGroupName, bool b)
void UpdateCameraYaw(double yawInDegrees)
void wheelEvent(QWheelEvent *event) override
void CameraPosChanged(const QVector3D &pos)
void UpdateCameraX(double x)
void UpdateCameraZ(double Z)
virtual void UpdateWorld()
float distance(void) const
void Rotate(float xRotateDegrees, float yRotateDegrees, float zRotateDegrees)
void set_distance(float distance)
void set_target_pos(float x, float y, float z)
TempRenderableObjGroup(void)
RenderableObject * takeFirst(void)
void append(RenderableObject *obj)
RenderableObject * takeLast(void)
bool isEnabled(void) const
~TempRenderableObjGroup(void)
QList< RenderableObject * > objGroupList_