summaryrefslogtreecommitdiffstats
path: root/dev/MinGfx/src/texture2d.cc
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dev/MinGfx/src/texture2d.cc464
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
+