goat3d
changeset 83:57e745dd13c2
almost working
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 12 May 2014 07:22:52 +0300 |
parents | 70b7c41a4f17 |
children | 022b13ed975b |
files | goatview/src/goatview.cc goatview/src/goatview.h src/goat3d.cc src/goat3d_readxml.cc |
diffstat | 4 files changed, 113 insertions(+), 23 deletions(-) [+] |
line diff
1.1 --- a/goatview/src/goatview.cc Sun May 11 22:04:54 2014 +0300 1.2 +++ b/goatview/src/goatview.cc Mon May 12 07:22:52 2014 +0300 1.3 @@ -17,30 +17,44 @@ 1.4 static float cam_theta, cam_phi, cam_dist = 8; 1.5 static float fov = 60.0; 1.6 static bool use_nodes = true; 1.7 +static bool use_lighting = true; 1.8 1.9 1.10 GoatView::GoatView() 1.11 { 1.12 glview = 0; 1.13 1.14 + QSettings *settings = new QSettings; 1.15 + resize(settings->value("main/size", QSize(1024, 768)).toSize()); 1.16 + move(settings->value("main/pos", QPoint(100, 100)).toPoint()); 1.17 + use_nodes = settings->value("use_nodes", true).toBool(); 1.18 + use_lighting = settings->value("use_lighting", true).toBool(); 1.19 + delete settings; 1.20 + 1.21 + make_center(); // must be first 1.22 make_menu(); 1.23 make_dock(); 1.24 - make_center(); 1.25 1.26 statusBar(); 1.27 1.28 setWindowTitle("GoatView"); 1.29 - 1.30 - QSettings *settings = new QSettings; 1.31 - resize(settings->value("main/size", QSize(1024, 768)).toSize()); 1.32 - move(settings->value("main/pos", QPoint(100, 100)).toPoint()); 1.33 - delete settings; 1.34 } 1.35 1.36 GoatView::~GoatView() 1.37 { 1.38 } 1.39 1.40 +void GoatView::closeEvent(QCloseEvent *ev) 1.41 +{ 1.42 + QSettings *settings = new QSettings; 1.43 + settings->setValue("main/size", size()); 1.44 + settings->setValue("main/pos", pos()); 1.45 + settings->setValue("use_nodes", use_nodes); 1.46 + settings->setValue("use_lighting", use_lighting); 1.47 + delete settings; 1.48 +} 1.49 + 1.50 + 1.51 bool GoatView::load_scene(const char *fname) 1.52 { 1.53 if(scene) { 1.54 @@ -53,7 +67,7 @@ 1.55 float bmin[3], bmax[3]; 1.56 if(goat3d_get_bounds(scene, bmin, bmax) != -1) { 1.57 float bsize = (Vector3(bmax[0], bmax[1], bmax[2]) - Vector3(bmin[0], bmin[1], bmin[2])).length(); 1.58 - cam_dist = bsize / tan(DEG_TO_RAD(fov) / 2.0) + bsize; 1.59 + cam_dist = bsize / tan(DEG_TO_RAD(fov) / 2.0); 1.60 printf("bounds size: %f, cam_dist: %f\n", bsize, cam_dist); 1.61 } 1.62 1.63 @@ -61,14 +75,6 @@ 1.64 return true; 1.65 } 1.66 1.67 -void GoatView::closeEvent(QCloseEvent *ev) 1.68 -{ 1.69 - QSettings *settings = new QSettings; 1.70 - settings->setValue("main/size", size()); 1.71 - settings->setValue("main/pos", pos()); 1.72 - delete settings; 1.73 -} 1.74 - 1.75 bool GoatView::make_menu() 1.76 { 1.77 // file menu 1.78 @@ -94,8 +100,22 @@ 1.79 QAction *act_use_nodes = new QAction("use nodes", this); 1.80 act_use_nodes->setCheckable(true); 1.81 act_use_nodes->setChecked(use_nodes); 1.82 - connect(act_use_nodes, &QAction::triggered, this, [&](){use_nodes = !use_nodes; glview->updateGL();}); 1.83 + connect(act_use_nodes, &QAction::triggered, this, 1.84 + [&](){ use_nodes = !use_nodes; glview->updateGL(); }); 1.85 menu_view->addAction(act_use_nodes); 1.86 + 1.87 + QAction *act_use_lighting = new QAction("lighting", this); 1.88 + act_use_lighting->setCheckable(true); 1.89 + act_use_lighting->setChecked(use_lighting); 1.90 + connect(act_use_lighting, &QAction::triggered, glview, &GoatViewport::toggle_lighting); 1.91 + menu_view->addAction(act_use_lighting); 1.92 + 1.93 + // help menu 1.94 + QMenu *menu_help = menuBar()->addMenu("&Help"); 1.95 + 1.96 + QAction *act_about = new QAction("&About", this); 1.97 + connect(act_about, &QAction::triggered, this, &GoatView::show_about); 1.98 + menu_help->addAction(act_about); 1.99 return true; 1.100 } 1.101 1.102 @@ -246,6 +266,13 @@ 1.103 1.104 glEnable(GL_DEPTH_TEST); 1.105 glEnable(GL_CULL_FACE); 1.106 + if(use_lighting) { 1.107 + glEnable(GL_LIGHTING); 1.108 + } 1.109 + glEnable(GL_LIGHT0); 1.110 + 1.111 + float ldir[] = {-1, 1, 2, 0}; 1.112 + glLightfv(GL_LIGHT0, GL_POSITION, ldir); 1.113 } 1.114 1.115 void GoatViewport::resizeGL(int xsz, int ysz) 1.116 @@ -272,7 +299,9 @@ 1.117 int node_count = goat3d_get_node_count(scene); 1.118 for(int i=0; i<node_count; i++) { 1.119 goat3d_node *node = goat3d_get_node(scene, i); 1.120 - draw_node(node); // only draw root nodes, the rest will be drawn recursively 1.121 + if(!goat3d_get_node_parent(node)) { 1.122 + draw_node(node); // only draw root nodes, the rest will be drawn recursively 1.123 + } 1.124 } 1.125 } else { 1.126 int mesh_count = goat3d_get_mesh_count(scene); 1.127 @@ -283,6 +312,17 @@ 1.128 } 1.129 } 1.130 1.131 +void GoatViewport::toggle_lighting() 1.132 +{ 1.133 + use_lighting = !use_lighting; 1.134 + if(use_lighting) { 1.135 + glEnable(GL_LIGHTING); 1.136 + } else { 1.137 + glDisable(GL_LIGHTING); 1.138 + } 1.139 + updateGL(); 1.140 +} 1.141 + 1.142 #ifndef GLEW_ARB_transpose_matrix 1.143 #error "GLEW_ARB_transpose_matrix undefined?" 1.144 #endif 1.145 @@ -301,16 +341,40 @@ 1.146 draw_mesh(mesh); 1.147 } 1.148 1.149 - /*int num_child = goat3d_get_node_child_count(node); 1.150 + int num_child = goat3d_get_node_child_count(node); 1.151 for(int i=0; i<num_child; i++) { 1.152 draw_node(goat3d_get_node_child(node, i)); 1.153 - }*/ 1.154 + } 1.155 1.156 glPopMatrix(); 1.157 } 1.158 1.159 static void draw_mesh(goat3d_mesh *mesh) 1.160 { 1.161 + static const float white[] = {1, 1, 1, 1}; 1.162 + static const float black[] = {0, 0, 0, 1}; 1.163 + 1.164 + const float *color; 1.165 + goat3d_material *mtl = goat3d_get_mesh_mtl(mesh); 1.166 + 1.167 + if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_DIFFUSE))) { 1.168 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color); 1.169 + } else { 1.170 + glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, white); 1.171 + } 1.172 + if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SPECULAR))) { 1.173 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, color); 1.174 + } else { 1.175 + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, black); 1.176 + } 1.177 + if(mtl && (color = goat3d_get_mtl_attrib(mtl, GOAT3D_MAT_ATTR_SHININESS))) { 1.178 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, color[0]); 1.179 + } else { 1.180 + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 60.0); 1.181 + } 1.182 + // TODO texture 1.183 + 1.184 + 1.185 int num_faces = goat3d_get_mesh_face_count(mesh); 1.186 int num_verts = goat3d_get_mesh_attrib_count(mesh, GOAT3D_MESH_ATTR_VERTEX); 1.187 1.188 @@ -370,3 +434,25 @@ 1.189 } 1.190 updateGL(); 1.191 } 1.192 + 1.193 +static const char *about_str = 1.194 + "GoatView - Goat3D scene file viewer<br>" 1.195 + "Copyright (C) 2014 John Tsiombikas <<a href=\"mailto:nuclear@mutantstargoat.com\">nuclear@mutantstargoat.com</a>><br>" 1.196 + "<br>" 1.197 + "This program is free software: you can redistribute it and/or modify<br>" 1.198 + "it under the terms of the GNU General Public License as published by<br>" 1.199 + "the Free Software Foundation, either version 3 of the License, or<br>" 1.200 + "(at your option) any later version.<br>" 1.201 + "<br>" 1.202 + "This program is distributed in the hope that it will be useful,<br>" 1.203 + "but WITHOUT ANY WARRANTY; without even the implied warranty of<br>" 1.204 + "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>" 1.205 + "GNU General Public License for more details.<br>" 1.206 + "<br>" 1.207 + "You should have received a copy of the GNU General Public License<br>" 1.208 + "along with this program. If not, see <a href=\"http://www.gnu.org/licenses/gpl\">http://www.gnu.org/licenses/gpl</a>."; 1.209 + 1.210 +void GoatView::show_about() 1.211 +{ 1.212 + QMessageBox::information(this, "About GoatView", about_str); 1.213 +}
2.1 --- a/goatview/src/goatview.h Sun May 11 22:04:54 2014 +0300 2.2 +++ b/goatview/src/goatview.h Mon May 12 07:22:52 2014 +0300 2.3 @@ -11,10 +11,10 @@ 2.4 class GoatViewport; 2.5 2.6 class GoatView : public QMainWindow { 2.7 +private: 2.8 Q_OBJECT 2.9 -private: 2.10 + 2.11 GoatViewport *glview; 2.12 - QStandardItemModel *sgmodel; // scene graph model 2.13 QTreeWidget *scntree; 2.14 2.15 void closeEvent(QCloseEvent *ev); 2.16 @@ -31,6 +31,8 @@ 2.17 ~GoatView(); 2.18 2.19 bool load_scene(const char *fname); 2.20 + 2.21 + void show_about(); 2.22 }; 2.23 2.24 class GoatViewport : public QGLWidget { 2.25 @@ -50,6 +52,8 @@ 2.26 void resizeGL(int xsz, int ysz); 2.27 void paintGL(); 2.28 2.29 + void toggle_lighting(); 2.30 + 2.31 void mousePressEvent(QMouseEvent *ev); 2.32 void mouseMoveEvent(QMouseEvent *ev); 2.33 };
3.1 --- a/src/goat3d.cc Sun May 11 22:04:54 2014 +0300 3.2 +++ b/src/goat3d.cc Mon May 12 07:22:52 2014 +0300 3.3 @@ -58,7 +58,7 @@ 3.4 3.5 GOAT3DAPI void goat3d_free(struct goat3d *g) 3.6 { 3.7 - delete g->search_path; 3.8 + delete [] g->search_path; 3.9 delete g->scn; 3.10 delete g; 3.11 }
4.1 --- a/src/goat3d_readxml.cc Sun May 11 22:04:54 2014 +0300 4.2 +++ b/src/goat3d_readxml.cc Mon May 12 07:22:52 2014 +0300 4.3 @@ -286,7 +286,7 @@ 4.4 if((elem = xml_node->FirstChildElement("pos"))) { 4.5 const char *val = elem->Attribute("float3"); 4.6 if(val && sscanf(val, "%f %f %f", vec, vec + 1, vec + 2) == 3) { 4.7 - node->set_position(Vector3(val[0], val[1], val[2])); 4.8 + node->set_position(Vector3(vec[0], vec[1], vec[2])); 4.9 } else { 4.10 logmsg(LOG_ERROR, "node %s: invalid position tag\n", node->get_name()); 4.11 }