From 342403a02f8063903d0f38327430721d4d0ae331 Mon Sep 17 00:00:00 2001 From: Matt Strapp Date: Mon, 20 Sep 2021 18:15:14 -0500 Subject: do ass1 --- dev/MinGfx/src/texture2d.cc | 464 ++++++++++++++++++++++---------------------- 1 file changed, 232 insertions(+), 232 deletions(-) (limited to 'dev/MinGfx/src/texture2d.cc') diff --git a/dev/MinGfx/src/texture2d.cc b/dev/MinGfx/src/texture2d.cc index 230ad5f..0134d00 100644 --- a/dev/MinGfx/src/texture2d.cc +++ b/dev/MinGfx/src/texture2d.cc @@ -1,232 +1,232 @@ -/* - Copyright (c) 2017,2018 Regents of the University of Minnesota. - All Rights Reserved. - See corresponding header file for details. - */ - -#include "texture2d.h" -#include "platform.h" - -#pragma warning (push) -#pragma warning (disable : 6001) -#pragma warning (disable : 6011) -#pragma warning (disable : 6262) -#pragma warning (disable : 6385) -#pragma warning (disable : 6387) -#pragma warning (disable : 26450) -#pragma warning (disable : 26451) -#pragma warning (disable : 26453) -#pragma warning (disable : 26495) -#pragma warning (disable : 26812) - -#ifdef WIN32 - // this is not needed on OSX or Linux, it must pick up the symbols from - // libnanogui.so, but it appears to be needed on Windows. - #define STB_IMAGE_IMPLEMENTATION -#endif -#include - -#pragma warning (pop) - -#include - - -namespace mingfx { - - - -Texture2D::Texture2D(GLenum wrapMode, GLenum filterMode) : - dataType_(GL_UNSIGNED_BYTE), data_ubyte_(NULL), data_float_(NULL), - width_(0), height_(0), handleMemInternally_(true), texID_(0), - wrapMode_(wrapMode), filterMode_(filterMode) -{ -} - -Texture2D::~Texture2D() { - - // Mem handled internally is always of type data_ubyte_ because that is - // what the stbi image loading library returns - if ((handleMemInternally_) && (data_ubyte_ != NULL)) { - // BUG, TODO: Not sure why the call below does not seem to work. - // There will be a mem leak unless we can call this somehow. - //stbi_image_free(data_); - } - - // This is how to delete GL's version of the texture on the GPU - // but you have to be very careful with this. For example, if we cause - // C++ to make a tmp copy of the Texture2D or we do an assignment tex1=tex2 - // we now have two Texture2D objects pointing to the same OpenGL texture id. - // If one of them is deleted before the other, then the other will not be - // able to draw itself because the OpenGL tex id will be invalid. For now, - // this is "addressed" by simply skipping the glDeleteTextures call. This - // leads to some wasted OpenGL memory, and that would be a good thing to - // fix in the future, maybe via a shared_ptr or static refcount that maps - // opengl texids to a count of Texture2D objects that reference them. Then, - // only delete the opengl tex if the refcount would go to 0. - //glDeleteTextures(1, &texID_); -} - - -bool Texture2D::InitFromFile(const std::string &filename) { - handleMemInternally_ = true; - dataType_ = GL_UNSIGNED_BYTE; - - - std::cout << "Loading texture from file: " << filename << std::endl; - - if (Platform::FileExists(filename)) { - stbi_set_unpremultiply_on_load(1); - stbi_convert_iphone_png_to_rgb(1); - int numChannels; - data_ubyte_ = stbi_load(filename.c_str(), &width_, &height_, &numChannels, 4); - if (data_ubyte_ == NULL) { - std::cerr << "Texture2D: Failed to load file " << filename << " - " << stbi_failure_reason() << std::endl; - return false; - } - } - else { - std::cerr << "Texture2D: File " << filename << " does not exist." << std::endl; - return false; - } - - return InitOpenGL(); -} - -bool Texture2D::InitFromBytes(int width, int height, const unsigned char * data) { - handleMemInternally_ = false; - width_ = width; - height_ = height; - data_ubyte_ = data; - dataType_ = GL_UNSIGNED_BYTE; - - return InitOpenGL(); -} - -bool Texture2D::InitFromFloats(int width, int height, const float * data) { - handleMemInternally_ = false; - width_ = width; - height_ = height; - data_float_ = data; - dataType_ = GL_FLOAT; - - return InitOpenGL(); -} - -bool Texture2D::InitOpenGL() { - glGenTextures(1, &texID_); - glBindTexture(GL_TEXTURE_2D, texID_); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode_); - - if (dataType_ == GL_UNSIGNED_BYTE) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, dataType_, data_ubyte_); - } - else if (dataType_ == GL_FLOAT) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, dataType_, data_float_); - } - else { - std::cerr << "Texture2D: Unsupported texture data type " << dataType_ << "." << std::endl; - return false; - } - - return true; -} - - -bool Texture2D::UpdateFromBytes(const unsigned char * data) { - dataType_ = GL_UNSIGNED_BYTE; - data_ubyte_ = data; - glBindTexture(GL_TEXTURE_2D, texID_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, dataType_, data_ubyte_); - // presumably glTexSubImage2D is faster, but this crashes on OSX for some reason - //glActiveTexture(texID_); - //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_RGBA, dataType_, data_ubyte_); - return true; -} - -bool Texture2D::UpdateFromFloats(const float * data) { - dataType_ = GL_FLOAT; - data_float_ = data; - glBindTexture(GL_TEXTURE_2D, texID_); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, dataType_, data_float_); - // presumably glTexSubImage2D is faster, but this crashes on OSX for some reason - //glActiveTexture(texID_); - //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_RGBA, dataType_, data_ubyte_); - return true; -} - - - -int Texture2D::width() const { - return width_; -} - -int Texture2D::height() const { - return height_; -} - - -GLuint Texture2D::opengl_id() const { - if (!initialized()) { - std::cerr << "Texture2D: Warning, accessing opengl_id() before it has been initialized." << std::endl - << "You might be calling opengl_id() before InitOpenGL(). Or, there might have been a" << std::endl - << "error loading texture data or binding it to OpenGL." << std::endl; - } - return texID_; -} - -GLenum Texture2D::wrap_mode() const { - return wrapMode_; -} - -GLenum Texture2D::filter_mode() const { - return filterMode_; -} - -void Texture2D::set_wrap_mode(GLenum wrapMode) { - wrapMode_ = wrapMode; - glBindTexture(GL_TEXTURE_2D, texID_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode_); -} - -void Texture2D::set_filter_mode(GLenum filterMode) { - filterMode_ = filterMode; - glBindTexture(GL_TEXTURE_2D, texID_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode_); -} - -bool Texture2D::initialized() const { - return texID_ != 0; -} - - -Color Texture2D::Pixel(int x, int y) const { - int index = y*4*width() + x*4; - - if (dataType_ == GL_UNSIGNED_BYTE) { - unsigned char r = data_ubyte_[index+0]; - unsigned char g = data_ubyte_[index+1]; - unsigned char b = data_ubyte_[index+2]; - unsigned char a = data_ubyte_[index+3]; - return Color((float)r/255.0f, (float)g/255.0f, (float)b/255.0f, (float)a/255.0f); - } - else if (dataType_ == GL_FLOAT) { - float r = data_float_[index+0]; - float g = data_float_[index+1]; - float b = data_float_[index+2]; - float a = data_float_[index+3]; - return Color(r, g, b, a); - } - else { - std::cerr << "Texture2D: Unsupported texture data type " << dataType_ << "." << std::endl; - return Color(); - } -} - -} // end namespace - +/* + Copyright (c) 2017,2018 Regents of the University of Minnesota. + All Rights Reserved. + See corresponding header file for details. + */ + +#include "texture2d.h" +#include "platform.h" + +#pragma warning (push) +#pragma warning (disable : 6001) +#pragma warning (disable : 6011) +#pragma warning (disable : 6262) +#pragma warning (disable : 6385) +#pragma warning (disable : 6387) +#pragma warning (disable : 26450) +#pragma warning (disable : 26451) +#pragma warning (disable : 26453) +#pragma warning (disable : 26495) +#pragma warning (disable : 26812) + +#ifdef WIN32 + // this is not needed on OSX or Linux, it must pick up the symbols from + // libnanogui.so, but it appears to be needed on Windows. + #define STB_IMAGE_IMPLEMENTATION +#endif +#include + +#pragma warning (pop) + +#include + + +namespace mingfx { + + + +Texture2D::Texture2D(GLenum wrapMode, GLenum filterMode) : + dataType_(GL_UNSIGNED_BYTE), data_ubyte_(NULL), data_float_(NULL), + width_(0), height_(0), handleMemInternally_(true), texID_(0), + wrapMode_(wrapMode), filterMode_(filterMode) +{ +} + +Texture2D::~Texture2D() { + + // Mem handled internally is always of type data_ubyte_ because that is + // what the stbi image loading library returns + if ((handleMemInternally_) && (data_ubyte_ != NULL)) { + // BUG, TODO: Not sure why the call below does not seem to work. + // There will be a mem leak unless we can call this somehow. + //stbi_image_free(data_); + } + + // This is how to delete GL's version of the texture on the GPU + // but you have to be very careful with this. For example, if we cause + // C++ to make a tmp copy of the Texture2D or we do an assignment tex1=tex2 + // we now have two Texture2D objects pointing to the same OpenGL texture id. + // If one of them is deleted before the other, then the other will not be + // able to draw itself because the OpenGL tex id will be invalid. For now, + // this is "addressed" by simply skipping the glDeleteTextures call. This + // leads to some wasted OpenGL memory, and that would be a good thing to + // fix in the future, maybe via a shared_ptr or static refcount that maps + // opengl texids to a count of Texture2D objects that reference them. Then, + // only delete the opengl tex if the refcount would go to 0. + //glDeleteTextures(1, &texID_); +} + + +bool Texture2D::InitFromFile(const std::string &filename) { + handleMemInternally_ = true; + dataType_ = GL_UNSIGNED_BYTE; + + + std::cout << "Loading texture from file: " << filename << std::endl; + + if (Platform::FileExists(filename)) { + stbi_set_unpremultiply_on_load(1); + stbi_convert_iphone_png_to_rgb(1); + int numChannels; + data_ubyte_ = stbi_load(filename.c_str(), &width_, &height_, &numChannels, 4); + if (data_ubyte_ == NULL) { + std::cerr << "Texture2D: Failed to load file " << filename << " - " << stbi_failure_reason() << std::endl; + return false; + } + } + else { + std::cerr << "Texture2D: File " << filename << " does not exist." << std::endl; + return false; + } + + return InitOpenGL(); +} + +bool Texture2D::InitFromBytes(int width, int height, const unsigned char * data) { + handleMemInternally_ = false; + width_ = width; + height_ = height; + data_ubyte_ = data; + dataType_ = GL_UNSIGNED_BYTE; + + return InitOpenGL(); +} + +bool Texture2D::InitFromFloats(int width, int height, const float * data) { + handleMemInternally_ = false; + width_ = width; + height_ = height; + data_float_ = data; + dataType_ = GL_FLOAT; + + return InitOpenGL(); +} + +bool Texture2D::InitOpenGL() { + glGenTextures(1, &texID_); + glBindTexture(GL_TEXTURE_2D, texID_); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode_); + + if (dataType_ == GL_UNSIGNED_BYTE) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, dataType_, data_ubyte_); + } + else if (dataType_ == GL_FLOAT) { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, dataType_, data_float_); + } + else { + std::cerr << "Texture2D: Unsupported texture data type " << dataType_ << "." << std::endl; + return false; + } + + return true; +} + + +bool Texture2D::UpdateFromBytes(const unsigned char * data) { + dataType_ = GL_UNSIGNED_BYTE; + data_ubyte_ = data; + glBindTexture(GL_TEXTURE_2D, texID_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, dataType_, data_ubyte_); + // presumably glTexSubImage2D is faster, but this crashes on OSX for some reason + //glActiveTexture(texID_); + //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_RGBA, dataType_, data_ubyte_); + return true; +} + +bool Texture2D::UpdateFromFloats(const float * data) { + dataType_ = GL_FLOAT; + data_float_ = data; + glBindTexture(GL_TEXTURE_2D, texID_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, dataType_, data_float_); + // presumably glTexSubImage2D is faster, but this crashes on OSX for some reason + //glActiveTexture(texID_); + //glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width_, height_, GL_RGBA, dataType_, data_ubyte_); + return true; +} + + + +int Texture2D::width() const { + return width_; +} + +int Texture2D::height() const { + return height_; +} + + +GLuint Texture2D::opengl_id() const { + if (!initialized()) { + std::cerr << "Texture2D: Warning, accessing opengl_id() before it has been initialized." << std::endl + << "You might be calling opengl_id() before InitOpenGL(). Or, there might have been a" << std::endl + << "error loading texture data or binding it to OpenGL." << std::endl; + } + return texID_; +} + +GLenum Texture2D::wrap_mode() const { + return wrapMode_; +} + +GLenum Texture2D::filter_mode() const { + return filterMode_; +} + +void Texture2D::set_wrap_mode(GLenum wrapMode) { + wrapMode_ = wrapMode; + glBindTexture(GL_TEXTURE_2D, texID_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode_); +} + +void Texture2D::set_filter_mode(GLenum filterMode) { + filterMode_ = filterMode; + glBindTexture(GL_TEXTURE_2D, texID_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filterMode_); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filterMode_); +} + +bool Texture2D::initialized() const { + return texID_ != 0; +} + + +Color Texture2D::Pixel(int x, int y) const { + int index = y*4*width() + x*4; + + if (dataType_ == GL_UNSIGNED_BYTE) { + unsigned char r = data_ubyte_[index+0]; + unsigned char g = data_ubyte_[index+1]; + unsigned char b = data_ubyte_[index+2]; + unsigned char a = data_ubyte_[index+3]; + return Color((float)r/255.0f, (float)g/255.0f, (float)b/255.0f, (float)a/255.0f); + } + else if (dataType_ == GL_FLOAT) { + float r = data_float_[index+0]; + float g = data_float_[index+1]; + float b = data_float_[index+2]; + float a = data_float_[index+3]; + return Color(r, g, b, a); + } + else { + std::cerr << "Texture2D: Unsupported texture data type " << dataType_ << "." << std::endl; + return Color(); + } +} + +} // end namespace + -- cgit v1.2.3