Blender & OpenGL

General discussion about the development of the open source Blender

Moderators: jesterKing, stiv

Post Reply
noselasd
Posts: 12
Joined: Wed Oct 16, 2002 12:08 pm

Blender & OpenGL

Post by noselasd »

How would I go on using an object created in Blender in an OpenGL
program ?

olivierb
Posts: 5
Joined: Fri Oct 18, 2002 5:37 pm

Post by olivierb »

Since there isn't any official OpenGL model format, you'll have to export your object into a format of your choice and then write a function in your OpenGL program to import the object.
You can use the 3ds file format (I think there is some Python plugins to export Blender objects into 3ds files), you'll find plenty of import functions on the Web to use your model in your OpenGL program.
But IMHO, the most practical way is to write your own export script with Python and create your own model format which will suit your needs. Then, you'll have to write a function to import your model in your OpenGL program.
I could post some examples here if you want.

Cheers,
Olivier

noselasd
Posts: 12
Joined: Wed Oct 16, 2002 12:08 pm

Post by noselasd »

>I could post some examples here if you want.
Would be very nice!

olivierb
Posts: 5
Joined: Fri Oct 18, 2002 5:37 pm

Post by olivierb »

here it is

This script were made by me (OlivierB, oliv.blin@laposte.net) and Metal3d (patrice.ferlet@wanadoo.fr).
Thanks to Sebastien Loss for his PovExport script that helped us.

First the python export script (load it in Blender in the text editor and laucnh it with alt-p)
(with a sort of GUI :), please change the dossier_export var to an existing folder)

***** export.py *****
import Blender
import Blender210
import string

from Blender.Draw import *
from Blender.BGL import *

#############################################
dossier_export = "/home/olivier/"
#############################################

# construction du menu et de la liste des objets mesh
list_obj = Blender.Object.Get()
list_nom = []
chaine_nom = "Objets disponibles :%t|None %x0"

num_obj = 0
for obj in list_obj:
if Blender210.isMesh(obj.name):
num_obj += 1
list_nom.append(obj.name)
chaine_nom += "|" + obj.name + " %x" + str(num_obj)

print "*** Export blm ***"

# fonction d'export
def export_blm(obj_name):

obj210 = Blender210.getObject(obj_name)
mesh210 = Blender210.getMesh(obj210.data)

file=open(dossier_export+obj_name+".blm","w");

#### vertex ####
file.write("vertex:")
file.write("\t%s\n" % len(mesh210.vertices))
for vertices in mesh210.vertices:
file.write("\t%s;%s;%s\n" % (vertices[0],vertices[2],vertices[1]))

### indices des faces ###
file.write("faces:")
nbfaces = 0
for faces in mesh210.faces:
nbfaces += 1
file.write("\t%s\n" % nbfaces)
for faces in mesh210.faces:
file.write("\t%s;%s;%s\n" % (faces[0],faces[1],faces[2]))

#### vecteurs normales ####
if len(mesh210.normals) <> 0:
file.write("normales:")
file.write("\t%s\n" % (3*len(mesh210.faces)))
for face in mesh210.faces:
for i in [0,1,2]: # on se limite a des triangles
vertex = face
normal = mesh210.normals[vertex]
file.write("\t%s;%s;%s\n" % (normal[0],normal[2],normal[1]))

#### couleurs ####
file.write("couleurs:")
file.write("\t%s\n" % len(mesh210.colors))
for color in mesh210.colors:
file.write("\t%s;%s;%s\n" % (color[0],color[1],color[2]))

#### coordonnees de textures UV ###
file.write("uv:")
if mesh210.texture:
file.write("\t%s\n" % (3*len(mesh210.texcoords)))
for uvtex in mesh210.texcoords:
file.write("\t%s;%s;%s;%s;%s;%s\n" % (uvtex[0][0],uvtex[0][1],uvtex[1][0],uvtex[1][1],uvtex[2][0],uvtex[2][1]))
else:
file.write("\t0\n")
file.close()

# fonction d'affichage
obj_num = Create(0)
def draw():
global obj_num
glClearColor(0.4,0.4,0.6,0.0)
glClear(GL_COLOR_BUFFER_BIT)
glRasterPos2d(80, 250)
Text("Export d'objets .blm (blENDER mODEL)")
glRasterPos2d(20, 220)
Text("- Convertissez votre objet en triangles:")
glRasterPos2d(40, 200)
Text("o Passez en Edit Mode (TAB)")
glRasterPos2d(40, 180)
Text("o Selectionnez tous les points (a)")
glRasterPos2d(40, 160)
Text("o Convertissez la selection en triangles (ctrl+t)")
glRasterPos2d(20, 130)
Text("- Retravaillez au besoin les faces mal decoupees")
glRasterPos2d(130, 110)
Text("(Edge Turning)")
glRasterPos2d(20,80)
Text("- Choisissez l'objet")
obj_num = Menu(chaine_nom,3,160,75,100,24,obj_num.val)
Button("Exporter",2,140,40,80,24)
Button("EXIT",1,140,5,80,24)

# evenements
def event(evt, val):
if (evt==QKEY and not val):
Exit()
print "*** Fin ***"

# evenements recus des boutons
def bevent(evt):
if (evt==1):
Exit()
print "*** Fin ***"
if (evt==2):
if (obj_num.val >0):
print "| Export de l'objet \"" + list_nom[obj_num.val-1] + "\" ..."
export_blm(list_nom[obj_num.val-1])
print "-> Export fini !"
if (evt==3):
print "Objet selectionne : "+str(obj_num.val)
if (obj_num.val > 0):
print "\t" + list_nom[obj_num.val-1]
else:
print "\tNone"

Register(draw, event, bevent)

---------------
---------------
---------------

Now the C code to import it (not bug-proof ...)

***** import.hpp *****

#ifndef __EN_TETE__
#define __EN_TETE__

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <SDL/SDL.h>

typedef struct {
int nbPoints;
int nbFaces;
int nbNormales;
int nbCouleurs;
int nbUv;
float *points;
int *faces;
float *normales;
float *couleurs;
float *uv;
} Modele;

int ChargerModele(char *filename, Modele *obj);

#endif
/* import.hpp inclus */

---------------

***** import.cpp *****
#include "import.hpp"

int ChargerModele(char *filename, Modele *obj)
{
FILE *fichier;

printf("*** Chargement du fichier \"%s\" ***\n", filename);
if ((fichier = fopen(filename, "r")) == NULL)
{
fprintf(stderr, "Ouverture du fichier \"%s\" impossible.\n", filename);
return EXIT_FAILURE;
}

/* lire les vertex */
fscanf(fichier, "vertex:\t%d\n", &obj->nbPoints);
printf("%d points\n", obj->nbPoints);
obj->points = (float *) calloc(obj->nbPoints, (3 * sizeof(float)));
for (int i=0; i<obj->nbPoints; i++)
{
fscanf(fichier, "\t%f;%f;%f\n", &obj->points[3*i], &obj->points[3*i+1], &obj->points[3*i+2]);
}

/* lire les faces */
fscanf(fichier, "faces:\t%d\n", &obj->nbFaces);
printf("%d faces\n", obj->nbFaces);
obj->faces = (int *) calloc(obj->nbFaces, (3 * sizeof(int)));
for (int i=0; i<obj->nbFaces; i++)
{
fscanf(fichier, "\t%u;%u;%u\n", &obj->faces[3*i], &obj->faces[3*i+1], &obj->faces[3*i+2]);
}

/* lire les normales */
fscanf(fichier, "normales:%d\n", &obj->nbNormales);
printf("%d normales\n", obj->nbNormales);
obj->normales = (float *) calloc(3*obj->nbFaces, (3 * sizeof(float)));
for (int i=0; i<3*obj->nbFaces; i++)
{
fscanf(fichier, "\t%f;%f;%f\n", &obj->normales[3*i], &obj->normales[3*i+1], &obj->normales[3*i+2]);
}

/* lire couleurs */
fscanf(fichier, "couleurs:\t%d\n", &obj->nbCouleurs);
printf("%d couleurs\n", obj->nbCouleurs);
obj->couleurs = (float *) calloc(obj->nbCouleurs,(3 * sizeof(float)));
for (int i=0; i<obj->nbCouleurs; i++)
{
fscanf(fichier, "\t%f;%f;%f\n", &obj->couleurs[3*i], &obj->couleurs[3*i+1], &obj->couleurs[3*i+2]);
}

/* lire les coordonn&#65533;es uv */
fscanf(fichier, "uv:\t%d\n", &obj->nbUv);
printf("%d uv coords\n", obj->nbUv);
obj->uv = (float *) calloc(3*obj->nbFaces, (4 * sizeof(float)));
for (int i=0; i<obj->nbFaces; i++)
{
fscanf(fichier, "\t%f;%f", &obj->uv[12*i], &obj->uv[12*i+1]);
obj->uv[12*i+2] = 0.;
obj->uv[12*i+3] = 1.;
fscanf(fichier, ";%f;%f", &obj->uv[12*i+4], &obj->uv[12*i+5]);
obj->uv[12*i+6] = 0.;
obj->uv[12*i+7] = 1.;
fscanf(fichier, ";%f;%f\n", &obj->uv[12*i+8], &obj->uv[12*i+9]);
obj->uv[12*i+10] = 0.;
obj->uv[12*i+11] = 1.;
}

fclose(fichier);
printf("*** Fichier \"%s\" charge ***\n", filename);

return EXIT_SUCCESS;
}

---------------
---------------
---------------

last but not least, an OpenGL function to draw the model :

***** draw.cpp *****
void affiche_modele(Modele *obj)
{
int indice1, indice2, indice3;
float *point1, *point2, *point3;

glBegin(GL_TRIANGLES);
/* pour toutes les faces */
for (int i=0; i<obj->nbFaces;i++)
{
/* on stocke les indices des 3 points de la face */
indice1 = obj->faces[3*i];
indice2 = obj->faces[3*i+1];
indice3 = obj->faces[3*i+2];
/* on fait pointer un pointeur sur chaque point de la face */
point1 = &obj->points[3*indice1];
point2 = &obj->points[3*indice2];
point3 = &obj->points[3*indice3];
/* on affiche le triangle form&#65533; de ces 3 points */
glVertex3fv(point1);
glVertex3fv(point2);
glVertex3fv(point3);
}
glEnd();
}

---------------
---------------
---------------

Sorry, comments and function names are in French :)

To use all of this, here's some example code :

Modele *mesh;
mesh = (Modele *) malloc(sizeof(Modele));
if (mesh0
{
ChargerModele("model_from_export_script.blm", mesh);
affiche_modele(mesh);
}


Good luck.
Any comments are welcome
Olivier

Post Reply