Skip to content

Commit

Permalink
Import
Browse files Browse the repository at this point in the history
  • Loading branch information
morgan3d committed Aug 31, 2016
1 parent 9110d85 commit a7b46b2
Show file tree
Hide file tree
Showing 4 changed files with 354 additions and 7 deletions.
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,16 @@ Graphics
==================================================================
- oculusSample - Oculus SDK OpenGL Sample. Windows Visual Studio project for initializing and rendering to a DK2 or later HMD using OpenGL. June 2015.
- terrain - Continuous detail GPU Terrain, with multi-scale texturing and a hardware optimized variant of the geo clipmap. April 2014 http://casual-effects.blogspot.com/2014/04/fast-terrain-rendering-with-continuous.html
- normal2bump - Compute bump map (height field/displacment) from a normal map. 2014.
- convertToOBJ - Convert various 3D model formats to OBJ, e.g., IFS, PLY, PLY3, 3DS. 2013
- cgpp3 - Minimal graphics support routines from Computer Graphics: Principles and Practice 3rd edition for loading a 3D model and image, and displaying and saving images. 2012.
- glToScreen - Reverse OpenGL projection from my [flipcode article](http://www.flipcode.com/archives/Object_To_Screen_Space.shtml). Pre-2005.
- glProject - Forward OpenGL projection from my [flipcode article](http://www.flipcode.com/archives/Projecting_3D_Points.shtml). Pre-2005.
- 2DOBB - 2D oriented bounding box collision test from my [flipcode article](http://www.flipcode.com/archives/2D_OBB_Intersection.shtml). Pre-2005.

C++
==================================================================
- sort - Elegant C++ reference implementations of heapSort, insertionSort, mergeSort, and quickSort. (now maintained in [The Graphics Codex](http://graphicscodex.com)). December 2012
- glToScreen - Reverse OpenGL projection from my [flipcode article](http://www.flipcode.com/archives/Object_To_Screen_Space.shtml). Pre-2005.
- glProject - Forward OpenGL projection from my [flipcode article](http://www.flipcode.com/archives/Projecting_3D_Points.shtml). Pre-2005.
- 2DOBB - 2D oriented bounding box collision test from my [flipcode article](http://www.flipcode.com/archives/2D_OBB_Intersection.shtml). Pre-2005
<li><a href="C++/normal2bump.cpp">normal2bump.cpp</a> - Compute bump map (height field/displacment) from a normal map (for G3D 8.x)</li>
<li><a href="C++/normal2bump-G3D10.cpp">normal2bump-G3D10.cpp</a> - Compute bump map (height field/displacment) from a normal map (for G3D 9.x and 10.x)</li>
<li><a href="C++/convertToOBJ.cpp">convertToOBJ.cpp</a> - Convert various 3D model formats to OBJ, e.g., IFS, PLY, PLY3, 3DS.</li>
<li><a href="C++/cgpp-support.h">cgpp-support.h</a>, <a href="C++/cgpp-support.cpp">cgpp-support.cpp</a> - Minimal graphics support routines from Computer Graphics: Principles and Practice for loading a 3D model and image, and displaying and saving images.</li>

<!--
- tachyonVR - Unity 5.4 VR Starter Project. August 2016.
Expand Down
4 changes: 4 additions & 0 deletions cgpp3/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Minimal graphics support routines from Computer Graphics: Principles and Practice 3rd edition
for loading a 3D model and image, and displaying and saving images.

Morgan McGuire 2012
151 changes: 151 additions & 0 deletions cgpp3/cgpp-support.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
/**
Created by Morgan McGuire in 2012
Released into the public domain
*/
#include <GLG3D/GLG3D.h>
#include <GL/glut.h>
#include "supportclasses.h"

int Image::PPMGammaCorrect(float radiance, float e) const {
// Note that the PPM gamma is fixed at 2.2
return int(pow(std::min(1.0f, std::max(0.0f, radiance * e)), 1.0f / 2.2f) * 255.0f);
}


void Image::save(const std::string& filename, float e) const {
FILE* file = fopen(filename.c_str(), "wt");
fprintf(file, "P3 %d %d 255\n", m_width, m_height);
for (int y = 0; y < m_height; ++y) {
fprintf(file, "\n# y = %d\n", y);
for (int x = 0; x < m_width; ++x) {
const Color3& c(get(x, y));
fprintf(file, "%d %d %d\n",
PPMGammaCorrect(c.r, e),
PPMGammaCorrect(c.g, e),
PPMGammaCorrect(c.b, e));
}
}
fclose(file);
}


#if USE_OPENGL

static void quitOnEscape(unsigned char key, int x, int y) {
if (key == 27) { ::exit(0); }
}


static void render() {
glClear(GL_COLOR_BUFFER_BIT);
// Draw a full-screen quad of the image
glDrawArrays(GL_QUADS, 0, 4);
glutSwapBuffers();
}


void Image::display(float exposureConstant, float deviceGamma) const {
int argc = 0;

// Initialize OpenGL
glutInit(&argc, NULL);
glutInitWindowSize(m_width, m_height);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutCreateWindow("Rendered result");
glutKeyboardFunc(&quitOnEscape);
glutDisplayFunc(&render);

// Initialize OpenGL extensions
glewInit();

// Set the color scale applied as textures are uploaded to be the exposure constant
glMatrixMode(GL_COLOR);
glLoadIdentity();
glScalef(exposureConstant, exposureConstant, exposureConstant);

// Create a gamma correction color table for texture load
std::vector<Color3> gammaTable(256);
for (unsigned int i = 0; i < gammaTable.size(); ++i) {
gammaTable[i] = (Color3::white() * i / (gammaTable.size() - 1.0f)).pow(1.0f / deviceGamma);
}
glColorTable(GL_POST_COLOR_MATRIX_COLOR_TABLE, GL_RGB, gammaTable.size(), GL_RGB, GL_FLOAT, &gammaTable[0]);
glEnable(GL_POST_COLOR_MATRIX_COLOR_TABLE);

// Create a texture, upload our image, and bind it (assume a
// version of GL that supports NPOT textures)
GLuint texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_width, m_height, 0, GL_RGB, GL_FLOAT, &m_data[0]);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glEnable(GL_TEXTURE_2D);

// The vertices of a 2D quad mesh containing a single CCW square
static const Vector2 corner[] = {Vector2(0,0), Vector2(0,1), Vector2(1,1), Vector2(1,0)};

// Bind the quad mesh as the active geometry
glVertexPointer(2, GL_FLOAT, 0, corner);
glTexCoordPointer(2, GL_FLOAT, 0, corner);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);

// Set orthographic projection that stretches the unit square to the
// dimensions of the image
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, 1, 1, 0, 0, 2);
glutMainLoop();
}

#endif

///////////////////////////////////////////////////////////////////////////////////

void Scene::addModel
(const std::string& filename,
const BSDF& bsdf,
const float scale,
const Vector3& origin,
float y, float p, float r) {

const G3D::CFrame& frame = G3D::CFrame::fromXYZYPRDegrees(origin.x, origin.y, origin.z, y, p, r);

// (It is much easier to use G3D::ArticulatedModel to load a
// model, however, that requires that OpenGL already be
// initialized. The following code works even without an OpenGL
// context and spells out some of the details of the model loading
// process.)
G3D::Array<int> index;
G3D::Array<Vector3> vertex, wvertex;
G3D::Array<Vector3> normal, wnormal;
G3D::Array<Vector2> texCoord;
std::string ignore;

G3D::IFSModel::load(filename, ignore, index, vertex, texCoord);
G3D::Welder::weld(vertex, texCoord, normal, index, G3D::Welder::Settings());

// Transform to a new position
for (int i = 0; i < vertex.size(); ++i) {
vertex[i] *= scale;
}
frame.pointToWorldSpace(vertex, wvertex);
frame.normalToWorldSpace(normal, wnormal);

//index.resize(12);
for (int i = 0; i < index.size(); i += 3) {
int i0 = index[i + 0];
int i1 = index[i + 1];
int i2 = index[i + 2];
triangleArray.push_back(Triangle(wvertex[i0], wvertex[i1], wvertex[i2],
wnormal[i0], wnormal[i1], wnormal[i2],
bsdf));
/*
G3D::debugPrintf("%s ", wvertex[i0].toString().c_str());
G3D::debugPrintf("%s ", wvertex[i1].toString().c_str());
G3D::debugPrintf("%s\n", wvertex[i2].toString().c_str());*/
}
}
193 changes: 193 additions & 0 deletions cgpp3/cgpp-support.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
/**
This is a tiny support code base that gives you enough
infrastructure to write a "setPixel"-based renderer without any
boilerplate in your own code.
It defines Vector3, Vector2, Color3, Ray, Triangle, and Image
classes. Image can save to a PPM or display on the screen. It
works on Windows, Linux, and OS X. Images are gamma-corrected and
exposure-adjusted both on disk and on screen.
This implementation uses a few pieces of some freely available
cross-platform libraries. You need to link to the non-OpenGL part
of G3D (for the geometry classes), OpenGL, GLUT, and GLEW. If you
don't like to depend on libraries with "GL" in the name, then change
the USE_OPENGL macro definition and the preprocessor will remove
Image::display(). If you don't like the G3D dependency either, then
download the alternative stripped-down version of the geometry
clases and you will have zero external dependencies.
Consider using the G3D library's GApp framework instead of this
minimal base. Doing so requires learning a little more C++ and a
new API. In return for that investment, G3D provides cross-platform
GUI support, model loading, in-engine debugging tools, and an
extensive set of utility routines (some of which a professor may
choose to outlaw in a graphics course).
Created by Morgan McGuire in 2012
Released into the public domain
*/
#ifndef supportclasses_h
#define supportclasses_h

#include <G3D/platform.h>
#include <G3D/Vector2.h>
#include <G3D/Vector3.h>
#include <G3D/Color3.h>
#include <G3D/Ray.h>
#include <G3D/Triangle.h>

// Make Microsoft Windows programs start from the main() entry point
G3D_START_AT_MAIN();

// If set to false, removes the Image::display() method and the GLUT,
// GLEW, and OpenGL dependencies.
#define USE_OPENGL true

using G3D::Vector2;
using G3D::Vector3;
using G3D::Color3;
using G3D::Ray;

#ifdef INFINITY
#undef INFINITY
#endif

#ifdef PI
#undef PI
#endif

#define INFINITY (std::numeric_limits<float>::infinity())
#define PI (3.1415926536f)

/** The scattering distribution function */
class BSDF {
public:
/** This is a probability */
Color3 lambertian;
Color3 glossy;
float glossySharpness;

BSDF() {}
BSDF(const Color3& lamb, const Color3& glos = Color3::zero(), float sharp = 100.0f) :
lambertian(lamb),
glossy(glos),
glossySharpness(sharp) {}

/** Returns L_o / L_i = f * w_i.dot(n) */
Color3 evaluateCos(const Vector3& w_i, const Vector3& w_o, const Vector3& n) const {
const Vector3& w_h = (w_i + w_o).direction();
return
(lambertian +
glossy * ((glossySharpness + 8.0f) *
powf(std::max(0.0f, w_h.dot(n)), glossySharpness) /
(8.0f * PI))) *
std::max(0.0f, w_i.dot(n));
}
};

class Camera {
public:
float zNear;
float zFar;
float fieldOfViewX;

Camera() : zNear(-0.1f), zFar(-100.0f), fieldOfViewX(PI / 2.0f) {}
};

class Triangle {
private:
Vector3 m_vertex[3];
Vector3 m_normal[3];
BSDF m_bsdf;

public:

Triangle() {}

Triangle(const Vector3& v0, const Vector3& v1, const Vector3& v2,
const Vector3& n0, const Vector3& n1, const Vector3& n2,
const BSDF& bsdf) : m_bsdf(bsdf) {
m_vertex[0] = v0; m_normal[0] = n0;
m_vertex[1] = v1; m_normal[1] = n1;
m_vertex[2] = v2; m_normal[2] = n2;
}

const Vector3& vertex(int i) const {
return m_vertex[i];
}

const Vector3& normal(int i) const {
return m_normal[i];
}

const BSDF& bsdf() const {
return m_bsdf;
}
};

class Image {
private:
int m_width;
int m_height;
std::vector<Color3> m_data;

/** \param displayConstant Radiance is scaled by this value, which should be chosen to
scale the brightest values to about 1.0.*/
int PPMGammaCorrect(float radiance, float displayConstant) const;

public:

Image(int width, int height, const Color3& init = Color3::black()) :
m_width(width), m_height(height), m_data(width * height, init) {}

int width() const { return m_width; }

int height() const { return m_height; }

void set(int x, int y, const Color3& value) {
m_data[x + y * m_width] = value;
}

const Color3& get(int x, int y) const {
return m_data[x + y * m_width];
}

void save(const std::string& filename, float displayConstant = 15.0f) const;

# if USE_OPENGL
/** Does not return */
void display(float displayConstant = 15.0f, float deviceGamma = 2.0f) const;
# endif
};


class Light {
public:
Vector3 position;

/** Over the entire sphere. */
Color3 power;
};

class Scene {
public:
std::vector<Triangle> triangleArray;
std::vector<Light> lightArray;

/** Load an IFS format model and add it to the scene.
\param origin Object position in meters
\param y Yaw rotation in degrees
\param p Pitch rotation in degrees
\param r Roll rotation in degrees
*/
void addModel
(const std::string& filename,
const BSDF& bsdf = Color3::white() * 0.9f,
float scale = 1.0f,
const Vector3& origin = Vector3::zero(),
float y = 0, float p = 0, float r = 0);
};

#endif

0 comments on commit a7b46b2

Please sign in to comment.