Use glu to draw primitives
parent
f2bc4417e0
commit
edeec37d01
|
@ -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 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.
|
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 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.
|
||||||
<img src="screenshot/dust3d_node_edge.png">
|
|
||||||
Added x,z axis, looks better than last screenshot.
|
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.
|
||||||
|
<img src="screenshot/dust3d_node_edge_with_glu.png">
|
||||||
- [ ] Export Wavefront .obj
|
- [ ] Export Wavefront .obj
|
||||||
- [ ] Render B-Mesh result
|
- [ ] Render B-Mesh result
|
||||||
- [ ] Design UI for monster parts configuration
|
- [ ] Design UI for monster parts configuration
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 101 KiB |
161
src/draw.cpp
161
src/draw.cpp
|
@ -3,110 +3,28 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <OpenGL/glu.h>
|
||||||
|
#else
|
||||||
|
#include <GL/glu.h>
|
||||||
|
#endif
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
|
|
||||||
/*
|
static GLUquadricObj *quadricId = 0;
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define XPLUS { 1, 0, 0 } /* X */
|
int drawInit(void) {
|
||||||
#define XMIN { -1, 0, 0 } /* -X */
|
if (0 == quadricId) {
|
||||||
#define YPLUS { 0, 1, 0 } /* Y */
|
quadricId = gluNewQuadric();
|
||||||
#define YMIN { 0, -1, 0 } /* -Y */
|
gluQuadricDrawStyle(quadricId, GLU_FILL);
|
||||||
#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];
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int drawSphere(vec3 *origin, float radius, int level) {
|
int drawSphere(vec3 *origin, float radius, int slices, int stacks) {
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(origin->x, origin->y, origin->z);
|
glTranslatef(origin->x, origin->y, origin->z);
|
||||||
glScalef(radius, radius, radius);
|
gluSphere(quadricId, radius, slices, stacks);
|
||||||
for (i = 0; i < newObj.npoly; ++i) {
|
|
||||||
drawTriangle(&newObj.poly[i]);
|
|
||||||
}
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
free(newObj.poly);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,11 +39,8 @@ void drawTriangle(triangle *poly) {
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices) {
|
int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices,
|
||||||
float theta = (2.0 * M_PI) / (float)slices;
|
int stacks) {
|
||||||
float a = 0.0f;
|
|
||||||
int lv;
|
|
||||||
float x, y, z;
|
|
||||||
vec3 zAxis = {0, 0, 1};
|
vec3 zAxis = {0, 0, 1};
|
||||||
vec3 p, t;
|
vec3 p, t;
|
||||||
float height = 0;
|
float height = 0;
|
||||||
|
@ -148,51 +63,7 @@ int drawCylinder(vec3 *topOrigin, vec3 *bottomOrigin, float radius, int slices)
|
||||||
glTranslatef(bottomOrigin->x, bottomOrigin->y,
|
glTranslatef(bottomOrigin->x, bottomOrigin->y,
|
||||||
bottomOrigin->z);
|
bottomOrigin->z);
|
||||||
glRotatef(angle, t.x, t.y, t.z);
|
glRotatef(angle, t.x, t.y, t.z);
|
||||||
|
gluCylinder(quadricId, radius, radius, height, slices, stacks);
|
||||||
// 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();
|
|
||||||
|
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,11 @@ typedef struct {
|
||||||
triangle *poly;
|
triangle *poly;
|
||||||
} object;
|
} 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);
|
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);
|
int drawGrid(float size, float step);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -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
|
|
|
@ -10,7 +10,7 @@
|
||||||
static int drawBmeshNode(bmesh *bm, bmeshNode *node) {
|
static int drawBmeshNode(bmesh *bm, bmeshNode *node) {
|
||||||
float color1[3] = {1, 0, 0};
|
float color1[3] = {1, 0, 0};
|
||||||
glColor3fv(color1);
|
glColor3fv(color1);
|
||||||
drawSphere(&node->position, node->radius, 3);
|
drawSphere(&node->position, node->radius, 36, 24);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ static int drawBmeshEdge(bmesh *bm, bmeshEdge *edge) {
|
||||||
glColor3fv(color2);
|
glColor3fv(color2);
|
||||||
bmeshNode *firstNode = bmeshGetNode(bm, edge->firstNode);
|
bmeshNode *firstNode = bmeshGetNode(bm, edge->firstNode);
|
||||||
bmeshNode *secondNode = bmeshGetNode(bm, edge->secondNode);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,8 +31,8 @@ Render::Render(QWidget *parent)
|
||||||
|
|
||||||
mouseX = 0;
|
mouseX = 0;
|
||||||
mouseY = 0;
|
mouseY = 0;
|
||||||
cameraAngleX = 50;
|
cameraAngleX = 45;
|
||||||
cameraAngleY = 70;
|
cameraAngleY = -45;
|
||||||
cameraDistance = 3;
|
cameraDistance = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,6 +74,8 @@ void Render::initializeGL() {
|
||||||
|
|
||||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
|
|
||||||
|
drawInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Render::paintGL() {
|
void Render::paintGL() {
|
||||||
|
@ -97,17 +99,17 @@ void Render::paintGL() {
|
||||||
bm = bmeshCreate();
|
bm = bmeshCreate();
|
||||||
|
|
||||||
memset(&node, 0, sizeof(node));
|
memset(&node, 0, sizeof(node));
|
||||||
node.position.x = -1.0;
|
node.position.x = 0;
|
||||||
node.position.y = 0.3;
|
node.position.y = 0;
|
||||||
node.position.z = 1.0;
|
node.position.z = 3;
|
||||||
node.radius = 0.45;
|
node.radius = 0.5;
|
||||||
bmeshAddNode(bm, &node);
|
bmeshAddNode(bm, &node);
|
||||||
|
|
||||||
memset(&node, 0, sizeof(node));
|
memset(&node, 0, sizeof(node));
|
||||||
node.position.x = -0.5;
|
node.position.x = 1;
|
||||||
node.position.y = 0.2;
|
node.position.y = 0;
|
||||||
node.position.z = 0.5;
|
node.position.z = 2;
|
||||||
node.radius = 0.1;
|
node.radius = 0.5;
|
||||||
bmeshAddNode(bm, &node);
|
bmeshAddNode(bm, &node);
|
||||||
|
|
||||||
memset(&edge, 0, sizeof(edge));
|
memset(&edge, 0, sizeof(edge));
|
||||||
|
@ -136,7 +138,7 @@ void Render::resizeGL(int w, int h) {
|
||||||
|
|
||||||
glMatrixMode(GL_PROJECTION);
|
glMatrixMode(GL_PROJECTION);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glFrustum(-2, 2, -1.5, 1.5, 1, 1000);
|
glFrustum(-2, 2, -1.5, 1.5, 1, 100);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
|
Loading…
Reference in New Issue