#include "togl.h" #include "material.h" #include "image.h" #include "ppm.h" #include #include typedef struct { float ambient[4]; float diffuse[4]; float specular[4]; float emission[4]; float shininess; } Material; // local variables static Material gMaterials[MAX_NUM_MATERIALS]; static TextureData gTextures[MAX_NUM_TEXTURES]; void make_material(int index, float r, float g, float b, float a, float ambient, float diffuse, float specular, float emission, float shininess) { gMaterials[index].ambient[0] = r*ambient; gMaterials[index].ambient[1] = g*ambient; gMaterials[index].ambient[2] = b*ambient; gMaterials[index].ambient[3] = a; gMaterials[index].diffuse[0] = r*diffuse; gMaterials[index].diffuse[1] = g*diffuse; gMaterials[index].diffuse[2] = b*diffuse; gMaterials[index].diffuse[3] = a; gMaterials[index].specular[0] = r*specular; gMaterials[index].specular[1] = g*specular; gMaterials[index].specular[2] = b*specular; gMaterials[index].specular[3] = a; gMaterials[index].emission[0] = r*emission; gMaterials[index].emission[1] = g*emission; gMaterials[index].emission[2] = b*emission; gMaterials[index].emission[3] = a; gMaterials[index].shininess = shininess; } void lmbind(int face, int index) { glMaterialfv(face, GL_AMBIENT, gMaterials[index].ambient); glMaterialfv(face, GL_DIFFUSE, gMaterials[index].diffuse); glMaterialfv(face, GL_SPECULAR, gMaterials[index].specular); glMaterialfv(face, GL_EMISSION, gMaterials[index].emission); glMaterialf(face, GL_SHININESS, gMaterials[index].shininess); } void clear_all_texture() { int i; for (i = 0; i < MAX_NUM_TEXTURES; i++) { gTextures[i].sizeX = 0; gTextures[i].sizeY = 0; gTextures[i].sizeZ = 0; if (gTextures[i].data != NULL) { delete[] gTextures[i].data; } } } void clear_texture(int index) { gTextures[index].sizeX = 0; gTextures[index].sizeY = 0; gTextures[index].sizeZ = 0; if (gTextures[index].data != NULL) { delete[] gTextures[index].data; } } int load_texture(int index, char *file) { char extension[4]; int i, str_len, size, result; static int first = 1; if (first) { for (i = 0; i < MAX_NUM_TEXTURES; i++) { gTextures[i].sizeX = 0; gTextures[i].sizeY = 0; gTextures[i].sizeZ = 0; gTextures[i].data = NULL; } first = 0; } str_len = strlen(file); for(i = 0; i < 3; i++) { extension[i] = file[str_len-3+i]; } extension[3] = NULL; if (!strcmp(extension, "ppm")) { PpmImage ppm; if ((result = LoadPpmFile(file, &ppm)) != 1) { return result; } size = ppm.width * ppm.height * 3; gTextures[index].sizeX = ppm.width; gTextures[index].sizeY = ppm.height; gTextures[index].sizeZ = 3; if (!(gTextures[index].data = new unsigned char[size])) { printf("Couldn't allocate memory for texture image pixel\n"); return -1; } memcpy(gTextures[index].data, ppm.data, size*sizeof(unsigned char)); delete[] ppm.data; } else if (!strcmp(extension, "rgb")) { TK_RGBImageRec *rgb; if (!(rgb = tkRGBImageLoad(file))) { return -1; } size = rgb->sizeX * rgb->sizeY * rgb->sizeZ; gTextures[index].sizeX = rgb->sizeX; gTextures[index].sizeY = rgb->sizeY; gTextures[index].sizeZ = rgb->sizeZ; if (!(gTextures[index].data = new unsigned char[size])) { printf("Couldn't allocate memory for texture image pixel\n"); return -1; } memcpy(gTextures[index].data, rgb->data, size*sizeof(unsigned char)); delete[] rgb->data; delete rgb; } else { printf("Unrecognizable texture file format, can only be ppm or rgb\n"); return 0; } return 1; } // sets up the current bound texture to the image specified by // the image structure pointer img // if shade is 1, lighting and materials also change the appearance // otherwise, no lighting effects are shown void texbind(int dummy, int index) { // the texture image // NOTE: height and width must be a power of 2 glTexImage2D(GL_TEXTURE_2D, 0, gTextures[index].sizeZ, gTextures[index].sizeX, gTextures[index].sizeY, 0, gTextures[index].sizeZ==3 ? GL_RGB : GL_RGBA, GL_UNSIGNED_BYTE, gTextures[index].data); // the texture environment glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // set up the texturing parameters 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_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); }