Browse Source

made a nd_array, and stub for new AA framework

master
Joshua Moerman 13 years ago
parent
commit
7b1e7fd7e3
  1. 11
      AwesomeAttractorND.xcodeproj/project.pbxproj
  2. 37
      AwesomeAttractorND/Canvas.hpp
  3. 147
      AwesomeAttractorND/Image.hpp
  4. 37
      AwesomeAttractorND/Tonemapper.hpp
  5. 92
      AwesomeAttractorND/main.cpp
  6. 152
      AwesomeAttractorND/nd_array.hpp

11
AwesomeAttractorND.xcodeproj/project.pbxproj

@ -25,9 +25,13 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
428EFECF145AF6E0001DBE1B /* Canvas.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Canvas.hpp; sourceTree = "<group>"; };
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Tonemapper.hpp; sourceTree = "<group>"; };
42C2D1521461676B001BF28D /* Image.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Image.hpp; sourceTree = "<group>"; };
42D2E11D1456175C00FBC16A /* AwesomeAttractorND */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AwesomeAttractorND; sourceTree = BUILT_PRODUCTS_DIR; };
42D2E1211456175C00FBC16A /* main.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = main.cpp; sourceTree = "<group>"; };
42D2E1231456175C00FBC16A /* AwesomeAttractorND.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = AwesomeAttractorND.1; sourceTree = "<group>"; };
42D2E12A1456176800FBC16A /* nd_array.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = nd_array.hpp; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -61,6 +65,10 @@
isa = PBXGroup;
children = (
42D2E1211456175C00FBC16A /* main.cpp */,
42D2E12A1456176800FBC16A /* nd_array.hpp */,
428EFECF145AF6E0001DBE1B /* Canvas.hpp */,
428EFED4145AFAB4001DBE1B /* Tonemapper.hpp */,
42C2D1521461676B001BF28D /* Image.hpp */,
42D2E1231456175C00FBC16A /* AwesomeAttractorND.1 */,
);
path = AwesomeAttractorND;
@ -171,6 +179,7 @@
42D2E1281456175C00FBC16A /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Debug;
@ -178,6 +187,7 @@
42D2E1291456175C00FBC16A /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)";
PRODUCT_NAME = "$(TARGET_NAME)";
};
name = Release;
@ -201,6 +211,7 @@
42D2E1291456175C00FBC16A /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};

37
AwesomeAttractorND/Canvas.hpp

@ -0,0 +1,37 @@
//
// Canvas.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 10/28/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_Canvas_hpp
#define AwesomeAttractorND_Canvas_hpp
#include "nd_array.hpp"
class Canvas2D : public nd_array<unsigned int, 2>{
typedef Canvas2D self;
typedef nd_array<unsigned int, 2> super;
public:
Canvas2D(size_t width, size_t height)
: super(width, height)
{}
void plot(double const * const position){
const size_t width = get_size(0);
const size_t height = get_size(1);
const size_t x = position[0]*width + width*.5;
const size_t y = position[1]*width + height*.5;
if(x < width && y < height) {
(*this)[x][y]++;
}
}
};
#endif

147
AwesomeAttractorND/Image.hpp

@ -0,0 +1,147 @@
//
// Image.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 11/2/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_Image_hpp
#define AwesomeAttractorND_Image_hpp
#include <ostream>
#include <fstream>
#include <stdexcept>
#include <tr1/memory>
struct pixel {
friend class Image;
pixel(double red, double green, double blue)
: red(clamp(255*red))
, green(clamp(255*green))
, blue(clamp(255*blue))
{}
pixel(int red, int green, int blue)
: red(clamp(red))
, green(clamp(green))
, blue(clamp(blue))
{}
private:
uint8_t clamp(int n){
return std::min(255, std::max(0, n));
}
uint8_t red;
uint8_t green;
uint8_t blue;
};
namespace ImageFormats {
namespace bmp {
struct bitmap_file_header {
uint32_t filesize;
uint16_t creator1;
uint16_t creator2;
uint32_t bmp_offset;
template <typename DIBT>
bitmap_file_header(DIBT dib_header):
filesize(dib_header.bytes() + dib_header.header_sz + 12 + 2),
creator1(0),
creator2(0),
bmp_offset(dib_header.header_sz + 12 + 2){}
void write(std::ostream& out) const {
out << "BM";
out.write(reinterpret_cast<const char*>(this), 12);
}
};
struct bitmapcoreheader {
uint32_t header_sz;
uint16_t width;
uint16_t height;
uint16_t nplanes;
uint16_t bitspp;
bitmapcoreheader(int width, int height, int bitspp = 24):
header_sz(sizeof(bitmapcoreheader)),
width(width),
height(height),
nplanes(1),
bitspp(bitspp){}
void write(std::ostream& out) const {
out.write(reinterpret_cast<const char*>(this), header_sz);
}
unsigned int bytes(){
return width*height*bitspp/8;
}
};
template <typename P = pixel, typename DIBT = bitmapcoreheader>
struct bitmap {
bitmap(int width, int height)
: dib_header(width, height, sizeof(P)*8)
, header(dib_header)
, data(0) {}
void write(std::string const & filename){
std::ofstream file(filename.c_str());
write(file);
}
void write(std::ostream& out){
header.write(out);
dib_header.write(out);
//std::copy_n((char const *)data, dib_header.bytes(), std::ostream_iterator<char>(out));
std::copy((char const *)data, (char const *)data + dib_header.bytes(), std::ostream_iterator<char>(out));
}
private:
DIBT dib_header;
bitmap_file_header header;
P const * data;
};
template <typename DIBT = bitmapcoreheader>
struct bitmap_stream {
typedef pixel pixel;
bitmap_stream(int width, int height, std::string filename)
: dib_header(width, height)
, header(dib_header)
, file(filename.c_str())
{
header.write(file);
dib_header.write(file);
}
bitmap_stream& operator<<(pixel const & p){
file.write(&p, 3);
++x;
if (x >= dib_header.width){
x = 0;
++y;
}
if (y >= dib_header.height){
throw std::out_of_range("Writing BMP image out of bounds.");
}
}
private:
DIBT dib_header;
bitmap_file_header header;
std::ofstream file;
uint16_t x;
uint16_t y;
};
}
}
#endif

37
AwesomeAttractorND/Tonemapper.hpp

@ -0,0 +1,37 @@
//
// Tonemapper.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 10/28/11.
// Copyright 2011 Vadovas. All rights reserved.
//
#ifndef AwesomeAttractorND_Tonemapper_hpp
#define AwesomeAttractorND_Tonemapper_hpp
#include <algorithm>
namespace Tonemappers {
class Normalizer2D {
unsigned int max;
template <typename C>
void analyse(C const & canvas){
max = *std::max_element(canvas.cbegin(), canvas.cend());
}
template <typename C, typename I>
void process(C const & canvas, I & image){
for (size_t x = 0; x < canvas.get_size(0); ++x) {
for (size_t y = 0; y < canvas.get_size(1); ++y) {
const double grayscale = (double) canvas[x][y] / (double) max;
image << I::pixel(grayscale, grayscale, grayscale);
}
}
}
};
}
#endif

92
AwesomeAttractorND/main.cpp

@ -8,11 +8,95 @@
#include <iostream>
int main (int argc, const char * argv[])
{
#include "nd_array.hpp"
#include "Canvas.hpp"
#include "Tonemapper.hpp"
#include "Image.hpp"
const size_t width = 512;
const size_t height = 64;
const size_t depth = 32;
typedef nd_array<double, 3> array;
double calculate1(array & c){
double mean = 0.0;
for (unsigned int x = 0; x < width; ++x) {
for (unsigned int y = 0; y < height; ++y) {
for (unsigned int z = 0; z < depth; ++z) {
mean += 1.0/(width*height*depth) * c[x][y][z];
}
}
}
return mean;
}
void calculate2(array & c, double mean){
for (unsigned int x = 0; x < width; ++x) {
for (unsigned int y = 0; y < height; ++y) {
for (unsigned int z = 0; z < depth; ++z) {
c[x][y][z] = c[x/3][y][z/2] * mean / 200.0 + mean - x;
}
}
}
}
void calculate(array & c){
std::cout << "Calculating..." << std::endl;
for (unsigned int i = 0; i < 1000; ++i) {
double mean = calculate1(c);
calculate2(c, mean);
}
}
void fill(array & c){
std::cout << "Filling..." << std::endl;
for (unsigned int x = 0; x < width; ++x) {
for (unsigned int y = 0; y < height; ++y) {
for (unsigned int z = 0; z < depth; ++z) {
c[x][y][z] = x + z;
if (y == 5) {
c[x][y][z] = 5;
}
}
}
}
}
void output(array & c){
std::cout << "Outputting..." << std::endl;
for (unsigned int y = 0; y < 10; ++y) {
for (unsigned int x = 0; x < 10; ++x) {
std::cout << c[x][y][2] << '\t';
}
std::cout << '\n';
}
std::cout << "Outputting addresses..." << std::endl;
for (unsigned int z = 20; z < 30; ++z) {
double & n = c[32][64][z];
std::cout << &n << '\n';
}
}
int main (int argc, const char * argv[]){
std::cout << "Creating..." << std::endl;
array c(width, height, depth);
fill(c);
calculate(c);
output(c);
std::cout << "Done" << std::endl;
// insert code here...
std::cout << "Hello, World!\n";
return 0;
}

152
AwesomeAttractorND/nd_array.hpp

@ -0,0 +1,152 @@
//
// nd_array.hpp
// AwesomeAttractorND
//
// Created by Joshua Moerman on 10/25/11.
// Copyright 2011 Vadovas. All rights reserved.
//
/*
Dynamic multi-dimensional array.
With the usual c-syntax: v[x][y][z].
Memory is allocated as one big block, instead of multiple smaller blocks (which is the case with std::vector<std::vector<...>>).
Showed no difference in speed compared to std::array<std::array<...>> (in release build).
it is not yet standard compliant.
*/
#ifndef AwesomeAttractorND_nd_array_hpp
#define AwesomeAttractorND_nd_array_hpp
#include <stdexcept>
#include <numeric>
#include <iterator>
#include <tr1/array>
template <typename T, size_t dimension>
class nd_array{
public:
typedef T & reference;
typedef T const & const_reference;
typedef T * iterator;
typedef T const * const_iterator;
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T value_type;
typedef T * pointer;
typedef T const * const_pointer;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
template <size_type N>
struct proxy {
nd_array * const data;
size_t const offset;
proxy(nd_array * const c, size_t o)
: data(c)
, offset(o)
{}
proxy<N-1> operator[](size_t y){
if (N == 0) throw std::logic_error("called operator[] on a value");
return proxy<N-1>(data, data->sizes[dimension - N]*offset + y);
}
operator reference(){
if (N != 0) throw std::logic_error("using a non-value");
return *(data->data + offset);
}
reference operator=(T const & n){
if (N != 0) throw std::logic_error("assignment to a non-value");
return *(data->data + offset) = n;
}
};
template <size_type N>
struct const_proxy {
nd_array const * const data;
size_t const offset;
const_proxy(nd_array const * const c, size_t o)
: data(c)
, offset(o)
{}
const_proxy<N-1> operator[](size_t y) const {
if (N == 0) throw std::logic_error("called operator[] on a value");
return proxy<N-1>(data, data->sizes[dimension - N]*offset + y);
}
operator const_reference() const {
if (N != 0) throw std::logic_error("using a non-value");
return *(data->data + offset);
}
};
nd_array(size_type width, size_type height)
: data(0)
, sizes()
{
if (dimension != 2) throw std::logic_error("wrong constructor");
sizes[0] = width;
sizes[1] = height;
data = new T[width*height];
}
nd_array(size_type width, size_type height, size_type depth)
: data(0)
, sizes()
{
if (dimension != 3) throw std::logic_error("wrong constructor");
sizes[0] = width;
sizes[1] = height;
sizes[2] = depth;
data = new T[width*height*depth];
}
~nd_array(){
delete[] data;
}
size_type get_size(size_type d) const {
return sizes[d];
}
size_type size() const {
return std::accumulate(sizes.begin(), sizes.end(), 0, std::multiplies<size_type>());
}
proxy<dimension-1> operator[](size_t x){
return proxy<dimension-1>(this, x);
}
const_proxy<dimension-1> operator[](size_t x) const {
return proxy<dimension-1>(this, x);
}
iterator begin(){
return data;
}
iterator end(){
size_type length = size();
return data + length;
}
const_iterator cbegin() const {
return data;
}
const_iterator cend() const {
size_type length = size();
return data + length;
}
private:
T * data;
std::tr1::array<size_type, dimension> sizes;
};
#endif