case GFX_VK:
return (char *)"vk_shaders";
}
- return (char*)"";
+ return (char *)"";
}
\ No newline at end of file
--- /dev/null
+#include <string.h>
+
+#include "imago2.h"
+#include "image.h"
+
+Image::Image()
+{
+ w = h = 0;
+ pixels = 0;
+}
+
+Image::~Image()
+{
+ delete [] pixels;
+}
+
+Image::Image(const Image &image)
+{
+ w = image.w;
+ h = image.h;
+
+ pixels = new unsigned char[w * h * 4];
+ memcpy(pixels, image.pixels, w * h * 4);
+}
+
+Image &Image::operator =(const Image &image)
+{
+ if(&image == this)
+ return *this;
+
+ delete [] pixels;
+
+ w = image.w;
+ h = image.h;
+
+ pixels = new unsigned char[w * h * 4];
+ memcpy(pixels, image.pixels, w * h * 4);
+
+ return *this;
+}
+
+Image::Image(Image &&image)
+{
+ w = image.w;
+ h = image.h;
+
+ pixels = image.pixels;
+ image.pixels = 0;
+}
+
+Image &Image::operator =(Image &&image)
+{
+ if(&image == this)
+ return *this;
+
+ delete [] pixels;
+
+ w = image.w;
+ h = image.h;
+
+ pixels = image.pixels;
+ image.pixels = 0;
+
+ return *this;
+}
+
+bool Image::load(const char *fname)
+{
+ unsigned char *imago_pixels;
+ if(!(imago_pixels = (unsigned char *)img_load_pixels(fname, &w, &h))) {
+ fprintf(stderr, "Failed to load pixels from file: %s.\n", fname);
+ return false;
+ }
+
+ delete [] pixels;
+ pixels = new unsigned char[w * h * 4];
+ memcpy(pixels, imago_pixels, w * h * 4);
+
+ img_free_pixels(imago_pixels);
+
+ return true;
+}
\ No newline at end of file
--- /dev/null
+#ifndef IMAGE_H_
+#define IMAGE_H_
+
+class Image {
+public:
+ int w;
+ int h;
+ unsigned char *pixels;
+
+ Image();
+ ~Image();
+
+ Image(const Image &image);
+ Image &operator =(const Image &image);
+
+ /*
+ move constructor: called when you assign
+ an rvalue reference
+ */
+ Image(Image &&image); // rvalue reference
+ Image &operator =(Image &&image);
+
+ bool load(const char *fname);
+};
+
+#endif // IMAGE_H_
\ No newline at end of file
TextureGL::TextureGL()
{
- w = 0;
- h = 0;
-
- pixels = 0;
tex = 0;
+ target = GL_TEXTURE_2D;
}
TextureGL::~TextureGL()
void TextureGL::update()
{
+ if(images.empty())
+ return;
+
if(!tex) {
+ target = is_cubemap() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
+
glGenTextures(1, &tex);
- glBindTexture(GL_TEXTURE_2D, tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glBindTexture(target, tex);
+ glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else {
- glBindTexture(GL_TEXTURE_2D, tex);
+ glBindTexture(target, tex);
}
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
- glGenerateMipmap(GL_TEXTURE_2D);
-}
+ static const unsigned int faces[] = {
+ GL_TEXTURE_CUBE_MAP_POSITIVE_X, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
+ GL_TEXTURE_CUBE_MAP_NEGATIVE_X, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
+ };
+ for(size_t i=0; i<images.size(); i++) {
+ int w = images[i].w;
+ int h = images[i].h;
+
+ unsigned char *pixels = images[i].pixels;
+ unsigned int t = is_cubemap() ? faces[i] : GL_TEXTURE_2D;
+ glTexImage2D(t, 0, GL_SRGB_ALPHA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
+ }
+
+ glGenerateMipmap(target);
+}
void TextureGL::bind()
{
class TextureGL : public Texture {
private:
unsigned int tex;
+ unsigned int target;
virtual void update() override;
public:
scene = 0;
camera = 0;
sprog = 0;
+
+ skytex = 0;
+ dskytex = 0;
}
Renderer::~Renderer()
object->mesh->update_vertex_data();
object->mesh->draw();
+}
+
+void Renderer::set_sky_tex(Texture *stex)
+{
+ skytex = stex;
+}
+
+void Renderer::set_diffuse_sky_tex(Texture *dstex)
+{
+ dskytex = dstex;
}
\ No newline at end of file
int mmviewproj_loc;
int mview_loc;
+ Texture *skytex, *dskytex;
ShaderProgram *sprog;
virtual void draw_object(Object *object) const;
virtual bool create();
virtual void draw() const;
+
+ virtual void set_sky_tex(Texture *stex);
+ virtual void set_diffuse_sky_tex(Texture *dstex);
};
#endif // RENDERER_H_
\ No newline at end of file
-#include "imago2.h"
+#include <string.h>
#include "texture.h"
Texture::Texture()
{
- w = 0;
- h = 0;
-
- pixels = 0;
}
Texture::~Texture()
{
- img_free_pixels(pixels);
}
bool Texture::load(const char *fname)
{
- if(!(pixels = (unsigned char *)img_load_pixels(fname, &w, &h))) {
- fprintf(stderr, "Failed to load pixels from file: %s.\n", fname);
- return false;
+ Image img;
+
+ if(img.load(fname)) {
+ images.clear();
+ images.push_back(img);
+
+ update();
+ return true;
}
+
+ /* check if it is a cubemap */
+ return load_cubemap(fname);
+}
+
+bool Texture::load_cubemap(const char *fname)
+{
+ const char *suffixes[] = {
+ "_px", "_py", "_pz",
+ "_nx", "_ny", "_nz"
+ };
+
+ for(int i=0; i<6; i++) {
+ char *buf = new char[strlen(fname) + 3 + 1];
+ strcpy(buf, fname);
+ char *suffix = strrchr(buf, '.');
+
+ if(suffix) {
+ memmove(suffix + 3, suffix, strlen(suffix) + 1);
+ memcpy(suffix, suffixes[i], 3);
+ } else {
+ strcat(buf, suffixes[i]);
+ }
+
+ Image img;
+ if(!img.load(buf)) {
+ images.clear();
+ return false;
+ }
+ images.push_back(img);
+ }
+
update();
return true;
+}
+
+bool Texture::is_cubemap() const
+{
+ return images.size() > 1;
}
\ No newline at end of file
#define TEXTURE_H_
#include <string>
+#include <vector>
+
+#include "image.h"
class Texture {
private:
virtual void update() = 0;
protected:
- int w;
- int h;
- unsigned char *pixels;
+ std::vector<Image> images;
public:
std::string name;
virtual ~Texture();
virtual bool load(const char *fname);
+ virtual bool load_cubemap(const char *fname);
+
+ virtual bool is_cubemap() const;
+
virtual void bind() = 0;
};