view3d

changeset 3:7e982a61852a

lights and shit
author John Tsiombikas <nuclear@mutantstargoat.com>
date Thu, 19 Jan 2012 06:15:10 +0200
parents 9b10c8183d4e
children 0aee5df08cfc
files src/main.c src/scene.c src/scene.h
diffstat 3 files changed, 136 insertions(+), 13 deletions(-) [+]
line diff
     1.1 --- a/src/main.c	Thu Jan 19 01:51:05 2012 +0200
     1.2 +++ b/src/main.c	Thu Jan 19 06:15:10 2012 +0200
     1.3 @@ -30,7 +30,7 @@
     1.4  int win_width, win_height;
     1.5  int stereo;
     1.6  int flip_winding;
     1.7 -int auto_rot = 1;
     1.8 +int auto_rot;
     1.9  float cam_theta, cam_phi, cam_dist = 10;
    1.10  float near_clip = 0.5;
    1.11  float far_clip = 1000.0;
    1.12 @@ -38,11 +38,13 @@
    1.13  float stereo_focus_dist = 1.0;
    1.14  float stereo_eye_sep = 1.0 / 30.0;
    1.15  
    1.16 +int verbose = 0;
    1.17 +
    1.18  struct scene scn;
    1.19  
    1.20  int main(int argc, char **argv)
    1.21  {
    1.22 -	float ldir[] = {1, -1, -1, 0};
    1.23 +	float ldir[] = {-1, 1, 1, 0};
    1.24  	float dx, dy, dz, diag;
    1.25  
    1.26  	glutInitWindowSize(800, 600);
    1.27 @@ -64,7 +66,9 @@
    1.28  	glutSpaceballMotionFunc(sball_motion);
    1.29  	glutSpaceballRotateFunc(sball_rotate);
    1.30  	glutSpaceballButtonFunc(sball_button);
    1.31 -	glutIdleFunc(glutPostRedisplay);
    1.32 +	if(auto_rot) {
    1.33 +		glutIdleFunc(glutPostRedisplay);
    1.34 +	}
    1.35  
    1.36  	glewInit();
    1.37  
    1.38 @@ -329,6 +333,10 @@
    1.39  				flip_winding = 1;
    1.40  				break;
    1.41  
    1.42 +			case 'v':
    1.43 +				verbose = !verbose;
    1.44 +				break;
    1.45 +
    1.46  			default:
    1.47  				goto inval;
    1.48  			}
     2.1 --- a/src/scene.c	Thu Jan 19 01:51:05 2012 +0200
     2.2 +++ b/src/scene.c	Thu Jan 19 06:15:10 2012 +0200
     2.3 @@ -12,11 +12,13 @@
     2.4  
     2.5  #include "scene.h"
     2.6  
     2.7 +static void setup_light(struct light *lt);
     2.8  static void color(float *dest, float r, float g, float b);
     2.9  static struct mesh *create_mesh(const struct aiScene *aiscn, struct aiMesh *aim);
    2.10  static unsigned int create_buffer(unsigned int type, void *data, size_t sz);
    2.11  static unsigned int load_texture(const char *fname);
    2.12  
    2.13 +extern int verbose;
    2.14  
    2.15  int load_scene(struct scene *scn, const char *fname)
    2.16  {
    2.17 @@ -24,7 +26,11 @@
    2.18  	const struct aiScene *aiscn;
    2.19  	unsigned int proc_flags = aiProcess_JoinIdenticalVertices |
    2.20  		aiProcess_PreTransformVertices | aiProcess_Triangulate |
    2.21 -		aiProcess_GenNormals | aiProcess_SortByPType;
    2.22 +		aiProcess_SortByPType;
    2.23 +
    2.24 +	if(verbose) {
    2.25 +		printf("scene: %s  (%d meshes, %d lights)\n", fname, aiscn->mNumMeshes, aiscn->mNumLights);
    2.26 +	}
    2.27  
    2.28  	if(!(aiscn = aiImportFile(fname, proc_flags))) {
    2.29  		fprintf(stderr, "failed to load: %s\n", fname);
    2.30 @@ -34,6 +40,63 @@
    2.31  	scn->meshes = 0;
    2.32  	scn->lights = 0;
    2.33  
    2.34 +	for(i=0; i<aiscn->mNumLights; i++) {
    2.35 +		struct light *lt;
    2.36 +		struct aiLight *ailt = aiscn->mLights[i];
    2.37 +
    2.38 +		if(!(lt = malloc(sizeof *lt))) {
    2.39 +			perror("failed to allocate light");
    2.40 +			return -1;
    2.41 +		}
    2.42 +
    2.43 +		if(verbose) {
    2.44 +			printf("- light(%s) ", ailt->mName.data);
    2.45 +		}
    2.46 +
    2.47 +		switch(ailt->mType) {
    2.48 +		case aiLightSource_POINT:
    2.49 +			lt->pos[0] = ailt->mPosition.x;
    2.50 +			lt->pos[1] = ailt->mPosition.y;
    2.51 +			lt->pos[2] = ailt->mPosition.z;
    2.52 +			lt->pos[3] = 1.0f;
    2.53 +			if(verbose) {
    2.54 +				printf("pos(%.2f %.2f %.2f) ", lt->pos[0], lt->pos[1], lt->pos[2]);
    2.55 +			}
    2.56 +			break;
    2.57 +
    2.58 +		case aiLightSource_DIRECTIONAL:
    2.59 +			lt->pos[0] = ailt->mDirection.x;
    2.60 +			lt->pos[1] = ailt->mDirection.y;
    2.61 +			lt->pos[2] = ailt->mDirection.z;
    2.62 +			lt->pos[3] = 0.0f;
    2.63 +			if(verbose) {
    2.64 +				printf("dir(%.2f %.2f %.2f) ", lt->pos[0], lt->pos[1], lt->pos[2]);
    2.65 +			}
    2.66 +			break;
    2.67 +
    2.68 +		default:
    2.69 +			fprintf(stderr, "error loading light: %s, unsupported type\n", ailt->mName.data);
    2.70 +			continue;
    2.71 +		}
    2.72 +		color(lt->color, ailt->mColorDiffuse.r, ailt->mColorDiffuse.g, ailt->mColorDiffuse.b);
    2.73 +		if(verbose) {
    2.74 +			printf("col(%.2f %.2f %.2f) ", lt->color[0], lt->color[1], lt->color[2]);
    2.75 +		}
    2.76 +
    2.77 +		lt->cone_inner = ailt->mAngleInnerCone;
    2.78 +		lt->cone_outer = ailt->mAngleOuterCone;
    2.79 +
    2.80 +		lt->att[0] = ailt->mAttenuationConstant;
    2.81 +		lt->att[1] = ailt->mAttenuationLinear;
    2.82 +		lt->att[2] = ailt->mAttenuationQuadratic;
    2.83 +		if(verbose) {
    2.84 +			printf("att(%.2f %.2f %.2f)\n", lt->att[0], lt->att[1], lt->att[2]);
    2.85 +		}
    2.86 +
    2.87 +		lt->next = scn->lights;
    2.88 +		scn->lights = lt;
    2.89 +	}
    2.90 +
    2.91  	scn->bbox.min[0] = scn->bbox.min[1] = scn->bbox.min[2] = FLT_MAX;
    2.92  	scn->bbox.max[0] = scn->bbox.max[1] = scn->bbox.max[2] = -FLT_MAX;
    2.93  
    2.94 @@ -57,8 +120,10 @@
    2.95  		scn->meshes = m;
    2.96  	}
    2.97  
    2.98 -	printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1],
    2.99 -			scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]);
   2.100 +	if(verbose) {
   2.101 +		printf("scene bounds: %.2f %.2f %.2f -> %.2f %.2f %.2f\n", scn->bbox.min[0], scn->bbox.min[1],
   2.102 +				scn->bbox.min[2], scn->bbox.max[0], scn->bbox.max[1], scn->bbox.max[2]);
   2.103 +	}
   2.104  
   2.105  	aiReleaseImport(aiscn);
   2.106  	return 0;
   2.107 @@ -87,6 +152,10 @@
   2.108  		return 0;
   2.109  	}
   2.110  
   2.111 +	if(verbose) {
   2.112 +		printf("- mesh(%s) v:%d f:%d\n", aim->mName.data, aim->mNumVertices, aim->mNumFaces);
   2.113 +	}
   2.114 +
   2.115  	/* default material */
   2.116  	color(m->mat.kd, 1, 1, 1);
   2.117  	color(m->mat.ks, 0, 0, 0);
   2.118 @@ -162,6 +231,10 @@
   2.119  		return 0;
   2.120  	}
   2.121  
   2.122 +	if(verbose) {
   2.123 +		printf("  - texture: %s (%dx%d)\n", fname, xsz, ysz);
   2.124 +	}
   2.125 +
   2.126  	glGenTextures(1, &tex);
   2.127  	glBindTexture(GL_TEXTURE_2D, tex);
   2.128  	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
   2.129 @@ -176,16 +249,54 @@
   2.130  
   2.131  void render_scene(struct scene *scn)
   2.132  {
   2.133 -	struct mesh *m = scn->meshes;
   2.134 -	while(m) {
   2.135 -		render_mesh(m);
   2.136 -		m = m->next;
   2.137 +	struct light *lt = scn->lights;
   2.138 +	int pass = 0;
   2.139 +
   2.140 +	while(lt || pass == 0) {
   2.141 +		struct mesh *m;
   2.142 +
   2.143 +		setup_light(lt);
   2.144 +
   2.145 +		glEnable(GL_BLEND);
   2.146 +
   2.147 +		if(pass > 0) {
   2.148 +			glBlendFunc(GL_SRC_ALPHA, GL_ONE);
   2.149 +			glDepthMask(0);
   2.150 +		} else {
   2.151 +			glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
   2.152 +			glDepthMask(1);
   2.153 +		}
   2.154 +
   2.155 +		m = scn->meshes;
   2.156 +		while(m) {
   2.157 +			render_mesh(m, pass);
   2.158 +			m = m->next;
   2.159 +		}
   2.160 +		pass++;
   2.161  	}
   2.162  }
   2.163  
   2.164 -void render_mesh(struct mesh *m)
   2.165 +static void setup_light(struct light *lt)
   2.166  {
   2.167 -	glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, m->mat.kd);
   2.168 +	if(!lt)
   2.169 +		return;
   2.170 +	glLightfv(GL_LIGHT0, GL_POSITION, lt->pos);
   2.171 +	glLightfv(GL_LIGHT0, GL_DIFFUSE, lt->color);
   2.172 +	glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, lt->att[0]);
   2.173 +	glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, lt->att[1]);
   2.174 +	glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, lt->att[2]);
   2.175 +	glEnable(GL_LIGHT0);
   2.176 +}
   2.177 +
   2.178 +void render_mesh(struct mesh *m, int pass)
   2.179 +{
   2.180 +	if(pass > 0) {
   2.181 +		float black[] = {0, 0, 0, 0};
   2.182 +		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, black);
   2.183 +	} else {
   2.184 +		glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, m->mat.kd);
   2.185 +	}
   2.186 +	glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, m->mat.kd);
   2.187  	glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, m->mat.ks);
   2.188  	glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, m->mat.shin);
   2.189  
     3.1 --- a/src/scene.h	Thu Jan 19 01:51:05 2012 +0200
     3.2 +++ b/src/scene.h	Thu Jan 19 06:15:10 2012 +0200
     3.3 @@ -27,6 +27,10 @@
     3.4  	float pos[4];
     3.5  	float color[4];
     3.6  
     3.7 +	float cone_inner, cone_outer;
     3.8 +
     3.9 +	float att[3];
    3.10 +
    3.11  	struct light *next;
    3.12  };
    3.13  
    3.14 @@ -41,6 +45,6 @@
    3.15  int load_scene(struct scene *scn, const char *fname);
    3.16  
    3.17  void render_scene(struct scene *scn);
    3.18 -void render_mesh(struct mesh *m);
    3.19 +void render_mesh(struct mesh *m, int pass);
    3.20  
    3.21  #endif	/* SCENE_H_ */