goat3d

annotate goatview/src/goatview.cc @ 75:76dea247f75c

in progress
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 08 May 2014 00:50:16 +0300
parents ab66cdabf6f2
children 9785847d52d4
rev   line source
nuclear@75 1 #include <GL/glu.h>
nuclear@73 2 #include "goatview.h"
nuclear@74 3 #include "goat3d.h"
nuclear@74 4
nuclear@74 5 goat3d *scene;
nuclear@75 6 QSettings *settings;
nuclear@75 7
nuclear@75 8 static long anim_time;
nuclear@75 9 static float cam_theta, cam_phi, cam_dist = 8;
nuclear@75 10
nuclear@73 11
nuclear@73 12 GoatView::GoatView()
nuclear@73 13 {
nuclear@73 14 make_menu();
nuclear@73 15 make_dock();
nuclear@73 16 make_center();
nuclear@73 17
nuclear@73 18 statusBar();
nuclear@73 19
nuclear@73 20 setWindowTitle("GoatView");
nuclear@75 21 resize(settings->value("main/size", QSize(1024, 768)).toSize());
nuclear@75 22 move(settings->value("main/pos", QPoint(100, 100)).toPoint());
nuclear@73 23 }
nuclear@73 24
nuclear@73 25 GoatView::~GoatView()
nuclear@73 26 {
nuclear@73 27 }
nuclear@73 28
nuclear@75 29 void GoatView::closeEvent(QCloseEvent *ev)
nuclear@75 30 {
nuclear@75 31 settings->setValue("main/size", size());
nuclear@75 32 settings->setValue("main/pos", pos());
nuclear@75 33 }
nuclear@75 34
nuclear@73 35 bool GoatView::make_menu()
nuclear@73 36 {
nuclear@73 37 QMenu *menu_file = menuBar()->addMenu("&File");
nuclear@73 38
nuclear@73 39 QAction *act_open_sce = new QAction("&Open Scene", this);
nuclear@73 40 act_open_sce->setShortcuts(QKeySequence::Open);
nuclear@73 41 connect(act_open_sce, &QAction::triggered, this, &GoatView::open_scene);
nuclear@73 42 menu_file->addAction(act_open_sce);
nuclear@73 43
nuclear@73 44 QAction *act_open_anm = new QAction("Open &Animation", this);
nuclear@73 45 connect(act_open_anm, &QAction::triggered, this, &GoatView::open_anim);
nuclear@73 46 menu_file->addAction(act_open_anm);
nuclear@73 47
nuclear@73 48 QAction *act_quit = new QAction("&Quit", this);
nuclear@73 49 act_quit->setShortcuts(QKeySequence::Quit);
nuclear@73 50 connect(act_quit, &QAction::triggered, [&](){qApp->quit();});
nuclear@73 51 menu_file->addAction(act_quit);
nuclear@73 52 return true;
nuclear@73 53 }
nuclear@73 54
nuclear@73 55 bool GoatView::make_dock()
nuclear@73 56 {
nuclear@73 57 // ---- side-dock ----
nuclear@73 58 QWidget *dock_cont = new QWidget;
nuclear@73 59 QVBoxLayout *dock_vbox = new QVBoxLayout;
nuclear@73 60 dock_cont->setLayout(dock_vbox);
nuclear@73 61
nuclear@73 62 QPushButton *bn_quit = new QPushButton("quit");
nuclear@73 63 dock_vbox->addWidget(bn_quit);
nuclear@73 64 connect(bn_quit, &QPushButton::clicked, [&](){qApp->quit();});
nuclear@73 65
nuclear@73 66 QDockWidget *dock = new QDockWidget("Scene graph", this);
nuclear@73 67 dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
nuclear@73 68 dock->setWidget(dock_cont);
nuclear@73 69 addDockWidget(Qt::LeftDockWidgetArea, dock);
nuclear@73 70
nuclear@73 71 // ---- bottom dock ----
nuclear@73 72 dock_cont = new QWidget;
nuclear@73 73 QHBoxLayout *dock_hbox = new QHBoxLayout;
nuclear@73 74 dock_cont->setLayout(dock_hbox);
nuclear@73 75
nuclear@73 76 QSlider *slider_time = new QSlider(Qt::Orientation::Horizontal);
nuclear@73 77 slider_time->setDisabled(true);
nuclear@73 78 dock_hbox->addWidget(slider_time);
nuclear@73 79
nuclear@73 80 dock = new QDockWidget("Animation", this);
nuclear@73 81 dock->setAllowedAreas(Qt::BottomDockWidgetArea);
nuclear@73 82 dock->setWidget(dock_cont);
nuclear@73 83 addDockWidget(Qt::BottomDockWidgetArea, dock);
nuclear@73 84
nuclear@73 85 return true;
nuclear@73 86 }
nuclear@73 87
nuclear@73 88 bool GoatView::make_center()
nuclear@73 89 {
nuclear@73 90 GoatViewport *vport = new GoatViewport;
nuclear@73 91 setCentralWidget(vport);
nuclear@73 92 return true;
nuclear@73 93 }
nuclear@73 94
nuclear@73 95 void GoatView::open_scene()
nuclear@73 96 {
nuclear@74 97 std::string fname = QFileDialog::getOpenFileName(this, "Open scene file", "",
nuclear@74 98 "Goat3D Scene (*.goatsce);;All Files (*)").toStdString();
nuclear@74 99 if(fname.empty()) {
nuclear@74 100 statusBar()->showMessage("Abort: No file selected!");
nuclear@74 101 return;
nuclear@74 102 }
nuclear@74 103
nuclear@74 104 if(scene) {
nuclear@74 105 goat3d_free(scene);
nuclear@74 106 }
nuclear@74 107
nuclear@74 108 statusBar()->showMessage("opening scene file");
nuclear@74 109 if(!(scene = goat3d_create()) || goat3d_load(scene, fname.c_str()) == -1) {
nuclear@74 110 statusBar()->showMessage("failed to load scene file");
nuclear@74 111 }
nuclear@73 112 }
nuclear@73 113
nuclear@73 114 void GoatView::open_anim()
nuclear@73 115 {
nuclear@73 116 statusBar()->showMessage("opening animation...");
nuclear@73 117 }
nuclear@73 118
nuclear@73 119
nuclear@73 120 // ---- OpenGL viewport ----
nuclear@73 121 GoatViewport::GoatViewport()
nuclear@73 122 : QGLWidget(QGLFormat(QGL::DepthBuffer))
nuclear@73 123 {
nuclear@73 124 }
nuclear@73 125
nuclear@73 126 GoatViewport::~GoatViewport()
nuclear@73 127 {
nuclear@73 128 }
nuclear@73 129
nuclear@73 130 QSize GoatViewport::sizeHint() const
nuclear@73 131 {
nuclear@73 132 return QSize(800, 600);
nuclear@73 133 }
nuclear@73 134
nuclear@73 135 void GoatViewport::initializeGL()
nuclear@73 136 {
nuclear@75 137 glClearColor(0.1, 0.1, 0.1, 1);
nuclear@73 138 }
nuclear@73 139
nuclear@73 140 void GoatViewport::resizeGL(int xsz, int ysz)
nuclear@73 141 {
nuclear@73 142 glViewport(0, 0, xsz, ysz);
nuclear@75 143 glMatrixMode(GL_PROJECTION);
nuclear@75 144 glLoadIdentity();
nuclear@75 145 gluPerspective(60.0, (float)xsz / (float)ysz, 0.5, 5000.0);
nuclear@73 146 }
nuclear@73 147
nuclear@75 148 static void draw_node(goat3d_node *node);
nuclear@75 149
nuclear@73 150 void GoatViewport::paintGL()
nuclear@73 151 {
nuclear@75 152 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
nuclear@75 153
nuclear@75 154 glMatrixMode(GL_MODELVIEW);
nuclear@75 155 glLoadIdentity();
nuclear@75 156 glTranslatef(0, 0, -cam_dist);
nuclear@75 157 glRotatef(cam_phi, 1, 0, 0);
nuclear@75 158 glRotatef(cam_theta, 0, 1, 0);
nuclear@75 159
nuclear@75 160 if(scene) {
nuclear@75 161 int node_count = goat3d_get_node_count(scene);
nuclear@75 162 for(int i=0; i<node_count; i++) {
nuclear@75 163 goat3d_node *node = goat3d_get_node(scene, i);
nuclear@75 164 draw_node(node);
nuclear@75 165 }
nuclear@75 166 }
nuclear@73 167 }
nuclear@75 168
nuclear@75 169 static void draw_node(goat3d_node *node)
nuclear@75 170 {
nuclear@75 171 float xform[16];
nuclear@75 172 goat3d_get_node_matrix(node, xform, anim_time);
nuclear@75 173 glMultMatrixf(xform);
nuclear@75 174
nuclear@75 175 if(goat3d_get_node_type(node) == GOAT3D_NODE_MESH) {
nuclear@75 176 goat3d_mesh *mesh = (goat3d_mesh*)goat3d_get_node_object(node);
nuclear@75 177
nuclear@75 178 int num_faces = goat3d_get_mesh_face_count(mesh);
nuclear@75 179 int num_verts = goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_VERTEX);
nuclear@75 180
nuclear@75 181 glEnableClientState(GL_VERTEX_ARRAY);
nuclear@75 182 glVertexPointer(3, GL_FLOAT, 0, goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_VERTEX));
nuclear@75 183
nuclear@75 184 float *data;
nuclear@75 185 if((data = (float*)goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_NORMAL))) {
nuclear@75 186 glEnableClientState(GL_NORMAL_ARRAY);
nuclear@75 187 glNormalPointer(GL_FLOAT, 0, data);
nuclear@75 188 }
nuclear@75 189 if((data = (float*)goat3d_get_mesh_attribs(mesh, GOAT3D_MESH_ATTR_TEXCOORD))) {
nuclear@75 190 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
nuclear@75 191 glTexCoordPointer(2, GL_FLOAT, 0, data);
nuclear@75 192 }
nuclear@75 193
nuclear@75 194 int *indices;
nuclear@75 195 if((indices = goat3d_get_mesh_faces(mesh))) {
nuclear@75 196 glDrawElements(GL_TRIANGLES, num_faces * 3, GL_UNSIGNED_INT, indices);
nuclear@75 197 } else {
nuclear@75 198 glDrawArrays(GL_TRIANGLES, 0, num_verts * 3);
nuclear@75 199 }
nuclear@75 200
nuclear@75 201 glDisableClientState(GL_VERTEX_ARRAY);
nuclear@75 202 glDisableClientState(GL_NORMAL_ARRAY);
nuclear@75 203 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
nuclear@75 204 }
nuclear@75 205
nuclear@75 206 int num_child = goat3d_get_node_child_count(node);
nuclear@75 207 for(int i=0; i<num_child; i++) {
nuclear@75 208 draw_node(goat3d_get_node_child(node, i));
nuclear@75 209 }
nuclear@75 210 }
nuclear@75 211
nuclear@75 212