Initial commit
This commit is contained in:
commit
edfc5298e1
252 changed files with 93965 additions and 0 deletions
250
source/Graphics/Texture.cpp
Normal file
250
source/Graphics/Texture.cpp
Normal file
|
|
@ -0,0 +1,250 @@
|
|||
|
||||
#include <Spectre/Graphics/Image.h>
|
||||
#include <Spectre/Graphics/OpenGL.h>
|
||||
#include <Spectre/Graphics/Texture.h>
|
||||
|
||||
namespace {
|
||||
|
||||
GLint pixelFormatToInternal(enum PixelFormat format) {
|
||||
|
||||
switch(format) {
|
||||
case PixelFormat::PF_RGBA : return GL_RGBA8;
|
||||
case PixelFormat::PF_RGB : return GL_RGB8;
|
||||
case PixelFormat::PF_Alpha :
|
||||
default : return GL_R8;
|
||||
}
|
||||
}
|
||||
|
||||
GLint pixelFormatToGL(enum PixelFormat format) {
|
||||
|
||||
switch(format) {
|
||||
case PixelFormat::PF_RGBA : return GL_RGBA;
|
||||
case PixelFormat::PF_RGB : return GL_RGB;
|
||||
case PixelFormat::PF_Alpha :
|
||||
default : return GL_RED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Texture::Texture() :
|
||||
m_id (0),
|
||||
m_size (0, 0)
|
||||
{
|
||||
}
|
||||
|
||||
Texture::~Texture()
|
||||
{
|
||||
destroy();
|
||||
}
|
||||
|
||||
void Texture::create(unsigned width, unsigned heigth, PixelFormat format)
|
||||
{
|
||||
std::vector<unsigned char> empty_pixels(width * heigth);
|
||||
|
||||
if (!m_id) {
|
||||
glGenTextures(1, &m_id);
|
||||
}
|
||||
|
||||
enable();
|
||||
|
||||
m_size = vec2u(width, heigth);
|
||||
m_format = format;
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0,
|
||||
pixelFormatToInternal(format), width, heigth, 0,
|
||||
GL_RED, GL_UNSIGNED_BYTE, &empty_pixels[0]);
|
||||
|
||||
setSmooth(true);
|
||||
setRepeat(false);
|
||||
|
||||
disable();
|
||||
}
|
||||
|
||||
void Texture::create(const Vector2u& size, PixelFormat format)
|
||||
{
|
||||
create(size.x, size.y, format);
|
||||
}
|
||||
|
||||
void Texture::create(const Image& image)
|
||||
{
|
||||
GLint srcFormat;
|
||||
GLint glFormat;
|
||||
|
||||
if (!m_id) {
|
||||
glGenTextures(1, &m_id);
|
||||
}
|
||||
|
||||
m_size = image.getSize();
|
||||
m_format = image.getFormat();
|
||||
|
||||
enable();
|
||||
|
||||
if (image.getFormat() == PixelFormat::PF_Alpha) {
|
||||
glFormat = GL_R8;
|
||||
srcFormat = GL_RED;
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
} else {
|
||||
glFormat = GL_RGBA;
|
||||
srcFormat = GL_RGBA;
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
}
|
||||
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, glFormat, m_size.x, m_size.y,
|
||||
0, srcFormat, GL_UNSIGNED_BYTE, image.getPixels());
|
||||
|
||||
setSmooth(true);
|
||||
setRepeat(false);
|
||||
|
||||
disable();
|
||||
}
|
||||
|
||||
void Texture::create(const std::string& filename, bool isTopDown)
|
||||
{
|
||||
Image img;
|
||||
|
||||
if (img.loadFromFile(filename)) {
|
||||
|
||||
// OpenGL expects bottom-up images, flip.
|
||||
if (isTopDown) {
|
||||
img.flipY();
|
||||
}
|
||||
|
||||
create(img);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture::destroy()
|
||||
{
|
||||
if (m_id) {
|
||||
glDeleteTextures(1, &m_id);
|
||||
m_id = 0;
|
||||
}
|
||||
|
||||
m_size = vec2u(0, 0);
|
||||
m_format = PixelFormat::PF_Unknown;
|
||||
}
|
||||
|
||||
bool Texture::isEmpty() const
|
||||
{
|
||||
return m_id == 0 || m_size == vec2u(0, 0);
|
||||
}
|
||||
|
||||
const Vector2u& Texture::getSize() const
|
||||
{
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void Texture::update(vec2u pos, const Image& image)
|
||||
{
|
||||
GLuint format;
|
||||
|
||||
enable();
|
||||
|
||||
if (image.getFormat() == PixelFormat::PF_Alpha) {
|
||||
format = GL_RED;
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
} else {
|
||||
format = GL_RGBA;
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
}
|
||||
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, pos.x, pos.y,
|
||||
image.getWidth(), image.getHeight(),
|
||||
format, GL_UNSIGNED_BYTE, image.getPixels());
|
||||
|
||||
disable();
|
||||
}
|
||||
|
||||
void Texture::update(const Image& image)
|
||||
{
|
||||
update(Vector2u(0, 0), image);
|
||||
}
|
||||
|
||||
Image Texture::copyToImage() const
|
||||
{
|
||||
Image img;
|
||||
|
||||
if (!isEmpty()) {
|
||||
std::vector<unsigned char> pixels(m_size.x * m_size.y * 4);
|
||||
|
||||
enable();
|
||||
|
||||
//glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
||||
glGetTexImage(GL_TEXTURE_2D, 0,
|
||||
pixelFormatToGL(m_format),
|
||||
GL_UNSIGNED_BYTE,
|
||||
&pixels[0]);
|
||||
|
||||
img.create(m_format, m_size.x, m_size.y, &pixels[0]);
|
||||
|
||||
disable();
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
|
||||
void Texture::setMinFilter(enum Filter filter)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
|
||||
}
|
||||
|
||||
void Texture::setMagFilter(enum Filter filter)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
|
||||
}
|
||||
|
||||
void Texture::setSmooth(bool value)
|
||||
{
|
||||
Filter filter = value ? Filter::Linear : Filter::Nearest;
|
||||
|
||||
setMinFilter(filter);
|
||||
setMagFilter(filter);
|
||||
}
|
||||
|
||||
void Texture::setWrapMode(enum WrapMode mode)
|
||||
{
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, mode);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, mode);
|
||||
}
|
||||
|
||||
void Texture::setRepeat(bool value)
|
||||
{
|
||||
setWrapMode(value ? WrapMode::Repeat : WrapMode::ClampToEdge);
|
||||
}
|
||||
|
||||
void Texture::enable() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, m_id);
|
||||
}
|
||||
|
||||
void Texture::disable() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
static unsigned int _getMaxSize() {
|
||||
|
||||
GLint size;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &size);
|
||||
return static_cast<unsigned int>(size);
|
||||
}
|
||||
|
||||
unsigned int Texture::getMaxSize()
|
||||
{
|
||||
static unsigned maxSize = _getMaxSize();
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
bool Texture::operator<(const Texture* other) const
|
||||
{
|
||||
return m_id < other->m_id;
|
||||
}
|
||||
|
||||
bool Texture::operator!=(const Texture* other) const
|
||||
{
|
||||
return m_id != other->m_id;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue