Skip to content

Instantly share code, notes, and snippets.

@neuro-sys
Created December 7, 2014 01:02
Show Gist options
  • Save neuro-sys/33d23051cf4e7266aba6 to your computer and use it in GitHub Desktop.
Save neuro-sys/33d23051cf4e7266aba6 to your computer and use it in GitHub Desktop.
sdl/gl/assimp
#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