Add missing modifies
parent
a074a8d846
commit
f2bc4417e0
|
@ -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.
|
||||
<img src="screenshot/dust3d_sphere_cylinder.png">
|
||||
- [ ] 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.
|
||||
<img src="screenshot/dust3d_node_edge.png">
|
||||
Added x,z axis, looks better than last screenshot.
|
||||
- [ ] Export Wavefront .obj
|
||||
- [ ] Render B-Mesh result
|
||||
- [ ] Design UI for monster parts configuration
|
||||
|
|
|
@ -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
|
||||
render.h \
|
||||
vector3d.h \
|
||||
draw.h \
|
||||
array.h \
|
||||
bmesh.h \
|
||||
matrix.h
|
|
@ -1,20 +0,0 @@
|
|||
#include "drawcommon.h"
|
||||
#include <math.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
106
src/drawsphere.c
106
src/drawsphere.c
|
@ -1,106 +0,0 @@
|
|||
#include "drawcommon.h"
|
||||
#include "drawsphere.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
|
@ -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
|
162
src/glwidget.cpp
162
src/glwidget.cpp
|
@ -1,162 +0,0 @@
|
|||
#include <QtGui>
|
||||
#include <QtOpenGL>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#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) {
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef GLWIDGET_H
|
||||
#define GLWIDGET_H
|
||||
|
||||
#include <QGLWidget>
|
||||
|
||||
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
|
Loading…
Reference in New Issue