#include "Texture.h" #include #include #include #include "graphics/Image.h" #include "utilities/GLUtilities.h" #include "utilities/IOUtilities.h" #include "utilities/JSONParser.h" Texture * Texture_create(const char * filePath) { Texture * self; self = malloc(sizeof(Texture)); Texture_init(self); return self; } void Texture_init(Texture * self) { self->image = NULL; self->name = 0; self->internalFormat = GL_RGBA; self->minFilter = GL_NEAREST; self->magFilter = GL_NEAREST; self->wrapS = GL_REPEAT; self->wrapT = GL_REPEAT; self->blend = false; } void Texture_dispose(Texture * self) { Image_dispose(self->image); glDeleteTextures(1, &self->name); free(self); } static void readPropertyFromJSONNode(GLenum * property, JSONNode * node) { if (node->type == JSON_TYPE_STRING) { stringToGLConstant(node->value.string, property); } else if (node->type == JSON_TYPE_NUMBER) { *property = node->value.number; } } void Texture_loadJSON(Texture * self, JSONNode * rootNode, const char * prefix) { size_t propertyIndex; char filePath[PATH_MAX]; // TODO: Validation for (propertyIndex = 0; propertyIndex < rootNode->numberOfChildren; propertyIndex++) { if (!strcmp("image", rootNode->children[propertyIndex].key)) { if (rootNode->children[propertyIndex].type == JSON_TYPE_STRING && strlen(rootNode->children[propertyIndex].value.string) > 4) { if (!strcmp(".png", rootNode->children[propertyIndex].value.string + (strlen(rootNode->children[propertyIndex].value.string) - 4))) { sprintf(filePath, "%s/%s", prefix, rootNode->children[propertyIndex].value.string); self->image = Image_loadFromPNG(filePath, IMAGE_PIXEL_FORMAT_RGBA, true); } else if (!strcmp(".jpg", rootNode->children[propertyIndex].value.string + (strlen(rootNode->children[propertyIndex].value.string) - 4))) { sprintf(filePath, "%s/%s", prefix, rootNode->children[propertyIndex].value.string); self->image = Image_loadFromJPEG(filePath, IMAGE_PIXEL_FORMAT_RGBA, true); } } } else if (!strcmp("internal_format", rootNode->children[propertyIndex].key)) { readPropertyFromJSONNode(&self->internalFormat, &rootNode->children[propertyIndex]); } else if (!strcmp("wrap_s", rootNode->children[propertyIndex].key)) { readPropertyFromJSONNode(&self->wrapS, &rootNode->children[propertyIndex]); } else if (!strcmp("wrap_t", rootNode->children[propertyIndex].key)) { readPropertyFromJSONNode(&self->wrapT, &rootNode->children[propertyIndex]); } else if (!strcmp("mag_filter", rootNode->children[propertyIndex].key)) { readPropertyFromJSONNode(&self->magFilter, &rootNode->children[propertyIndex]); } else if (!strcmp("min_filter", rootNode->children[propertyIndex].key)) { readPropertyFromJSONNode(&self->minFilter, &rootNode->children[propertyIndex]); } else if (!strcmp("blend", rootNode->children[propertyIndex].key)) { self->blend = rootNode->children[propertyIndex].value.boolean; } } if (self->image != NULL) { float maxAnisotropy; glGenTextures(1, &self->name); glBindTexture(GL_TEXTURE_2D, self->name); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, self->wrapS); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, self->wrapT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, self->magFilter); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, self->minFilter); glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, maxAnisotropy); if (self->minFilter == GL_NEAREST_MIPMAP_NEAREST || self->minFilter == GL_LINEAR_MIPMAP_NEAREST || self->minFilter == GL_NEAREST_MIPMAP_LINEAR || self->minFilter == GL_LINEAR_MIPMAP_LINEAR) { #if TARGET_OPENGL_ES glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); glTexImage2D(GL_TEXTURE_2D, 0, self->internalFormat, self->image->width, self->image->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, self->image->pixels); #else gluBuild2DMipmaps(GL_TEXTURE_2D, self->internalFormat, self->image->width, self->image->height, GL_RGBA, GL_UNSIGNED_BYTE, self->image->pixels); #endif } else { glTexImage2D(GL_TEXTURE_2D, 0, self->internalFormat, self->image->width, self->image->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, self->image->pixels); } } } void Texture_activate(Texture * self) { glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, self->name); if (self->blend) { glEnable(GL_BLEND); } } void Texture_deactivate(Texture * self) { if (self->blend) { glDisable(GL_BLEND); } glBindTexture(GL_TEXTURE_2D, 0); glDisable(GL_TEXTURE_2D); }