試験的なプログラムを書くだけでいちいちモデルを読み込むライブラリを使うのが面倒なので、Blender PythonでC++OpenGLのコードをprintする。まだやってなかったっけという感じなんだがやっていたら申し訳ない。
import bpy import sys def as_cpp_array(outputto): obj = bpy.context.active_object mesh = obj.data pvecname = "points" # 頂点データの配列の変数名 vnvecname = "vnorms" # 頂点法線の配列の変数名 fvecname = "faces" # 面データの配列の変数名 fnvecname = "fnorms" # 面法線の配列の変数名 print("/////////////////////////////////////") if not pvecname is None: print("//std::vector<std::array<float, 3> > ",pvecname,";",file=outputto) if not vnvecname is None: print("//std::vector<std::array<float, 3> > ",vnvecname,";",file=outputto) if not fvecname is None: print("//std::vector<std::array<int, 3> > ",fvecname,";",file=outputto) if not fnvecname is None: print("//std::vector<std::array<float, 3> > ",fnvecname,";",file=outputto) if not pvecname is None: for v in mesh.vertices: print( pvecname + ".push_back({", v.co.x,",", v.co.y,",", v.co.z, "});", file=outputto ) if not vnvecname is None: for v in mesh.vertices: print( vnvecname + ".push_back({", v.normal.x,",", v.normal.y,",", v.normal.z, "});", file=outputto ) if not fvecname is None: for f in mesh.polygons: print( fvecname + ".push_back({", f.vertices[0],",", f.vertices[1],",", f.vertices[2], "});", file=outputto ) if not fnvecname is None: for f in mesh.polygons: print( fnvecname + ".push_back({", f.normal.x,",", f.normal.y,",", f.normal.z, "});", file=outputto ) as_cpp_array(sys.stdout)
これをactive_objectに対して走らせると、例えば以下のような結果が得られる。
/////////////////////////////////////
//std::vector<std::array<float, 3> > points ;
//std::vector<std::array<float, 3> > vnorms ;
//std::vector<std::array<int, 3> > faces ;
//std::vector<std::array<float, 3> > fnorms ;
points.push_back({ 0.0 , 0.0 , -0.57135009765625 });
points.push_back({ 0.4134289026260376 , -0.3003701865673065 , -0.25551632046699524 });
points.push_back({ -0.15791259706020355 , -0.4860132336616516 , -0.25551632046699524 });
points.push_back({ -0.5110297799110413 , 0.0 , -0.25551632046699524 });
points.push_back({ -0.15791259706020355 , 0.4860132336616516 , -0.25551632046699524 });
points.push_back({ 0.4134289026260376 , 0.3003701865673065 , -0.25551632046699524 });
points.push_back({ 0.15791259706020355 , -0.4860132336616516 , 0.25551632046699524 });
points.push_back({ -0.4134289026260376 , -0.3003701865673065 , 0.25551632046699524 });
points.push_back({ -0.4134289026260376 , 0.3003701865673065 , 0.25551632046699524 });
points.push_back({ 0.15791259706020355 , 0.4860132336616516 , 0.25551632046699524 });
points.push_back({ 0.5110297799110413 , 0.0 , 0.25551632046699524 });
points.push_back({ 0.0 , 0.0 , 0.57135009765625 });
vnorms.push_back({ 0.0 , 0.0 , -1.0 });
vnorms.push_back({ 0.7235938310623169 , -0.5257118344306946 , -0.44718772172927856 });
vnorms.push_back({ -0.2763756215572357 , -0.8506424427032471 , -0.44718772172927856 });
vnorms.push_back({ -0.8944059610366821 , 0.0 , -0.44718772172927856 });
vnorms.push_back({ -0.2763756215572357 , 0.8506424427032471 , -0.44718772172927856 });
vnorms.push_back({ 0.7235938310623169 , 0.5257118344306946 , -0.44718772172927856 });
vnorms.push_back({ 0.2763756215572357 , -0.8506424427032471 , 0.44718772172927856 });
vnorms.push_back({ -0.7235938310623169 , -0.5257118344306946 , 0.44718772172927856 });
vnorms.push_back({ -0.7235938310623169 , 0.5257118344306946 , 0.44718772172927856 });
vnorms.push_back({ 0.2763756215572357 , 0.8506424427032471 , 0.44718772172927856 });
vnorms.push_back({ 0.8944059610366821 , 0.0 , 0.44718772172927856 });
vnorms.push_back({ 0.0 , 0.0 , 1.0 });
faces.push_back({ 0 , 1 , 2 });
faces.push_back({ 1 , 0 , 5 });
faces.push_back({ 0 , 2 , 3 });
faces.push_back({ 0 , 3 , 4 });
faces.push_back({ 0 , 4 , 5 });
faces.push_back({ 1 , 5 , 10 });
faces.push_back({ 2 , 1 , 6 });
faces.push_back({ 3 , 2 , 7 });
faces.push_back({ 4 , 3 , 8 });
faces.push_back({ 5 , 4 , 9 });
faces.push_back({ 1 , 10 , 6 });
faces.push_back({ 2 , 6 , 7 });
faces.push_back({ 3 , 7 , 8 });
faces.push_back({ 4 , 8 , 9 });
faces.push_back({ 5 , 9 , 10 });
faces.push_back({ 6 , 10 , 11 });
faces.push_back({ 7 , 6 , 11 });
faces.push_back({ 8 , 7 , 11 });
faces.push_back({ 9 , 8 , 11 });
faces.push_back({ 10 , 9 , 11 });
fnorms.push_back({ 0.18759654462337494 , -0.5773536562919617 , -0.7946510910987854 });
fnorms.push_back({ 0.6070646643638611 , 0.0 , -0.7946524620056152 });
fnorms.push_back({ -0.4911220967769623 , -0.35682904720306396 , -0.7946522235870361 });
fnorms.push_back({ -0.4911220967769623 , 0.35682904720306396 , -0.7946522235870361 });
fnorms.push_back({ 0.18759654462337494 , 0.5773536562919617 , -0.7946510910987854 });
fnorms.push_back({ 0.9822461009025574 , 0.0 , -0.18759679794311523 });
fnorms.push_back({ 0.3035355508327484 , -0.9341715574264526 , -0.1875891536474228 });
fnorms.push_back({ -0.7946491241455078 , -0.5773593187332153 , -0.1875869631767273 });
fnorms.push_back({ -0.7946491241455078 , 0.5773593187332153 , -0.1875869780778885 });
fnorms.push_back({ 0.3035355508327484 , 0.9341715574264526 , -0.1875891238451004 });
fnorms.push_back({ 0.7946491241455078 , -0.5773593187332153 , 0.1875869780778885 });
fnorms.push_back({ -0.3035355508327484 , -0.9341715574264526 , 0.1875891238451004 });
fnorms.push_back({ -0.9822461009025574 , 0.0 , 0.18759679794311523 });
fnorms.push_back({ -0.3035355508327484 , 0.9341715574264526 , 0.1875891536474228 });
fnorms.push_back({ 0.7946491241455078 , 0.5773593187332153 , 0.1875869631767273 });
fnorms.push_back({ 0.4911220967769623 , -0.35682904720306396 , 0.7946522235870361 });
fnorms.push_back({ -0.18759654462337494 , -0.5773536562919617 , 0.7946510910987854 });
fnorms.push_back({ -0.6070646643638611 , 0.0 , 0.7946524620056152 });
fnorms.push_back({ -0.18759654462337494 , 0.5773536562919617 , 0.7946510910987854 });
fnorms.push_back({ 0.4911220967769623 , 0.35682904720306396 , 0.7946522235870361 });
これをC++で書いたOpenGLの表示コードに貼り付ける。
#include <iostream> #include <cstdlib> #include <Windows.h> #include <gl/GL.h> #include <gl/glfw/glfw3.h> #pragma comment(lib,"opengl32.lib") #pragma comment(lib,"glfw3.lib") #include <gl/GLU.h> #pragma comment(lib,"glu32.lib") #include<vector> #include<array>
struct d3item { std::vector<std::array<float, 3> > points; std::vector<std::array<float, 3> > vnorms; std::vector<std::array<int, 3> > faces; std::vector<std::array<float, 3> > fnorms; public: void init() { points.push_back({ 0.0 , 0.0 , -0.57135009765625 }); points.push_back({ 0.4134289026260376 , -0.3003701865673065 , -0.25551632046699524 }); points.push_back({ -0.15791259706020355 , -0.4860132336616516 , -0.25551632046699524 }); points.push_back({ -0.5110297799110413 , 0.0 , -0.25551632046699524 }); points.push_back({ -0.15791259706020355 , 0.4860132336616516 , -0.25551632046699524 }); points.push_back({ 0.4134289026260376 , 0.3003701865673065 , -0.25551632046699524 }); points.push_back({ 0.15791259706020355 , -0.4860132336616516 , 0.25551632046699524 }); points.push_back({ -0.4134289026260376 , -0.3003701865673065 , 0.25551632046699524 }); points.push_back({ -0.4134289026260376 , 0.3003701865673065 , 0.25551632046699524 }); points.push_back({ 0.15791259706020355 , 0.4860132336616516 , 0.25551632046699524 }); points.push_back({ 0.5110297799110413 , 0.0 , 0.25551632046699524 }); points.push_back({ 0.0 , 0.0 , 0.57135009765625 }); vnorms.push_back({ 0.0 , 0.0 , -1.0 }); vnorms.push_back({ 0.7235938310623169 , -0.5257118344306946 , -0.44718772172927856 }); vnorms.push_back({ -0.2763756215572357 , -0.8506424427032471 , -0.44718772172927856 }); vnorms.push_back({ -0.8944059610366821 , 0.0 , -0.44718772172927856 }); vnorms.push_back({ -0.2763756215572357 , 0.8506424427032471 , -0.44718772172927856 }); vnorms.push_back({ 0.7235938310623169 , 0.5257118344306946 , -0.44718772172927856 }); vnorms.push_back({ 0.2763756215572357 , -0.8506424427032471 , 0.44718772172927856 }); vnorms.push_back({ -0.7235938310623169 , -0.5257118344306946 , 0.44718772172927856 }); vnorms.push_back({ -0.7235938310623169 , 0.5257118344306946 , 0.44718772172927856 }); vnorms.push_back({ 0.2763756215572357 , 0.8506424427032471 , 0.44718772172927856 }); vnorms.push_back({ 0.8944059610366821 , 0.0 , 0.44718772172927856 }); vnorms.push_back({ 0.0 , 0.0 , 1.0 }); faces.push_back({ 0 , 1 , 2 }); faces.push_back({ 1 , 0 , 5 }); faces.push_back({ 0 , 2 , 3 }); faces.push_back({ 0 , 3 , 4 }); faces.push_back({ 0 , 4 , 5 }); faces.push_back({ 1 , 5 , 10 }); faces.push_back({ 2 , 1 , 6 }); faces.push_back({ 3 , 2 , 7 }); faces.push_back({ 4 , 3 , 8 }); faces.push_back({ 5 , 4 , 9 }); faces.push_back({ 1 , 10 , 6 }); faces.push_back({ 2 , 6 , 7 }); faces.push_back({ 3 , 7 , 8 }); faces.push_back({ 4 , 8 , 9 }); faces.push_back({ 5 , 9 , 10 }); faces.push_back({ 6 , 10 , 11 }); faces.push_back({ 7 , 6 , 11 }); faces.push_back({ 8 , 7 , 11 }); faces.push_back({ 9 , 8 , 11 }); faces.push_back({ 10 , 9 , 11 }); fnorms.push_back({ 0.18759654462337494 , -0.5773536562919617 , -0.7946510910987854 }); fnorms.push_back({ 0.6070646643638611 , 0.0 , -0.7946524620056152 }); fnorms.push_back({ -0.4911220967769623 , -0.35682904720306396 , -0.7946522235870361 }); fnorms.push_back({ -0.4911220967769623 , 0.35682904720306396 , -0.7946522235870361 }); fnorms.push_back({ 0.18759654462337494 , 0.5773536562919617 , -0.7946510910987854 }); fnorms.push_back({ 0.9822461009025574 , 0.0 , -0.18759679794311523 }); fnorms.push_back({ 0.3035355508327484 , -0.9341715574264526 , -0.1875891536474228 }); fnorms.push_back({ -0.7946491241455078 , -0.5773593187332153 , -0.1875869631767273 }); fnorms.push_back({ -0.7946491241455078 , 0.5773593187332153 , -0.1875869780778885 }); fnorms.push_back({ 0.3035355508327484 , 0.9341715574264526 , -0.1875891238451004 }); fnorms.push_back({ 0.7946491241455078 , -0.5773593187332153 , 0.1875869780778885 }); fnorms.push_back({ -0.3035355508327484 , -0.9341715574264526 , 0.1875891238451004 }); fnorms.push_back({ -0.9822461009025574 , 0.0 , 0.18759679794311523 }); fnorms.push_back({ -0.3035355508327484 , 0.9341715574264526 , 0.1875891536474228 }); fnorms.push_back({ 0.7946491241455078 , 0.5773593187332153 , 0.1875869631767273 }); fnorms.push_back({ 0.4911220967769623 , -0.35682904720306396 , 0.7946522235870361 }); fnorms.push_back({ -0.18759654462337494 , -0.5773536562919617 , 0.7946510910987854 }); fnorms.push_back({ -0.6070646643638611 , 0.0 , 0.7946524620056152 }); fnorms.push_back({ -0.18759654462337494 , 0.5773536562919617 , 0.7946510910987854 }); fnorms.push_back({ 0.4911220967769623 , 0.35682904720306396 , 0.7946522235870361 }); } void draw() { auto color = std::array<float, 4>{1.0, 0, 0, 1}; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color.data()); glColor3d(1, 1, 1); glBegin(GL_TRIANGLES); for (size_t f = 0; f < faces.size(); f++) { //面法線 glNormal3fv(fnorms[f].data()); size_t p0 = faces[f][0]; size_t p1 = faces[f][1]; size_t p2 = faces[f][2]; //頂点法線 //glNormal3fv(vnorms[p0].data()); glVertex3fv(points[p0].data()); //頂点法線 //glNormal3fv(vnorms[p1].data()); glVertex3fv(points[p1].data()); //頂点法線 //glNormal3fv(vnorms[p2].data()); glVertex3fv(points[p2].data()); } glEnd(); } };
int main() { //////////////////////////////////////////////////////////////////////////////// // GLFW の初期化 if (glfwInit() == GL_FALSE) { // 初期化に失敗したら終了 return 1; } //////////////////////////////////////////////////////////////////////////////// // ウィンドウを作成 GLFWwindow* window = glfwCreateWindow( 400, //width 400, //height "window title",//title NULL, //monitor NULL //share ); //////////////////////////////////////////////////////////////////////////////// // ウィンドウを作成できなければ終了 if (window == nullptr) { glfwTerminate(); return 1; } d3item item; item.init(); glfwMakeContextCurrent(window); while (glfwWindowShouldClose(window) == GL_FALSE) { int width, height; glfwGetFramebufferSize(window, &width, &height); const GLfloat lightPos[] = { -3 , 0 , 0 , 1 }; const GLfloat lightCol[] = { 1 , 1 , 1 , 1 }; glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_DIFFUSE, lightCol); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); glEnable(GL_DEPTH_TEST); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); ///////////////////// // 描画 glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); gluPerspective(45, width / (double)height, 0.01, 10); { glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); static int angle = 0; glTranslated(0, 0, -2); glRotated(angle++, 1, 1, 1); item.draw(); glPopMatrix(); } glMatrixMode(GL_PROJECTION); glPopMatrix(); // ///////////////////// //glFlush(); glfwSwapBuffers(window); // イベント取得 glfwWaitEvents(); } glfwTerminate(); }