diff --git a/README.md b/README.md index df4670c9..6639a320 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,10 @@ From my initial thought, Dust3D should be a tool like [Makehuman](http://www.mak Progress ============== -Drawing Sphere +Drawing Primitives ----------- +*Sphere* I don't want the whole project have any unnecessary dependent, like glu library. -Let's start with [drawing a sphere without gluSphere]( http://stackoverflow.com/questions/7687148/drawing-sphere-in-opengl-without-using-glusphere), because I want implement the same balls which presented in the [B-Mesh paper](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.357.7134&rep=rep1&type=pdf). +Let's start with [drawing a sphere without gluSphere]( http://stackoverflow.com/questions/7687148/drawing-sphere-in-opengl-without-using-glusphere), because I want implement the same balls which presented in the [B-Mesh paper](http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.357.7134&rep=rep1&type=pdf). +*Cylinder* +Two caps and many strips composites a cylinder. diff --git a/src/drawcommon.h b/src/drawcommon.h index 10cb6167..befdacc5 100644 --- a/src/drawcommon.h +++ b/src/drawcommon.h @@ -23,6 +23,7 @@ typedef struct { void normalize(point *p); void midpoint(point *a, point *b, point *mid); void drawTriangle(triangle *poly); +int drawCylinder(int slices, float radius, float height); #ifdef __cplusplus } diff --git a/src/drawsphere.h b/src/drawsphere.h index 839dde5f..3d6a9929 100644 --- a/src/drawsphere.h +++ b/src/drawsphere.h @@ -1,5 +1,6 @@ #ifndef DRAW_SPHERE_H #define DRAW_SPHERE_H +#include "drawcommon.h" #ifdef __cplusplus extern "C" { diff --git a/src/glwidget.cpp b/src/glwidget.cpp index f2167858..797cc18b 100644 --- a/src/glwidget.cpp +++ b/src/glwidget.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "glwidget.h" #include "drawcommon.h" #include "drawsphere.h" @@ -16,8 +17,71 @@ void drawTriangle(triangle *poly) { 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; + } + + // 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(); + + // 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(); + + return 0; +} + GLWidget::GLWidget(QWidget *parent) - : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) { + : QGLWidget(QGLFormat(QGL::SampleBuffers), parent) { + QTimer *timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(update())); + timer->start(100); } GLWidget::~GLWidget() { @@ -47,8 +111,14 @@ void GLWidget::initializeGL() { } void GLWidget::paintGL() { + static int angle = 0; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - drawSphere(3); + //drawSphere(3); + glPushMatrix(); + glRotatef(angle, 1, 0, 0); + angle = (angle + 1) % 360; + drawCylinder(50, 0.2, 2); + glPopMatrix(); } void GLWidget::resizeGL(int w, int h) {