diff --git a/README.md b/README.md index 04737b6a..67fbd5f9 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,10 @@ Now, for just beginning, I think it's a not bad start. 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. - +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 that the demo app is very beautiful. Added x,z axis, looks better than last screenshot. +I have to use the GLU library, the previous implementation of drawSphere and drawCylinder looks not good, and take too much time to debug. + - [ ] Export Wavefront .obj - [ ] Render B-Mesh result - [ ] Design UI for monster parts configuration diff --git a/screenshot/dust3d_node_edge_with_glu.png b/screenshot/dust3d_node_edge_with_glu.png new file mode 100644 index 00000000..0fb959b3 Binary files /dev/null and b/screenshot/dust3d_node_edge_with_glu.png differ diff --git a/src/draw.cpp b/src/draw.cpp index d6b91f2f..953c5bb2 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -3,110 +3,28 @@ #include #include #include +#ifdef __APPLE__ +#include +#else +#include +#endif #include "draw.h" -/* - * This drawSphere function modified from [Jon Leech's implementation of sphere](ftp://ftp.ee.lbl.gov/sphere.c) - * Jeremy HU (huxingyi@msn.com) 2016/12/16 -*/ +static GLUquadricObj *quadricId = 0; -#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]; - vec3 a, b, c; - - vec3Midpoint(&oldt->pt[0], &oldt->pt[2], &a); - vec3Midpoint(&oldt->pt[0], &oldt->pt[1], &b); - vec3Midpoint(&oldt->pt[1], &oldt->pt[2], &c); - - vec3Normalize(&a); - vec3Normalize(&b); - vec3Normalize(&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 drawInit(void) { + if (0 == quadricId) { + quadricId = gluNewQuadric(); + gluQuadricDrawStyle(quadricId, GLU_FILL); } + return 0; } -int drawSphere(vec3 *origin, float radius, 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; - } - +int drawSphere(vec3 *origin, float radius, int slices, int stacks) { glPushMatrix(); glTranslatef(origin->x, origin->y, origin->z); - glScalef(radius, radius, radius); - for (i = 0; i < newObj.npoly; ++i) { - drawTriangle(&newObj.poly[i]); - } + gluSphere(quadricId, radius, slices, stacks); glPopMatrix(); - - free(newObj.poly); - return 0; } @@ -121,11 +39,8 @@ void drawTriangle(triangle *poly) { glEnd(); } -int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices) { - float theta = (2.0 * M_PI) / (float)slices; - float a = 0.0f; - int lv; - float x, y, z; +int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices, + int stacks) { vec3 zAxis = {0, 0, 1}; vec3 p, t; float height = 0; @@ -148,51 +63,7 @@ int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices) glTranslatef(bottomOrigin->x, bottomOrigin->y, bottomOrigin->z); glRotatef(angle, t.x, t.y, t.z); - - // 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 = 0; - glNormal3f(cosa, sina, 0); - glVertex3f(x, y, z); - z = height; - glNormal3f(cosa, sina, 0); - glVertex3f(x, y, z); - a += theta; - } - glEnd(); - - // bottom cap - z = 0; - 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 = height; - 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(); + gluCylinder(quadricId, radius, radius, height, slices, stacks); glPopMatrix(); diff --git a/src/draw.h b/src/draw.h index 243c1d9d..257d6020 100644 --- a/src/draw.h +++ b/src/draw.h @@ -15,9 +15,11 @@ typedef struct { triangle *poly; } object; -int drawSphere(vec3 *origin, float radius, int level); +int drawInit(void); +int drawSphere(vec3 *origin, float radius, int slices, int stacks); void drawTriangle(triangle *poly); -int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices); +int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices, + int stacks); int drawGrid(float size, float step); #ifdef __cplusplus diff --git a/src/drawcommon.h b/src/drawcommon.h deleted file mode 100644 index 38de7647..00000000 --- a/src/drawcommon.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef DRAW_COMMON_H -#define DRAW_COMMON_H -#include "vector3d.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - vec3 pt[3]; -} triangle; - -typedef struct { - int npoly; - triangle *poly; -} object; - -void drawTriangle(triangle *poly); -int drawCylinder(int slices, float radius, float height); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/render.cpp b/src/render.cpp index 4293474c..24b1c6a4 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -10,7 +10,7 @@ static int drawBmeshNode(bmesh *bm, bmeshNode *node) { float color1[3] = {1, 0, 0}; glColor3fv(color1); - drawSphere(&node->position, node->radius, 3); + drawSphere(&node->position, node->radius, 36, 24); return 0; } @@ -19,7 +19,7 @@ static int drawBmeshEdge(bmesh *bm, bmeshEdge *edge) { glColor3fv(color2); bmeshNode *firstNode = bmeshGetNode(bm, edge->firstNode); bmeshNode *secondNode = bmeshGetNode(bm, edge->secondNode); - drawCylinder(&firstNode->position, &secondNode->position, 0.04, 40); + drawCylinder(&firstNode->position, &secondNode->position, 0.1, 36, 24); return 0; } @@ -31,8 +31,8 @@ Render::Render(QWidget *parent) mouseX = 0; mouseY = 0; - cameraAngleX = 50; - cameraAngleY = 70; + cameraAngleX = 45; + cameraAngleY = -45; cameraDistance = 3; } @@ -74,6 +74,8 @@ void Render::initializeGL() { glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); + + drawInit(); } void Render::paintGL() { @@ -97,17 +99,17 @@ void Render::paintGL() { bm = bmeshCreate(); memset(&node, 0, sizeof(node)); - node.position.x = -1.0; - node.position.y = 0.3; - node.position.z = 1.0; - node.radius = 0.45; + node.position.x = 0; + node.position.y = 0; + node.position.z = 3; + node.radius = 0.5; bmeshAddNode(bm, &node); memset(&node, 0, sizeof(node)); - node.position.x = -0.5; - node.position.y = 0.2; - node.position.z = 0.5; - node.radius = 0.1; + node.position.x = 1; + node.position.y = 0; + node.position.z = 2; + node.radius = 0.5; bmeshAddNode(bm, &node); memset(&edge, 0, sizeof(edge)); @@ -136,7 +138,7 @@ void Render::resizeGL(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glFrustum(-2, 2, -1.5, 1.5, 1, 1000); + glFrustum(-2, 2, -1.5, 1.5, 1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity();