Created
December 7, 2014 01:02
-
-
Save neuro-sys/33d23051cf4e7266aba6 to your computer and use it in GitHub Desktop.
sdl/gl/assimp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SDL/SDL.h> | |
#include <GL/gl.h> | |
#include <GL/glu.h> | |
#include <assimp/cimport.h> | |
#include <assimp/scene.h> | |
#include <assimp/postprocess.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define MODEL "dwarf.x" | |
const struct aiScene* scene = NULL; | |
int width = 640; | |
int height = 480; | |
GLuint scene_list; | |
static float angle = 0.f; | |
struct aiVector3D scene_min, scene_max, scene_center; | |
#define aisgl_min(x, y) (x<y?x:y) | |
#define aisgl_max(x, y) (y>x?y:x) | |
void init_video (void) | |
{ | |
const SDL_VideoInfo* info = NULL; | |
int bpp = 0; | |
int flags = 0; | |
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { | |
fprintf(stderr, "Video failed.\n"); | |
abort(); | |
} | |
info = SDL_GetVideoInfo(); | |
if ( !info ) { | |
fprintf(stderr, "Video failed.\n"); | |
abort(); | |
} | |
bpp = info->vfmt->BitsPerPixel; | |
if (SDL_SetVideoMode (width, height, bpp, SDL_OPENGL ) == 0 ) { | |
fprintf(stderr, "Video mode set failed\n"); | |
abort(); | |
} | |
fprintf(stderr, "Video initialized.\n"); | |
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); | |
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); | |
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); | |
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); | |
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | |
} | |
void get_bounding_box_for_node( | |
struct aiNode* nd, | |
struct aiVector3D* min, | |
struct aiVector3D* max, | |
struct aiMatrix4x4* trafo | |
){ | |
struct aiMatrix4x4 prev; | |
unsigned int n = 0, t; | |
prev = *trafo; | |
aiMultiplyMatrix4(trafo, &nd->mTransformation); | |
for (; n < nd->mNumMeshes; n++) { | |
const struct aiMesh * mesh = scene->mMeshes[nd->mMeshes[n]]; | |
for (t = 0; t < mesh->mNumVertices; t++) { | |
struct aiVector3D tmp = mesh->mVertices[t]; | |
aiTransformVecByMatrix4(&tmp, trafo); | |
min->x = aisgl_min(min->x, tmp.x); | |
min->y = aisgl_min(min->y, tmp.y); | |
min->z = aisgl_min(min->z, tmp.z); | |
max->x = aisgl_max(max->x, tmp.x); | |
max->y = aisgl_max(max->y, tmp.y); | |
max->z = aisgl_max(max->z, tmp.z); | |
} | |
} | |
for (n = 0; n < nd->mNumChildren; n++) { | |
get_bounding_box_for_node(nd->mChildren[n], min, max, trafo); | |
} | |
*trafo = prev; | |
} | |
void get_bounding_box(struct aiVector3D *min, struct aiVector3D *max) | |
{ | |
struct aiMatrix4x4 trafo; | |
aiIdentityMatrix4(&trafo); | |
min->x = min->y = min->z = 1e10f; | |
max->x = max->y = max->z = -1e10f; | |
get_bounding_box_for_node(scene->mRootNode, min, max, &trafo); | |
} | |
void init_model(void) | |
{ | |
scene = aiImportFile(MODEL, aiProcess_CalcTangentSpace | | |
aiProcess_Triangulate | | |
aiProcess_JoinIdenticalVertices | | |
aiProcess_SortByPType); | |
if (!scene) { | |
fprintf(stderr, "Model couldn't be loaded\n"); | |
abort(); | |
} | |
get_bounding_box(&scene_min, &scene_max); | |
scene_center.x = (scene_min.x + scene_max.x) / 2.f; | |
scene_center.y = (scene_min.y + scene_max.y) / 2.f; | |
scene_center.z = (scene_min.z + scene_max.z) / 2.f; | |
fprintf(stderr, "Model loaded.\n"); | |
fprintf(stderr, "Number of meshes: %d\n", scene->mNumMeshes); | |
} | |
void recursive_render(const struct aiScene *sc, const struct aiNode * nd) | |
{ | |
unsigned int i; | |
unsigned int n = 0, t; | |
struct aiMatrix4x4 m = nd->mTransformation; | |
aiTransposeMatrix4(&m); | |
glPushMatrix(); | |
glMultMatrixf((float *) &m); | |
for (; n < nd->mNumMeshes; ++n) { | |
const struct aiMesh * mesh = scene->mMeshes[nd->mMeshes[n]]; | |
//apply_material | |
// | |
//if (mesh->mNormals == NULL) | |
glDisable(GL_LIGHTING); | |
//else | |
// glEnable(GL_LIGHTING); | |
for (t = 0; t < mesh->mNumFaces; t++) { | |
const struct aiFace* face = &mesh->mFaces[t]; | |
GLenum face_mode; | |
switch (face->mNumIndices) { | |
case 1: face_mode = GL_POINT; break; | |
case 2: face_mode = GL_LINES; break; | |
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) { | |
glColor4fv((GLfloat*)&mesh->mColors[0][index]); | |
} | |
if (mesh->mNormals != NULL) | |
glNormal3fv(&mesh->mNormals[index].x); | |
glVertex3fv(&mesh->mVertices[index].x); | |
} | |
glEnd(); | |
} | |
} | |
for (n = 0; n < nd->mNumChildren; ++n) { | |
recursive_render(sc, nd->mChildren[n]); | |
} | |
glPopMatrix(); | |
} | |
void display(void) | |
{ | |
float tmp; | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
gluLookAt(0.f, 0.f, 3.f, 0.f, 0.f, -5.f, 0.f, 1.f, 0.f); | |
glRotatef(angle, 0.f, 1.f, 0.f); | |
angle += 1; | |
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*3., tmp*3., tmp*3.); | |
glTranslatef( -scene_center.x, -scene_center.y, -scene_center.z); | |
if (scene_list == 0) { | |
scene_list = glGenLists(1); | |
glNewList(scene_list, GL_COMPILE); | |
recursive_render(scene, scene->mRootNode); | |
glEndList(); | |
} | |
glCallList(scene_list); | |
SDL_GL_SwapBuffers(); | |
} | |
void init_opengl(void) | |
{ | |
float ratio = (float) width / (float) height; | |
glShadeModel(GL_SMOOTH); | |
//glCullFace (GL_BACK); | |
glFrontFace(GL_CCW); | |
glEnable(GL_CULL_FACE); | |
glClearColor(0, 0, 0, 0); | |
glViewport(0, 0, width, height); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE); | |
gluPerspective(60., ratio, 1., 1024.); | |
fprintf(stderr, "OpenGL initialized\n"); | |
} | |
int main(int argc, const char *argv[]) | |
{ | |
init_video(); | |
init_opengl(); | |
init_model(); | |
while (1) { | |
display(); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment