Skip to content

Commit

Permalink
Added Camera class & code refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
denizdiktas committed Jun 12, 2023
1 parent 99fd1e3 commit 9f404ab
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 60 deletions.
6 changes: 5 additions & 1 deletion Arrangement_on_surface_2/demo/earth/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,18 @@ qt_standard_project_setup()
qt_add_executable(earth
main.cpp
mainwidget.cpp mainwidget.h
Camera.h
)


set_target_properties(earth PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)

set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE")
if (MSVC)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SUBSYSTEM:CONSOLE")
endif (MSVC)

target_link_libraries(earth PRIVATE
Qt6::Core
Expand Down
58 changes: 58 additions & 0 deletions Arrangement_on_surface_2/demo/earth/Camera.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@

#ifndef CAMERA_H
#define CAMERA_H


#include <qvector3d.h>
#include <qmatrix4x4.h>


class Camera
{
public:

Camera() :
m_ux(1, 0, 0),
m_uy(0, 1, 0),
m_uz(0, 0, 1)
{
}

void set_pos(const QVector3D& pos) { m_pos = pos; }
void set_pos(float x, float y, float z) { m_pos = QVector3D(x,y,z); }

QMatrix4x4 get_view_matrix() const
{
QMatrix4x4 view;
const QVector3D center = m_pos - m_uz;
view.lookAt(m_pos, center, m_uy);
return view;
}

// rotate the camera around its own axes
void rotate(float theta_around_x, float theta_around_y)
{
// rotate the camera around its x-axis
QMatrix4x4 rot;
rot.rotate(theta_around_x, m_ux);
m_pos = m_pos * rot;
m_uy = m_uy * rot;
m_uz = m_uz * rot;

// rotate the camera around its y-axis
rot.setToIdentity();
rot.rotate(theta_around_y, m_uy);
m_pos = m_pos * rot;
m_ux = m_ux * rot;
m_uz = m_uz * rot;
}

private:
QVector3D m_pos;
QVector3D m_ux;
QVector3D m_uy;
QVector3D m_uz;
};


#endif
2 changes: 1 addition & 1 deletion Arrangement_on_surface_2/demo/earth/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ int main(int argc, char *argv[])
format.setDepthBufferSize(24);
QSurfaceFormat::setDefaultFormat(format);

app.setApplicationName("cube");
app.setApplicationName("Earth");
app.setApplicationVersion("0.1");
#ifndef QT_NO_OPENGL
MainWidget widget;
Expand Down
80 changes: 30 additions & 50 deletions Arrangement_on_surface_2/demo/earth/mainwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <iostream>
#include <string>


namespace {
// vertex shader
const char* vertex_shader_code = R"vs(
Expand Down Expand Up @@ -89,63 +90,40 @@ void main()

MainWidget::~MainWidget()
{
// Make sure the context is current when deleting the texture
// and the buffers.
makeCurrent();
doneCurrent();
// Make sure the context is current when deleting the texture and the buffers.
makeCurrent();
doneCurrent();
}

bool mouse_pressed = false;
QVector2D last_mouse_pos;

void MainWidget::mousePressEvent(QMouseEvent *e)
{
// Save mouse press position
m_mouse_press_position = QVector2D(e->position());

mouse_pressed = true;
last_mouse_pos = QVector2D(e->position());
m_mouse_pressed = true;
m_last_mouse_pos = QVector2D(e->position());
}


QVector3D cam_pos(0, 0, 10);
QVector3D cam_ux(1, 0, 0);
QVector3D cam_uy(0, 1, 0);
QVector3D cam_uz(0, 0, 1);


void MainWidget::mouseMoveEvent(QMouseEvent* e)
{
//last_mouse_pos = QVector2D(e->position());
auto current_mouse_pos = QVector2D(e->position());

if (mouse_pressed)
{

auto diff = current_mouse_pos - last_mouse_pos;
if (m_mouse_pressed)
{
const auto diff = current_mouse_pos - m_last_mouse_pos;
const float scale_factor = 0.1f;
auto angle = scale_factor * QVector2D(diff.y(), diff.x());
const float theta_around_x = scale_factor * diff.y();
const float theta_around_y = scale_factor * diff.x();

// rotate the camera around its x-axis
QMatrix4x4 rot;
rot.rotate(angle.x(), cam_ux);
cam_pos = cam_pos * rot;
cam_uy = cam_uy * rot;
cam_uz = cam_uz * rot;

// rotate the camera around its y-axis
rot.setToIdentity();
rot.rotate(angle.y(), cam_uy);
cam_pos = cam_pos * rot;
cam_ux = cam_ux * rot;
cam_uz = cam_uz * rot;
m_camera.rotate(theta_around_x, theta_around_y);
}

last_mouse_pos = current_mouse_pos;
m_last_mouse_pos = current_mouse_pos;
}
void MainWidget::mouseReleaseEvent(QMouseEvent *e)
{
mouse_pressed = false;
m_mouse_pressed = false;

}
void MainWidget::timerEvent(QTimerEvent *)
Expand All @@ -161,6 +139,7 @@ void MainWidget::initializeGL()

glClearColor(0, 0, 0, 1);

m_camera.set_pos(0,0,10);
init_geometry();
init_shader_program();

Expand Down Expand Up @@ -208,39 +187,39 @@ void MainWidget::add_shader(GLuint the_program, const char* shader_code,
}
void MainWidget::init_shader_program()
{
shader = glCreateProgram();
if (!shader)
m_shader = glCreateProgram();
if (!m_shader)
{
std::cout << "error creating shader program!\n";
return;
}

add_shader(shader, vertex_shader_code, GL_VERTEX_SHADER);
add_shader(m_shader, vertex_shader_code, GL_VERTEX_SHADER);
//add_shader(shader, geometry_shader_code, GL_GEOMETRY_SHADER);
add_shader(shader, fragment_shader_code, GL_FRAGMENT_SHADER);
add_shader(m_shader, fragment_shader_code, GL_FRAGMENT_SHADER);

GLint result = 0;
GLchar elog[1024] = { 0 };

glLinkProgram(shader);
glGetProgramiv(shader, GL_LINK_STATUS, &result);
glLinkProgram(m_shader);
glGetProgramiv(m_shader, GL_LINK_STATUS, &result);
if (!result)
{
glGetProgramInfoLog(shader, sizeof(elog), NULL, elog);
glGetProgramInfoLog(m_shader, sizeof(elog), NULL, elog);
std::cout << "! error linking program:\n" << elog << std::endl;
return;
}

glValidateProgram(shader);
glGetProgramiv(shader, GL_VALIDATE_STATUS, &result);
glValidateProgram(m_shader);
glGetProgramiv(m_shader, GL_VALIDATE_STATUS, &result);
if (!result)
{
glGetProgramInfoLog(shader, sizeof(elog), NULL, elog);
glGetProgramInfoLog(m_shader, sizeof(elog), NULL, elog);
std::cout << "! error validating program:\n" << elog << std::endl;
return;
}

m_uniform_mvp = glGetUniformLocation(shader, "MVP");
m_uniform_mvp = glGetUniformLocation(m_shader, "MVP");
std::cout << "uniform loc = " << m_uniform_mvp << std::endl;
}

Expand Down Expand Up @@ -275,8 +254,9 @@ void MainWidget::paintGL()
//const QVector3D eye(0, 10, 10), center(0, 0, 0), up(0, 1, 0);
// view.lookAt(eye, center, up);

const QVector3D center(0, 0, 0);
view.lookAt(cam_pos, center, cam_uy);
//const QVector3D center(0, 0, 0);
//view.lookAt(camera.pos, center, cam_uy);
view = m_camera.get_view_matrix();

QMatrix4x4 model;
//static float angle = 0;
Expand All @@ -290,7 +270,7 @@ void MainWidget::paintGL()
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);


glUseProgram(shader);
glUseProgram(m_shader);
auto mvp = m_projection * view * model;
glUniformMatrix4fv(m_uniform_mvp, 1, GL_FALSE, mvp.data());

Expand Down
16 changes: 8 additions & 8 deletions Arrangement_on_surface_2/demo/earth/mainwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include <qopenglwidget.h>
#include <qopenglfunctions_3_3_core.h>
#include <qopenglfunctions_4_5_core.h>

#include "Camera.h"

class Sphere;
using OpenGLFunctionsBase = QOpenGLFunctions_3_3_Core;
Expand Down Expand Up @@ -52,17 +52,17 @@ class MainWidget : public QOpenGLWidget, protected OpenGLFunctionsBase

std::unique_ptr<Sphere> m_sphere;

GLuint shader;
GLuint m_shader;
GLuint m_uniform_mvp; // uniform location for MVP-matrix in the shader

QBasicTimer m_timer;

// camera & controls
Camera m_camera;
bool m_mouse_pressed = false;
QVector2D m_last_mouse_pos;
QMatrix4x4 m_projection;

QVector2D m_mouse_press_position;
QVector3D m_rotation_axis;
qreal m_angular_speed = 0;
QQuaternion m_rotation;

QBasicTimer m_timer;
};

class Sphere : protected OpenGLFunctionsBase
Expand Down

0 comments on commit 9f404ab

Please sign in to comment.