hx3d  1
2D/3D Simple Game Framework
texture.cpp
1 /*
2  Texture.
3  Copyright (C) 2015 Denis BOURGE
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Lesser General Public
7  License as published by the Free Software Foundation; either
8  version 2.1 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Lesser General Public License for more details.
14 
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
18  USA
19 */
20 
21 #include "hx3d/graphics/texture.hpp"
22 
23 #include "hx3d/utils/file.hpp"
24 #include "hx3d/utils/log.hpp"
25 
26 #include "hx3d/graphics/font.hpp"
27 #include "hx3d/graphics/error.hpp"
28 
29 #define STB_IMAGE_IMPLEMENTATION
30 #include <stb_image.h>
31 
32 namespace hx3d {
33 namespace graphics {
34 
35 Ptr<Texture> Texture::Blank(nullptr);
36 
37 Texture::Texture(std::string pathToImage): Texture() {
38  load(pathToImage);
39 }
40 
42  _width = image._width;
43  _height = image._height;
44 
45  glGenTextures(1, &_id);
46  glBindTexture(GL_TEXTURE_2D, _id);
47 
48  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image._buffer);
49 
50  // Base filter = Nearest
55 
56  glBindTexture(GL_TEXTURE_2D, 0);
57 }
58 
60  _id(0),
61  _width(0),
62  _height(0)
63 {}
64 
65 Texture::~Texture()
66 {
67  if (glIsTexture(_id)) {
68  glDeleteTextures(1, &_id);
69  }
70 }
71 
72 bool Texture::load(std::string pathToImage) {
73  const Ptr<File>& file = File::loadBinaryFile(pathToImage);
74 
75  int bpp = 0;
76  unsigned char* file_content = reinterpret_cast<unsigned char*>(file->getData());
77  unsigned char* content = stbi_load_from_memory(file_content, file->getSize(), (int*)&_width, (int*)&_height, &bpp, 0);
78 
79  glGenTextures(1, &_id);
80  glBindTexture(GL_TEXTURE_2D, _id);
81 
82  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, content);
83 
84  // Base filter = Nearest
89 
90  glBindTexture(GL_TEXTURE_2D, 0);
91 
92  Log.Info("Texture %s loaded: %d x %d", pathToImage.c_str(), _width, _height);
93 
94  stbi_image_free(content);
95  return true;
96 }
97 
99  GLenum filterType;
100  GLenum filterValue;
101 
102  filterType =
103  type == FilterType::Min ? GL_TEXTURE_MIN_FILTER :
104  type == FilterType::Max ? GL_TEXTURE_MAG_FILTER :
105 
106  type == FilterType::WrapX ? GL_TEXTURE_WRAP_S :
107  type == FilterType::WrapY ? GL_TEXTURE_WRAP_T : GL_INVALID_ENUM;
108 
109  filterValue =
110  value == FilterValue::Linear ? GL_LINEAR :
111  value == FilterValue::Nearest ? GL_NEAREST :
112 
113  value == FilterValue::LinearMipmapLinear ? GL_LINEAR_MIPMAP_LINEAR :
114  value == FilterValue::NearestMipmapLinear ? GL_NEAREST_MIPMAP_LINEAR :
115  value == FilterValue::LinearMipmapNearest ? GL_LINEAR_MIPMAP_NEAREST :
116  value == FilterValue::NearestMipmapNearest ? GL_NEAREST_MIPMAP_NEAREST :
117 
118  value == FilterValue::ClampToEdge ? GL_CLAMP_TO_EDGE :
119  value == FilterValue::MirroredRepeat ? GL_MIRRORED_REPEAT :
120  value == FilterValue::Repeat ? GL_REPEAT : GL_INVALID_ENUM;
121 
122  glBindTexture(GL_TEXTURE_2D, _id);
123  glTexParameteri(GL_TEXTURE_2D, filterType, filterValue);
124  glBindTexture(GL_TEXTURE_2D, 0);
125 }
126 
127 void Texture::use(Ptr<Texture> texture) {
128  glBindTexture(GL_TEXTURE_2D, texture->_id);
129 }
130 
131 void Texture::use(Ptr<Font> font, int characterSize) {
132  Font::Data& data = font->getFontData(characterSize);
133  glBindTexture(GL_TEXTURE_2D, data.atlas->id);
134 }
135 
137  glBindTexture(GL_TEXTURE_2D, 0);
138 }
139 
140 Ptr<Texture> Texture::createColorBuffer(unsigned int width, unsigned int height) {
141  Ptr<Texture> texture(Make<Texture>());
142 
143  texture->_width = width;
144  texture->_height = height;
145 
146  glGenTextures(1, &texture->_id);
147  glBindTexture(GL_TEXTURE_2D, texture->_id);
148 
149  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->_width, texture->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
150 
151  // Base filter = Nearest
152  texture->setFilter(FilterType::Min, FilterValue::Nearest);
153  texture->setFilter(FilterType::Max, FilterValue::Nearest);
154  texture->setFilter(FilterType::WrapX, FilterValue::ClampToEdge);
155  texture->setFilter(FilterType::WrapY, FilterValue::ClampToEdge);
156 
157  glBindTexture(GL_TEXTURE_2D, 0);
158  return texture;
159 }
160 
161 GLuint Texture::getID() {
162  return _id;
163 }
164 
165 unsigned int Texture::getWidth() {
166  return _width;
167 }
168 
169 unsigned int Texture::getHeight() {
170  return _height;
171 }
172 
173 void Texture::updateZone(unsigned int x, unsigned int y, unsigned int w, unsigned int h, Uint8* data) {
174  glBindTexture(GL_TEXTURE_2D, _id);
175  glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, data);
176  glBindTexture(GL_TEXTURE_2D, 0);
177 }
178 
180  Ptr<Texture> texture(Make<Texture>());
181 
182  texture->_width = 1;
183  texture->_height = 1;
184 
185  glGenTextures(1, &texture->_id);
186  glBindTexture(GL_TEXTURE_2D, texture->_id);
187 
188  int pixels[] = {
189  -1, -1, -1, 0,
190  };
191 
192  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->_width, texture->_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
193 
194  // Base filter = Nearest
195  texture->setFilter(FilterType::Min, FilterValue::Nearest);
196  texture->setFilter(FilterType::Max, FilterValue::Nearest);
197  texture->setFilter(FilterType::WrapX, FilterValue::ClampToEdge);
198  texture->setFilter(FilterType::WrapY, FilterValue::ClampToEdge);
199 
200  glBindTexture(GL_TEXTURE_2D, 0);
201  Blank = texture;
202 }
203 
204 } /* graphics */
205 } /* hx3d */
Texture()
Construct an empty texture. See load to build the texture.
Definition: texture.cpp:59
unsigned int getWidth()
Get the texture width.
Definition: texture.cpp:165
hx3d framework namespace
Definition: audio.hpp:26
FilterValue
Filtering value.
Definition: texture.hpp:61
Internal font data.
Definition: font.hpp:45
void setFilter(FilterType type, FilterValue value)
Set the texture filters.
Definition: texture.cpp:98
GLuint getID()
Get the texture ID.
Definition: texture.cpp:161
void updateZone(unsigned int x, unsigned int y, unsigned int w, unsigned int h, Uint8 *data)
Update a zone in the texture.
Definition: texture.cpp:173
bool load(std::string pathToImage)
Build the texture from an image.
Definition: texture.cpp:72
texture_atlas_t * atlas
Internal atlas.
Definition: font.hpp:49
unsigned int getHeight()
Get the texture height.
Definition: texture.cpp:169
static hx3d::LogImpl Log
Current log implementation.
Definition: log.hpp:91
static Ptr< Texture > createColorBuffer(unsigned int width, unsigned int height)
Create a color buffer (used in framebuffers).
Definition: texture.cpp:140
Real-time editable texture.
Definition: image.hpp:36
static Ptr< Texture > Blank
Default blank texture.
Definition: texture.hpp:92
FilterType
Filtering type.
Definition: texture.hpp:45
2D/3D texture management.
Definition: texture.hpp:39
static void disable()
Clear the current texture for drawing.
Definition: texture.cpp:136
static void use(Ptr< Texture > texture)
Use the current texture for drawing.
Definition: texture.cpp:127
static Ptr< File > loadBinaryFile(std::string path)
Load a binary file from a path.
Definition: file.cpp:62
static void generateBlankTexture()
Used to create the Texture::Blank texture.
Definition: texture.cpp:179
std::shared_ptr< T > Ptr
Quick-typing shared ptr.
Definition: ptr.hpp:34
void Info(const std::string fmt,...)
Write an info message.
Definition: log.cpp:58