From ffe4f07ace60f5b82425d70060a7ae4ba14d66f6 Mon Sep 17 00:00:00 2001 From: josh Date: Sun, 3 Jun 2007 02:38:40 +0000 Subject: [PATCH] stl: added the beginning of a viewer git-svn-id: svn://anubis/misc/stl@5 bd8a9e45-a331-0410-811e-c64571078777 --- Makefile | 14 ++++++ stl-viewer.c | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++ stl.c | 19 ++++++-- stl.h | 4 +- test.stl | Bin 0 -> 684 bytes 5 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 Makefile create mode 100644 stl-viewer.c create mode 100644 test.stl diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..21bc13d --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ + +CFLAGS = -O2 `sdl-config --cflags` +LDFLAGS = `sdl-config --libs` -lGL -lGLU + +all: stl-viewer + +stl-viewer: stl-viewer.o stl.o + gcc -o $@ $^ $(LDFLAGS) + +stl-viewer.o: stl-viewer.c stl.h + gcc -c -o $@ $< $(CFLAGS) + +stl.o: stl.c stl.h + gcc -c -o $@ $< $(CFLAGS) diff --git a/stl-viewer.c b/stl-viewer.c new file mode 100644 index 0000000..f4f0462 --- /dev/null +++ b/stl-viewer.c @@ -0,0 +1,133 @@ + +#include +#include +#include +#include "stl.h" + +#define WIDTH 500 +#define HEIGHT 500 + +stl_t * stl = NULL; +GLuint stldl; +GLfloat default_color[] = {1, 1, 1, 1}; + +GLuint buildDL(void); +void init(void); +void display(void); +void reshape(GLsizei w, GLsizei h); + +void init(void) +{ + glClearColor (0.0, 0.0, 0.0, 0.0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glShadeModel(GL_SMOOTH); +} + +void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBegin(GL_QUADS); + glVertex3f(-2.0, -1.0, 0.0); + glVertex3f(-2.0, 1.0, 0.0); + glVertex3f(0.0, 1.0, 0.0); + glVertex3f(0.0, -1.0, 0.0); + glEnd(); + SDL_GL_SwapBuffers(); +} + +void reshape(GLsizei w, GLsizei h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, 1.0*(GLfloat)w/(GLfloat)h, 1.0, 30.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -3.6); +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) + { + fprintf(stderr, "Usage: %s \n", argv[0]); + return -1; + } + + stl = stl_load(argv[1]); + if (stl == NULL) + { + fprintf(stderr, "Error loading '%s'\n", argv[1]); + return -2; + } + stldl = buildDL(); + + if (SDL_Init(SDL_INIT_VIDEO)) + { + fprintf(stderr, "Failed to initialize SDL!\n"); + return 1; + } + + atexit(SDL_Quit); + + SDL_Surface *screen; + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + if (!(screen = SDL_SetVideoMode(WIDTH, HEIGHT, 16, SDL_OPENGL))) + { + fprintf(stderr, "Failed to set video mode!\n"); + return 2; + } + SDL_WM_SetCaption(argv[0], argv[0]); + + init(); + reshape(WIDTH, HEIGHT); + display(); + SDL_Event event; + while (SDL_WaitEvent(&event)) + { + if (event.type == SDL_QUIT) + break; + else if (event.type == SDL_KEYDOWN) + { + if (event.key.keysym.sym == SDLK_ESCAPE) + break; + } + } + + free(stl); +} + +GLuint buildDL(void) +{ + unsigned int n_faces = stl_num_faces(stl); + unsigned int i; + int dfltClrAct = 1; + GLfloat color[4]; + color[3] = 0.0f; + GLuint dl = glGenLists(1); + glNewList(dl, GL_COMPILE); + glBegin(GL_TRIANGLES); + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, default_color); + for (i = 0; i < n_faces; i++) + { + if (stl_attr_color_valid(stl_face(stl, i).attribute)) + { + color[0] = stl_attr_color_r(stl_face(stl, i).attribute) / (float) 255; + color[1] = stl_attr_color_g(stl_face(stl, i).attribute) / (float) 255; + color[2] = stl_attr_color_b(stl_face(stl, i).attribute) / (float) 255; + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, color); + dfltClrAct = 0; + } + else if (!dfltClrAct) + glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, + default_color); + int j; + for (j = 0; j < 3; j++) + glVertex3fv(stl_face(stl, i).vertices[j]); + } + glEnd(); + glEndList(); + return dl; +} diff --git a/stl.c b/stl.c index d9bcb37..ef41827 100644 --- a/stl.c +++ b/stl.c @@ -1,6 +1,7 @@ -#include -#include +#include /* struct stat */ +#include /* malloc() */ +#include /* fprintf() */ #include "stl.h" /* load a STL file and return a pointer to the stl_t struct */ @@ -8,19 +9,29 @@ stl_t * stl_load(const char * filename) { struct stat s; if (stat(filename, &s)) + { + fprintf(stderr, "Couldn't stat '%s'\n", filename); return NULL; - int size = s.st_size; - if (size < sizeof(stl_t)) + } + if (s.st_size < sizeof(stl_t)) + { + fprintf(stderr, "Size of '%s' only %d bytes!\n", filename, s.st_size); return NULL; + } FILE *fil; if ((fil = fopen(filename, "rb")) == NULL) + { + fprintf(stderr, "Couldn't open '%s'\n", filename); return NULL; + } stl_t * stl = (stl_t *) malloc(s.st_size); fread(stl, 1, s.st_size, fil); fclose(fil); if (s.st_size < sizeof(stl_t) + sizeof(stl_face_t) * (stl_num_faces(stl)-1)) { + fprintf(stderr, "Size of '%s' only %d bytes, but has %d faces!\n", + filename, s.st_size, stl_num_faces(stl)); free(stl); return NULL; } diff --git a/stl.h b/stl.h index 5ca140b..0c93291 100644 --- a/stl.h +++ b/stl.h @@ -25,14 +25,14 @@ typedef struct stl_face_s float normal[3]; float vertices[3][3]; unsigned short attribute; -} stl_face_t; +} __attribute__ ((packed)) stl_face_t; typedef struct stl_s { char header[STL_HEADER_LENGTH]; unsigned int n_faces; stl_face_t faces[1]; -} stl_t; +} __attribute__ ((packed)) stl_t; /* functions */ diff --git a/test.stl b/test.stl new file mode 100644 index 0000000000000000000000000000000000000000..0124a066f0ca275e71b19aeeb0bee32fdded3a25 GIT binary patch literal 684 zcmZ?D%u6h)R0t07QOGYXDJU&bNGr}b)C5!=EI`rk z5IaD2!R)aIs@@OM1+o{n4rEndfu^uRU5cs$WCqM1$o3JZ16dVvC}7$F3J(xQ)`9Fo m+&Yj|A%`2P4rCc*9mwH^TL-c#;^G52+=$bGtP0sa1qA@xA;cg6 literal 0 HcmV?d00001