mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-06 17:30:20 +01:00
progs/objviewer: Wavefront .obj file loader/viewer demo
Adapted from code written by Nate Robins. See README.txt.
This commit is contained in:
parent
e32a341be6
commit
ca1bda552d
20 changed files with 764987 additions and 0 deletions
161
progs/objviewer/GreatLakesBiplaneHP.mtl
Normal file
161
progs/objviewer/GreatLakesBiplaneHP.mtl
Normal file
|
|
@ -0,0 +1,161 @@
|
|||
# Exported from Wings 3D 0.99.03
|
||||
|
||||
# Top flaps
|
||||
newmtl BottomWing
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 0.0 0.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd TopBotMap.rgb
|
||||
|
||||
newmtl CompBall_auv
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd CompBall_auv.rgb
|
||||
|
||||
newmtl EngMat1
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.334 0.334 0.334
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl EngMat2
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.78688 0.78688 0.78688
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl Fuselage_auv
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 0.0 0.0 0.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd SidesMap.rgb
|
||||
|
||||
newmtl Glass
|
||||
Ns 100.0
|
||||
d 0.5
|
||||
illum 2
|
||||
#Kd 0.5533333333333333 1.0 1.0
|
||||
Kd 1.0 1.0 1.0
|
||||
#Ka 0.37333333333333335 0.68 1.0
|
||||
Ka 0.0 0.0 0.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl Grip
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.47386 0.47386 0.47386
|
||||
Ka 0.6203799999999999 0.6203799999999999 0.6203799999999999
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl Interior
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.70696 0.70696 0.70696
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl Prop
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 0.6266666666666667
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd PropMap.rgb
|
||||
|
||||
# Rudder
|
||||
newmtl Sides
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 0.0 0.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd SidesMap.rgb
|
||||
|
||||
newmtl TailHoriz
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 0.0 0.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd TopBotMap.rgb
|
||||
|
||||
# Top wing, bot wing, fuselage
|
||||
newmtl TopWing
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd TopBotMap.rgb
|
||||
|
||||
newmtl Wheels
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.0 0.0 0.0
|
||||
Ka 0.0 0.0 0.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd WheelsMap.rgb
|
||||
|
||||
newmtl cylinder58_auv
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd cylinder58_auv.rgb
|
||||
|
||||
newmtl default
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 0.0 1.0 1.0
|
||||
Ka 0.0 1.0 1.0
|
||||
Ks 0.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
|
||||
newmtl gage_auv
|
||||
Ns 100.0
|
||||
d 1.0
|
||||
illum 2
|
||||
Kd 1.0 1.0 1.0
|
||||
Ka 1.0 1.0 1.0
|
||||
Ks 1.0 1.0 1.0
|
||||
Ke 0.0 0.0 0.0
|
||||
map_Kd gage_auv.rgb
|
||||
|
||||
497539
progs/objviewer/GreatLakesBiplaneHP.obj
Normal file
497539
progs/objviewer/GreatLakesBiplaneHP.obj
Normal file
File diff suppressed because it is too large
Load diff
83
progs/objviewer/Makefile
Normal file
83
progs/objviewer/Makefile
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
TOP = ../..
|
||||
include $(TOP)/configs/current
|
||||
|
||||
INCDIR = $(TOP)/include
|
||||
|
||||
LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) \
|
||||
-l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
|
||||
|
||||
# using : to avoid APP_CC pointing to CC loop
|
||||
CC := $(APP_CC)
|
||||
CFLAGS := -I$(INCDIR) $(CFLAGS)
|
||||
LDLIBS = $(LIBS)
|
||||
|
||||
SOURCES = \
|
||||
glm.c \
|
||||
glmdraw.c \
|
||||
objview.c \
|
||||
trackball.c \
|
||||
skybox.c \
|
||||
readtex.c \
|
||||
shaderutil.c
|
||||
|
||||
HEADERS = \
|
||||
extfuncs.h \
|
||||
readtex.h \
|
||||
shaderutil.h \
|
||||
trackball.h
|
||||
|
||||
OBJS = $(SOURCES:.c=.o)
|
||||
|
||||
PROG = objview
|
||||
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
default: $(PROG)
|
||||
|
||||
$(PROG): $(OBJS)
|
||||
$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@
|
||||
|
||||
$(OBJS): $(HEADERS)
|
||||
|
||||
|
||||
### Extra dependencies
|
||||
|
||||
extfuncs.h: $(TOP)/progs/util/extfuncs.h
|
||||
cp $< .
|
||||
|
||||
readtex.c: $(TOP)/progs/util/readtex.c
|
||||
cp $< .
|
||||
|
||||
readtex.h: $(TOP)/progs/util/readtex.h
|
||||
cp $< .
|
||||
|
||||
shaderutil.c: $(TOP)/progs/util/shaderutil.c
|
||||
cp $< .
|
||||
|
||||
shaderutil.h: $(TOP)/progs/util/shaderutil.h
|
||||
cp $< .
|
||||
|
||||
trackball.c: $(TOP)/progs/util/trackball.c
|
||||
cp $< .
|
||||
|
||||
trackball.h: $(TOP)/progs/util/trackball.h
|
||||
cp $< .
|
||||
|
||||
|
||||
clean:
|
||||
-rm -f $(PROG) $(OBJS)
|
||||
-rm -f *.o *~
|
||||
-rm -f extfuncs.h
|
||||
-rm -f shaderutil.*
|
||||
-rm -f trackball.*
|
||||
-rm -f readtex.*
|
||||
|
||||
|
||||
depend: $(SOURCES)
|
||||
@$(MKDEP) $(MKDEP_OPTIONS) $(INCLUDE_DIRS) $(SOURCES) \
|
||||
> /dev/null 2>/dev/null
|
||||
|
||||
|
||||
-include depend
|
||||
15
progs/objviewer/README.txt
Normal file
15
progs/objviewer/README.txt
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
This .obj viewer is based on the "smooth" program by Nate Robins
|
||||
found in the Kilgard GLUT package.
|
||||
|
||||
The alpine sky box textures come from http://www.hazelwhorley.com/skyboxtex3_bitmaps.html
|
||||
|
||||
The bunny.obj and buddha.obj models come from Stanford.
|
||||
|
||||
The GreatLakesBiplaneHP.obj model comes from http://www.sharecg.com/v/25978/3D-Model/Great-Lakes-Biplane-Model
|
||||
|
||||
The bobcat.obj model comes from http://www.sharecg.com/v/24771/3D-Model/Bobcat,3d-studio-and-wavefront-objects
|
||||
|
||||
The .obj file reader code in glm.c isn't perfect. Not all .obj files are
|
||||
parsed correctly. There are often mistakes in material-to-triangle assignments.
|
||||
|
||||
BIN
progs/objviewer/alpine_down.rgb
Normal file
BIN
progs/objviewer/alpine_down.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_east.rgb
Normal file
BIN
progs/objviewer/alpine_east.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_north.rgb
Normal file
BIN
progs/objviewer/alpine_north.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_south.rgb
Normal file
BIN
progs/objviewer/alpine_south.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_up.rgb
Normal file
BIN
progs/objviewer/alpine_up.rgb
Normal file
Binary file not shown.
BIN
progs/objviewer/alpine_west.rgb
Normal file
BIN
progs/objviewer/alpine_west.rgb
Normal file
Binary file not shown.
72
progs/objviewer/bobcat.mtl
Normal file
72
progs/objviewer/bobcat.mtl
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Exported from Wings 3D 0.99.00b
|
||||
newmtl black
|
||||
Ns 48.6667
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 1.00000e-3 1.00000e-3 1.00000e-3
|
||||
Ka 1.00000 1.00000 1.00000
|
||||
Ks 1.00000 1.00000 1.00000
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl blanco
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 1.00000 1.00000 1.00000
|
||||
Ka 0.620380 0.620380 0.620380
|
||||
Ks 0.806860 0.806860 0.806860
|
||||
Ke 1.00000e-3 1.00000e-3 1.00000e-3
|
||||
|
||||
newmtl blue
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 0.105111 0.125293 0.366667
|
||||
Ka 1.00000 1.00000 1.00000
|
||||
Ks 1.00000 1.00000 1.00000
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl default
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 1.00000 1.00000 1.00000
|
||||
Ka 1.00000 1.00000 1.00000
|
||||
Ks 1.00000 1.00000 1.00000
|
||||
Ka 0.10000 0.10000 0.10000
|
||||
Ks 0.50000 0.50000 0.500000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl gre
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 0.200800 0.200800 0.200800
|
||||
Ka 1.00000 1.00000 1.00000
|
||||
Ks 1.00000 1.00000 1.00000
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl red
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 0.460000 0.00000e+0 0.00000e+0
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 0.00000e+0 0.00000e+0 0.00000e+0
|
||||
|
||||
newmtl rojo
|
||||
Ns 100.000
|
||||
d 1.00000
|
||||
illum 2
|
||||
Kd 0.700000 0.00000e+0 0.00000e+0
|
||||
Ka 0.00000 0.00000 0.00000
|
||||
Ks 0.00000 0.00000 0.00000
|
||||
Ke 1.00000e-3 1.00000e-3 1.00000e-3
|
||||
|
||||
9251
progs/objviewer/bobcat.obj
Normal file
9251
progs/objviewer/bobcat.obj
Normal file
File diff suppressed because it is too large
Load diff
149990
progs/objviewer/buddha.obj
Normal file
149990
progs/objviewer/buddha.obj
Normal file
File diff suppressed because it is too large
Load diff
104501
progs/objviewer/bunny.obj
Normal file
104501
progs/objviewer/bunny.obj
Normal file
File diff suppressed because it is too large
Load diff
1917
progs/objviewer/glm.c
Normal file
1917
progs/objviewer/glm.c
Normal file
File diff suppressed because it is too large
Load diff
287
progs/objviewer/glm.h
Normal file
287
progs/objviewer/glm.h
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* GLM library. Wavefront .obj file format reader/writer/manipulator.
|
||||
*
|
||||
* Written by Nate Robins, 1997.
|
||||
* email: ndr@pobox.com
|
||||
* www: http://www.pobox.com/~ndr
|
||||
*/
|
||||
|
||||
#ifndef GLM_H
|
||||
#define GLM_H
|
||||
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265
|
||||
#endif
|
||||
|
||||
|
||||
/* defines */
|
||||
#define GLM_NONE (0) /* render with only vertices */
|
||||
#define GLM_FLAT (1 << 0) /* render with facet normals */
|
||||
#define GLM_SMOOTH (1 << 1) /* render with vertex normals */
|
||||
#define GLM_TEXTURE (1 << 2) /* render with texture coords */
|
||||
#define GLM_COLOR (1 << 3) /* render with colors */
|
||||
#define GLM_MATERIAL (1 << 4) /* render with materials */
|
||||
|
||||
|
||||
/* structs */
|
||||
|
||||
/* GLMmaterial: Structure that defines a material in a model.
|
||||
*/
|
||||
typedef struct _GLMmaterial
|
||||
{
|
||||
char* name; /* name of material */
|
||||
float diffuse[4]; /* diffuse component */
|
||||
float ambient[4]; /* ambient component */
|
||||
float specular[4]; /* specular component */
|
||||
float emmissive[4]; /* emmissive component */
|
||||
float shininess; /* specular exponent */
|
||||
char *map_kd; /* diffuse texture map file */
|
||||
uint texture_kd; /* diffuse texture map */
|
||||
uint texture_ks; /* specular texture map */
|
||||
int uDiffuse, uAmbient, uSpecular, uShininess, uDiffTex, uSpecTex;
|
||||
uint prog;
|
||||
} GLMmaterial;
|
||||
|
||||
/* GLMtriangle: Structure that defines a triangle in a model.
|
||||
*/
|
||||
typedef struct {
|
||||
uint vindices[3]; /* array of triangle vertex indices */
|
||||
uint nindices[3]; /* array of triangle normal indices */
|
||||
uint tindices[3]; /* array of triangle texcoord indices*/
|
||||
uint findex; /* index of triangle facet normal */
|
||||
} GLMtriangle;
|
||||
|
||||
/* GLMgroup: Structure that defines a group in a model.
|
||||
*/
|
||||
typedef struct _GLMgroup {
|
||||
char* name; /* name of this group */
|
||||
uint numtriangles; /* number of triangles in this group */
|
||||
uint* triangles; /* array of triangle indices */
|
||||
uint material; /* index to material for group */
|
||||
uint * triIndexes;
|
||||
uint minIndex, maxIndex;
|
||||
struct _GLMgroup* next; /* pointer to next group in model */
|
||||
} GLMgroup;
|
||||
|
||||
/* GLMmodel: Structure that defines a model.
|
||||
*/
|
||||
typedef struct {
|
||||
char* pathname; /* path to this model */
|
||||
char* mtllibname; /* name of the material library */
|
||||
|
||||
uint numvertices; /* number of vertices in model */
|
||||
float* vertices; /* array of vertices */
|
||||
|
||||
uint numnormals; /* number of normals in model */
|
||||
float* normals; /* array of normals */
|
||||
|
||||
uint numtexcoords; /* number of texcoords in model */
|
||||
float* texcoords; /* array of texture coordinates */
|
||||
|
||||
uint numfacetnorms; /* number of facetnorms in model */
|
||||
float* facetnorms; /* array of facetnorms */
|
||||
|
||||
uint numtriangles; /* number of triangles in model */
|
||||
GLMtriangle* triangles; /* array of triangles */
|
||||
|
||||
uint nummaterials; /* number of materials in model */
|
||||
GLMmaterial* materials; /* array of materials */
|
||||
|
||||
uint numgroups; /* number of groups in model */
|
||||
GLMgroup* groups; /* linked list of groups */
|
||||
|
||||
float position[3]; /* position of the model */
|
||||
float scale;
|
||||
|
||||
uint vbo; /* OpenGL VBO for vertex data */
|
||||
uint vertexSize; /* number of floats per vertex */
|
||||
uint posOffset; /* offset of position within vertex, in bytes */
|
||||
uint normOffset; /* offset of normal within vertex, in bytes */
|
||||
uint texOffset; /* offset of texcoord within vertex, in bytes */
|
||||
} GLMmodel;
|
||||
|
||||
|
||||
/* public functions */
|
||||
|
||||
/* glmUnitize: "unitize" a model by translating it to the origin and
|
||||
* scaling it to fit in a unit cube around the origin. Returns the
|
||||
* scalefactor used.
|
||||
*
|
||||
* model - properly initialized GLMmodel structure
|
||||
*/
|
||||
float
|
||||
glmUnitize(GLMmodel* model);
|
||||
|
||||
/* glmDimensions: Calculates the dimensions (width, height, depth) of
|
||||
* a model.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* dimensions - array of 3 floats (float dimensions[3])
|
||||
*/
|
||||
void
|
||||
glmDimensions(GLMmodel* model, float* dimensions);
|
||||
|
||||
/* glmScale: Scales a model by a given amount.
|
||||
*
|
||||
* model - properly initialized GLMmodel structure
|
||||
* scale - scalefactor (0.5 = half as large, 2.0 = twice as large)
|
||||
*/
|
||||
void
|
||||
glmScale(GLMmodel* model, float scale);
|
||||
|
||||
/* glmReverseWinding: Reverse the polygon winding for all polygons in
|
||||
* this model. Default winding is counter-clockwise. Also changes
|
||||
* the direction of the normals.
|
||||
*
|
||||
* model - properly initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmReverseWinding(GLMmodel* model);
|
||||
|
||||
/* glmFacetNormals: Generates facet normals for a model (by taking the
|
||||
* cross product of the two vectors derived from the sides of each
|
||||
* triangle). Assumes a counter-clockwise winding.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmFacetNormals(GLMmodel* model);
|
||||
|
||||
/* glmVertexNormals: Generates smooth vertex normals for a model.
|
||||
* First builds a list of all the triangles each vertex is in. Then
|
||||
* loops through each vertex in the the list averaging all the facet
|
||||
* normals of the triangles each vertex is in. Finally, sets the
|
||||
* normal index in the triangle for the vertex to the generated smooth
|
||||
* normal. If the dot product of a facet normal and the facet normal
|
||||
* associated with the first triangle in the list of triangles the
|
||||
* current vertex is in is greater than the cosine of the angle
|
||||
* parameter to the function, that facet normal is not added into the
|
||||
* average normal calculation and the corresponding vertex is given
|
||||
* the facet normal. This tends to preserve hard edges. The angle to
|
||||
* use depends on the model, but 90 degrees is usually a good start.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* angle - maximum angle (in degrees) to smooth across
|
||||
*/
|
||||
void
|
||||
glmVertexNormals(GLMmodel* model, float angle);
|
||||
|
||||
/* glmLinearTexture: Generates texture coordinates according to a
|
||||
* linear projection of the texture map. It generates these by
|
||||
* linearly mapping the vertices onto a square.
|
||||
*
|
||||
* model - pointer to initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmLinearTexture(GLMmodel* model);
|
||||
|
||||
/* glmSpheremapTexture: Generates texture coordinates according to a
|
||||
* spherical projection of the texture map. Sometimes referred to as
|
||||
* spheremap, or reflection map texture coordinates. It generates
|
||||
* these by using the normal to calculate where that vertex would map
|
||||
* onto a sphere. Since it is impossible to map something flat
|
||||
* perfectly onto something spherical, there is distortion at the
|
||||
* poles. This particular implementation causes the poles along the X
|
||||
* axis to be distorted.
|
||||
*
|
||||
* model - pointer to initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmSpheremapTexture(GLMmodel* model);
|
||||
|
||||
/* glmDelete: Deletes a GLMmodel structure.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
*/
|
||||
void
|
||||
glmDelete(GLMmodel* model);
|
||||
|
||||
/* glmReadOBJ: Reads a model description from a Wavefront .OBJ file.
|
||||
* Returns a pointer to the created object which should be free'd with
|
||||
* glmDelete().
|
||||
*
|
||||
* filename - name of the file containing the Wavefront .OBJ format data.
|
||||
*/
|
||||
GLMmodel*
|
||||
glmReadOBJ(char* filename);
|
||||
|
||||
/* glmWriteOBJ: Writes a model description in Wavefront .OBJ format to
|
||||
* a file.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* filename - name of the file to write the Wavefront .OBJ format data to
|
||||
* mode - a bitwise or of values describing what is written to the file
|
||||
* GLM_NONE - write only vertices
|
||||
* GLM_FLAT - write facet normals
|
||||
* GLM_SMOOTH - write vertex normals
|
||||
* GLM_TEXTURE - write texture coords
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
void
|
||||
glmWriteOBJ(GLMmodel* model, char* filename, uint mode);
|
||||
|
||||
/* glmDraw: Renders the model to the current OpenGL context using the
|
||||
* mode specified.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* mode - a bitwise OR of values describing what is to be rendered.
|
||||
* GLM_NONE - render with only vertices
|
||||
* GLM_FLAT - render with facet normals
|
||||
* GLM_SMOOTH - render with vertex normals
|
||||
* GLM_TEXTURE - render with texture coords
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
void
|
||||
glmDraw(GLMmodel* model, uint mode);
|
||||
|
||||
/* glmList: Generates and returns a display list for the model using
|
||||
* the mode specified.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* mode - a bitwise OR of values describing what is to be rendered.
|
||||
* GLM_NONE - render with only vertices
|
||||
* GLM_FLAT - render with facet normals
|
||||
* GLM_SMOOTH - render with vertex normals
|
||||
* GLM_TEXTURE - render with texture coords
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
uint
|
||||
glmList(GLMmodel* model, uint mode);
|
||||
|
||||
/* glmWeld: eliminate (weld) vectors that are within an epsilon of
|
||||
* each other.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* epsilon - maximum difference between vertices
|
||||
* ( 0.00001 is a good start for a unitized model)
|
||||
*
|
||||
*/
|
||||
void
|
||||
glmWeld(GLMmodel* model, float epsilon);
|
||||
|
||||
void
|
||||
glmReIndex(GLMmodel *model);
|
||||
|
||||
void
|
||||
glmMakeVBOs(GLMmodel *model);
|
||||
|
||||
void
|
||||
glmDrawVBO(GLMmodel *model);
|
||||
|
||||
void
|
||||
glmPrint(const GLMmodel *model);
|
||||
|
||||
void
|
||||
glmShaderMaterial(GLMmaterial *mat);
|
||||
|
||||
void
|
||||
glmLoadTextures(GLMmodel *model);
|
||||
|
||||
void
|
||||
glmSpecularTexture(GLMmodel *model, uint cubeTex);
|
||||
|
||||
#endif /* GLM_H */
|
||||
480
progs/objviewer/glmdraw.c
Normal file
480
progs/objviewer/glmdraw.c
Normal file
|
|
@ -0,0 +1,480 @@
|
|||
/* */
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glm.h"
|
||||
#include "readtex.h"
|
||||
#include "shaderutil.h"
|
||||
|
||||
|
||||
/* defines */
|
||||
#define T(x) model->triangles[(x)]
|
||||
|
||||
|
||||
/* glmDraw: Renders the model to the current OpenGL context using the
|
||||
* mode specified.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* mode - a bitwise OR of values describing what is to be rendered.
|
||||
* GLM_NONE - render with only vertices
|
||||
* GLM_FLAT - render with facet normals
|
||||
* GLM_SMOOTH - render with vertex normals
|
||||
* GLM_TEXTURE - render with texture coords
|
||||
* GLM_COLOR - render with colors (color material)
|
||||
* GLM_MATERIAL - render with materials
|
||||
* GLM_COLOR and GLM_MATERIAL should not both be specified.
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
GLvoid
|
||||
glmDraw(GLMmodel* model, GLuint mode)
|
||||
{
|
||||
GLuint i;
|
||||
GLMgroup* group;
|
||||
|
||||
assert(model);
|
||||
assert(model->vertices);
|
||||
|
||||
/* do a bit of warning */
|
||||
if (mode & GLM_FLAT && !model->facetnorms) {
|
||||
printf("glmDraw() warning: flat render mode requested "
|
||||
"with no facet normals defined.\n");
|
||||
mode &= ~GLM_FLAT;
|
||||
}
|
||||
if (mode & GLM_SMOOTH && !model->normals) {
|
||||
printf("glmDraw() warning: smooth render mode requested "
|
||||
"with no normals defined.\n");
|
||||
mode &= ~GLM_SMOOTH;
|
||||
}
|
||||
if (mode & GLM_TEXTURE && !model->texcoords) {
|
||||
printf("glmDraw() warning: texture render mode requested "
|
||||
"with no texture coordinates defined.\n");
|
||||
mode &= ~GLM_TEXTURE;
|
||||
}
|
||||
if (mode & GLM_FLAT && mode & GLM_SMOOTH) {
|
||||
printf("glmDraw() warning: flat render mode requested "
|
||||
"and smooth render mode requested (using smooth).\n");
|
||||
mode &= ~GLM_FLAT;
|
||||
}
|
||||
if (mode & GLM_COLOR && !model->materials) {
|
||||
printf("glmDraw() warning: color render mode requested "
|
||||
"with no materials defined.\n");
|
||||
mode &= ~GLM_COLOR;
|
||||
}
|
||||
if (mode & GLM_MATERIAL && !model->materials) {
|
||||
printf("glmDraw() warning: material render mode requested "
|
||||
"with no materials defined.\n");
|
||||
mode &= ~GLM_MATERIAL;
|
||||
}
|
||||
if (mode & GLM_COLOR && mode & GLM_MATERIAL) {
|
||||
printf("glmDraw() warning: color and material render mode requested "
|
||||
"using only material mode\n");
|
||||
mode &= ~GLM_COLOR;
|
||||
}
|
||||
if (mode & GLM_COLOR)
|
||||
glEnable(GL_COLOR_MATERIAL);
|
||||
if (mode & GLM_MATERIAL)
|
||||
glDisable(GL_COLOR_MATERIAL);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(model->position[0], model->position[1], model->position[2]);
|
||||
|
||||
glBegin(GL_TRIANGLES);
|
||||
group = model->groups;
|
||||
while (group) {
|
||||
if (mode & GLM_MATERIAL) {
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,
|
||||
model->materials[group->material].ambient);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
|
||||
model->materials[group->material].diffuse);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
|
||||
model->materials[group->material].specular);
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS,
|
||||
model->materials[group->material].shininess);
|
||||
}
|
||||
|
||||
if (mode & GLM_COLOR) {
|
||||
glColor3fv(model->materials[group->material].diffuse);
|
||||
}
|
||||
|
||||
for (i = 0; i < group->numtriangles; i++) {
|
||||
if (mode & GLM_FLAT)
|
||||
glNormal3fv(&model->facetnorms[3 * T(group->triangles[i]).findex]);
|
||||
|
||||
if (mode & GLM_SMOOTH)
|
||||
glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[0]]);
|
||||
if (mode & GLM_TEXTURE)
|
||||
glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[0]]);
|
||||
glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[0]]);
|
||||
#if 0
|
||||
printf("%f %f %f\n",
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[0] + X],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[0] + Y],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[0] + Z]);
|
||||
#endif
|
||||
|
||||
if (mode & GLM_SMOOTH)
|
||||
glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[1]]);
|
||||
if (mode & GLM_TEXTURE)
|
||||
glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[1]]);
|
||||
glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[1]]);
|
||||
#if 0
|
||||
printf("%f %f %f\n",
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[1] + X],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[1] + Y],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[1] + Z]);
|
||||
#endif
|
||||
|
||||
if (mode & GLM_SMOOTH)
|
||||
glNormal3fv(&model->normals[3 * T(group->triangles[i]).nindices[2]]);
|
||||
if (mode & GLM_TEXTURE)
|
||||
glTexCoord2fv(&model->texcoords[2*T(group->triangles[i]).tindices[2]]);
|
||||
glVertex3fv(&model->vertices[3 * T(group->triangles[i]).vindices[2]]);
|
||||
#if 0
|
||||
printf("%f %f %f\n",
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[2] + X],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[2] + Y],
|
||||
model->vertices[3 * T(group->triangles[i]).vindices[2] + Z]);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
group = group->next;
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
glmMakeVBOs(GLMmodel *model)
|
||||
{
|
||||
uint bytes, vertexFloats, i;
|
||||
float *buffer;
|
||||
|
||||
vertexFloats = 3;
|
||||
model->posOffset = 0;
|
||||
|
||||
if (model->numnormals > 0) {
|
||||
assert(model->numnormals == model->numvertices);
|
||||
model->normOffset = vertexFloats * sizeof(GLfloat);
|
||||
vertexFloats += 3;
|
||||
}
|
||||
|
||||
if (model->numtexcoords > 0) {
|
||||
assert(model->numtexcoords == model->numvertices);
|
||||
model->texOffset = vertexFloats * sizeof(GLfloat);
|
||||
vertexFloats += 2;
|
||||
}
|
||||
|
||||
model->vertexSize = vertexFloats;
|
||||
|
||||
bytes = (model->numvertices + 1) * vertexFloats * sizeof(float);
|
||||
|
||||
buffer = (float *) malloc(bytes);
|
||||
for (i = 0; i < model->numvertices; i++) {
|
||||
/* copy vertex pos */
|
||||
uint j = 0;
|
||||
buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 0];
|
||||
buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 1];
|
||||
buffer[i * vertexFloats + j++] = model->vertices[i * 3 + 2];
|
||||
if (model->numnormals > 0) {
|
||||
buffer[i * vertexFloats + j++] = model->normals[i * 3 + 0];
|
||||
buffer[i * vertexFloats + j++] = model->normals[i * 3 + 1];
|
||||
buffer[i * vertexFloats + j++] = model->normals[i * 3 + 2];
|
||||
}
|
||||
if (model->numtexcoords > 0) {
|
||||
buffer[i * vertexFloats + j++] = model->texcoords[i * 2 + 0];
|
||||
buffer[i * vertexFloats + j++] = model->texcoords[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
|
||||
glGenBuffersARB(1, &model->vbo);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, model->vbo);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, bytes, buffer, GL_STATIC_DRAW_ARB);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
_glmLoadTexture(GLMmaterial *mat)
|
||||
{
|
||||
if (mat->map_kd) {
|
||||
GLint imgWidth, imgHeight;
|
||||
GLenum imgFormat;
|
||||
GLubyte *image = NULL;
|
||||
|
||||
glGenTextures(1, &mat->texture_kd);
|
||||
|
||||
image = LoadRGBImage( mat->map_kd, &imgWidth, &imgHeight, &imgFormat );
|
||||
if (!image) {
|
||||
/*fprintf(stderr, "Couldn't open texture %s\n", mat->map_kd);*/
|
||||
free(mat->map_kd);
|
||||
mat->map_kd = NULL;
|
||||
mat->texture_kd = 0;
|
||||
return;
|
||||
}
|
||||
if (0)
|
||||
printf("load texture %s %d x %d\n", mat->map_kd, imgWidth, imgHeight);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, mat->texture_kd);
|
||||
gluBuild2DMipmaps(GL_TEXTURE_2D, 3, imgWidth, imgHeight,
|
||||
imgFormat, GL_UNSIGNED_BYTE, image);
|
||||
free(image);
|
||||
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR );
|
||||
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
glmLoadTextures(GLMmodel *model)
|
||||
{
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < model->nummaterials; i++) {
|
||||
GLMmaterial *mat = &model->materials[i];
|
||||
_glmLoadTexture(mat);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
glmDrawVBO(GLMmodel *model)
|
||||
{
|
||||
GLMgroup* group;
|
||||
int mode = GLM_MATERIAL;
|
||||
|
||||
assert(model->vbo);
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, model->vbo);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, model->vertexSize * sizeof(float),
|
||||
(void *) model->posOffset);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
|
||||
if (model->numnormals > 0) {
|
||||
glNormalPointer(GL_FLOAT, model->vertexSize * sizeof(float),
|
||||
(void *) model->normOffset);
|
||||
glEnableClientState(GL_NORMAL_ARRAY);
|
||||
}
|
||||
|
||||
if (model->numtexcoords > 0) {
|
||||
glTexCoordPointer(2, GL_FLOAT, model->vertexSize * sizeof(float),
|
||||
(void *) model->texOffset);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(model->position[0], model->position[1], model->position[2]);
|
||||
glScalef(model->scale, model->scale, model->scale);
|
||||
|
||||
for (group = model->groups; group; group = group->next) {
|
||||
if (0&&strcmp(group->name, "Fuselage") != 0)
|
||||
continue;
|
||||
|
||||
if (group->numtriangles > 0) {
|
||||
|
||||
if (model->materials && (mode & GLM_MATERIAL)) {
|
||||
#if 0
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT,
|
||||
model->materials[group->material].ambient);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE,
|
||||
model->materials[group->material].diffuse);
|
||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR,
|
||||
model->materials[group->material].specular);
|
||||
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS,
|
||||
model->materials[group->material].shininess);
|
||||
#else
|
||||
glmShaderMaterial(&model->materials[group->material]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
glDrawElements(GL_TRIANGLES, 3 * group->numtriangles,
|
||||
GL_UNSIGNED_INT, group->triIndexes);
|
||||
#else
|
||||
glDrawRangeElements(GL_TRIANGLES,
|
||||
group->minIndex, group->maxIndex,
|
||||
3 * group->numtriangles,
|
||||
GL_UNSIGNED_INT, group->triIndexes);
|
||||
#endif
|
||||
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_NORMAL_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* glmList: Generates and returns a display list for the model using
|
||||
* the mode specified.
|
||||
*
|
||||
* model - initialized GLMmodel structure
|
||||
* mode - a bitwise OR of values describing what is to be rendered.
|
||||
* GLM_NONE - render with only vertices
|
||||
* GLM_FLAT - render with facet normals
|
||||
* GLM_SMOOTH - render with vertex normals
|
||||
* GLM_TEXTURE - render with texture coords
|
||||
* GLM_COLOR - render with colors (color material)
|
||||
* GLM_MATERIAL - render with materials
|
||||
* GLM_COLOR and GLM_MATERIAL should not both be specified.
|
||||
* GLM_FLAT and GLM_SMOOTH should not both be specified.
|
||||
*/
|
||||
GLuint
|
||||
glmList(GLMmodel* model, GLuint mode)
|
||||
{
|
||||
GLuint list;
|
||||
|
||||
list = glGenLists(1);
|
||||
glNewList(list, GL_COMPILE);
|
||||
glmDraw(model, mode);
|
||||
glEndList();
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static const char *VertexShader =
|
||||
"varying vec3 normal; \n"
|
||||
"void main() { \n"
|
||||
" gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; \n"
|
||||
" normal = gl_NormalMatrix * gl_Normal; \n"
|
||||
" gl_TexCoord[0] = gl_MultiTexCoord0; \n"
|
||||
"} \n";
|
||||
|
||||
/**
|
||||
* Two %s substitutions:
|
||||
* diffuse texture? true/false
|
||||
* specular texture? true/false
|
||||
*/
|
||||
static const char *TexFragmentShader =
|
||||
"uniform vec4 ambient, diffuse, specular; \n"
|
||||
"uniform vec4 ambientLight, diffuseLight, specularLight; \n"
|
||||
"uniform float shininess; \n"
|
||||
"uniform sampler2D diffTex; \n"
|
||||
"uniform samplerCube specTex; \n"
|
||||
"varying vec3 normal; \n"
|
||||
"\n"
|
||||
"void main() \n"
|
||||
"{ \n"
|
||||
" vec4 diffTerm, specTerm; \n"
|
||||
" float dotProd = max(dot(gl_LightSource[0].position.xyz, \n"
|
||||
" normalize(normal)), 0.0);\n"
|
||||
" float dotProd2 = max(dot(-gl_LightSource[0].position.xyz, \n"
|
||||
" normalize(normal)), 0.0);\n"
|
||||
" dotProd += dotProd2; \n"
|
||||
" \n"
|
||||
" diffTerm = diffuse * diffuseLight * dotProd; \n"
|
||||
" if (%s) \n"
|
||||
" diffTerm *= texture2D(diffTex, gl_TexCoord[0].st); \n"
|
||||
" \n"
|
||||
" specTerm = specular * specularLight * pow(dotProd, shininess); \n"
|
||||
" if (%s) \n"
|
||||
" specTerm *= textureCube(specTex, normal); \n"
|
||||
" \n"
|
||||
" gl_FragColor = ambient * ambientLight + diffTerm + specTerm; \n"
|
||||
"} \n";
|
||||
|
||||
|
||||
void
|
||||
glmShaderMaterial(GLMmaterial *mat)
|
||||
{
|
||||
static const float ambientLight[4] = { 0.1, 0.1, 0.1, 0.0 };
|
||||
static const float diffuseLight[4] = { 0.75, 0.75, 0.75, 1.0 };
|
||||
static const float specularLight[4] = { 1.0, 1.0, 1.0, 0.0 };
|
||||
|
||||
if (!mat->prog) {
|
||||
/* make shader now */
|
||||
char newShader[10000];
|
||||
GLuint vs, fs;
|
||||
const char *diffuseTex = mat->texture_kd ? "true" : "false";
|
||||
const char *specularTex = mat->texture_ks ? "true" : "false";
|
||||
GLint uAmbientLight, uDiffuseLight, uSpecularLight;
|
||||
|
||||
/* replace %d with 0 or 1 */
|
||||
sprintf(newShader, TexFragmentShader, diffuseTex, specularTex);
|
||||
if (0)
|
||||
printf("===== new shader =====\n%s\n============\n", newShader);
|
||||
|
||||
vs = CompileShaderText(GL_VERTEX_SHADER, VertexShader);
|
||||
fs = CompileShaderText(GL_FRAGMENT_SHADER, newShader);
|
||||
mat->prog = LinkShaders(vs, fs);
|
||||
assert(mat->prog);
|
||||
|
||||
glUseProgram(mat->prog);
|
||||
|
||||
mat->uAmbient = glGetUniformLocation(mat->prog, "ambient");
|
||||
mat->uDiffuse = glGetUniformLocation(mat->prog, "diffuse");
|
||||
mat->uSpecular = glGetUniformLocation(mat->prog, "specular");
|
||||
mat->uShininess = glGetUniformLocation(mat->prog, "shininess");
|
||||
mat->uDiffTex = glGetUniformLocation(mat->prog, "diffTex");
|
||||
mat->uSpecTex = glGetUniformLocation(mat->prog, "specTex");
|
||||
|
||||
uAmbientLight = glGetUniformLocation(mat->prog, "ambientLight");
|
||||
uDiffuseLight = glGetUniformLocation(mat->prog, "diffuseLight");
|
||||
uSpecularLight = glGetUniformLocation(mat->prog, "specularLight");
|
||||
|
||||
glUniform4fv(mat->uAmbient, 1, mat->ambient);
|
||||
glUniform4fv(mat->uDiffuse, 1, mat->diffuse);
|
||||
glUniform4fv(mat->uSpecular, 1, mat->specular);
|
||||
glUniform1f(mat->uShininess, mat->shininess);
|
||||
glUniform1i(mat->uDiffTex, 0);
|
||||
glUniform1i(mat->uSpecTex, 1);
|
||||
|
||||
glUniform4fv(uAmbientLight, 1, ambientLight);
|
||||
glUniform4fv(uDiffuseLight, 1, diffuseLight);
|
||||
glUniform4fv(uSpecularLight, 1, specularLight);
|
||||
}
|
||||
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
if (mat->texture_ks)
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, mat->texture_ks);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
if (mat->texture_kd)
|
||||
glBindTexture(GL_TEXTURE_2D, mat->texture_kd);
|
||||
else
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
if (mat->diffuse[3] < 1.0) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else {
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
glUseProgram(mat->prog);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
glmSpecularTexture(GLMmodel *model, uint cubeTex)
|
||||
{
|
||||
uint i;
|
||||
|
||||
for (i = 0; i < model->nummaterials; i++) {
|
||||
model->materials[i].texture_ks = cubeTex;
|
||||
}
|
||||
}
|
||||
487
progs/objviewer/objview.c
Normal file
487
progs/objviewer/objview.c
Normal file
|
|
@ -0,0 +1,487 @@
|
|||
/*
|
||||
* .obj file viewer based on "smooth" by Nate Robins, 1997
|
||||
*
|
||||
* Brian Paul
|
||||
* 1 Oct 2009
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/glut.h>
|
||||
#include "glm.h"
|
||||
#include "readtex.h"
|
||||
#include "skybox.h"
|
||||
#include "trackball.h"
|
||||
|
||||
|
||||
static char *Model_file = NULL; /* name of the obect file */
|
||||
static GLMmodel *Model;
|
||||
static GLfloat Scale = 4.0; /* scaling factor */
|
||||
static GLboolean Performance = GL_FALSE;
|
||||
static GLboolean Stats = GL_FALSE;
|
||||
static GLboolean Animate = GL_TRUE;
|
||||
static GLuint SkyboxTex;
|
||||
static GLboolean Skybox = GL_TRUE;
|
||||
static GLboolean Cull = GL_TRUE;
|
||||
static GLboolean WireFrame = GL_FALSE;
|
||||
static GLenum FrontFace = GL_CCW;
|
||||
static GLfloat Yrot = 0.0;
|
||||
static GLint WinWidth = 1024, WinHeight = 768;
|
||||
static GLuint NumInstances = 1;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float CurQuat[4];
|
||||
float Distance;
|
||||
/* When mouse is moving: */
|
||||
GLboolean Rotating, Translating;
|
||||
GLint StartX, StartY;
|
||||
float StartDistance;
|
||||
} ViewInfo;
|
||||
|
||||
static ViewInfo View;
|
||||
|
||||
static void
|
||||
InitViewInfo(ViewInfo *view)
|
||||
{
|
||||
view->Rotating = GL_FALSE;
|
||||
view->Translating = GL_FALSE;
|
||||
view->StartX = view->StartY = 0;
|
||||
view->Distance = 12.0;
|
||||
view->StartDistance = 0.0;
|
||||
view->CurQuat[0] = 0.0;
|
||||
view->CurQuat[1] = 1.0;
|
||||
view->CurQuat[2] = 0.0;
|
||||
view->CurQuat[3] = 0.0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* text: general purpose text routine. draws a string according to
|
||||
* format in a stroke font at x, y after scaling it by the scale
|
||||
* specified (scale is in window-space (lower-left origin) pixels).
|
||||
*
|
||||
* x - position in x (in window-space)
|
||||
* y - position in y (in window-space)
|
||||
* scale - scale in pixels
|
||||
* format - as in printf()
|
||||
*/
|
||||
static void
|
||||
text(GLuint x, GLuint y, GLfloat scale, char* format, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buffer[255], *p;
|
||||
GLfloat font_scale = 119.05 + 33.33;
|
||||
|
||||
va_start(args, format);
|
||||
vsprintf(buffer, format, args);
|
||||
va_end(args);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
gluOrtho2D(0, glutGet(GLUT_WINDOW_WIDTH), 0, glutGet(GLUT_WINDOW_HEIGHT));
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
|
||||
glPushAttrib(GL_ENABLE_BIT);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glTranslatef(x, y, 0.0);
|
||||
|
||||
glScalef(scale/font_scale, scale/font_scale, scale/font_scale);
|
||||
|
||||
for(p = buffer; *p; p++)
|
||||
glutStrokeCharacter(GLUT_STROKE_ROMAN, *p);
|
||||
|
||||
glPopAttrib();
|
||||
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
ComputeFPS(void)
|
||||
{
|
||||
static double t0 = -1.0;
|
||||
static int frames = 0;
|
||||
double t = glutGet(GLUT_ELAPSED_TIME) / 1000.0;
|
||||
static float fps = 0;
|
||||
|
||||
frames++;
|
||||
|
||||
if (t0 < 0.0) {
|
||||
t0 = t;
|
||||
fps = 0.0;
|
||||
}
|
||||
else if (t - t0 >= 4.0) {
|
||||
fps = (frames / (t - t0) + 0.5);
|
||||
t0 = t;
|
||||
frames = 0;
|
||||
return fps;
|
||||
}
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_model(void)
|
||||
{
|
||||
float objScale;
|
||||
|
||||
/* read in the model */
|
||||
Model = glmReadOBJ(Model_file);
|
||||
objScale = glmUnitize(Model);
|
||||
glmFacetNormals(Model);
|
||||
if (Model->numnormals == 0) {
|
||||
GLfloat smoothing_angle = 90.0;
|
||||
printf("Generating normals.");
|
||||
glmVertexNormals(Model, smoothing_angle);
|
||||
}
|
||||
|
||||
glmLoadTextures(Model);
|
||||
glmReIndex(Model);
|
||||
glmMakeVBOs(Model);
|
||||
if (0)
|
||||
glmPrint(Model);
|
||||
}
|
||||
|
||||
static void
|
||||
init_skybox(void)
|
||||
{
|
||||
SkyboxTex = LoadSkyBoxCubeTexture("alpine_east.rgb",
|
||||
"alpine_west.rgb",
|
||||
"alpine_up.rgb",
|
||||
"alpine_down.rgb",
|
||||
"alpine_south.rgb",
|
||||
"alpine_north.rgb");
|
||||
glmSpecularTexture(Model, SkyboxTex);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
init_gfx(void)
|
||||
{
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_NORMALIZE);
|
||||
glClearColor(0.3, 0.3, 0.9, 0.0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
reshape(int width, int height)
|
||||
{
|
||||
float ar = 0.5 * (float) width / (float) height;
|
||||
|
||||
WinWidth = width;
|
||||
WinHeight = height;
|
||||
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glFrustum(-ar, ar, -0.5, 0.5, 1.0, 300.0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glTranslatef(0.0, 0.0, -3.0);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
Idle(void)
|
||||
{
|
||||
float q[4];
|
||||
trackball(q, 100, 0, 99.99, 0);
|
||||
add_quats(q, View.CurQuat, View.CurQuat);
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
display(void)
|
||||
{
|
||||
GLfloat rot[4][4];
|
||||
float fps;
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
glPushMatrix();
|
||||
glTranslatef(0.0, 0.0, -View.Distance);
|
||||
glRotatef(Yrot, 0, 1, 0);
|
||||
build_rotmatrix(rot, View.CurQuat);
|
||||
glMultMatrixf(&rot[0][0]);
|
||||
glScalef(Scale, Scale, Scale );
|
||||
|
||||
glUseProgram(0);
|
||||
|
||||
if (Skybox)
|
||||
DrawSkyBoxCubeTexture(SkyboxTex);
|
||||
|
||||
if (WireFrame)
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
else
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
|
||||
if (Cull)
|
||||
glEnable(GL_CULL_FACE);
|
||||
else
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
if (NumInstances == 1) {
|
||||
glmDrawVBO(Model);
|
||||
}
|
||||
else {
|
||||
/* draw > 1 instance */
|
||||
float dr = 360.0 / NumInstances;
|
||||
float r;
|
||||
for (r = 0.0; r < 360.0; r += dr) {
|
||||
glPushMatrix();
|
||||
glRotatef(r, 0, 1, 0);
|
||||
glTranslatef(1.4, 0.0, 0.0);
|
||||
glmDrawVBO(Model);
|
||||
glPopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
if (Stats) {
|
||||
glColor3f(1.0, 1.0, 1.0);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*1), 20, "%s",
|
||||
Model->pathname);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*2), 20, "%d vertices",
|
||||
Model->numvertices);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*3), 20, "%d triangles",
|
||||
Model->numtriangles);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*4), 20, "%d normals",
|
||||
Model->numnormals);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*5), 20, "%d texcoords",
|
||||
Model->numtexcoords);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*6), 20, "%d groups",
|
||||
Model->numgroups);
|
||||
text(5, glutGet(GLUT_WINDOW_HEIGHT) - (5+20*7), 20, "%d materials",
|
||||
Model->nummaterials);
|
||||
}
|
||||
|
||||
glutSwapBuffers();
|
||||
|
||||
fps = ComputeFPS();
|
||||
if (fps)
|
||||
printf("%f FPS\n", fps);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
keyboard(unsigned char key, int x, int y)
|
||||
{
|
||||
switch (key) {
|
||||
case 'h':
|
||||
printf("help\n\n");
|
||||
printf("a - Toggle animation\n");
|
||||
printf("d/D - Decrease/Incrase number of models\n");
|
||||
printf("w - Toggle wireframe/filled\n");
|
||||
printf("c - Toggle culling\n");
|
||||
printf("n - Toggle facet/smooth normal\n");
|
||||
printf("r - Reverse polygon winding\n");
|
||||
printf("p - Toggle performance indicator\n");
|
||||
printf("s - Toggle skybox\n");
|
||||
printf("z/Z - Scale model smaller/larger\n");
|
||||
printf("i - Show model info/stats\n");
|
||||
printf("q/escape - Quit\n\n");
|
||||
break;
|
||||
case 'a':
|
||||
Animate = !Animate;
|
||||
if (Animate)
|
||||
glutIdleFunc(Idle);
|
||||
else
|
||||
glutIdleFunc(NULL);
|
||||
break;
|
||||
case 'd':
|
||||
if (NumInstances > 1)
|
||||
NumInstances--;
|
||||
break;
|
||||
case 'D':
|
||||
NumInstances++;
|
||||
break;
|
||||
case 'i':
|
||||
Stats = !Stats;
|
||||
break;
|
||||
case 'p':
|
||||
Performance = !Performance;
|
||||
break;
|
||||
case 'w':
|
||||
WireFrame = !WireFrame;
|
||||
break;
|
||||
case 'c':
|
||||
Cull = !Cull;
|
||||
printf("Polygon culling: %d\n", Cull);
|
||||
break;
|
||||
case 'r':
|
||||
if (FrontFace == GL_CCW)
|
||||
FrontFace = GL_CW;
|
||||
else
|
||||
FrontFace = GL_CCW;
|
||||
glFrontFace(FrontFace);
|
||||
printf("Front face:: %s\n", FrontFace == GL_CCW ? "CCW" : "CW");
|
||||
break;
|
||||
case 's':
|
||||
Skybox = !Skybox;
|
||||
if (Skybox)
|
||||
glmSpecularTexture(Model, SkyboxTex);
|
||||
else
|
||||
glmSpecularTexture(Model, 0);
|
||||
break;
|
||||
case 'z':
|
||||
Scale *= 0.9;
|
||||
break;
|
||||
case 'Z':
|
||||
Scale *= 1.1;
|
||||
break;
|
||||
case 'q':
|
||||
case 27:
|
||||
exit(0);
|
||||
break;
|
||||
}
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
menu(int item)
|
||||
{
|
||||
keyboard((unsigned char)item, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle mouse button.
|
||||
*/
|
||||
static void
|
||||
Mouse(int button, int state, int x, int y)
|
||||
{
|
||||
if (button == GLUT_LEFT_BUTTON) {
|
||||
if (state == GLUT_DOWN) {
|
||||
View.StartX = x;
|
||||
View.StartY = y;
|
||||
View.Rotating = GL_TRUE;
|
||||
}
|
||||
else if (state == GLUT_UP) {
|
||||
View.Rotating = GL_FALSE;
|
||||
}
|
||||
}
|
||||
else if (button == GLUT_MIDDLE_BUTTON) {
|
||||
if (state == GLUT_DOWN) {
|
||||
View.StartX = x;
|
||||
View.StartY = y;
|
||||
View.StartDistance = View.Distance;
|
||||
View.Translating = GL_TRUE;
|
||||
}
|
||||
else if (state == GLUT_UP) {
|
||||
View.Translating = GL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle mouse motion
|
||||
*/
|
||||
static void
|
||||
Motion(int x, int y)
|
||||
{
|
||||
int i;
|
||||
if (View.Rotating) {
|
||||
float x0 = (2.0 * View.StartX - WinWidth) / WinWidth;
|
||||
float y0 = (WinHeight - 2.0 * View.StartY) / WinHeight;
|
||||
float x1 = (2.0 * x - WinWidth) / WinWidth;
|
||||
float y1 = (WinHeight - 2.0 * y) / WinHeight;
|
||||
float q[4];
|
||||
|
||||
trackball(q, x0, y0, x1, y1);
|
||||
View.StartX = x;
|
||||
View.StartY = y;
|
||||
for (i = 0; i < 1; i++)
|
||||
add_quats(q, View.CurQuat, View.CurQuat);
|
||||
|
||||
glutPostRedisplay();
|
||||
}
|
||||
else if (View.Translating) {
|
||||
float dz = 0.02 * (y - View.StartY);
|
||||
View.Distance = View.StartDistance + dz;
|
||||
glutPostRedisplay();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
glutInitWindowSize(WinWidth, WinHeight);
|
||||
glutInit(&argc, argv);
|
||||
|
||||
if (argc > 1) {
|
||||
Model_file = argv[1];
|
||||
}
|
||||
if (!Model_file) {
|
||||
fprintf(stderr, "usage: objview file.obj\n");
|
||||
fprintf(stderr, "(using default bunny.obj)\n");
|
||||
Model_file = "bunny.obj";
|
||||
}
|
||||
|
||||
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
|
||||
glutCreateWindow("objview");
|
||||
|
||||
glewInit();
|
||||
|
||||
glutReshapeFunc(reshape);
|
||||
glutDisplayFunc(display);
|
||||
glutKeyboardFunc(keyboard);
|
||||
glutMouseFunc(Mouse);
|
||||
glutMotionFunc(Motion);
|
||||
if (Animate)
|
||||
glutIdleFunc(Idle);
|
||||
|
||||
glutCreateMenu(menu);
|
||||
glutAddMenuEntry("[a] Toggle animate", 'a');
|
||||
glutAddMenuEntry("[d] Fewer models", 'd');
|
||||
glutAddMenuEntry("[D] More models", 'D');
|
||||
glutAddMenuEntry("[w] Toggle wireframe/filled", 'w');
|
||||
glutAddMenuEntry("[c] Toggle culling on/off", 'c');
|
||||
glutAddMenuEntry("[r] Reverse polygon winding", 'r');
|
||||
glutAddMenuEntry("[z] Scale model smaller", 'z');
|
||||
glutAddMenuEntry("[Z] Scale model larger", 'Z');
|
||||
glutAddMenuEntry("[p] Toggle performance indicator", 'p');
|
||||
glutAddMenuEntry("[i] Show model stats", 'i');
|
||||
glutAddMenuEntry("", 0);
|
||||
glutAddMenuEntry("[q] Quit", 27);
|
||||
glutAttachMenu(GLUT_RIGHT_BUTTON);
|
||||
|
||||
InitViewInfo(&View);
|
||||
|
||||
init_model();
|
||||
init_skybox();
|
||||
init_gfx();
|
||||
|
||||
glutMainLoop();
|
||||
|
||||
return 0;
|
||||
}
|
||||
186
progs/objviewer/skybox.c
Normal file
186
progs/objviewer/skybox.c
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <GL/glew.h>
|
||||
#include <GL/glu.h>
|
||||
#include "readtex.h"
|
||||
#include "skybox.h"
|
||||
|
||||
|
||||
static int
|
||||
load(GLenum target, const char *filename,
|
||||
GLboolean flipTB, GLboolean flipLR)
|
||||
{
|
||||
GLint w, h;
|
||||
GLenum format;
|
||||
GLubyte *img = LoadRGBImage( filename, &w, &h, &format );
|
||||
if (!img) {
|
||||
printf("Error: couldn't load texture image %s\n", filename);
|
||||
return 0;
|
||||
}
|
||||
assert(format == GL_RGB);
|
||||
|
||||
printf("Load cube face 0x%x: %s %d x %d\n", target, filename, w, h);
|
||||
|
||||
/* <sigh> the way the texture cube mapping works, we have to flip
|
||||
* images to make things look right.
|
||||
*/
|
||||
if (flipTB) {
|
||||
const int stride = 3 * w;
|
||||
GLubyte temp[3*1024];
|
||||
int i;
|
||||
for (i = 0; i < h / 2; i++) {
|
||||
memcpy(temp, img + i * stride, stride);
|
||||
memcpy(img + i * stride, img + (h - i - 1) * stride, stride);
|
||||
memcpy(img + (h - i - 1) * stride, temp, stride);
|
||||
}
|
||||
}
|
||||
if (flipLR) {
|
||||
const int stride = 3 * w;
|
||||
GLubyte temp[3];
|
||||
GLubyte *row;
|
||||
int i, j;
|
||||
for (i = 0; i < h; i++) {
|
||||
row = img + i * stride;
|
||||
for (j = 0; j < w / 2; j++) {
|
||||
int k = w - j - 1;
|
||||
temp[0] = row[j*3+0];
|
||||
temp[1] = row[j*3+1];
|
||||
temp[2] = row[j*3+2];
|
||||
row[j*3+0] = row[k*3+0];
|
||||
row[j*3+1] = row[k*3+1];
|
||||
row[j*3+2] = row[k*3+2];
|
||||
row[k*3+0] = temp[0];
|
||||
row[k*3+1] = temp[1];
|
||||
row[k*3+2] = temp[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gluBuild2DMipmaps(target, GL_RGB, w, h, format, GL_UNSIGNED_BYTE, img);
|
||||
free(img);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
GLuint
|
||||
LoadSkyBoxCubeTexture(const char *filePosX,
|
||||
const char *fileNegX,
|
||||
const char *filePosY,
|
||||
const char *fileNegY,
|
||||
const char *filePosZ,
|
||||
const char *fileNegZ)
|
||||
{
|
||||
GLuint tex;
|
||||
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
|
||||
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_X, filePosX, GL_TRUE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, fileNegX, GL_TRUE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, filePosY, 1+GL_FALSE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, fileNegY, 1+GL_FALSE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, filePosZ, GL_TRUE, GL_TRUE))
|
||||
return 0;
|
||||
if (!load(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, fileNegZ, GL_TRUE, GL_TRUE))
|
||||
return 0;
|
||||
|
||||
return tex;
|
||||
}
|
||||
|
||||
|
||||
#define eps1 0.99
|
||||
#define br 20.0 /* box radius */
|
||||
|
||||
void
|
||||
DrawSkyBoxCubeTexture(GLuint tex)
|
||||
{
|
||||
struct vertex {
|
||||
float x, y, z, s, t, r;
|
||||
};
|
||||
|
||||
static const struct vertex verts[24] = {
|
||||
/* +X side */
|
||||
{ br, -br, -br, 1.0, -eps1, -eps1 },
|
||||
{ br, -br, br, 1.0, -eps1, eps1 },
|
||||
{ br, br, br, 1.0, eps1, eps1 },
|
||||
{ br, br, -br, 1.0, eps1, -eps1 },
|
||||
|
||||
/* -X side */
|
||||
{ -br, br, -br, -1.0, eps1, -eps1 },
|
||||
{ -br, br, br, -1.0, eps1, eps1 },
|
||||
{ -br, -br, br, -1.0, -eps1, eps1 },
|
||||
{ -br, -br, -br, -1.0, -eps1, -eps1 },
|
||||
|
||||
/* +Y side */
|
||||
{ br, br, -br, eps1, 1.0, -eps1 },
|
||||
{ br, br, br, eps1, 1.0, eps1 },
|
||||
{ -br, br, br, -eps1, 1.0, eps1 },
|
||||
{ -br, br, -br, -eps1, 1.0, -eps1 },
|
||||
|
||||
/* -Y side */
|
||||
{ -br, -br, -br, -eps1, -1.0, -eps1 },
|
||||
{ -br, -br, br, -eps1, -1.0, eps1 },
|
||||
{ br, -br, br, eps1, -1.0, eps1 },
|
||||
{ br, -br, -br, eps1, -1.0, -eps1 },
|
||||
|
||||
/* +Z side */
|
||||
{ br, -br, br, eps1, -eps1, 1.0 },
|
||||
{ -br, -br, br, -eps1, -eps1, 1.0 },
|
||||
{ -br, br, br, -eps1, eps1, 1.0 },
|
||||
{ br, br, br, eps1, eps1, 1.0 },
|
||||
|
||||
/* -Z side */
|
||||
{ br, br, -br, eps1, eps1, -1.0 },
|
||||
{ -br, br, -br, -eps1, eps1, -1.0 },
|
||||
{ -br, -br, -br, -eps1, -eps1, -1.0 },
|
||||
{ br, -br, -br, eps1, -eps1, -1.0 },
|
||||
};
|
||||
|
||||
static GLuint vbo = 0;
|
||||
|
||||
if (!vbo ) {
|
||||
glGenBuffersARB(1, &vbo);
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
|
||||
glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts), verts,
|
||||
GL_STATIC_DRAW_ARB);
|
||||
}
|
||||
else {
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
|
||||
}
|
||||
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, sizeof(struct vertex),
|
||||
(void *) offsetof(struct vertex, x));
|
||||
glTexCoordPointer(3, GL_FLOAT, sizeof(struct vertex),
|
||||
(void *) offsetof(struct vertex, s));
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
|
||||
glEnable(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
//glDisable(GL_LIGHTING);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
glDrawArrays(GL_QUADS, 0, 24);
|
||||
|
||||
//glEnable(GL_LIGHTING);
|
||||
|
||||
glDisable(GL_TEXTURE_CUBE_MAP);
|
||||
|
||||
glDisableClientState(GL_VERTEX_ARRAY);
|
||||
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
|
||||
glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
|
||||
}
|
||||
|
||||
18
progs/objviewer/skybox.h
Normal file
18
progs/objviewer/skybox.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
#ifndef SKYBOX_H
|
||||
#define SKYBOX_H
|
||||
|
||||
|
||||
extern GLuint
|
||||
LoadSkyBoxCubeTexture(const char *filePosX,
|
||||
const char *fileNegX,
|
||||
const char *filePosY,
|
||||
const char *fileNegY,
|
||||
const char *filePosZ,
|
||||
const char *fileNegZ);
|
||||
|
||||
extern void
|
||||
DrawSkyBoxCubeTexture(GLuint tex);
|
||||
|
||||
|
||||
#endif /* SKYBOX_H */
|
||||
Loading…
Add table
Reference in a new issue