diff --git a/game_scene.cpp b/game_scene.cpp index c0400de..fd6eaec 100644 --- a/game_scene.cpp +++ b/game_scene.cpp @@ -103,9 +103,12 @@ void GameScene::render() { camera->camera_transform.basis = Basis(Vector3(0, 1, 0), rot); rot += 0.01; + Ref d = texture->get_data(); + + texture->create_from_image(d); + camera->bind(); - //sprite->render(); //material->bind(); //color_material->bind(); @@ -142,7 +145,7 @@ GameScene::GameScene() { texture = new Texture(); //texture->load_image("icon.png"); - texture->set_image(image); + texture->create_from_image(image); //ha a textúrának van alpha csatornája: //texture->load_image("download.bmp", GL_RGBA, GL_RGBA); @@ -181,7 +184,6 @@ GameScene::GameScene() { tile_map->transform.scale(Vector2(32, 32)); tile_map->transform.set_origin(Vector2(500, 500)); - camera = new PerspectiveCamera(); //camera->width = 2; diff --git a/sfw/render_core/texture.cpp b/sfw/render_core/texture.cpp index dbe90d9..9715f60 100644 --- a/sfw/render_core/texture.cpp +++ b/sfw/render_core/texture.cpp @@ -3,83 +3,72 @@ #include "memory.h" #include -void Texture::_get_gl_and_format(Image::Format p_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_supported) const { - r_gl_format = 0; - r_supported = true; - - switch (p_format) { - case Image::FORMAT_L8: { - r_gl_internal_format = GL_LUMINANCE; - r_gl_format = GL_LUMINANCE; - r_gl_type = GL_UNSIGNED_BYTE; - } break; - case Image::FORMAT_LA8: { - r_gl_internal_format = GL_LUMINANCE_ALPHA; - r_gl_format = GL_LUMINANCE_ALPHA; - r_gl_type = GL_UNSIGNED_BYTE; - } break; - case Image::FORMAT_R8: { - r_gl_internal_format = GL_ALPHA; - r_gl_format = GL_ALPHA; - r_gl_type = GL_UNSIGNED_BYTE; - - } break; - case Image::FORMAT_RG8: { - ERR_PRINT("RG texture not supported! Convert it to to RGB8."); - - r_supported = false; - } break; - case Image::FORMAT_RGB8: { - r_gl_internal_format = GL_RGB; - r_gl_format = GL_RGB; - r_gl_type = GL_UNSIGNED_BYTE; - - } break; - case Image::FORMAT_RGBA8: { - r_gl_format = GL_RGBA; - r_gl_internal_format = GL_RGBA; - r_gl_type = GL_UNSIGNED_BYTE; - - } break; - case Image::FORMAT_RGBA4444: { - r_gl_internal_format = GL_RGBA; - r_gl_format = GL_RGBA; - r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4; - - } break; - case Image::FORMAT_RGBA5551: { - r_gl_internal_format = GL_RGB5_A1; - r_gl_format = GL_RGBA; - r_gl_type = GL_UNSIGNED_SHORT_5_5_5_1; - - } break; - case Image::FORMAT_RF: { - r_gl_internal_format = GL_ALPHA; - r_gl_format = GL_ALPHA; - r_gl_type = GL_FLOAT; - } break; - case Image::FORMAT_RGF: { - ERR_PRINT("RG float texture not supported! Convert it to RGB8."); - r_supported = false; - } break; - case Image::FORMAT_RGBF: { - r_gl_internal_format = GL_RGB; - r_gl_format = GL_RGB; - r_gl_type = GL_FLOAT; - } break; - case Image::FORMAT_RGBAF: { - r_gl_internal_format = GL_RGBA; - r_gl_format = GL_RGBA; - r_gl_type = GL_FLOAT; - } break; - default: { - r_supported = false; - ERR_FAIL_COND(true); - } +void Texture::create_from_image(const Ref &img) { + if (_image == img) { + return; } + + _image = img; + + _texture_width = 0; + _texture_height = 0; + + if (!_image.is_valid()) { + if (_texture) { + glDeleteTextures(1, &_texture); + _texture = 0; + } + + return; + } + + upload(); } -void Texture::texture_update() { +Ref Texture::get_data() { + ERR_FAIL_COND_V(!_texture, Ref()); + ERR_FAIL_COND_V(_data_size == 0, Ref()); + //TODO Error if not render target + + //GLES + + GLenum gl_format; + GLenum gl_internal_format; + GLenum gl_type; + bool supported; + _get_gl_format(_texture_format, gl_format, gl_internal_format, gl_type, supported); + + if (!supported) { + return Ref(); + } + + Vector data; + + int data_size = Image::get_image_data_size(_texture_width, _texture_height, _texture_format, _mipmaps > 1); + + data.resize(data_size * 2); //add some memory at the end, just in case for buggy drivers + uint8_t *wb = data.ptrw(); + + glActiveTexture(GL_TEXTURE0); + + glBindTexture(GL_TEXTURE_2D, _texture); + glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); + + for (int i = 0; i < _mipmaps; i++) { + int ofs = Image::get_image_mipmap_offset(_texture_width, _texture_height, _texture_format, i); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glGetTexImage(GL_TEXTURE_2D, i, gl_format, gl_type, &wb[ofs]); + } + + data.resize(data_size); + + Image *img = memnew(Image(_texture_width, _texture_height, _mipmaps > 1, _texture_format, data)); + + return Ref(img); +} + +void Texture::upload() { if (!_image.is_valid()) { return; } @@ -88,13 +77,15 @@ void Texture::texture_update() { GLenum gl_internal_format; GLenum gl_type; bool supported; - _get_gl_and_format(_image->get_format(), gl_format, gl_internal_format, gl_type, supported); + Image::Format image_format = _image->get_format(); + _get_gl_format(image_format, gl_format, gl_internal_format, gl_type, supported); if (!supported) { return; } _data_size = _image->get_data().size(); + _texture_format = image_format; Vector image_data = _image->get_data(); if (image_data.size() == 0) { @@ -181,26 +172,80 @@ void Texture::texture_update() { glBindTexture(texture_type, 0); } -void Texture::set_image(const Ref &img) { - if (_image == img) { - return; - } +void Texture::_get_gl_format(Image::Format p_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_supported) const { + r_gl_format = 0; + r_supported = true; - _image = img; + switch (p_format) { + case Image::FORMAT_L8: { + r_gl_internal_format = GL_LUMINANCE; + r_gl_format = GL_LUMINANCE; + r_gl_type = GL_UNSIGNED_BYTE; + } break; + case Image::FORMAT_LA8: { + r_gl_internal_format = GL_LUMINANCE_ALPHA; + r_gl_format = GL_LUMINANCE_ALPHA; + r_gl_type = GL_UNSIGNED_BYTE; + } break; + case Image::FORMAT_R8: { + r_gl_internal_format = GL_ALPHA; + r_gl_format = GL_ALPHA; + r_gl_type = GL_UNSIGNED_BYTE; - _texture_width = 0; - _texture_height = 0; + } break; + case Image::FORMAT_RG8: { + ERR_PRINT("RG texture not supported! Convert it to to RGB8."); - if (!_image.is_valid()) { - if (_texture) { - glDeleteTextures(1, &_texture); - _texture = 0; + r_supported = false; + } break; + case Image::FORMAT_RGB8: { + r_gl_internal_format = GL_RGB; + r_gl_format = GL_RGB; + r_gl_type = GL_UNSIGNED_BYTE; + + } break; + case Image::FORMAT_RGBA8: { + r_gl_format = GL_RGBA; + r_gl_internal_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_BYTE; + + } break; + case Image::FORMAT_RGBA4444: { + r_gl_internal_format = GL_RGBA; + r_gl_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_SHORT_4_4_4_4; + + } break; + case Image::FORMAT_RGBA5551: { + r_gl_internal_format = GL_RGB5_A1; + r_gl_format = GL_RGBA; + r_gl_type = GL_UNSIGNED_SHORT_5_5_5_1; + + } break; + case Image::FORMAT_RF: { + r_gl_internal_format = GL_ALPHA; + r_gl_format = GL_ALPHA; + r_gl_type = GL_FLOAT; + } break; + case Image::FORMAT_RGF: { + ERR_PRINT("RG float texture not supported! Convert it to RGB8."); + r_supported = false; + } break; + case Image::FORMAT_RGBF: { + r_gl_internal_format = GL_RGB; + r_gl_format = GL_RGB; + r_gl_type = GL_FLOAT; + } break; + case Image::FORMAT_RGBAF: { + r_gl_internal_format = GL_RGBA; + r_gl_format = GL_RGBA; + r_gl_type = GL_FLOAT; + } break; + default: { + r_supported = false; + ERR_FAIL_COND(true); } - - return; } - - texture_update(); } Texture::Texture() { @@ -211,6 +256,8 @@ Texture::Texture() { _data_size = 0; _texture_index = 0; _flags = 0; + _render_target = false; + _texture_format = Image::FORMAT_RGBA8; } Texture::~Texture() { diff --git a/sfw/render_core/texture.h b/sfw/render_core/texture.h index f40c4f4..09ea094 100644 --- a/sfw/render_core/texture.h +++ b/sfw/render_core/texture.h @@ -17,24 +17,33 @@ public: return _texture; } - void texture_update(); + //TODO + //set_as_render_target() + //unset_render_target() - void set_image(const Ref &img); + void create_from_image(const Ref &img); + + Ref get_data(); + + void upload(); Texture(); virtual ~Texture(); protected: - void _get_gl_and_format(Image::Format p_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_supported) const; + void _get_gl_format(Image::Format p_format, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_supported) const; + + Ref _image; int _texture_width; int _texture_height; - Ref _image; + Image::Format _texture_format; int _flags; int _texture_index; int _data_size; int _mipmaps; + bool _render_target; GLuint _texture; };