- FEATURE : Add improved OpenGL sample sent by Brad Grantham, many thanks for your work!
- BUGFIX : Fix the library input path for AssImp-library. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@498 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
4639ef0d1b
commit
14283aa036
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
// Simple sample to prove that Assimp is absolutely easy to use with OpenGL.
|
// Simple sample to prove that Assimp is easy to use with OpenGL.
|
||||||
// It takes a file name as command line parameter, loads it using standard
|
// It takes a file name as command line parameter, loads it using standard
|
||||||
// settings and displays it.
|
// settings and displays it.
|
||||||
//
|
//
|
||||||
|
@ -20,7 +19,8 @@
|
||||||
|
|
||||||
// the global Assimp scene object
|
// the global Assimp scene object
|
||||||
const struct aiScene* scene = NULL;
|
const struct aiScene* scene = NULL;
|
||||||
struct aiVector3D scene_min,scene_max;
|
GLuint scene_list = 0;
|
||||||
|
struct aiVector3D scene_min, scene_max, scene_center;
|
||||||
|
|
||||||
// current rotation angle
|
// current rotation angle
|
||||||
static float angle = 0.f;
|
static float angle = 0.f;
|
||||||
|
@ -49,6 +49,7 @@ void get_bounding_box_for_node (const struct aiNode* nd,
|
||||||
struct aiMatrix4x4 prev;
|
struct aiMatrix4x4 prev;
|
||||||
unsigned int n = 0, t;
|
unsigned int n = 0, t;
|
||||||
|
|
||||||
|
prev = *trafo;
|
||||||
aiMultiplyMatrix4(trafo,&nd->mTransformation);
|
aiMultiplyMatrix4(trafo,&nd->mTransformation);
|
||||||
|
|
||||||
for (; n < nd->mNumMeshes; ++n) {
|
for (; n < nd->mNumMeshes; ++n) {
|
||||||
|
@ -68,7 +69,6 @@ void get_bounding_box_for_node (const struct aiNode* nd,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
prev = nd->mTransformation;
|
|
||||||
for (n = 0; n < nd->mNumChildren; ++n) {
|
for (n = 0; n < nd->mNumChildren; ++n) {
|
||||||
get_bounding_box_for_node(nd->mChildren[n],min,max,trafo);
|
get_bounding_box_for_node(nd->mChildren[n],min,max,trafo);
|
||||||
}
|
}
|
||||||
|
@ -87,37 +87,156 @@ void get_bounding_box (struct aiVector3D* min, struct aiVector3D* max)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
void recursive_render (const struct aiNode* nd)
|
|
||||||
|
void color4_to_float4(const struct aiColor4D *c, float f[4])
|
||||||
{
|
{
|
||||||
|
f[0] = c->r;
|
||||||
|
f[1] = c->g;
|
||||||
|
f[2] = c->b;
|
||||||
|
f[3] = c->a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_float4(float f[4], float a, float b, float c, float d)
|
||||||
|
{
|
||||||
|
f[0] = a;
|
||||||
|
f[1] = b;
|
||||||
|
f[2] = c;
|
||||||
|
f[3] = d;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void apply_material(const struct aiMaterial *mtl)
|
||||||
|
{
|
||||||
|
float c[4];
|
||||||
|
|
||||||
|
GLenum fill_mode;
|
||||||
|
int ret1, ret2;
|
||||||
|
struct aiColor4D diffuse;
|
||||||
|
struct aiColor4D specular;
|
||||||
|
struct aiColor4D ambient;
|
||||||
|
struct aiColor4D emission;
|
||||||
|
float shininess, strength;
|
||||||
|
int two_sided;
|
||||||
|
int wireframe;
|
||||||
|
int max;
|
||||||
|
|
||||||
|
set_float4(c, 0.8f, 0.8f, 0.8f, 1.0f);
|
||||||
|
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_DIFFUSE, &diffuse))
|
||||||
|
color4_to_float4(&diffuse, c);
|
||||||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c);
|
||||||
|
|
||||||
|
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_SPECULAR, &specular))
|
||||||
|
color4_to_float4(&specular, c);
|
||||||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
|
||||||
|
|
||||||
|
set_float4(c, 0.2f, 0.2f, 0.2f, 1.0f);
|
||||||
|
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_AMBIENT, &ambient))
|
||||||
|
color4_to_float4(&ambient, c);
|
||||||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c);
|
||||||
|
|
||||||
|
set_float4(c, 0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
if(AI_SUCCESS == aiGetMaterialColor(mtl, AI_MATKEY_COLOR_EMISSIVE, &emission))
|
||||||
|
color4_to_float4(&emission, c);
|
||||||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c);
|
||||||
|
|
||||||
|
max = 1;
|
||||||
|
ret1 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS, &shininess, &max);
|
||||||
|
max = 1;
|
||||||
|
ret2 = aiGetMaterialFloatArray(mtl, AI_MATKEY_SHININESS_STRENGTH, &strength, &max);
|
||||||
|
if((ret1 == AI_SUCCESS) && (ret2 == AI_SUCCESS))
|
||||||
|
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess * strength);
|
||||||
|
else {
|
||||||
|
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.0f);
|
||||||
|
set_float4(c, 0.0f, 0.0f, 0.0f, 0.0f);
|
||||||
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
max = 1;
|
||||||
|
if(AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_ENABLE_WIREFRAME, &wireframe, &max))
|
||||||
|
fill_mode = wireframe ? GL_LINE : GL_FILL;
|
||||||
|
else
|
||||||
|
fill_mode = GL_FILL;
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, fill_mode);
|
||||||
|
|
||||||
|
max = 1;
|
||||||
|
if((AI_SUCCESS == aiGetMaterialIntegerArray(mtl, AI_MATKEY_TWOSIDED, &two_sided, &max)) && two_sided)
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
else
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Can't send color down as a pointer to aiColor4D because AI colors are ABGR.
|
||||||
|
void Color4f(const struct aiColor4D *color)
|
||||||
|
{
|
||||||
|
glColor4f(color->r, color->g, color->b, color->a);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void recursive_render (const struct aiScene *sc, const struct aiNode* nd)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
unsigned int n = 0, t;
|
unsigned int n = 0, t;
|
||||||
struct aiMatrix4x4 m = nd->mTransformation;
|
struct aiMatrix4x4 m = nd->mTransformation;
|
||||||
|
|
||||||
// update transform
|
// update transform
|
||||||
aiTransposeMatrix4(&m);
|
aiTransposeMatrix4(&m);
|
||||||
|
glPushMatrix();
|
||||||
glMultMatrixf((float*)&m);
|
glMultMatrixf((float*)&m);
|
||||||
|
|
||||||
// draw all meshes assigned to this node
|
// draw all meshes assigned to this node
|
||||||
for (; n < nd->mNumMeshes; ++n) {
|
for (; n < nd->mNumMeshes; ++n) {
|
||||||
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
|
const struct aiMesh* mesh = scene->mMeshes[nd->mMeshes[n]];
|
||||||
|
|
||||||
glBegin(GL_TRIANGLES);
|
apply_material(sc->mMaterials[mesh->mMaterialIndex]);
|
||||||
|
|
||||||
|
if(mesh->mNormals == NULL) {
|
||||||
|
glDisable(GL_LIGHTING);
|
||||||
|
} else {
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mesh->mColors[0] != NULL) {
|
||||||
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_COLOR_MATERIAL);
|
||||||
|
}
|
||||||
|
|
||||||
for (t = 0; t < mesh->mNumFaces; ++t) {
|
for (t = 0; t < mesh->mNumFaces; ++t) {
|
||||||
const struct aiFace* face = &mesh->mFaces[t];
|
const struct aiFace* face = &mesh->mFaces[t];
|
||||||
|
GLenum face_mode;
|
||||||
|
|
||||||
glColor3f(1.f,0.f,0.f);
|
switch(face->mNumIndices) {
|
||||||
glVertex3fv(&mesh->mVertices[face->mIndices[0]].x);
|
case 1: face_mode = GL_POINTS; break;
|
||||||
glVertex3fv(&mesh->mVertices[face->mIndices[1]].x);
|
case 2: face_mode = GL_LINES; break;
|
||||||
glVertex3fv(&mesh->mVertices[face->mIndices[2]].x);
|
case 3: face_mode = GL_TRIANGLES; break;
|
||||||
|
default: face_mode = GL_POLYGON; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBegin(face_mode);
|
||||||
|
|
||||||
|
for(i = 0; i < face->mNumIndices; i++) {
|
||||||
|
int index = face->mIndices[i];
|
||||||
|
if(mesh->mColors[0] != NULL)
|
||||||
|
Color4f(&mesh->mColors[0][index]);
|
||||||
|
if(mesh->mNormals != NULL)
|
||||||
|
glNormal3fv(&mesh->mNormals[index].x);
|
||||||
|
glVertex3fv(&mesh->mVertices[index].x);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw all children
|
// draw all children
|
||||||
for (n = 0; n < nd->mNumChildren; ++n) {
|
for (n = 0; n < nd->mNumChildren; ++n) {
|
||||||
recursive_render(nd->mChildren[n]);
|
recursive_render(sc, nd->mChildren[n]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glPopMatrix();
|
||||||
}
|
}
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
@ -136,29 +255,40 @@ void do_motion (void)
|
||||||
void display(void)
|
void display(void)
|
||||||
{
|
{
|
||||||
float tmp;
|
float tmp;
|
||||||
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f);
|
gluLookAt(0.f,0.f,3.f,0.f,0.f,-5.f,0.f,1.f,0.f);
|
||||||
|
|
||||||
// scale the whole asset to fit into our view frustum
|
|
||||||
tmp = scene_max.x-scene_min.x;
|
|
||||||
tmp = aisgl_max(scene_max.y-scene_min.y,tmp);
|
|
||||||
tmp = aisgl_max(scene_max.z-scene_min.z,tmp);
|
|
||||||
|
|
||||||
tmp = 1.f/(tmp);
|
|
||||||
glScalef(tmp,tmp,tmp);
|
|
||||||
|
|
||||||
// fixme: center around origin
|
|
||||||
|
|
||||||
// rotate it around the y axis
|
// rotate it around the y axis
|
||||||
glRotatef(angle,0.f,1.f,0.f);
|
glRotatef(angle,0.f,1.f,0.f);
|
||||||
|
|
||||||
// now begin at the root node of the imported data and traverse
|
// scale the whole asset to fit into our view frustum
|
||||||
// the scenegraph by multipliying subsequent local transforms
|
tmp = scene_max.x-scene_min.x;
|
||||||
// together on GL's matrix stack.
|
tmp = aisgl_max(scene_max.y - scene_min.y,tmp);
|
||||||
recursive_render(scene->mRootNode);
|
tmp = aisgl_max(scene_max.z - scene_min.z,tmp);
|
||||||
|
tmp = 1.f / tmp;
|
||||||
|
glScalef(tmp, tmp, tmp);
|
||||||
|
|
||||||
|
// center the model
|
||||||
|
glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z );
|
||||||
|
|
||||||
|
// if the display list has not been made yet, create a new one and
|
||||||
|
// fill it with scene contents
|
||||||
|
if(scene_list == 0) {
|
||||||
|
scene_list = glGenLists(1);
|
||||||
|
glNewList(scene_list, GL_COMPILE);
|
||||||
|
// now begin at the root node of the imported data and traverse
|
||||||
|
// the scenegraph by multiplying subsequent local transforms
|
||||||
|
// together on GL's matrix stack.
|
||||||
|
recursive_render(scene, scene->mRootNode);
|
||||||
|
glEndList();
|
||||||
|
}
|
||||||
|
|
||||||
|
glCallList(scene_list);
|
||||||
|
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
|
|
||||||
do_motion();
|
do_motion();
|
||||||
|
@ -172,8 +302,10 @@ int loadasset (const char* path)
|
||||||
scene = aiImportFile(path,aiProcessPreset_TargetRealtime_Quality);
|
scene = aiImportFile(path,aiProcessPreset_TargetRealtime_Quality);
|
||||||
|
|
||||||
if (scene) {
|
if (scene) {
|
||||||
|
|
||||||
get_bounding_box(&scene_min,&scene_max);
|
get_bounding_box(&scene_min,&scene_max);
|
||||||
|
scene_center.x = (scene_min.x + scene_max.x) / 2.0f;
|
||||||
|
scene_center.y = (scene_min.y + scene_max.y) / 2.0f;
|
||||||
|
scene_center.z = (scene_min.z + scene_max.z) / 2.0f;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -183,6 +315,7 @@ int loadasset (const char* path)
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct aiLogStream stream;
|
struct aiLogStream stream;
|
||||||
|
|
||||||
glutInitWindowSize(900,600);
|
glutInitWindowSize(900,600);
|
||||||
glutInitWindowPosition(100,100);
|
glutInitWindowPosition(100,100);
|
||||||
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
|
||||||
|
@ -209,10 +342,22 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glPolygonMode(GL_FRONT,GL_LINE);
|
|
||||||
glPolygonMode(GL_BACK,GL_LINE);
|
|
||||||
glClearColor(0.1f,0.1f,0.1f,1.f);
|
glClearColor(0.1f,0.1f,0.1f,1.f);
|
||||||
|
|
||||||
|
glEnable(GL_LIGHTING);
|
||||||
|
glEnable(GL_LIGHT0); // Uses default lighting parameters
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
|
||||||
|
glEnable(GL_NORMALIZE);
|
||||||
|
|
||||||
|
// XXX docs say all polygons are emitted CCW, but tests show that some aren't.
|
||||||
|
if(getenv("MODEL_IS_BROKEN"))
|
||||||
|
glFrontFace(GL_CW);
|
||||||
|
|
||||||
|
glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
|
||||||
|
|
||||||
glutGet(GLUT_ELAPSED_TIME);
|
glutGet(GLUT_ELAPSED_TIME);
|
||||||
glutMainLoop();
|
glutMainLoop();
|
||||||
|
|
||||||
|
|
|
@ -63,7 +63,7 @@
|
||||||
Name="VCLinkerTool"
|
Name="VCLinkerTool"
|
||||||
AdditionalDependencies="glut32.lib assimp.lib"
|
AdditionalDependencies="glut32.lib assimp.lib"
|
||||||
LinkIncremental="2"
|
LinkIncremental="2"
|
||||||
AdditionalLibraryDirectories="..\..\..\glut;"..\..\..\..\lib\assimp_release-dll_win32""
|
AdditionalLibraryDirectories="..\..\..\glut;"..\..\..\..\lib\assimp_debug_win32""
|
||||||
GenerateDebugInformation="true"
|
GenerateDebugInformation="true"
|
||||||
SubSystem="1"
|
SubSystem="1"
|
||||||
TargetMachine="1"
|
TargetMachine="1"
|
||||||
|
|
Loading…
Reference in New Issue