#include "texture.h" #include "glassert.h" #include "image.h" #include Texture::Texture() : type(GL_TEXTURE_2D) { glAssert(glGenTextures(1, &texId)); glAssert(glBindTexture(type, texId)); createNoiseTexture(GL_TEXTURE_2D, 512, 512, 10, 1.5f); setWrap(GL_REPEAT); setFiltering(GL_LINEAR); } Texture::Texture(Image* myImage) : type(GL_TEXTURE_2D) { glAssert(glGenTextures(1, &texId)); glAssert(glBindTexture(type, texId)); createTexture(myImage, GL_TEXTURE_2D); setWrap(GL_REPEAT); setFiltering(GL_LINEAR); } Texture::Texture(Image* myCubemapImages[6]) : type(GL_TEXTURE_CUBE_MAP) { glAssert(glActiveTexture(GL_TEXTURE0)); glAssert(glGenTextures(1, &texId)); glAssert(glBindTexture(type, texId)); for(int i=0; i<6; ++i) { createTexture(myCubemapImages[i], GL_TEXTURE_CUBE_MAP_POSITIVE_X + i); setWrap(GL_CLAMP_TO_EDGE); setFiltering(GL_LINEAR); } } Texture::~Texture() { glAssert(glDeleteTextures(1, &texId)); } void Texture::createNoiseTexture(GLenum textureSlot, int width, int height, float frequency, float amplitude) { GLubyte *data = new GLubyte[ width * height * 4]; float xFactor = 1.0f / (width - 1); float yFactor = 1.0f / (height - 1); for( int row = 0; row < height; row++ ) { for( int col = 0 ; col < width; col++ ) { float x = xFactor * col; float y = yFactor * row; float sum = 0.0f; float freq = frequency; float scale = amplitude; // Compute the sum for each octave for( int oct = 0; oct < 4 ; oct++ ) { glm::vec2 p(x * freq, y * freq); float val = glm::perlin(p, glm::vec2(freq)) / scale; sum += val; float result = (sum + 1.0f)/ 2.0f; // Store in texture buffer data[((row * width + col) * 4) + oct] = (GLubyte) ( result * 255.0f ); freq *= 2.0f; // Double the frequency scale *= amplitude; // Next power of b } } } glAssert(glTexImage2D(textureSlot, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data)); } void Texture::createTexture(Image* myImage, GLenum textureSlot) { switch(myImage->depth) { case 32: glAssert(glTexImage2D(textureSlot, 0, GL_RGBA, myImage->width, myImage->height, 0, GL_BGRA, GL_UNSIGNED_BYTE, myImage->pixels)); break; case 24: glAssert(glTexImage2D(textureSlot, 0, GL_RGB, myImage->width, myImage->height, 0, GL_BGR, GL_UNSIGNED_BYTE, myImage->pixels)); break; case 8: glAssert(glTexImage2D(textureSlot, 0, GL_R8, myImage->width, myImage->height, 0, GL_RED, GL_UNSIGNED_BYTE, myImage->pixels)); break; } } void Texture::setWrap(GLint wrap) { glAssert(glTexParameteri(type, GL_TEXTURE_WRAP_S, wrap)); glAssert(glTexParameteri(type, GL_TEXTURE_WRAP_T, wrap)); glAssert(glTexParameteri(type, GL_TEXTURE_WRAP_R, wrap)); } void Texture::setFiltering(GLint filter) { glAssert(glTexParameteri(type, GL_TEXTURE_MIN_FILTER, filter)); glAssert(glTexParameteri(type, GL_TEXTURE_MAG_FILTER, filter)); } void Texture::bind(int slot) { GLenum texSlot = GL_TEXTURE0+slot; glAssert(glActiveTexture(texSlot)); glAssert(glBindTexture(type, texId)); }