diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aed8138 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +.DS_Store +xcuserdata \ No newline at end of file diff --git a/J.xcodeproj/project.pbxproj b/J.xcodeproj/project.pbxproj index 32f197f..f3a243d 100644 --- a/J.xcodeproj/project.pbxproj +++ b/J.xcodeproj/project.pbxproj @@ -16,6 +16,7 @@ 4268136F140A321800CBF943 /* J.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4268136E140A321800CBF943 /* J.mm */; }; 4283A45F14115AC400036A5D /* interpolator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4283A45E14115AC300036A5D /* interpolator.h */; }; 4283A4641411707700036A5D /* array.h in Headers */ = {isa = PBXBuildFile; fileRef = 4283A4631411707700036A5D /* array.h */; }; + 429E3BAB159616FD0044306C /* texture_objc.mm in Sources */ = {isa = PBXBuildFile; fileRef = 429E3BAA159616FD0044306C /* texture_objc.mm */; }; 42ED6A6B140A380000402F76 /* fbo.h in Headers */ = {isa = PBXBuildFile; fileRef = 42ED6A68140A380000402F76 /* fbo.h */; }; 42ED6A6C140A380000402F76 /* shader.h in Headers */ = {isa = PBXBuildFile; fileRef = 42ED6A69140A380000402F76 /* shader.h */; }; 42ED6A6D140A380000402F76 /* to_string.h in Headers */ = {isa = PBXBuildFile; fileRef = 42ED6A6A140A380000402F76 /* to_string.h */; }; @@ -33,6 +34,9 @@ 4268136E140A321800CBF943 /* J.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = J.mm; sourceTree = ""; }; 4283A45E14115AC300036A5D /* interpolator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = interpolator.h; sourceTree = ""; }; 4283A4631411707700036A5D /* array.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = array.h; sourceTree = ""; }; + 429E3BA715960FCA0044306C /* texture.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = texture.h; sourceTree = ""; }; + 429E3BA9159616C00044306C /* texture_objc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = texture_objc.h; sourceTree = ""; }; + 429E3BAA159616FD0044306C /* texture_objc.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = texture_objc.mm; sourceTree = ""; }; 42ED6A68140A380000402F76 /* fbo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = fbo.h; sourceTree = ""; }; 42ED6A69140A380000402F76 /* shader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shader.h; sourceTree = ""; }; 42ED6A6A140A380000402F76 /* to_string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = to_string.h; sourceTree = ""; }; @@ -115,6 +119,9 @@ 425E9DF1140A74DA00A81A65 /* basic.h */, 425E9DF5140A774D00A81A65 /* basic.cpp */, 42ED6A68140A380000402F76 /* fbo.h */, + 429E3BA715960FCA0044306C /* texture.h */, + 429E3BA9159616C00044306C /* texture_objc.h */, + 429E3BAA159616FD0044306C /* texture_objc.mm */, 425E9DF8140A7EB400A81A65 /* fbo.mm */, 42ED6A69140A380000402F76 /* shader.h */, ); diff --git a/J/fbo.h b/J/fbo.h index 0c7355a..a8a5c5a 100644 --- a/J/fbo.h +++ b/J/fbo.h @@ -23,6 +23,7 @@ #include "to_string.h" #include "basic.h" +#include "texture.h" @class EAGLContext; @class CAEAGLLayer; @@ -45,14 +46,15 @@ public: public: // standard ctor, makes use of textures - fbo(int width, int height) : width(width), height(height), fbo_number(0), renderbuffers(), texture_id(0) { + template + fbo(int width, int height, Texture const & texture = no_texture()) : width(width), height(height), fbo_number(0), renderbuffers(), texture_id(0) { glGenFramebuffers(1, &fbo_number); bind(); // generate texture glGenTextures(1, &texture_id); glBindTexture(GL_TEXTURE_2D, texture_id); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + bool should_clear = !make_tex(texture); glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_id, 0); // attach depth @@ -61,8 +63,10 @@ public: check_error(); check_status(); - glClearColor(0.0, 0.0, 0.0, 0.0); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + if(should_clear){ + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + } unbind(); } @@ -96,6 +100,17 @@ public: } private: + template + bool make_tex(Texture const & texture){ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, Texture::gl_format, Texture::gl_type, texture.data()); + return true; + } + + bool make_tex(no_texture const &){ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + return false; + } + void bind(){ glBindFramebuffer(GL_FRAMEBUFFER, fbo_number); check_error(); diff --git a/J/texture.h b/J/texture.h new file mode 100644 index 0000000..7cc080a --- /dev/null +++ b/J/texture.h @@ -0,0 +1,86 @@ +// +// texture.h +// J +// +// Created by Joshua Moerman on 6/23/12. +// Copyright (c) 2012 Vadovas. All rights reserved. +// + +#ifndef J_texture_h +#define J_texture_h + +#include "basic.h" +#include +#include + +namespace J { + +struct no_texture {}; + +template +struct gl_type {}; + +template <> +struct gl_type { + static constexpr GLenum value = GL_UNSIGNED_BYTE; +}; + +template +struct rgba { + typedef typename std::vector::iterator iterator; + typedef typename std::vector::iterator const_iterator; + typedef typename std::vector::size_type size_type; + static constexpr GLenum gl_type = J::gl_type::value; + static constexpr GLenum gl_format = GL_RGBA; + + rgba(size_type w, size_type h, T const * data = nullptr) + : width_(w) + , height_(h) + , pixels(w*h*4){ + if(data) + std::copy_n(data, w*h*4, pixels.begin()); + } + + size_type size() const { return pixels.size(); } + size_type width() const { return width; } + size_type height() const { return height; } + + struct row_proxy { + row_proxy(T* data) : data(data) {} + T& operator[](size_type x){ return data[x]; } + T operator[](size_type x) const { return data[x]; } + T* data; + }; + + row_proxy operator[](size_type y){ + return &pixels[y*width()]; + } + + struct const_row_proxy { + const_row_proxy(T const * data) : data(data) {} + T operator[](size_type x) const { return data[x]; } + T const * data; + }; + + const_row_proxy operator[](size_type y) const { + return &pixels[y*width()]; + } + + T * data() { return pixels.data(); } + T const * data() const { return pixels.data(); } + + iterator begin() { return pixels.begin(); } + iterator end() { return pixels.begin(); } + + const_iterator begin() const { return pixels.begin(); } + const_iterator end() const { return pixels.begin(); } + +private: + size_type width_; + size_type height_; + std::vector pixels; +}; + +} + +#endif diff --git a/J/texture_objc.h b/J/texture_objc.h new file mode 100644 index 0000000..9485925 --- /dev/null +++ b/J/texture_objc.h @@ -0,0 +1,22 @@ +// +// texture_objc.h +// J +// +// Created by Joshua Moerman on 6/23/12. +// Copyright (c) 2012 Vadovas. All rights reserved. +// + +#ifndef J_texture_objc_h +#define J_texture_objc_h + +#include "texture.h" + +@class UIImage; + +namespace J { + +rgba<> texture_from_UIImage(UIImage * image); + +} + +#endif diff --git a/J/texture_objc.mm b/J/texture_objc.mm new file mode 100644 index 0000000..7ee0ba3 --- /dev/null +++ b/J/texture_objc.mm @@ -0,0 +1,23 @@ +// +// texture_objc.mm +// J +// +// Created by Joshua Moerman on 6/23/12. +// Copyright (c) 2012 Vadovas. All rights reserved. +// + +#include "texture_objc.h" + +#import +//#import + +namespace J { + rgba<> texture_from_UIImage(UIImage * image){ + CGImageRef cgImage = image.CGImage; + CGDataProviderRef provider = CGImageGetDataProvider(cgImage); + CFDataRef bitmapData = CGDataProviderCopyData(provider); + CFDataGetBytePtr(bitmapData); + + return rgba<>(image.size.width, image.size.height, CFDataGetBytePtr(bitmapData)); + } +} \ No newline at end of file