106 lines
3.0 KiB
C++
106 lines
3.0 KiB
C++
#include "texture.h"
|
|
#include "glassert.h"
|
|
#include "utils.h"
|
|
#include <glm/gtc/noise.hpp>
|
|
|
|
|
|
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(const std::string filename) : type(GL_TEXTURE_2D)
|
|
{
|
|
glAssert(glGenTextures(1, &texId));
|
|
glAssert(glBindTexture(type, texId));
|
|
|
|
createTexture(filename, GL_TEXTURE_2D);
|
|
setWrap(GL_REPEAT);
|
|
setFiltering(GL_LINEAR);
|
|
}
|
|
|
|
Texture::Texture(const std::string filename[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(filename[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_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data));
|
|
}
|
|
|
|
void Texture::createTexture(std::string filename, GLenum textureSlot)
|
|
{
|
|
Utils::Image img(filename);
|
|
int bpp = (img.depth() == 32) ? GL_RGBA : GL_RGB;
|
|
int format = (img.depth() == 32) ? GL_BGRA : GL_BGR;
|
|
glAssert(glTexImage2D(textureSlot, 0, bpp, img.width(), img.height(), 0, format, GL_UNSIGNED_BYTE, img.pixels()));
|
|
}
|
|
|
|
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));
|
|
}
|
|
|