⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 object.cpp

📁 Algo de codigo de openGL que obtuve en la web :P
💻 CPP
字号:
/* GL_shadow: an implementation of the stencil shadow volume technique * Copyright (C) 2005 Angelo "Encelo" Theodorou *  * object.c: simple and DIRTY Wavefront OBJ loader */   #include <stdlib.h>#include <string.h>#include <SDL/SDL.h>#include <gl/gl.h>#include "object.h"/* Loads a 3D object in OBJ format */Object *LoadObject(char *objfile){	FILE *fd;	Object *obj;	char buf[128];		char namebuf[128];	int nv, nt, nn, nf;	char texbuf[128];	char matfile[128];	char material[128], mat[128];	Point *vertices, *texcoords, *normals;	int fv[3], ft[3], fn[3];	int i;	int mat_flag = 0;		/* ----- Processing the .obj file ----- */	fd = fopen(objfile, "r");	if (fd == NULL) {		printf("Unable to open %s\n", objfile);		return NULL;	}	obj = (Object *)malloc(sizeof(Object));	nv = nt = nn = nf = 0;	/* Element count */	while(fgets(buf, 128, fd) != NULL) {		switch(buf[0]) {			case 'm':				if (strncmp(buf, "mtllib", 6) == 0) {					sscanf(buf, "mtllib %s\n", matfile);				}			case 'o':				sscanf(buf, "o %s\n", namebuf);				break;			case 'v':				switch(buf[1]) {					case ' ':						nv++;						break;					/* Number of texcoords and normal vectors is equal to 3 times the number of faces */					/* This is true only for Blender 2.37a OBJ importer script, not for 2.40 one */				}				break;			case 'u':				if (strncmp(buf, "usemat", 6) == 0) {					sscanf(buf, "usemat %s\n", texbuf);				}				if (strncmp(buf, "usemtl", 6) == 0) {					sscanf(buf, "usemtl %s\n", material);				}				break;			case 'f':				nf++;				break;		}	}	/* ----- Object initialization ----- */	/* Name */	obj->Name = malloc(sizeof(char) * strlen(namebuf));	strncpy(obj->Name, namebuf, strlen(namebuf));	(obj->Name)[strlen(namebuf)] = '\0'; /* Terminating the string, '\n' becomes '\0' */	/* Texture */	obj->TexId = LoadTexture(texbuf);	/* nFaces */	obj->nFaces = nf;	/* Faces */	obj->Faces = malloc(sizeof(Face) * nf);	/* nVertices */	obj->nVertices = nv;	/* Vertices */	obj->Vertices = (Point *)malloc(sizeof(Point) * nv);	/* TexCoords */	obj->TexCoords = (Point *)malloc(sizeof(Point) * 3 * nf);	/* Normals */	obj->Normals = (Point *)malloc(sizeof(Point) * 3 * nf);		rewind(fd);	nv = nt = nn = nf = 0;	while(fgets(buf, 128, fd) != NULL) {		switch(buf[0]) {			case 'v':				switch(buf[1]) {					case ' ':						sscanf(buf, "v %f %f %f\n", &obj->Vertices[nv].x, &obj->Vertices[nv].y, &obj->Vertices[nv].z);						nv++;						break;					case 't':						sscanf(buf, "vt %f %f %f\n", &obj->TexCoords[nt].x, &obj->TexCoords[nt].y, &obj->TexCoords[nt].z);						nt++;						break;					case 'n':						sscanf(buf, "vn %f %f %f\n", &obj->Normals[nn].x,  &obj->Normals[nn].y,  &obj->Normals[nn].z);						nn++;						break;				}				break;			case 'f':				sscanf(buf, "f %u/%u/%u %u/%u/%u %u/%u/%u \n", &fv[0], &ft[0], &fn[0],					&fv[1], &ft[1], &fn[1],					&fv[2], &ft[2], &fn[2]);				for(i = 0; i < 3; i++) {					fv[i]--; ft[i]--; fn[i]--; /* Face indices starts from 1 in Obj format */					obj->Faces[nf].VertIdx[i] = fv[i];					obj->Faces[nf].TexIdx[i] = ft[i];					obj->Faces[nf].NorIdx[i] = fn[i];					obj->Faces[nf].NeighIdx[i] = -1; /* Connectivity will be calculated later */				}				nf++;				break;		}	}	fclose(fd);	/* ----- Processing the .mtl file ----- */	fd = fopen(matfile, "r");	if (fd == NULL) {		printf("Unable to open %s\n", matfile);		return NULL;	}	while(fgets(buf, 128, fd) != NULL) {		/* Search the correct material */		if (strncmp(buf, "newmtl", 6) == 0) {			sscanf(buf, "newmtl %s", mat);			if (strncmp(mat, material, strlen(material)) == 0) {				mat_flag = 1;				continue;			}			else {				mat_flag = 0;				continue;			}		}	if (mat_flag == 1)		switch(buf[0]){			case 'K':				switch(buf[1]){					case 'd':						sscanf(buf, "Kd %f %f %f\n", &obj->Diffuse[0], &obj->Diffuse[1], &obj->Diffuse[2]);						break;					case 'a':						sscanf(buf, "Ka %f %f %f\n", &obj->Ambient[0], &obj->Ambient[1], &obj->Ambient[2]);						break;					case 's':						sscanf(buf, "Ks %f %f %f\n", &obj->Specular[0], &obj->Specular[1], &obj->Specular[2]);						break;				}				break;			case 'd':				sscanf(buf, "d %f\n", &obj->Diffuse[3]);				obj->Ambient[3] = obj->Specular[3] = obj->Diffuse[3];				break;		}	}	return obj;}/* Simple code to load a texture and return its id */GLuint LoadTexture(char *tex_name){	GLuint tex_num;			SDL_Surface *tex_img;	glGenTextures(1, &tex_num);	if(tex_img = (SDL_Surface *) IMG_Load(tex_name)) {        glBindTexture(GL_TEXTURE_2D, tex_num);		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);		if ((tex_img->format)->Amask)	        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex_img->w, tex_img->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tex_img->pixels);		else			glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, tex_img->w, tex_img->h, 0, GL_RGB, GL_UNSIGNED_BYTE, tex_img->pixels);        SDL_FreeSurface (tex_img);    }	else		printf("Texture not found!\n");	return tex_num;}/* Edge connectivity */void SetConnectivity(Object *obj){	int nf1, nf2;   	int e1, e2;	int v1a, v1b, v2a, v2b;	Face *face1, *face2;		for(nf1=0; nf1 < obj->nFaces; nf1++){ /* For each face in the object */		face1 = &obj->Faces[nf1];		for(e1=0; e1<3; e1++){ /* For each edge of the face */			if(face1->NeighIdx[e1] == -1){ /* If connectivity is not yet set for this edge */				for(nf2=0; nf2 < obj->nFaces; nf2++){ /* Checking connectivity against any other face */					face2 = &obj->Faces[nf2];					if (nf2 == nf1) /* Skipping checking connectivity against the same face we are checking on */						continue;					for(e2=0; e2<3; e2++){						v1a = face1->VertIdx[e1];						v1b = face1->VertIdx[(e1+1)%3];						v2a = face2->VertIdx[e2];						v2b = face2->VertIdx[(e2+1)%3];						if((v1a == v1b && v2a == v2b) || (v1a == v2b && v2a == v1b)){							face1->NeighIdx[e1] = nf2;							face2->NeighIdx[e2] = nf1;							break;						}					}				}			}		}	}}/* Calculates the equation of the plane on which a face is laying on */void CalculatePlane(Object *obj, int nf){	Point v1, v2, v3;	Face *face;	face = &obj->Faces[nf];	v1 = obj->Vertices[face->VertIdx[0]];	v2 = obj->Vertices[face->VertIdx[1]];	v3 = obj->Vertices[face->VertIdx[2]];		face->pEq.a = v1.y*(v2.z-v3.z) + v2.y*(v3.z-v1.z) + v3.y*(v1.z-v2.z);	face->pEq.b = v1.z*(v2.x-v3.x) + v2.z*(v3.x-v1.x) + v3.z*(v1.x-v2.x);	face->pEq.c = v1.x*(v2.y-v3.y) + v2.x*(v3.y-v1.y) + v3.x*(v1.y-v2.y);	face->pEq.d = -(v1.x*(v2.y*v3.z-v3.y*v2.z)		+ v2.x*(v3.y*v1.z-v1.y*v3.z)		+ v3.x*(v1.y*v2.z-v2.y*v1.z));}Object *InitObject(char *objfile){	int nf;	Object *obj;			if((obj = LoadObject(objfile)) != NULL){		SetConnectivity(obj);		for(nf=0; nf < obj->nFaces; nf++)			CalculatePlane(obj, nf);	}	return obj;}void FreeObject(Object *obj){	glDeleteTextures(1, &(obj->TexId));	free(obj->Normals);	free(obj->TexCoords);	free(obj->Vertices);	free(obj->Faces);	free(obj->Name);}void DrawObject(Object *obj){	int nf, i;	Face *face;	Point *n, *t, *v;		glBindTexture(GL_TEXTURE_2D, obj->TexId);	glBegin(GL_TRIANGLES);	for(nf=0; nf < obj->nFaces; nf++) {		face = &obj->Faces[nf];		for(i=0; i<3; i++) {			n = &obj->Normals[face->NorIdx[i]];			t = &obj->TexCoords[face->TexIdx[i]];			v = &obj->Vertices[face->VertIdx[i]];						glNormal3f(n->x, n->y, n->z);			glTexCoord3f(t->x, t->y, t->z);			glVertex3f(v->x, v->y, v->z);		}	}	glEnd();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -