diff options
Diffstat (limited to 'dev/MinGfx/src/texture2d.cc')
-rw-r--r-- | dev/MinGfx/src/texture2d.cc | 464 |
1 files changed, 232 insertions, 232 deletions
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 <stb_image.h> - -#pragma warning (pop) - -#include <iostream> - - -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 <stb_image.h>
+
+#pragma warning (pop)
+
+#include <iostream>
+
+
+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
+
|