diff --git a/README.md b/README.md index dbf3ee2a..04737b6a 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,14 @@ Two caps and many strips composites a cylinder. Almost all 3D editor have a infinite grid ground, I just made a finite one, in the future, I should expand the grid outside of the screen to make it infinite. Now, for just beginning, I think it's a not bad start. -- [ ] Implement B-Mesh algorithm +- [ ] Implement B-Mesh algorithm (Dec 18, 2016 ~ Dec 19, 2016) +*Drawing Skeletal Shape Balls* +Draw shape ball is easy, no need to rotate, I just need scale it along the ball's radius. +Draw the cylinder which connects two shape balls is more difficult, I need do some math to rotate it. [Here](http://www.thjsmith.com/40/cylinder-between-two-points-opengl-c) described it. +*Camera Control* +Camera rotate/zoom implemented, [here](http://www.songho.ca/opengl/gl_transform.html) is a good article which explained the theory of OpenGL Transformation. Most important is the demo apps all are very beautiful. + +Added x,z axis, looks better than last screenshot. - [ ] Export Wavefront .obj - [ ] Render B-Mesh result - [ ] Design UI for monster parts configuration diff --git a/build/dust3d.pro b/build/dust3d.pro index fd47d561..5c8eef14 100644 --- a/build/dust3d.pro +++ b/build/dust3d.pro @@ -8,11 +8,17 @@ INCLUDEPATH += ../src SOURCES += main.cpp \ mainwindow.cpp \ - glwidget.cpp \ - drawcommon.c \ - drawsphere.c + render.cpp \ + vector3d.c \ + draw.cpp \ + array.c \ + bmesh.c \ + matrix.c HEADERS += mainwindow.h \ - glwidget.h \ - drawcommon.h \ - drawsphere.h \ No newline at end of file + render.h \ + vector3d.h \ + draw.h \ + array.h \ + bmesh.h \ + matrix.h \ No newline at end of file diff --git a/src/drawcommon.c b/src/drawcommon.c deleted file mode 100644 index 8f31acd8..00000000 --- a/src/drawcommon.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "drawcommon.h" -#include - -void normalize(point *p) { - double mag; - mag = p->x * p->x + p->y * p->y + p->z * p->z; - if (mag != 0.0) { - mag = 1.0 / sqrt(mag); - p->x *= mag; - p->y *= mag; - p->z *= mag; - } -} - -void midpoint(point *a, point *b, point *mid) { - mid->x = (a->x + b->x) * 0.5; - mid->y = (a->y + b->y) * 0.5; - mid->z = (a->z + b->z) * 0.5; -} - diff --git a/src/drawsphere.c b/src/drawsphere.c deleted file mode 100644 index 02f825b1..00000000 --- a/src/drawsphere.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "drawcommon.h" -#include "drawsphere.h" -#include -#include -#include - -/* - * This function modified from [Jon Leech's implementation of sphere](ftp://ftp.ee.lbl.gov/sphere.c) - * Jeremy HU (huxingyi@msn.com) 2016/12/16 -*/ - -#define XPLUS { 1, 0, 0 } /* X */ -#define XMIN { -1, 0, 0 } /* -X */ -#define YPLUS { 0, 1, 0 } /* Y */ -#define YMIN { 0, -1, 0 } /* -Y */ -#define ZPLUS { 0, 0, 1 } /* Z */ -#define ZMIN { 0, 0, -1 } /* -Z */ - -static const triangle octahedron[] = { - {{XPLUS, ZPLUS, YPLUS}}, - {{YPLUS, ZPLUS, XMIN}}, - {{XMIN, ZPLUS, YMIN}}, - {{YMIN, ZPLUS, XPLUS}}, - {{XPLUS, YPLUS, ZMIN}}, - {{YPLUS, XMIN, ZMIN}}, - {{XMIN, YMIN, ZMIN}}, - {{YMIN, XPLUS, ZMIN}}, -}; - -static void subdivide(object *old, object *subdivided) { - int i; - for (i = 0; i < old->npoly; ++i) { - triangle *oldt = &old->poly[i]; - triangle *newt = &subdivided->poly[i * 4]; - point a, b, c; - - midpoint(&oldt->pt[0], &oldt->pt[2], &a); - midpoint(&oldt->pt[0], &oldt->pt[1], &b); - midpoint(&oldt->pt[1], &oldt->pt[2], &c); - - normalize(&a); - normalize(&b); - normalize(&c); - - newt->pt[0] = oldt->pt[0]; - newt->pt[1] = b; - newt->pt[2] = a; - newt++; - - newt->pt[0] = b; - newt->pt[1] = oldt->pt[1]; - newt->pt[2] = c; - newt++; - - newt->pt[0] = a; - newt->pt[1] = b; - newt->pt[2] = c; - newt++; - - newt->pt[0] = a; - newt->pt[1] = c; - newt->pt[2] = oldt->pt[2]; - } -} - -int drawSphere(int level) { - int lv, i; - object oldObj, newObj; - - if (level < 1) { - fprintf(stderr, "%s:level max greater than 0.\n", __FUNCTION__); - return -1; - } - - oldObj.npoly = sizeof(octahedron) / sizeof(octahedron[0]); - oldObj.poly = (triangle *)malloc(oldObj.npoly * sizeof(triangle)); - if (!oldObj.poly) { - fprintf(stderr, "%s:insufficient memory.\n", __FUNCTION__); - return -1; - } - memcpy(oldObj.poly, octahedron, oldObj.npoly * sizeof(triangle)); - - for (lv = 0; lv < level; lv++) { - newObj.npoly = oldObj.npoly * 4; - newObj.poly = (triangle *)malloc(newObj.npoly * sizeof(triangle)); - if (!newObj.poly) { - fprintf(stderr, "%s:insufficient memory(levelLoop:%d).\n", - __FUNCTION__, lv); - free(oldObj.poly); - return -1; - } - - subdivide(&oldObj, &newObj); - - free(oldObj.poly); - oldObj = newObj; - } - - for (i = 0; i < newObj.npoly; ++i) { - drawTriangle(&newObj.poly[i]); - } - - free(newObj.poly); - - return 0; -} diff --git a/src/drawsphere.h b/src/drawsphere.h deleted file mode 100644 index 3d6a9929..00000000 --- a/src/drawsphere.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef DRAW_SPHERE_H -#define DRAW_SPHERE_H -#include "drawcommon.h" - -#ifdef __cplusplus -extern "C" { -#endif - -int drawSphere(int level); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/glwidget.cpp b/src/glwidget.cpp deleted file mode 100644 index ffdedcef..00000000 --- a/src/glwidget.cpp +++ /dev/null @@ -1,162 +0,0 @@ -#include -#include -#include -#include -#include "glwidget.h" -#include "drawcommon.h" -#include "drawsphere.h" - -void drawTriangle(triangle *poly) { - int i; - glBegin(GL_TRIANGLES); - for (i = 0; i < 3; ++i) { - point *pt = &poly->pt[i]; - glNormal3f(pt->x, pt->y, pt->z); - glVertex3f(pt->x, pt->y, pt->z); - } - glEnd(); -} - -int drawCylinder(int slices, float radius, float height) { - float theta = (2.0 * M_PI) / (float)slices; - float a = 0.0f; - int lv; - float halfHeight = height / 2; - float x, y, z; - - if (slices <= 0) { - fprintf(stderr, "%s:Invalid parameter(slices:%d).\n", __FUNCTION__, slices); - return -1; - } - - // strips - glBegin(GL_TRIANGLE_STRIP); - for (a = 0, lv = 0; lv <= slices; ++lv) { - float cosa = cos(a); - float sina = sin(a); - x = cosa * radius; - y = sina * radius; - z = -halfHeight; - glNormal3f(cosa, sina, 0); - glVertex3f(x, y, z); - z = halfHeight; - glNormal3f(cosa, sina, 0); - glVertex3f(x, y, z); - a += theta; - } - glEnd(); - - // bottom cap - z = -halfHeight; - glBegin(GL_TRIANGLE_FAN); - glNormal3f(0, 0, -1); - glVertex3f(0, 0, z); - for (a = 0, lv = 0; lv <= slices; ++lv) { - x = cos(a) * radius; - y = sin(a) * radius; - glNormal3f(0, 0, -1); - glVertex3f(x, y, z); - a += theta; - } - glEnd(); - - // top cap - z = halfHeight; - glBegin(GL_TRIANGLE_FAN); - glNormal3f(0, 0, 1); - glVertex3f(0, 0, z); - for (a = 0, lv = 0; lv <= slices; ++lv) { - x = cos(a) * radius; - y = sin(a) * radius; - glNormal3f(0, 0, 1); - glVertex3f(x, y, z); - a += theta; - } - glEnd(); - - return 0; -} - -GLWidget::GLWidget(QWidget *parent) - : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) { - QTimer *timer = new QTimer(this); - connect(timer, SIGNAL(timeout()), this, SLOT(update())); - timer->start(100); -} - -GLWidget::~GLWidget() { -} - -void GLWidget::initializeGL() { - GLfloat mat_ambient[] = { 0.0 , 0.0 , 0.0 , 1.0 }; - GLfloat mat_diffuse[] = { 0.55 , 0.55 , 0.55 , 1.0 }; - GLfloat mat_specular[] = {0.7 , 0.7 , 0.7, 1.0 }; - GLfloat mat_shininess[] = { 32 }; - - GLfloat light_diffuse[] = { 1.0 , 1.0 , 1.0 , 1.0 }; - GLfloat light_specular[] = { 1.0 , 1.0 , 1.0 , 1.0 }; - GLfloat light_ambient[] = { 0.2 , 0.2 , 0.2 , 1.0 }; - GLfloat light_position[] = { -1,1,1 , 0 }; - - glClearColor(0.0, 0.0, 0.0, 0.0); - glShadeModel(GL_SMOOTH); - - glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); - glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); - glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); - glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); - - glLightfv(GL_LIGHT0 , GL_POSITION , light_position); - glLightfv(GL_LIGHT0 , GL_DIFFUSE , light_diffuse); - glLightfv(GL_LIGHT0 , GL_AMBIENT , light_ambient); - glLightfv(GL_LIGHT0 , GL_SPECULAR , light_specular); - - glDepthFunc(GL_LESS); - - glEnable(GL_LIGHTING); - glEnable(GL_LIGHT0); - glEnable(GL_DEPTH_TEST); -} - -void GLWidget::paintGL() { - static int angle = 0; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - glBegin(GL_LINES); - for (GLfloat i = -2.5; i <= 2.5; i += 0.25) { - glVertex3f(i, 0, 2.5); glVertex3f(i, 0, -2.5); - glVertex3f(2.5, 0, i); glVertex3f(-2.5, 0, i); - } - glEnd(); - - drawSphere(4); - - glPushMatrix(); - glRotatef(angle, 1, 1, 0); - angle = (angle + 1) % 360; - drawCylinder(40, 0.2, 2.1); - glPopMatrix(); -} - -void GLWidget::resizeGL(int w, int h) { - glViewport(0, 0, (GLsizei)w, (GLsizei)h); - - glClearColor(0.92, 0.92, 0.92, 1.0); - glColor3f(1.0, 1.0, 1.0); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glFrustum(-2, 2, -1.5, 1.5, 1, 10); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glTranslatef(0, 0, -2); - glRotatef(50, 1, 0, 0); - glRotatef(70, 0, 1, 0); -} - -void GLWidget::mousePressEvent(QMouseEvent *event) { -} - -void GLWidget::mouseMoveEvent(QMouseEvent *event) { -} diff --git a/src/glwidget.h b/src/glwidget.h deleted file mode 100644 index e18370b0..00000000 --- a/src/glwidget.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef GLWIDGET_H -#define GLWIDGET_H - -#include - -class GLWidget : public QGLWidget -{ - Q_OBJECT - -public: - GLWidget(QWidget *parent = 0); - ~GLWidget(); - -protected: - void initializeGL(); - void paintGL(); - void resizeGL(int width, int height); - void mousePressEvent(QMouseEvent *event); - void mouseMoveEvent(QMouseEvent *event); -}; - -#endif