博主写程序一般用matlab, 因为最方便, 基本不用写基本函数, 只需要调用写好的库就行了。 然而, matlab并不是万能的, 有些事情matlab就不擅长, 比如画三维图形。
经研究, 可以采用折中的解决方案, 即: 使用opengl画三维图形, 同时离线渲染, 保存到内存中, 然后用matlab读取内存, 得到结果。
这里, 离线渲染是指不显示窗口, 直接渲染到数组里。 所以glut是不能用了, 我采用的是osmesa。 这是一个开源的linux opengl库, 不过也可以在windows下编译。
编译osmesa见http://stackoverflow.com/questions/17871781/building-mesa-for-windows-7-mesa-9-1, 照做基本没问题, 我使用mesa 10.4, vs2010成功编译出了32位和64位。
得到osmesa之后, 可以参考mesa自带的demo, 然后结合matlab的mex函数, 即可在matlab调用opengl。
如示例, 这里我写了一个draw skeleton的程序。
parse。h
#ifndef REPARSE_H_
#define REPARSE_H_
#include <iostream>
using namespace std;
#include <vector>
typedef vector<float> mypoint;// x, y, z
typedef vector<mypoint> myskeleton;
myskeleton readsingle(double *da)
{
int jo = 15;
myskeleton skel;
skel.resize(jo);
for (int j = 0; j < 15; j++)
{
skel[j].resize(3);
skel[j][0] = da[j];
skel[j][1] = da[j + 15];
skel[j][2] = da[j + 30];
}
return skel;
}
#endif
show.cpp
#include <GL/osmesa.h>
#include <gl/GLU.h>
#include <gl/glut.h>
#include <mex.h>
#include <iostream>
using namespace std;
#include "reparse.h"
static myskeleton mk;
static GLfloat width = 640;
static GLfloat height = 480;
// 已知三点坐标,求法向量
float *CalNormal(float *p1, float * p2, float * p3)
{
float a = ( (p2[1]-p1[1])*(p3[2]-p1[2])-(p2[2]-p1[2])*(p3[1]-p1[1]) );
float b = ( (p2[2]-p1[2])*(p3[0]-p1[0])-(p2[0]-p1[0])*(p3[2]-p1[2]) );
float c = ( (p2[0]-p1[0])*(p3[1]-p1[1])-(p2[1]-p1[1])*(p3[0]-p1[0]) );
float vnorm[3] = {a, b, c};
return vnorm;
}
// draw sphere
void drawSphere(GLfloat xx, GLfloat yy, GLfloat zz, GLfloat radius, GLfloat M, GLfloat N)
{
GLfloat PI = 3.1416;
float step_z = PI / M;
float step_xy = 2 * PI / N;
float x[4], y[4], z[4];
float angle_z = 0.0;
float angle_xy = 0.0;
int i = 0, j = 0;
glBegin(GL_QUADS);
for (i = 0; i < M; i