memory refactor Texture and ImageData
This commit is contained in:
parent
ce9c5b97c7
commit
c0dca31e98
@ -1,7 +1,7 @@
|
|||||||
#include "png.hpp"
|
#include "png.hpp"
|
||||||
|
|
||||||
#include "../graphics/core/ImageData.hpp"
|
#include "../graphics/core/ImageData.hpp"
|
||||||
#include "../graphics/core/Texture.hpp"
|
#include "../graphics/core/GLTexture.hpp"
|
||||||
#include "../files/files.hpp"
|
#include "../files/files.hpp"
|
||||||
#include "../debug/Logger.hpp"
|
#include "../debug/Logger.hpp"
|
||||||
|
|
||||||
@ -159,8 +159,8 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
|||||||
color_type = 6;
|
color_type = 6;
|
||||||
bit_depth = png_get_bit_depth(png, info);
|
bit_depth = png_get_bit_depth(png, info);
|
||||||
|
|
||||||
std::unique_ptr<png_byte[]> image_data (new png_byte[row_bytes * height]);
|
auto image_data = std::make_unique<png_byte[]>(row_bytes * height);
|
||||||
std::unique_ptr<png_byte*[]> row_pointers (new png_byte*[height]);
|
auto row_pointers = std::make_unique<png_byte*[]>(height);
|
||||||
for (int i = 0; i < height; ++i ) {
|
for (int i = 0; i < height; ++i ) {
|
||||||
row_pointers[height - 1 - i] = image_data.get() + i * row_bytes;
|
row_pointers[height - 1 - i] = image_data.get() + i * row_bytes;
|
||||||
}
|
}
|
||||||
@ -180,7 +180,7 @@ std::unique_ptr<ImageData> _png_load(const char* file){
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
auto image = std::make_unique<ImageData>(format, width, height, (void*)image_data.release());
|
auto image = std::make_unique<ImageData>(format, width, height, std::move(image_data));
|
||||||
png_destroy_read_struct(&png, &info, &end_info);
|
png_destroy_read_struct(&png, &info, &end_info);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return image;
|
return image;
|
||||||
@ -336,7 +336,7 @@ std::unique_ptr<ImageData> png::load_image(const std::string& filename) {
|
|||||||
|
|
||||||
std::unique_ptr<Texture> png::load_texture(const std::string& filename) {
|
std::unique_ptr<Texture> png::load_texture(const std::string& filename) {
|
||||||
auto image = load_image(filename);
|
auto image = load_image(filename);
|
||||||
auto texture = Texture::from(image.get());
|
auto texture = GLTexture::from(image.get());
|
||||||
texture->setNearestFilter();
|
texture->setNearestFilter();
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,10 +17,11 @@ Batch2D::Batch2D(size_t capacity) : capacity(capacity), color(1.0f){
|
|||||||
mesh = std::make_unique<Mesh>(buffer.get(), 0, attrs);
|
mesh = std::make_unique<Mesh>(buffer.get(), 0, attrs);
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
ubyte pixels[] = {
|
const ubyte pixels[] = {
|
||||||
0xFF, 0xFF, 0xFF, 0xFF
|
0xFF, 0xFF, 0xFF, 0xFF
|
||||||
};
|
};
|
||||||
blank = std::make_unique<Texture>(pixels, 1, 1, ImageFormat::rgba8888);
|
ImageData image(ImageFormat::rgba8888, 1, 1, pixels);
|
||||||
|
blank = Texture::from(&image);
|
||||||
currentTexture = nullptr;
|
currentTexture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -20,10 +20,11 @@ Batch3D::Batch3D(size_t capacity)
|
|||||||
mesh = std::make_unique<Mesh>(buffer.get(), 0, attrs);
|
mesh = std::make_unique<Mesh>(buffer.get(), 0, attrs);
|
||||||
index = 0;
|
index = 0;
|
||||||
|
|
||||||
ubyte pixels[] = {
|
const ubyte pixels[] = {
|
||||||
255, 255, 255, 255,
|
255, 255, 255, 255,
|
||||||
};
|
};
|
||||||
blank = std::make_unique<Texture>(pixels, 1, 1, ImageFormat::rgba8888);
|
ImageData image(ImageFormat::rgba8888, 1, 1, pixels);
|
||||||
|
blank = Texture::from(&image);
|
||||||
currentTexture = nullptr;
|
currentTexture = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|
||||||
Cubemap::Cubemap(uint width, uint height, ImageFormat imageFormat)
|
Cubemap::Cubemap(uint width, uint height, ImageFormat imageFormat)
|
||||||
: Texture(0, width, height)
|
: GLTexture(0, width, height)
|
||||||
{
|
{
|
||||||
glGenTextures(1, &id);
|
glGenTextures(1, &id);
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, id);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, id);
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
#ifndef GRAPHICS_CORE_CUBEMAP_HPP_
|
#ifndef GRAPHICS_CORE_CUBEMAP_HPP_
|
||||||
#define GRAPHICS_CORE_CUBEMAP_HPP_
|
#define GRAPHICS_CORE_CUBEMAP_HPP_
|
||||||
|
|
||||||
#include "Texture.hpp"
|
#include "GLTexture.hpp"
|
||||||
|
|
||||||
/// @brief Cubemap texture
|
/// @brief Cubemap texture
|
||||||
class Cubemap : public Texture {
|
class Cubemap : public GLTexture {
|
||||||
public:
|
public:
|
||||||
Cubemap(uint width, uint height, ImageFormat format);
|
Cubemap(uint width, uint height, ImageFormat format);
|
||||||
|
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
#include "Framebuffer.hpp"
|
#include "Framebuffer.hpp"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
#include "Texture.hpp"
|
#include "GLTexture.hpp"
|
||||||
|
|
||||||
Framebuffer::Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture)
|
Framebuffer::Framebuffer(uint fbo, uint depth, std::unique_ptr<Texture> texture)
|
||||||
: fbo(fbo), depth(depth), texture(std::move(texture))
|
: fbo(fbo), depth(depth), texture(std::move(texture))
|
||||||
@ -25,7 +25,7 @@ static std::unique_ptr<Texture> create_texture(int width, int height, int format
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
|
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex, 0);
|
||||||
return std::make_unique<Texture>(tex, width, height);
|
return std::make_unique<GLTexture>(tex, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
Framebuffer::Framebuffer(uint width, uint height, bool alpha)
|
Framebuffer::Framebuffer(uint width, uint height, bool alpha)
|
||||||
|
|||||||
75
src/graphics/core/GLTexture.cpp
Normal file
75
src/graphics/core/GLTexture.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "GLTexture.hpp"
|
||||||
|
#include "gl_util.hpp"
|
||||||
|
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
uint Texture::MAX_RESOLUTION = 1024; // Window.initialize overrides it
|
||||||
|
|
||||||
|
GLTexture::GLTexture(uint id, uint width, uint height)
|
||||||
|
: Texture(width, height), id(id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
GLTexture::GLTexture(const ubyte* data, uint width, uint height, ImageFormat imageFormat)
|
||||||
|
: Texture(width, height) {
|
||||||
|
glGenTextures(1, &id);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||||
|
|
||||||
|
GLenum format = gl::to_glenum(imageFormat);
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D, 0, format, width, height, 0,
|
||||||
|
format, GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(data)
|
||||||
|
);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
GLTexture::~GLTexture() {
|
||||||
|
glDeleteTextures(1, &id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLTexture::bind(){
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLTexture::unbind() {
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLTexture::reload(const ubyte* data){
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
||||||
|
GL_RGBA, GL_UNSIGNED_BYTE, static_cast<const GLvoid*>(data));
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ImageData> GLTexture::readData() {
|
||||||
|
auto data = std::make_unique<ubyte[]>(width * height * 4);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, id);
|
||||||
|
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.get());
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
return std::make_unique<ImageData>(ImageFormat::rgba8888, width, height, data.release());
|
||||||
|
}
|
||||||
|
|
||||||
|
void GLTexture::setNearestFilter() {
|
||||||
|
bind();
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<GLTexture> GLTexture::from(const ImageData* image) {
|
||||||
|
uint width = image->getWidth();
|
||||||
|
uint height = image->getHeight();
|
||||||
|
void* data = image->getData();
|
||||||
|
return std::make_unique<GLTexture>(static_cast<ubyte*>(data), width, height, image->getFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
uint GLTexture::getId() const {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
26
src/graphics/core/GLTexture.hpp
Normal file
26
src/graphics/core/GLTexture.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef GRAPHICS_CORE_GLTEXTURE_HPP_
|
||||||
|
#define GRAPHICS_CORE_GLTEXTURE_HPP_
|
||||||
|
|
||||||
|
#include "Texture.hpp"
|
||||||
|
|
||||||
|
class GLTexture : public Texture {
|
||||||
|
protected:
|
||||||
|
uint id;
|
||||||
|
public:
|
||||||
|
GLTexture(uint id, uint width, uint height);
|
||||||
|
GLTexture(const ubyte* data, uint width, uint height, ImageFormat format);
|
||||||
|
virtual ~GLTexture();
|
||||||
|
|
||||||
|
virtual void bind() override;
|
||||||
|
virtual void unbind() override;
|
||||||
|
virtual void reload(const ubyte* data);
|
||||||
|
|
||||||
|
void setNearestFilter();
|
||||||
|
|
||||||
|
virtual std::unique_ptr<ImageData> readData() override;
|
||||||
|
virtual uint getId() const override;
|
||||||
|
|
||||||
|
static std::unique_ptr<GLTexture> from(const ImageData* image);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // GRAPHICS_CORE_GLTEXTURE_HPP_
|
||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
inline int min(int a, int b) {
|
inline int min(int a, int b) {
|
||||||
return (a < b) ? a : b;
|
return (a < b) ? a : b;
|
||||||
@ -13,25 +14,34 @@ inline int max(int a, int b) {
|
|||||||
|
|
||||||
ImageData::ImageData(ImageFormat format, uint width, uint height)
|
ImageData::ImageData(ImageFormat format, uint width, uint height)
|
||||||
: format(format), width(width), height(height) {
|
: format(format), width(width), height(height) {
|
||||||
|
size_t pixsize;
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case ImageFormat::rgb888: data = new ubyte[width*height*3]{}; break;
|
case ImageFormat::rgb888: pixsize = 3; break;
|
||||||
case ImageFormat::rgba8888: data = new ubyte[width*height*4]{}; break;
|
case ImageFormat::rgba8888: pixsize = 4; break;
|
||||||
default:
|
default:
|
||||||
throw std::runtime_error("format is not supported");
|
throw std::runtime_error("format is not supported");
|
||||||
}
|
}
|
||||||
|
data = std::make_unique<ubyte[]>(width * height * pixsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageData::ImageData(ImageFormat format, uint width, uint height, void* data)
|
ImageData::ImageData(ImageFormat format, uint width, uint height, std::unique_ptr<ubyte[]> data)
|
||||||
: format(format), width(width), height(height), data(data) {
|
: format(format), width(width), height(height), data(std::move(data)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageData::ImageData(ImageFormat format, uint width, uint height, const ubyte* data)
|
||||||
|
: format(format), width(width), height(height) {
|
||||||
|
size_t pixsize;
|
||||||
|
switch (format) {
|
||||||
|
case ImageFormat::rgb888: pixsize = 3; break;
|
||||||
|
case ImageFormat::rgba8888: pixsize = 4; break;
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("format is not supported");
|
||||||
|
}
|
||||||
|
this->data = std::make_unique<ubyte[]>(width * height * pixsize);
|
||||||
|
std::memcpy(this->data.get(), data, width * height * pixsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageData::~ImageData() {
|
ImageData::~ImageData() {
|
||||||
switch (format) {
|
|
||||||
case ImageFormat::rgb888:
|
|
||||||
case ImageFormat::rgba8888:
|
|
||||||
delete[] (ubyte*)data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageData::flipX() {
|
void ImageData::flipX() {
|
||||||
@ -39,13 +49,12 @@ void ImageData::flipX() {
|
|||||||
case ImageFormat::rgb888:
|
case ImageFormat::rgb888:
|
||||||
case ImageFormat::rgba8888: {
|
case ImageFormat::rgba8888: {
|
||||||
uint size = (format == ImageFormat::rgba8888) ? 4 : 3;
|
uint size = (format == ImageFormat::rgba8888) ? 4 : 3;
|
||||||
ubyte* pixels = (ubyte*)data;
|
|
||||||
for (uint y = 0; y < height; y++) {
|
for (uint y = 0; y < height; y++) {
|
||||||
for (uint x = 0; x < width/2; x++) {
|
for (uint x = 0; x < width/2; x++) {
|
||||||
for (uint c = 0; c < size; c++) {
|
for (uint c = 0; c < size; c++) {
|
||||||
ubyte temp = pixels[(y * width + x) * size + c];
|
ubyte temp = data[(y * width + x) * size + c];
|
||||||
pixels[(y * width + x) * size + c] = pixels[(y * width + (width - x - 1)) * size + c];
|
data[(y * width + x) * size + c] = data[(y * width + (width - x - 1)) * size + c];
|
||||||
pixels[(y * width + (width - x - 1)) * size + c] = temp;
|
data[(y * width + (width - x - 1)) * size + c] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -61,14 +70,13 @@ void ImageData::flipY() {
|
|||||||
case ImageFormat::rgb888:
|
case ImageFormat::rgb888:
|
||||||
case ImageFormat::rgba8888: {
|
case ImageFormat::rgba8888: {
|
||||||
uint size = (format == ImageFormat::rgba8888) ? 4 : 3;
|
uint size = (format == ImageFormat::rgba8888) ? 4 : 3;
|
||||||
ubyte* pixels = (ubyte*)data;
|
|
||||||
for (uint y = 0; y < height/2; y++) {
|
for (uint y = 0; y < height/2; y++) {
|
||||||
for (uint x = 0; x < width; x++) {
|
for (uint x = 0; x < width; x++) {
|
||||||
for (uint c = 0; c < size; c++) {
|
for (uint c = 0; c < size; c++) {
|
||||||
ubyte temp = pixels[(y * width + x) * size + c];
|
ubyte temp = data[(y * width + x) * size + c];
|
||||||
pixels[(y * width + x) * size + c] =
|
data[(y * width + x) * size + c] =
|
||||||
pixels[((height-y-1) * width + x) * size + c];
|
data[((height-y-1) * width + x) * size + c];
|
||||||
pixels[((height-y-1) * width + x) * size + c] = temp;
|
data[((height-y-1) * width + x) * size + c] = temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,8 +101,7 @@ void ImageData::blit(const ImageData* image, int x, int y) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ImageData::blitRGB_on_RGBA(const ImageData* image, int x, int y) {
|
void ImageData::blitRGB_on_RGBA(const ImageData* image, int x, int y) {
|
||||||
ubyte* pixels = static_cast<ubyte*>(data);
|
ubyte* source = image->getData();
|
||||||
ubyte* source = static_cast<ubyte*>(image->getData());
|
|
||||||
uint srcwidth = image->getWidth();
|
uint srcwidth = image->getWidth();
|
||||||
uint srcheight = image->getHeight();
|
uint srcheight = image->getHeight();
|
||||||
|
|
||||||
@ -105,9 +112,9 @@ void ImageData::blitRGB_on_RGBA(const ImageData* image, int x, int y) {
|
|||||||
uint dstidx = (dsty * width + dstx) * 4;
|
uint dstidx = (dsty * width + dstx) * 4;
|
||||||
uint srcidx = (srcy * srcwidth + srcx) * 3;
|
uint srcidx = (srcy * srcwidth + srcx) * 3;
|
||||||
for (uint c = 0; c < 3; c++) {
|
for (uint c = 0; c < 3; c++) {
|
||||||
pixels[dstidx + c] = source[srcidx + c];
|
data[dstidx + c] = source[srcidx + c];
|
||||||
}
|
}
|
||||||
pixels[dstidx + 3] = 255;
|
data[dstidx + 3] = 255;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,8 +127,7 @@ void ImageData::blitMatchingFormat(const ImageData* image, int x, int y) {
|
|||||||
default:
|
default:
|
||||||
throw std::runtime_error("only unsigned byte formats supported");
|
throw std::runtime_error("only unsigned byte formats supported");
|
||||||
}
|
}
|
||||||
ubyte* pixels = static_cast<ubyte*>(data);
|
ubyte* source = image->getData();
|
||||||
ubyte* source = static_cast<ubyte*>(image->getData());
|
|
||||||
uint srcwidth = image->getWidth();
|
uint srcwidth = image->getWidth();
|
||||||
uint srcheight = image->getHeight();
|
uint srcheight = image->getHeight();
|
||||||
|
|
||||||
@ -132,7 +138,7 @@ void ImageData::blitMatchingFormat(const ImageData* image, int x, int y) {
|
|||||||
uint dstidx = (dsty * width + dstx) * comps;
|
uint dstidx = (dsty * width + dstx) * comps;
|
||||||
uint srcidx = (srcy * srcwidth + srcx) * comps;
|
uint srcidx = (srcy * srcwidth + srcx) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = source[srcidx + c];
|
data[dstidx + c] = source[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -148,17 +154,14 @@ void ImageData::extrude(int x, int y, int w, int h) {
|
|||||||
default:
|
default:
|
||||||
throw std::runtime_error("only unsigned byte formats supported");
|
throw std::runtime_error("only unsigned byte formats supported");
|
||||||
}
|
}
|
||||||
ubyte* pixels = static_cast<ubyte*>(data);
|
|
||||||
|
|
||||||
int rx = x + w - 1;
|
int rx = x + w - 1;
|
||||||
int ry = y + h - 1;
|
int ry = y + h - 1;
|
||||||
|
|
||||||
// top-left pixel
|
// top-left pixel
|
||||||
if (x > 0 && (uint)x < width && y > 0 && (uint)y < height) {
|
if (x > 0 && (uint)x < width && y > 0 && (uint)y < height) {
|
||||||
uint srcidx = (y * width + x) * comps;
|
uint srcidx = (y * width + x) * comps;
|
||||||
uint dstidx = ((y - 1) * width + x - 1) * comps;
|
uint dstidx = ((y - 1) * width + x - 1) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = pixels[srcidx + c];
|
data[dstidx + c] = data[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +170,7 @@ void ImageData::extrude(int x, int y, int w, int h) {
|
|||||||
uint srcidx = (y * width + rx) * comps;
|
uint srcidx = (y * width + rx) * comps;
|
||||||
uint dstidx = ((y - 1) * width + rx + 1) * comps;
|
uint dstidx = ((y - 1) * width + rx + 1) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = pixels[srcidx + c];
|
data[dstidx + c] = data[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,7 +179,7 @@ void ImageData::extrude(int x, int y, int w, int h) {
|
|||||||
uint srcidx = (ry * width + x) * comps;
|
uint srcidx = (ry * width + x) * comps;
|
||||||
uint dstidx = ((ry + 1) * width + x - 1) * comps;
|
uint dstidx = ((ry + 1) * width + x - 1) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = pixels[srcidx + c];
|
data[dstidx + c] = data[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +188,7 @@ void ImageData::extrude(int x, int y, int w, int h) {
|
|||||||
uint srcidx = (ry * width + rx) * comps;
|
uint srcidx = (ry * width + rx) * comps;
|
||||||
uint dstidx = ((ry + 1) * width + rx + 1) * comps;
|
uint dstidx = ((ry + 1) * width + rx + 1) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = pixels[srcidx + c];
|
data[dstidx + c] = data[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +198,7 @@ void ImageData::extrude(int x, int y, int w, int h) {
|
|||||||
uint srcidx = (ey * width + x) * comps;
|
uint srcidx = (ey * width + x) * comps;
|
||||||
uint dstidx = (ey * width + x - 1) * comps;
|
uint dstidx = (ey * width + x - 1) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = pixels[srcidx + c];
|
data[dstidx + c] = data[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,7 +209,7 @@ void ImageData::extrude(int x, int y, int w, int h) {
|
|||||||
uint srcidx = (y * width + ex) * comps;
|
uint srcidx = (y * width + ex) * comps;
|
||||||
uint dstidx = ((y-1) * width + ex) * comps;
|
uint dstidx = ((y-1) * width + ex) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = pixels[srcidx + c];
|
data[dstidx + c] = data[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -217,7 +220,7 @@ void ImageData::extrude(int x, int y, int w, int h) {
|
|||||||
uint srcidx = (ey * width + rx) * comps;
|
uint srcidx = (ey * width + rx) * comps;
|
||||||
uint dstidx = (ey * width + rx + 1) * comps;
|
uint dstidx = (ey * width + rx + 1) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = pixels[srcidx + c];
|
data[dstidx + c] = data[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -228,25 +231,23 @@ void ImageData::extrude(int x, int y, int w, int h) {
|
|||||||
uint srcidx = (ry * width + ex) * comps;
|
uint srcidx = (ry * width + ex) * comps;
|
||||||
uint dstidx = ((ry+1) * width + ex) * comps;
|
uint dstidx = ((ry+1) * width + ex) * comps;
|
||||||
for (uint c = 0; c < comps; c++) {
|
for (uint c = 0; c < comps; c++) {
|
||||||
pixels[dstidx + c] = pixels[srcidx + c];
|
data[dstidx + c] = data[srcidx + c];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageData::fixAlphaColor() {
|
void ImageData::fixAlphaColor() {
|
||||||
ubyte* pixels = static_cast<ubyte*>(data);
|
|
||||||
|
|
||||||
// Fixing black transparent pixels for Mip-Mapping
|
// Fixing black transparent pixels for Mip-Mapping
|
||||||
for (uint ly = 0; ly < height-1; ly++) {
|
for (uint ly = 0; ly < height-1; ly++) {
|
||||||
for (uint lx = 0; lx < width-1; lx++) {
|
for (uint lx = 0; lx < width-1; lx++) {
|
||||||
if (pixels[((ly) * width + lx) * 4 + 3]) {
|
if (data[((ly) * width + lx) * 4 + 3]) {
|
||||||
for (int c = 0; c < 3; c++) {
|
for (int c = 0; c < 3; c++) {
|
||||||
int val = pixels[((ly) + + lx) * 4 + c];
|
int val = data[((ly) + + lx) * 4 + c];
|
||||||
if (pixels[((ly) * width + lx + 1) * 4 + 3] == 0)
|
if (data[((ly) * width + lx + 1) * 4 + 3] == 0)
|
||||||
pixels[((ly) * width + lx + 1) * 4 + c] = val;
|
data[((ly) * width + lx + 1) * 4 + c] = val;
|
||||||
if (pixels[((ly + 1) * width + lx) * 4 + 3] == 0)
|
if (data[((ly + 1) * width + lx) * 4 + 3] == 0)
|
||||||
pixels[((ly + 1) * width + lx) * 4 + c] = val;
|
data[((ly + 1) * width + lx) * 4 + c] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,7 +265,7 @@ ImageData* add_atlas_margins(ImageData* image, int grid_size) {
|
|||||||
int dstheight = srcheight + grid_size * 2;
|
int dstheight = srcheight + grid_size * 2;
|
||||||
|
|
||||||
const ubyte* srcdata = (const ubyte*)image->getData();
|
const ubyte* srcdata = (const ubyte*)image->getData();
|
||||||
ubyte* dstdata = new ubyte[dstwidth*dstheight * 4];
|
auto dstdata = std::make_unique<ubyte[]>(dstwidth*dstheight * 4);
|
||||||
|
|
||||||
int imgres = image->getWidth() / grid_size;
|
int imgres = image->getWidth() / grid_size;
|
||||||
for (int row = 0; row < grid_size; row++) {
|
for (int row = 0; row < grid_size; row++) {
|
||||||
@ -299,5 +300,5 @@ ImageData* add_atlas_margins(ImageData* image, int grid_size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ImageData(image->getFormat(), dstwidth, dstheight, dstdata);
|
return new ImageData(image->getFormat(), dstwidth, dstheight, std::move(dstdata));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
#include "../../typedefs.hpp"
|
#include "../../typedefs.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
enum class ImageFormat {
|
enum class ImageFormat {
|
||||||
rgb888,
|
rgb888,
|
||||||
rgba8888
|
rgba8888
|
||||||
@ -12,10 +14,11 @@ class ImageData {
|
|||||||
ImageFormat format;
|
ImageFormat format;
|
||||||
uint width;
|
uint width;
|
||||||
uint height;
|
uint height;
|
||||||
void* data;
|
std::unique_ptr<ubyte[]> data;
|
||||||
public:
|
public:
|
||||||
ImageData(ImageFormat format, uint width, uint height);
|
ImageData(ImageFormat format, uint width, uint height);
|
||||||
ImageData(ImageFormat format, uint width, uint height, void* data);
|
ImageData(ImageFormat format, uint width, uint height, std::unique_ptr<ubyte[]> data);
|
||||||
|
ImageData(ImageFormat format, uint width, uint height, const ubyte* data);
|
||||||
~ImageData();
|
~ImageData();
|
||||||
|
|
||||||
void flipX();
|
void flipX();
|
||||||
@ -27,8 +30,8 @@ public:
|
|||||||
void extrude(int x, int y, int w, int h);
|
void extrude(int x, int y, int w, int h);
|
||||||
void fixAlphaColor();
|
void fixAlphaColor();
|
||||||
|
|
||||||
void* getData() const {
|
ubyte* getData() const {
|
||||||
return data;
|
return data.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFormat getFormat() const {
|
ImageFormat getFormat() const {
|
||||||
|
|||||||
@ -1,83 +1,6 @@
|
|||||||
#include "Texture.hpp"
|
#include "Texture.hpp"
|
||||||
#include "gl_util.hpp"
|
#include "GLTexture.hpp"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
uint Texture::MAX_RESOLUTION = 1024; // Window.initialize overrides it
|
|
||||||
|
|
||||||
Texture::Texture(uint id, uint width, uint height)
|
|
||||||
: id(id), width(width), height(height) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture::Texture(ubyte* data, uint width, uint height, ImageFormat imageFormat)
|
|
||||||
: width(width), height(height) {
|
|
||||||
glGenTextures(1, &id);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
|
||||||
|
|
||||||
GLenum format = gl::to_glenum(imageFormat);
|
|
||||||
glTexImage2D(
|
|
||||||
GL_TEXTURE_2D, 0, format, width, height, 0,
|
|
||||||
format, GL_UNSIGNED_BYTE, (GLvoid *) data
|
|
||||||
);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Texture::~Texture() {
|
|
||||||
glDeleteTextures(1, &id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::bind(){
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::unbind() {
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::reload(ubyte* data){
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
|
||||||
GL_RGBA, GL_UNSIGNED_BYTE, (GLvoid *) data);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<ImageData> Texture::readData() {
|
|
||||||
std::unique_ptr<ubyte[]> data (new ubyte[width * height * 4]);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id);
|
|
||||||
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data.get());
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
return std::make_unique<ImageData>(ImageFormat::rgba8888, width, height, data.release());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Texture::setNearestFilter() {
|
|
||||||
bind();
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<Texture> Texture::from(const ImageData* image) {
|
std::unique_ptr<Texture> Texture::from(const ImageData* image) {
|
||||||
uint width = image->getWidth();
|
return GLTexture::from(image);
|
||||||
uint height = image->getHeight();
|
|
||||||
const void* data = image->getData();
|
|
||||||
return std::make_unique<Texture>((ubyte*)data, width, height, image->getFormat());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint Texture::getWidth() const {
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint Texture::getHeight() const {
|
|
||||||
return height;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint Texture::getId() const {
|
|
||||||
return id;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,28 +8,28 @@
|
|||||||
|
|
||||||
class Texture {
|
class Texture {
|
||||||
protected:
|
protected:
|
||||||
uint id;
|
|
||||||
uint width;
|
uint width;
|
||||||
uint height;
|
uint height;
|
||||||
|
|
||||||
|
Texture(uint width, uint height) : width(width), height(height) {}
|
||||||
public:
|
public:
|
||||||
static uint MAX_RESOLUTION;
|
static uint MAX_RESOLUTION;
|
||||||
|
|
||||||
Texture(uint id, uint width, uint height);
|
virtual ~Texture() {}
|
||||||
Texture(ubyte* data, uint width, uint height, ImageFormat format);
|
|
||||||
virtual ~Texture();
|
|
||||||
|
|
||||||
virtual void bind();
|
virtual void bind() = 0;
|
||||||
virtual void unbind();
|
virtual void unbind() = 0;
|
||||||
virtual void reload(ubyte* data);
|
|
||||||
|
|
||||||
void setNearestFilter();
|
virtual std::unique_ptr<ImageData> readData() = 0;
|
||||||
|
|
||||||
virtual std::unique_ptr<ImageData> readData();
|
virtual uint getWidth() const {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
virtual uint getHeight() const {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
virtual uint getWidth() const;
|
virtual uint getId() const = 0;
|
||||||
virtual uint getHeight() const;
|
|
||||||
|
|
||||||
virtual uint getId() const;
|
|
||||||
|
|
||||||
static std::unique_ptr<Texture> from(const ImageData* image);
|
static std::unique_ptr<Texture> from(const ImageData* image);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
#include "TextureAnimation.hpp"
|
#include "TextureAnimation.hpp"
|
||||||
#include "Texture.hpp"
|
#include "GLTexture.hpp"
|
||||||
#include "Framebuffer.hpp"
|
#include "Framebuffer.hpp"
|
||||||
|
|
||||||
#include <GL/glew.h>
|
#include <GL/glew.h>
|
||||||
|
|||||||
@ -43,10 +43,11 @@ ModelBatch::ModelBatch(size_t capacity, Assets* assets, Chunks* chunks)
|
|||||||
assets(assets),
|
assets(assets),
|
||||||
chunks(chunks)
|
chunks(chunks)
|
||||||
{
|
{
|
||||||
ubyte pixels[] = {
|
const ubyte pixels[] = {
|
||||||
255, 255, 255, 255,
|
255, 255, 255, 255,
|
||||||
};
|
};
|
||||||
blank = std::make_unique<Texture>(pixels, 1, 1, ImageFormat::rgba8888);
|
ImageData image(ImageFormat::rgba8888, 1, 1, pixels);
|
||||||
|
blank = Texture::from(&image);
|
||||||
}
|
}
|
||||||
|
|
||||||
ModelBatch::~ModelBatch() {
|
ModelBatch::~ModelBatch() {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user