Compare commits

...

10 commits

Author SHA1 Message Date
bd3d72eb96 added readme 2023-08-24 14:50:50 +05:00
Muaz Ahmad
e58ad18fb1 Added comments 2023-08-03 14:43:11 +05:00
Muaz Ahmad
509e94ac58 Iterators now use size_t, light parameters changed 2023-08-03 13:55:58 +05:00
Muaz Ahmad
3fb63a2887 Added help option 2023-05-04 16:27:32 +05:00
Muaz Ahmad
1ad927f8d1 Made obj and mtl files command line inputs 2023-05-04 16:22:45 +05:00
Muaz Ahmad
26336815b4 Moved obj and mtl file loading to main instead 2023-05-04 15:43:30 +05:00
Muaz Ahmad
22d1b57a48 converted to proper directory structure 2023-05-04 15:31:09 +05:00
Muaz Ahmad
2b491ac83e added camera controls 2023-05-04 15:01:53 +05:00
Muaz Ahmad
518a7b74c2 Updated gitignore 2023-05-04 14:38:05 +05:00
Muaz Ahmad
b86fe3561d Added movement controls, removed moc generated files 2023-05-04 14:37:43 +05:00
14 changed files with 383 additions and 718 deletions

3
.gitignore vendored
View file

@ -4,3 +4,6 @@ Makefile
ui_mainwindow.h ui_mainwindow.h
untitled.mtl untitled.mtl
untitled.obj untitled.obj
moc*
build/
bin/

View file

@ -4,10 +4,6 @@
TEMPLATE = app TEMPLATE = app
TARGET = 3dobj-renderer TARGET = 3dobj-renderer
INCLUDEPATH += . \
/usr/include/GL
DEPENDPATH += . \
/usr/include/GL
# You can make your code fail to compile if you use deprecated APIs. # You can make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line. # In order to do so, uncomment the following line.
@ -17,7 +13,11 @@ DEPENDPATH += . \
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
# Input # Input
SOURCES += main.cpp opglwidget.cpp obj.cpp SOURCES += src/main.cpp src/opglwidget.cpp src/obj.cpp
HEADERS += ui_mainwindow.h opglwidget.h obj.h HEADERS += include/opglwidget.h include/obj.h
FORMS += mainwindow.ui FORMS += forms/mainwindow.ui
MOC_DIR += build/moc
UI_DIR += include/
OBJECTS_DIR += build/objects
QT += core gui widgets QT += core gui widgets
DESTDIR = $$PWD/bin

13
README.md Normal file
View file

@ -0,0 +1,13 @@
# 3d-obj-renderer
Barebones 3d model (.obj) viewer.
Single object only, no vertex textures. Requires triangulated meshes.
Tested with direct export from blender.
Move camera with `wasd`. Click and drag to reorient.
Pass in obj and material files as command args `-o` and `-m` respectively.
*Caution*. It seems to break on first run of each file from boot and vertex coords break. Works fine on rerun though. Not tested.

View file

@ -31,7 +31,11 @@
<number>0</number> <number>0</number>
</property> </property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="OPGLWidget" name="openGLWidget"/> <widget class="OPGLWidget" name="openGLWidget">
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>

View file

@ -1,14 +1,20 @@
// not good at using namespaces, bear with me
#include <vector> #include <vector>
#include <string> #include <string>
using namespace std; using namespace std;
// struct to hold vertex position
struct Vertex { struct Vertex {
float pos[3]; float pos[3];
}; };
// struct to hold normal vectors
struct Normal { struct Normal {
float dir[3]; float dir[3];
}; };
// struct to hold material information
struct Material { struct Material {
int idx; int idx;
string name; string name;
@ -17,12 +23,15 @@ struct Material {
float diffuse[4]; float diffuse[4];
}; };
// meta struct for each individual face, pointers to its set of
// vertices, normals and material structs
struct Face { struct Face {
vector<Vertex*> vertices; vector<Vertex*> vertices;
vector<Normal*> normals; vector<Normal*> normals;
Material* mtl; Material* mtl;
}; };
// class to load and handle .obj and .mtl parsing and face data construction
class ObjectLoader class ObjectLoader
{ {
public: public:

37
include/opglwidget.h Normal file
View file

@ -0,0 +1,37 @@
#include <QtWidgets/QOpenGLWidget>
#include "obj.h"
#include <QKeyEvent>
#include <QMouseEvent>
class OPGLWidget : public QOpenGLWidget
{
Q_OBJECT
public:
OPGLWidget(QWidget *parent) : QOpenGLWidget(parent) {}
ObjectLoader obj;
public slots:
void paintGL(); // for repaint loop
void update_camera(); // for mouse movement
protected:
void initializeGL();
void resizeGL(int w, int h);
void reorient();
// camera controls
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
// init values
int mtl_idx = -1; // index to store current material to use
float loc[3] = {0, 0, 10}; // initial camera position
float f[3] = {0, 0, -1}; // initial camera direction
float up[3] = {0, 1, 0}; // initial camera up vector
float right[3] = {1, 0, 0}; // initial camera right vector
float vel[3] = {0, 0, 0}; // initial camera velocity
float speed = 0; // placeholder init for abs speed (for limit and slowing mostly)
bool key_states[6] = {false, false, false, false, false, false}; // camera control states
float mouse_loc_old[2]; // for calculating camera direction changes with mouse movement
};

View file

@ -1,19 +0,0 @@
#include <QtWidgets/QApplication>
#include <QMainWindow>
#include <QTimer>
#include "ui_mainwindow.h"
int main(int argc, char **argv) {
QApplication app(argc, argv);
QMainWindow w;
Ui::MainWindow ui;
ui.setupUi(&w);
QTimer timer_draw;
QTimer timer_cam;
w.connect(&timer_draw, SIGNAL(timeout()), ui.openGLWidget, SLOT(paintGL()));
w.connect(&timer_cam, SIGNAL(timeout()), ui.openGLWidget, SLOT(update_camera()));
timer_draw.start(16);
timer_cam.start(16);
w.show();
return app.exec();
}

View file

@ -1,123 +0,0 @@
/****************************************************************************
** Meta object code from reading C++ file 'opglwidget.h'
**
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.15.9)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#include <memory>
#include "opglwidget.h"
#include <QtCore/qbytearray.h>
#include <QtCore/qmetatype.h>
#if !defined(Q_MOC_OUTPUT_REVISION)
#error "The header file 'opglwidget.h' doesn't include <QObject>."
#elif Q_MOC_OUTPUT_REVISION != 67
#error "This file was generated using the moc from 5.15.9. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
QT_BEGIN_MOC_NAMESPACE
QT_WARNING_PUSH
QT_WARNING_DISABLE_DEPRECATED
struct qt_meta_stringdata_OPGLWidget_t {
QByteArrayData data[4];
char stringdata0[34];
};
#define QT_MOC_LITERAL(idx, ofs, len) \
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
qptrdiff(offsetof(qt_meta_stringdata_OPGLWidget_t, stringdata0) + ofs \
- idx * sizeof(QByteArrayData)) \
)
static const qt_meta_stringdata_OPGLWidget_t qt_meta_stringdata_OPGLWidget = {
{
QT_MOC_LITERAL(0, 0, 10), // "OPGLWidget"
QT_MOC_LITERAL(1, 11, 7), // "paintGL"
QT_MOC_LITERAL(2, 19, 0), // ""
QT_MOC_LITERAL(3, 20, 13) // "update_camera"
},
"OPGLWidget\0paintGL\0\0update_camera"
};
#undef QT_MOC_LITERAL
static const uint qt_meta_data_OPGLWidget[] = {
// content:
8, // revision
0, // classname
0, 0, // classinfo
2, 14, // methods
0, 0, // properties
0, 0, // enums/sets
0, 0, // constructors
0, // flags
0, // signalCount
// slots: name, argc, parameters, tag, flags
1, 0, 24, 2, 0x0a /* Public */,
3, 0, 25, 2, 0x0a /* Public */,
// slots: parameters
QMetaType::Void,
QMetaType::Void,
0 // eod
};
void OPGLWidget::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
{
if (_c == QMetaObject::InvokeMetaMethod) {
auto *_t = static_cast<OPGLWidget *>(_o);
(void)_t;
switch (_id) {
case 0: _t->paintGL(); break;
case 1: _t->update_camera(); break;
default: ;
}
}
(void)_a;
}
QT_INIT_METAOBJECT const QMetaObject OPGLWidget::staticMetaObject = { {
QMetaObject::SuperData::link<QOpenGLWidget::staticMetaObject>(),
qt_meta_stringdata_OPGLWidget.data,
qt_meta_data_OPGLWidget,
qt_static_metacall,
nullptr,
nullptr
} };
const QMetaObject *OPGLWidget::metaObject() const
{
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
}
void *OPGLWidget::qt_metacast(const char *_clname)
{
if (!_clname) return nullptr;
if (!strcmp(_clname, qt_meta_stringdata_OPGLWidget.stringdata0))
return static_cast<void*>(this);
return QOpenGLWidget::qt_metacast(_clname);
}
int OPGLWidget::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
{
_id = QOpenGLWidget::qt_metacall(_c, _id, _a);
if (_id < 0)
return _id;
if (_c == QMetaObject::InvokeMetaMethod) {
if (_id < 2)
qt_static_metacall(this, _c, _id, _a);
_id -= 2;
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
if (_id < 2)
*reinterpret_cast<int*>(_a[0]) = -1;
_id -= 2;
}
return _id;
}
QT_WARNING_POP
QT_END_MOC_NAMESPACE

View file

@ -1,462 +0,0 @@
#define __DBL_MIN_EXP__ (-1021)
#define __cpp_nontype_template_parameter_auto 201606L
#define __UINT_LEAST16_MAX__ 0xffff
#define __FLT16_HAS_QUIET_NAN__ 1
#define __ATOMIC_ACQUIRE 2
#define __FLT128_MAX_10_EXP__ 4932
#define __FLT_MIN__ 1.17549435082228750796873653722224568e-38F
#define __GCC_IEC_559_COMPLEX 2
#define __cpp_aggregate_nsdmi 201304L
#define __UINT_LEAST8_TYPE__ unsigned char
#define __SIZEOF_FLOAT80__ 16
#define __BFLT16_DENORM_MIN__ 9.18354961579912115600575419704879436e-41BF16
#define __INTMAX_C(c) c ## L
#define __CHAR_BIT__ 8
#define __UINT8_MAX__ 0xff
#define __SCHAR_WIDTH__ 8
#define __WINT_MAX__ 0xffffffffU
#define __FLT32_MIN_EXP__ (-125)
#define __cpp_static_assert 201411L
#define __BFLT16_MIN_10_EXP__ (-37)
#define __ORDER_LITTLE_ENDIAN__ 1234
#define __WCHAR_MAX__ 0x7fffffff
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
#define __GCC_ATOMIC_CHAR_LOCK_FREE 2
#define __GCC_IEC_559 2
#define __FLT32X_DECIMAL_DIG__ 17
#define __FLT_EVAL_METHOD__ 0
#define __cpp_binary_literals 201304L
#define __FLT64_DECIMAL_DIG__ 17
#define __cpp_noexcept_function_type 201510L
#define __GCC_ATOMIC_CHAR32_T_LOCK_FREE 2
#define __cpp_variadic_templates 200704L
#define __UINT_FAST64_MAX__ 0xffffffffffffffffUL
#define __SIG_ATOMIC_TYPE__ int
#define __DBL_MIN_10_EXP__ (-307)
#define __FINITE_MATH_ONLY__ 0
#define __cpp_variable_templates 201304L
#define __FLT32X_MAX_EXP__ 1024
#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
#define __FLT32_HAS_DENORM__ 1
#define __UINT_FAST8_MAX__ 0xff
#define __cpp_rvalue_reference 200610L
#define __cpp_nested_namespace_definitions 201411L
#define __DEC64_MAX_EXP__ 385
#define __INT8_C(c) c
#define __LDBL_HAS_INFINITY__ 1
#define __INT_LEAST8_WIDTH__ 8
#define __cpp_variadic_using 201611L
#define __UINT_LEAST64_MAX__ 0xffffffffffffffffUL
#define __INT_LEAST8_MAX__ 0x7f
#define __cpp_attributes 200809L
#define __cpp_capture_star_this 201603L
#define __SHRT_MAX__ 0x7fff
#define __LDBL_MAX__ 1.18973149535723176502126385303097021e+4932L
#define __FLT64X_MAX_10_EXP__ 4932
#define __cpp_if_constexpr 201606L
#define __BFLT16_MAX_10_EXP__ 38
#define __BFLT16_MAX_EXP__ 128
#define __LDBL_IS_IEC_60559__ 1
#define __FLT64X_HAS_QUIET_NAN__ 1
#define __UINT_LEAST8_MAX__ 0xff
#define __GCC_ATOMIC_BOOL_LOCK_FREE 2
#define __FLT128_DENORM_MIN__ 6.47517511943802511092443895822764655e-4966F128
#define __UINTMAX_TYPE__ long unsigned int
#define __cpp_nsdmi 200809L
#define __BFLT16_DECIMAL_DIG__ 4
#define __linux 1
#define __DEC32_EPSILON__ 1E-6DF
#define __FLT_EVAL_METHOD_TS_18661_3__ 0
#define __OPTIMIZE__ 1
#define __UINT32_MAX__ 0xffffffffU
#define __GXX_EXPERIMENTAL_CXX0X__ 1
#define __DBL_DENORM_MIN__ double(4.94065645841246544176568792868221372e-324L)
#define __FLT128_MIN_EXP__ (-16381)
#define __WINT_MIN__ 0U
#define __FLT128_MIN_10_EXP__ (-4931)
#define __FLT32X_IS_IEC_60559__ 1
#define __INT_LEAST16_WIDTH__ 16
#define __SCHAR_MAX__ 0x7f
#define __FLT128_MANT_DIG__ 113
#define __WCHAR_MIN__ (-__WCHAR_MAX__ - 1)
#define __INT64_C(c) c ## L
#define __SSP_STRONG__ 3
#define __GCC_ATOMIC_POINTER_LOCK_FREE 2
#define __ATOMIC_SEQ_CST 5
#define __unix 1
#define __INT_LEAST64_MAX__ 0x7fffffffffffffffL
#define __FLT32X_MANT_DIG__ 53
#define __GCC_ATOMIC_CHAR16_T_LOCK_FREE 2
#define __cpp_aligned_new 201606L
#define __FLT32_MAX_10_EXP__ 38
#define __FLT64X_EPSILON__ 1.08420217248550443400745280086994171e-19F64x
#define __STDC_HOSTED__ 1
#define __DEC64_MIN_EXP__ (-382)
#define __cpp_decltype_auto 201304L
#define __DBL_DIG__ 15
#define __FLT_EPSILON__ 1.19209289550781250000000000000000000e-7F
#define __GXX_WEAK__ 1
#define __SHRT_WIDTH__ 16
#define __FLT32_IS_IEC_60559__ 1
#define __LDBL_MIN__ 3.36210314311209350626267781732175260e-4932L
#define __DBL_IS_IEC_60559__ 1
#define __DEC32_MAX__ 9.999999E96DF
#define __cpp_threadsafe_static_init 200806L
#define __cpp_enumerator_attributes 201411L
#define __FLT64X_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951F64x
#define __FLT32X_HAS_INFINITY__ 1
#define __unix__ 1
#define __INT_WIDTH__ 32
#define __STDC_IEC_559__ 1
#define __STDC_ISO_10646__ 201706L
#define __DECIMAL_DIG__ 21
#define __STDC_IEC_559_COMPLEX__ 1
#define __FLT64_EPSILON__ 2.22044604925031308084726333618164062e-16F64
#define __gnu_linux__ 1
#define __INT16_MAX__ 0x7fff
#define __FLT64_MIN_EXP__ (-1021)
#define __FLT64X_MIN_10_EXP__ (-4931)
#define __LDBL_HAS_QUIET_NAN__ 1
#define __cpp_return_type_deduction 201304L
#define __FLT16_MIN_EXP__ (-13)
#define __FLT64_MANT_DIG__ 53
#define __FLT64X_MANT_DIG__ 64
#define __BFLT16_DIG__ 2
#define __GNUC__ 13
#define __GXX_RTTI 1
#define __pie__ 2
#define __MMX__ 1
#define __FLT_HAS_DENORM__ 1
#define __SIZEOF_LONG_DOUBLE__ 16
#define __BIGGEST_ALIGNMENT__ 16
#define __STDC_UTF_16__ 1
#define __FLT64_MAX_10_EXP__ 308
#define __BFLT16_IS_IEC_60559__ 0
#define __FLT16_MAX_10_EXP__ 4
#define __cpp_delegating_constructors 200604L
#define __DBL_MAX__ double(1.79769313486231570814527423731704357e+308L)
#define __cpp_raw_strings 200710L
#define __INT_FAST32_MAX__ 0x7fffffffffffffffL
#define __DBL_HAS_INFINITY__ 1
#define __INT64_MAX__ 0x7fffffffffffffffL
#define __SIZEOF_FLOAT__ 4
#define __HAVE_SPECULATION_SAFE_VALUE 1
#define __cpp_fold_expressions 201603L
#define __DEC32_MIN_EXP__ (-94)
#define __INTPTR_WIDTH__ 64
#define __UINT_LEAST32_MAX__ 0xffffffffU
#define __FLT32X_HAS_DENORM__ 1
#define __INT_FAST16_TYPE__ long int
#define __MMX_WITH_SSE__ 1
#define __LDBL_HAS_DENORM__ 1
#define __SEG_GS 1
#define __BFLT16_EPSILON__ 7.81250000000000000000000000000000000e-3BF16
#define __cplusplus 201703L
#define __cpp_ref_qualifiers 200710L
#define __DEC32_MIN__ 1E-95DF
#define __DEPRECATED 1
#define __cpp_rvalue_references 200610L
#define __DBL_MAX_EXP__ 1024
#define __WCHAR_WIDTH__ 32
#define __FLT32_MAX__ 3.40282346638528859811704183484516925e+38F32
#define __DEC128_EPSILON__ 1E-33DL
#define __FLT16_DECIMAL_DIG__ 5
#define __SSE2_MATH__ 1
#define __ATOMIC_HLE_RELEASE 131072
#define __PTRDIFF_MAX__ 0x7fffffffffffffffL
#define __amd64 1
#define __ATOMIC_HLE_ACQUIRE 65536
#define __GNUG__ 13
#define __LONG_LONG_MAX__ 0x7fffffffffffffffLL
#define __SIZEOF_SIZE_T__ 8
#define __BFLT16_HAS_INFINITY__ 1
#define __FLT64X_MIN_EXP__ (-16381)
#define __SIZEOF_WINT_T__ 4
#define __FLT32X_DIG__ 15
#define __LONG_LONG_WIDTH__ 64
#define __cpp_initializer_lists 200806L
#define __FLT32_MAX_EXP__ 128
#define __cpp_hex_float 201603L
#define __GXX_ABI_VERSION 1018
#define __FLT_MIN_EXP__ (-125)
#define __GCC_HAVE_DWARF2_CFI_ASM 1
#define __x86_64 1
#define __cpp_lambdas 200907L
#define __INT_FAST64_TYPE__ long int
#define __BFLT16_MAX__ 3.38953138925153547590470800371487867e+38BF16
#define __FLT64_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F64
#define __cpp_template_auto 201606L
#define __FLT16_DENORM_MIN__ 5.96046447753906250000000000000000000e-8F16
#define __FLT128_EPSILON__ 1.92592994438723585305597794258492732e-34F128
#define __FLT64X_NORM_MAX__ 1.18973149535723176502126385303097021e+4932F64x
#define __SIZEOF_POINTER__ 8
#define __SIZE_TYPE__ long unsigned int
#define __LP64__ 1
#define __DBL_HAS_QUIET_NAN__ 1
#define __FLT32X_EPSILON__ 2.22044604925031308084726333618164062e-16F32x
#define __LDBL_MAX_EXP__ 16384
#define __DECIMAL_BID_FORMAT__ 1
#define __FLT64_MIN_10_EXP__ (-307)
#define __FLT16_MIN_10_EXP__ (-4)
#define __FLT64X_DECIMAL_DIG__ 21
#define __DEC128_MIN__ 1E-6143DL
#define __REGISTER_PREFIX__
#define __UINT16_MAX__ 0xffff
#define __FLT128_HAS_INFINITY__ 1
#define __FLT32_MIN__ 1.17549435082228750796873653722224568e-38F32
#define __UINT8_TYPE__ unsigned char
#define __FLT_DIG__ 6
#define __DEC_EVAL_METHOD__ 2
#define __FLT_MANT_DIG__ 24
#define __LDBL_DECIMAL_DIG__ 21
#define __VERSION__ "13.1.1 20230429"
#define __UINT64_C(c) c ## UL
#define __cpp_unicode_characters 201411L
#define _STDC_PREDEF_H 1
#define __INT_LEAST32_MAX__ 0x7fffffff
#define __GCC_ATOMIC_INT_LOCK_FREE 2
#define __FLT128_MAX_EXP__ 16384
#define __FLT32_MANT_DIG__ 24
#define __FLOAT_WORD_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __FLT32X_MIN_EXP__ (-1021)
#define __STDC_IEC_60559_COMPLEX__ 201404L
#define __cpp_aggregate_bases 201603L
#define __BFLT16_MIN__ 1.17549435082228750796873653722224568e-38BF16
#define __FLT128_HAS_DENORM__ 1
#define __FLT32_DECIMAL_DIG__ 9
#define __FLT128_DIG__ 33
#define __INT32_C(c) c
#define __DEC64_EPSILON__ 1E-15DD
#define __ORDER_PDP_ENDIAN__ 3412
#define __DEC128_MIN_EXP__ (-6142)
#define __DEC128_MAX__ 9.999999999999999999999999999999999E6144DL
#define __INT_FAST32_TYPE__ long int
#define __UINT_LEAST16_TYPE__ short unsigned int
#define __DEC128_MAX_EXP__ 6145
#define unix 1
#define __DBL_HAS_DENORM__ 1
#define __cpp_rtti 199711L
#define __UINT64_MAX__ 0xffffffffffffffffUL
#define __FLT_IS_IEC_60559__ 1
#define __GNUC_WIDE_EXECUTION_CHARSET_NAME "UTF-32LE"
#define __FLT64X_DIG__ 18
#define __INT8_TYPE__ signed char
#define __cpp_digit_separators 201309L
#define __ELF__ 1
#define __GCC_ASM_FLAG_OUTPUTS__ 1
#define __UINT32_TYPE__ unsigned int
#define __BFLT16_HAS_QUIET_NAN__ 1
#define __FLT_RADIX__ 2
#define __INT_LEAST16_TYPE__ short int
#define __LDBL_EPSILON__ 1.08420217248550443400745280086994171e-19L
#define __UINTMAX_C(c) c ## UL
#define __FLT16_DIG__ 3
#define __k8 1
#define __FLT32X_MIN__ 2.22507385850720138309023271733240406e-308F32x
#define __SIG_ATOMIC_MAX__ 0x7fffffff
#define __cpp_constexpr 201603L
#define __GCC_ATOMIC_WCHAR_T_LOCK_FREE 2
#define __USER_LABEL_PREFIX__
#define __STDC_IEC_60559_BFP__ 201404L
#define __SIZEOF_PTRDIFF_T__ 8
#define __FLT64X_HAS_INFINITY__ 1
#define __SIZEOF_LONG__ 8
#define __LDBL_DIG__ 18
#define __FLT64_IS_IEC_60559__ 1
#define __x86_64__ 1
#define __FLT16_IS_IEC_60559__ 1
#define __FLT16_MAX_EXP__ 16
#define __DEC32_SUBNORMAL_MIN__ 0.000001E-95DF
#define __INT_FAST16_MAX__ 0x7fffffffffffffffL
#define __GCC_CONSTRUCTIVE_SIZE 64
#define __FLT64_DIG__ 15
#define __UINT_FAST32_MAX__ 0xffffffffffffffffUL
#define __UINT_LEAST64_TYPE__ long unsigned int
#define __FLT16_EPSILON__ 9.76562500000000000000000000000000000e-4F16
#define __FLT_HAS_QUIET_NAN__ 1
#define __FLT_MAX_10_EXP__ 38
#define __LONG_MAX__ 0x7fffffffffffffffL
#define __FLT64X_HAS_DENORM__ 1
#define __DEC128_SUBNORMAL_MIN__ 0.000000000000000000000000000000001E-6143DL
#define __FLT_HAS_INFINITY__ 1
#define __GNUC_EXECUTION_CHARSET_NAME "UTF-8"
#define __cpp_unicode_literals 200710L
#define __UINT_FAST16_TYPE__ long unsigned int
#define __DEC64_MAX__ 9.999999999999999E384DD
#define __INT_FAST32_WIDTH__ 64
#define __CHAR16_TYPE__ short unsigned int
#define __PRAGMA_REDEFINE_EXTNAME 1
#define __SIZE_WIDTH__ 64
#define __SEG_FS 1
#define __INT_LEAST16_MAX__ 0x7fff
#define __FLT16_NORM_MAX__ 6.55040000000000000000000000000000000e+4F16
#define __DEC64_MANT_DIG__ 16
#define __FLT32_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F32
#define __SIG_ATOMIC_WIDTH__ 32
#define __INT_LEAST64_TYPE__ long int
#define __INT16_TYPE__ short int
#define __INT_LEAST8_TYPE__ signed char
#define __FLT16_MAX__ 6.55040000000000000000000000000000000e+4F16
#define __FLT128_MIN__ 3.36210314311209350626267781732175260e-4932F128
#define __cpp_structured_bindings 201606L
#define __SIZEOF_INT__ 4
#define __DEC32_MAX_EXP__ 97
#define __INT_FAST8_MAX__ 0x7f
#define __FLT128_MAX__ 1.18973149535723176508575932662800702e+4932F128
#define __INTPTR_MAX__ 0x7fffffffffffffffL
#define __cpp_sized_deallocation 201309L
#define __cpp_guaranteed_copy_elision 201606L
#define linux 1
#define __FLT64_HAS_QUIET_NAN__ 1
#define __FLT32_MIN_10_EXP__ (-37)
#define __EXCEPTIONS 1
#define __UINT16_C(c) c
#define __PTRDIFF_WIDTH__ 64
#define __LDBL_MANT_DIG__ 64
#define __cpp_range_based_for 201603L
#define __INT_FAST16_WIDTH__ 64
#define __FLT64_HAS_INFINITY__ 1
#define __FLT64X_MAX__ 1.18973149535723176502126385303097021e+4932F64x
#define __FLT16_HAS_INFINITY__ 1
#define __STDCPP_DEFAULT_NEW_ALIGNMENT__ 16
#define __SIG_ATOMIC_MIN__ (-__SIG_ATOMIC_MAX__ - 1)
#define __code_model_small__ 1
#define __GCC_ATOMIC_LONG_LOCK_FREE 2
#define __cpp_nontype_template_args 201411L
#define __DEC32_MANT_DIG__ 7
#define __k8__ 1
#define __INTPTR_TYPE__ long int
#define __UINT16_TYPE__ short unsigned int
#define __WCHAR_TYPE__ int
#define __pic__ 2
#define __UINTPTR_MAX__ 0xffffffffffffffffUL
#define __INT_FAST64_WIDTH__ 64
#define __cpp_decltype 200707L
#define __INT_FAST64_MAX__ 0x7fffffffffffffffL
#define __GCC_ATOMIC_TEST_AND_SET_TRUEVAL 1
#define __FLT_NORM_MAX__ 3.40282346638528859811704183484516925e+38F
#define __FLT32_HAS_INFINITY__ 1
#define __FLT64X_MAX_EXP__ 16384
#define __UINT_FAST64_TYPE__ long unsigned int
#define __cpp_inline_variables 201606L
#define __BFLT16_MIN_EXP__ (-125)
#define __INT_MAX__ 0x7fffffff
#define __linux__ 1
#define __INT64_TYPE__ long int
#define __FLT_MAX_EXP__ 128
#define __ORDER_BIG_ENDIAN__ 4321
#define __DBL_MANT_DIG__ 53
#define __cpp_inheriting_constructors 201511L
#define __SIZEOF_FLOAT128__ 16
#define __BFLT16_MANT_DIG__ 8
#define __DEC64_MIN__ 1E-383DD
#define __WINT_TYPE__ unsigned int
#define __UINT_LEAST32_TYPE__ unsigned int
#define __SIZEOF_SHORT__ 2
#define __FLT32_NORM_MAX__ 3.40282346638528859811704183484516925e+38F32
#define __SSE__ 1
#define __LDBL_MIN_EXP__ (-16381)
#define __FLT64_MAX__ 1.79769313486231570814527423731704357e+308F64
#define __amd64__ 1
#define __WINT_WIDTH__ 32
#define __INT_LEAST64_WIDTH__ 64
#define __FLT32X_MAX_10_EXP__ 308
#define __cpp_namespace_attributes 201411L
#define __SIZEOF_INT128__ 16
#define __FLT16_MIN__ 6.10351562500000000000000000000000000e-5F16
#define __FLT64X_IS_IEC_60559__ 1
#define __LDBL_MAX_10_EXP__ 4932
#define __ATOMIC_RELAXED 0
#define __DBL_EPSILON__ double(2.22044604925031308084726333618164062e-16L)
#define __INT_LEAST32_TYPE__ int
#define _LP64 1
#define __UINT8_C(c) c
#define __FLT64_MAX_EXP__ 1024
#define __SIZEOF_WCHAR_T__ 4
#define __GNUC_PATCHLEVEL__ 1
#define __FLT128_NORM_MAX__ 1.18973149535723176508575932662800702e+4932F128
#define __FLT64_NORM_MAX__ 1.79769313486231570814527423731704357e+308F64
#define __FLT128_HAS_QUIET_NAN__ 1
#define __INTMAX_MAX__ 0x7fffffffffffffffL
#define __INT_FAST8_TYPE__ signed char
#define __FLT64X_MIN__ 3.36210314311209350626267781732175260e-4932F64x
#define __STDCPP_THREADS__ 1
#define __BFLT16_HAS_DENORM__ 1
#define __GNUC_STDC_INLINE__ 1
#define __FLT64_HAS_DENORM__ 1
#define __FLT32_EPSILON__ 1.19209289550781250000000000000000000e-7F32
#define __FLT16_HAS_DENORM__ 1
#define __DBL_DECIMAL_DIG__ 17
#define __STDC_UTF_32__ 1
#define __INT_FAST8_WIDTH__ 8
#define __FXSR__ 1
#define __FLT32X_MAX__ 1.79769313486231570814527423731704357e+308F32x
#define __DBL_NORM_MAX__ double(1.79769313486231570814527423731704357e+308L)
#define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
#define __GCC_DESTRUCTIVE_SIZE 64
#define __INTMAX_WIDTH__ 64
#define __cpp_runtime_arrays 198712L
#define __FLT32_DIG__ 6
#define __UINT64_TYPE__ long unsigned int
#define __UINT32_C(c) c ## U
#define __cpp_alias_templates 200704L
#define __FLT_DENORM_MIN__ 1.40129846432481707092372958328991613e-45F
#define __FLT128_IS_IEC_60559__ 1
#define __INT8_MAX__ 0x7f
#define __LONG_WIDTH__ 64
#define __DBL_MIN__ double(2.22507385850720138309023271733240406e-308L)
#define __PIC__ 2
#define __INT32_MAX__ 0x7fffffff
#define __UINT_FAST32_TYPE__ long unsigned int
#define __FLT16_MANT_DIG__ 11
#define __FLT32X_NORM_MAX__ 1.79769313486231570814527423731704357e+308F32x
#define __CHAR32_TYPE__ unsigned int
#define __FLT_MAX__ 3.40282346638528859811704183484516925e+38F
#define __SSE2__ 1
#define __cpp_deduction_guides 201703L
#define __BFLT16_NORM_MAX__ 3.38953138925153547590470800371487867e+38BF16
#define __INT32_TYPE__ int
#define __SIZEOF_DOUBLE__ 8
#define __cpp_exceptions 199711L
#define __FLT_MIN_10_EXP__ (-37)
#define __FLT64_MIN__ 2.22507385850720138309023271733240406e-308F64
#define __INT_LEAST32_WIDTH__ 32
#define __INTMAX_TYPE__ long int
#define __GLIBCXX_BITSIZE_INT_N_0 128
#define __FLT32X_HAS_QUIET_NAN__ 1
#define __ATOMIC_CONSUME 1
#define __GNUC_MINOR__ 1
#define __GLIBCXX_TYPE_INT_N_0 __int128
#define __UINTMAX_MAX__ 0xffffffffffffffffUL
#define __PIE__ 2
#define __FLT32X_DENORM_MIN__ 4.94065645841246544176568792868221372e-324F32x
#define __cpp_template_template_args 201611L
#define __DBL_MAX_10_EXP__ 308
#define __LDBL_DENORM_MIN__ 3.64519953188247460252840593361941982e-4951L
#define __INT16_C(c) c
#define __STDC__ 1
#define __PTRDIFF_TYPE__ long int
#define __FLT32X_MIN_10_EXP__ (-307)
#define __UINTPTR_TYPE__ long unsigned int
#define __DEC64_SUBNORMAL_MIN__ 0.000000000000001E-383DD
#define __DEC128_MANT_DIG__ 34
#define __LDBL_MIN_10_EXP__ (-4931)
#define __cpp_generic_lambdas 201304L
#define __SSE_MATH__ 1
#define __SIZEOF_LONG_LONG__ 8
#define __cpp_user_defined_literals 200809L
#define __FLT128_DECIMAL_DIG__ 36
#define __GCC_ATOMIC_LLONG_LOCK_FREE 2
#define __FLT32_HAS_QUIET_NAN__ 1
#define __FLT_DECIMAL_DIG__ 9
#define __UINT_FAST16_MAX__ 0xffffffffffffffffUL
#define __LDBL_NORM_MAX__ 1.18973149535723176502126385303097021e+4932L
#define __GCC_ATOMIC_SHORT_LOCK_FREE 2
#define __SIZE_MAX__ 0xffffffffffffffffUL
#define __UINT_FAST8_TYPE__ unsigned char
#define _GNU_SOURCE 1
#define __cpp_init_captures 201304L
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_RELEASE 3

View file

@ -1,79 +0,0 @@
#include "opglwidget.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
void OPGLWidget::initializeGL() {
glClearDepth(1.0f);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
GLfloat light_array[] = {0.4, 0.4, 0.4, 0.4};
GLfloat light_position[] = {10.0, 20.0, 10.0, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_array);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_array);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_array);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
obj.load_mtl("untitled.mtl");
obj.load_obj("untitled.obj");
}
void OPGLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
reorient();
glPolygonMode(GL_FRONT, GL_FILL);
glBegin(GL_TRIANGLES);
for (int i = 0; i < obj.faces.size(); i++) {
Material* mtl_ptr = obj.faces[i].mtl;
if (mtl_idx != mtl_ptr->idx) {
glMaterialfv(GL_FRONT, GL_AMBIENT, mtl_ptr -> ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mtl_ptr -> diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mtl_ptr -> specular);
glMaterialf(GL_FRONT, GL_SHININESS, {128.0f});
mtl_idx =mtl_ptr->idx;
};
for (int j = 0; j < 3; j++) {
glVertex3fv(obj.faces[i].vertices[j] -> pos);
glNormal3fv(obj.faces[i].normals[j] -> dir);
};
};
glEnd();
glFlush();
update();
}
void OPGLWidget::reorient() {
GLfloat s[] = {-f[2], 0, f[0]};
float s_mag = pow(pow(s[0], 2) + pow(s[1], 2) + pow(s[2], 2), 0.5);
GLfloat u[] = {(s[1] * f[2] - s[2] * f[1]) / s_mag, -(s[0] * f[2] - s[2] * f[0]) / s_mag, (s[0] * f[1] - s[1] * f[0]) / s_mag};
const GLfloat m[] = {s[0], u[0], -f[0], 0, s[1], u[1], -f[1], 0, s[2], u[2], -f[2], 0, 0, 0, 0, 1};
glMultMatrixf(m);
glTranslatef(-loc[0], -loc[1], -loc[2]);
}
void OPGLWidget::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect = w / float(h);
float top = 0.2f * tan(M_PI / 8);
float right = 0.2f * tan(M_PI / 8) * aspect;
glFrustum(-right, right, -top, top, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
void OPGLWidget::update_camera() {
for (int i = 0; i < 3; i++) {
loc[i] += vel[i];
};
}

View file

@ -1,22 +0,0 @@
#include <QtWidgets/QOpenGLWidget>
#include "obj.h"
class OPGLWidget : public QOpenGLWidget
{
Q_OBJECT
public:
OPGLWidget(QWidget *parent) : QOpenGLWidget(parent) {}
public slots:
void paintGL();
void update_camera();
protected:
void initializeGL();
void resizeGL(int w, int h);
void reorient();
int mtl_idx = -1;
float loc[3] = {0, 0, 10};
float f[3] = {0, 0, -1};
float vel[3] = {0, 0, -0.01};
ObjectLoader obj;
};

43
src/main.cpp Normal file
View file

@ -0,0 +1,43 @@
#include <QtWidgets/QApplication>
#include <QMainWindow>
#include <QTimer>
#include "include/ui_mainwindow.h"
#include <QCommandLineParser>
#include <QCommandLineOption>
// main loop
int main(int argc, char **argv) {
QApplication app(argc, argv);
QCommandLineParser parser;
// pass in files as -m and -o
QCommandLineOption mtl_filepath_opt({"m", "material"}, "Material file path, required", "path");
QCommandLineOption obj_filepath_opt({"o", "object"}, "Object file path, required", "path");
parser.addHelpOption();
parser.addOption(mtl_filepath_opt);
parser.addOption(obj_filepath_opt);
parser.process(app);
QString mtl_filepath = parser.value(mtl_filepath_opt);
QString obj_filepath = parser.value(obj_filepath_opt);
if (mtl_filepath.isEmpty() || obj_filepath.isEmpty()) {
return 1;
}
QMainWindow w;
Ui::MainWindow ui;
ui.setupUi(&w);
// parse obj and mtl files
ui.openGLWidget->obj.load_mtl(mtl_filepath.toStdString());
ui.openGLWidget->obj.load_obj(obj_filepath.toStdString());
// timers for drawing and movement loops
QTimer timer_draw;
QTimer timer_cam;
w.connect(&timer_draw, SIGNAL(timeout()), ui.openGLWidget, SLOT(paintGL()));
w.connect(&timer_cam, SIGNAL(timeout()), ui.openGLWidget, SLOT(update_camera()));
// update every 16ms
timer_draw.start(16);
timer_cam.start(16);
w.show();
return app.exec();
}

View file

@ -1,15 +1,20 @@
#include "obj.h" #include "include/obj.h"
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <string> #include <string>
#include <cstring> #include <cstring>
#include <regex> #include <regex>
// .mtl file load and parse
void ObjectLoader::load_mtl(string filename) { void ObjectLoader::load_mtl(string filename) {
string tmp; string tmp;
ifstream f(filename); ifstream f(filename); // open file
int mtl_idx = -1; int mtl_idx = -1; // init index outside of valid range
while (getline(f, tmp)) { while (getline(f, tmp)) {
// if line defines a new material
// create new and set its name
// following lines will define ambient, spec, diffuse info for
// the newly defined material
if (tmp.rfind("newmtl", 0) == 0) { if (tmp.rfind("newmtl", 0) == 0) {
mtl_idx += 1; mtl_idx += 1;
mtls.push_back(*(new Material)); mtls.push_back(*(new Material));
@ -29,23 +34,30 @@ void ObjectLoader::load_mtl(string filename) {
default: default:
continue; continue;
}; };
// parse syntax
// eg; Kd 0.2 0.2 0.2
// delim by space, split and parse value
char delim = ' '; char delim = ' ';
char *token = strtok(const_cast<char*>(tmp.c_str()), &delim); char *token = strtok(const_cast<char*>(tmp.c_str()), &delim);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
token = strtok(NULL, &delim); token = strtok(NULL, &delim);
target_list[i] = atof(token); target_list[i] = atof(token);
}; };
// set alpha val since blender doesn't output it
target_list[3] = 1.0f; target_list[3] = 1.0f;
}; };
}; };
}; };
// .obj file load and parsing
// only supports single object files
void ObjectLoader::load_obj(string filename) { void ObjectLoader::load_obj(string filename) {
string tmp; string tmp;
ifstream f(filename); ifstream f(filename);
while (getline(f, tmp)) { while (getline(f, tmp)) {
Material* mtl_ptr; Material* mtl_ptr;
if (tmp[0] == 'v') { if (tmp[0] == 'v') {
// if vertex (v) or vertex normal (vn), create new vertex struct
float* target_list; float* target_list;
switch (tmp[1]) { switch (tmp[1]) {
case ' ': case ' ':
@ -59,6 +71,11 @@ void ObjectLoader::load_obj(string filename) {
default: default:
continue; continue;
}; };
// same parsing as material values above
// something breaks here somehow on first run i think
// no clue if its pointer wierdness or something with
// the files but vector floats get borked
// works perfectly fine on next runs so... eh?
char delim = ' '; char delim = ' ';
char *token = strtok(const_cast<char*>(tmp.c_str()), &delim); char *token = strtok(const_cast<char*>(tmp.c_str()), &delim);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
@ -67,8 +84,14 @@ void ObjectLoader::load_obj(string filename) {
}; };
} else if (tmp.rfind("usemtl", 0) == 0) { } else if (tmp.rfind("usemtl", 0) == 0) {
// if line declares material scope, point the pointer to said material
mtl_ptr = get_mtl_ptr(tmp.substr(tmp.find(' ') + 1)); mtl_ptr = get_mtl_ptr(tmp.substr(tmp.find(' ') + 1));
} else if (tmp[0] == 'f') { } else if (tmp[0] == 'f') {
// face declared as set of v/vt/vn indexes
// currently ignoring vt and only using files without any vt exported
// (like generic meshes with materials)
// also only handles triangle mesh objects
// assign it a metal and its corresponding vertexes and normals
faces.push_back(*(new Face)); faces.push_back(*(new Face));
faces.back().mtl = mtl_ptr; faces.back().mtl = mtl_ptr;
regex re("f (\\d*)//(\\d*) (\\d*)//(\\d*) (\\d*)//(\\d*)"); regex re("f (\\d*)//(\\d*) (\\d*)//(\\d*) (\\d*)//(\\d*)");
@ -85,10 +108,13 @@ void ObjectLoader::load_obj(string filename) {
}; };
}; };
// just finds the pointer to the given material from its string
Material* ObjectLoader::get_mtl_ptr(string mtl_name) { Material* ObjectLoader::get_mtl_ptr(string mtl_name) {
for (int i = 0; i < mtls.size(); i++) { for (size_t i = 0; i < mtls.size(); i++) {
if (mtls[i].name == mtl_name) { if (mtls[i].name == mtl_name) {
return &(mtls[i]); return &(mtls[i]);
}; };
}; };
}; }

235
src/opglwidget.cpp Normal file
View file

@ -0,0 +1,235 @@
#include "include/opglwidget.h"
#include <GL/gl.h>
#include <GL/glu.h>
#include <math.h>
#include <QKeyEvent>
// probably should have learned OpenGL and rendering
// first, not even going to pretend to know what the first half
// does
void OPGLWidget::initializeGL() {
glClearDepth(1.0f);
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
// values here largely just copied from default light object in blender
GLfloat light_ambient[] = {0.0, 0.0, 0.0, 1.0};
GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light_specular[] = {0.0, 0.5, 0.5, 0.2};
GLfloat light_position[] = {4.0, 1.0, 6.0, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
}
// paint loop
void OPGLWidget::paintGL() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
reorient(); // implementation of gluPerspective to shift camera perspective
// mostly just because I could not figure out how to get GLU included properly
glShadeModel(GL_SMOOTH);
glPolygonMode(GL_FRONT, GL_FILL);
glBegin(GL_TRIANGLES);
// for each face, check if its material is different from the one
// currently selected in mtl_idx. if different, populate new values and move idx
// then draw each vertex and normal
for (size_t i = 0; i < obj.faces.size(); i++) {
Material* mtl_ptr = obj.faces[i].mtl;
if (mtl_idx != mtl_ptr->idx) {
glMaterialfv(GL_FRONT, GL_AMBIENT, mtl_ptr -> ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, mtl_ptr -> diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, mtl_ptr -> specular);
glMaterialf(GL_FRONT, GL_SHININESS, {128.0f});
mtl_idx =mtl_ptr->idx;
};
for (int j = 0; j < 3; j++) {
glVertex3fv(obj.faces[i].vertices[j] -> pos);
glNormal3fv(obj.faces[i].normals[j] -> dir);
};
};
glEnd();
glFlush();
update();
}
// cursed implementation of gluPerscpective here: https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml
void OPGLWidget::reorient() {
GLfloat s[] = {-f[2], 0, f[0]};
float s_mag = pow(pow(s[0], 2) + pow(s[1], 2) + pow(s[2], 2), 0.5);
GLfloat u[] = {(s[1] * f[2] - s[2] * f[1]) / s_mag, -(s[0] * f[2] - s[2] * f[0]) / s_mag, (s[0] * f[1] - s[1] * f[0]) / s_mag};
const GLfloat m[] = {s[0], u[0], -f[0], 0, s[1], u[1], -f[1], 0, s[2], u[2], -f[2], 0, 0, 0, 0, 1};
glMultMatrixf(m);
glTranslatef(-loc[0], -loc[1], -loc[2]);
}
// window resize
void OPGLWidget::resizeGL(int w, int h) {
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
float aspect = w / float(h);
float top = 0.2f * tan(M_PI / 8);
float right = 0.2f * tan(M_PI / 8) * aspect;
glFrustum(-right, right, -top, top, 0.1f, 100.0f);
glMatrixMode(GL_MODELVIEW);
}
// camera update, movement simulation
void OPGLWidget::update_camera() {
// update location in direction of velocity by 1/100 of speed each tick
for (int i = 0; i < 3; i++) {
loc[i] += vel[i] * speed/100.0f;
};
// cursed, but its here, update velocity by corresponding key
if (key_states[0]) {
for (int i = 0; i < 3; i++) {
vel[i] += f[i];
}
};
if (key_states[1]) {
for (int i = 0; i < 3; i++) {
vel[i] -= f[i];
}
};
if (key_states[2]) {
for (int i = 0; i < 3; i++) {
vel[i] += right[i];
}
};
if (key_states[3]) {
for (int i = 0; i < 3; i++) {
vel[i] -= right[i];
}
};
if (key_states[4]) {
for (int i = 0; i < 3; i++) {
vel[i] += up[i];
}
};
if (key_states[5]) {
for (int i = 0; i < 3; i++) {
vel[i] -= up[i];
}
};
speed = pow(pow(vel[0], 2) + pow(vel[1], 2) + pow(vel[2], 2), 0.5);
// speed limit, update vel if over
if (speed > 2) {
for (int i = 0; i < 3; i++) {
vel[i] = vel[i] / speed;
}
}
// if no key pressed, decay speed until threshold then stop
bool allFalse = true;
for (int i = 0; i < 6; i++) {
if (key_states[i]) {
allFalse = false;
break;
}
}
if (allFalse) {
for (int i = 0; i < 3; i++) {
if (speed > 0.1f) {
vel[i] -= vel[i] * speed / 10.0f;
} else {
vel[i] = 0.0f;
}
}
}
}
// key mappings
void OPGLWidget::keyPressEvent(QKeyEvent *event) {
switch (event -> key()) {
case Qt::Key_W:
key_states[0] = true;
break;
case Qt::Key_S:
key_states[1] = true;
break;
case Qt::Key_D:
key_states[2] = true;
break;
case Qt::Key_A:
key_states[3] = true;
break;
case Qt::Key_Space:
key_states[4] = true;
break;
case Qt::Key_Control:
key_states[5] = true;
break;
};
}
void OPGLWidget::keyReleaseEvent(QKeyEvent *event) {
switch (event -> key()) {
case Qt::Key_W:
key_states[0] = false;
break;
case Qt::Key_S:
key_states[1] = false;
break;
case Qt::Key_D:
key_states[2] = false;
break;
case Qt::Key_A:
key_states[3] = false;
break;
case Qt::Key_Space:
key_states[4] = false;
break;
case Qt::Key_Control:
key_states[5] = false;
break;
};
}
// camera panning only happens on drag, also makes it so I don't
// have to bother with mouse capture and other wierdness from i3 tiling
void OPGLWidget::mousePressEvent(QMouseEvent *event) {
setMouseTracking(true);
mouse_loc_old[0] = event -> x();
mouse_loc_old[1] = event -> y();
}
// stop tracking on release
void OPGLWidget::mouseReleaseEvent(QMouseEvent *event) {
setMouseTracking(false);
mouse_loc_old[0] = event -> x();
mouse_loc_old[1] = event -> y();
}
// actual camera panning implementation
void OPGLWidget::mouseMoveEvent(QMouseEvent *event) {
// calc a delta movement from old, then new -> old
float delta_x = event->x() - mouse_loc_old[0];
float delta_y = event->y() - mouse_loc_old[1];
mouse_loc_old[0] = event->x();
mouse_loc_old[1] = event->y();
// shift forward vector appropriately with movement
for (int i = 0; i < 3; i++) {
f[i] += right[i] * delta_x / 1000.0f;
f[i] -= up[i] * delta_y / 1000.0f;
}
// since up is static, cross product to find right, which is simply:
right[0] = -f[2];
right[2] = f[0];
// normalize forward and right
float F_mag = pow(pow(f[0], 2) + pow(f[1], 2) + pow(f[2], 2), 0.5);
float right_mag = pow(pow(right[0], 2) + pow(right[1], 2) + pow(right[2], 2), 0.5);
for (int i = 0; i < 3; i++) {
f[i] = f[i] / F_mag;
right[i] = right[i] / right_mag;
}
}