Question
As provided, the code will draw and rotate a simple triangle in 3D. You are to modify the code to draw a cube in 3d
As provided, the code will draw and rotate a simple triangle in 3D. You are to modify the code to draw a cube in 3d with each vertex having its own color. Details: You are to draw a cube centered on the origin. It should be 1.0 - 1.5 units on a side. The 8 vertices of the cube should be coded using the colors black, red, green, blue, yellow, magenta, cyan, and white. You will have to change the data that is used by the OpenGL calls in order to do this. A vertex and fragment shader will also be provided that will provide the functionality you need for this project.
////////////////////////////////////////////////////////////////////////////// // // --- LoadShaders.cxx --- // ////////////////////////////////////////////////////////////////////////////// #include#include #define GLEW_STATIC #include #include "LoadShaders.h" #ifdef __cplusplus extern "C" { #endif // __cplusplus //---------------------------------------------------------------------------- static const GLchar* ReadShader( const char* filename ) { #ifdef WIN32 FILE* infile; fopen_s( &infile, filename, "rb" ); #else FILE* infile; fopen_s(&infile, filename, "rb"); // FILE* infile = fopen( filename, "rb" ); #endif // WIN32 if ( !infile ) { #ifdef _DEBUG std::cerr << "Unable to open file '" << filename << "'" << std::endl; #endif /* DEBUG */ return NULL; } fseek( infile, 0, SEEK_END ); int len = ftell( infile ); fseek( infile, 0, SEEK_SET ); GLchar* source = new GLchar[len+1]; fread( source, 1, len, infile ); fclose( infile ); source[len] = 0; return const_cast (source); } //---------------------------------------------------------------------------- GLuint LoadShaders( ShaderInfo* shaders ) { if ( shaders == NULL ) { return 0; } GLuint program = glCreateProgram(); ShaderInfo* entry = shaders; while ( entry->type != GL_NONE ) { GLuint shader = glCreateShader( entry->type ); entry->shader = shader; const GLchar* source = ReadShader( entry->filename ); if ( source == NULL ) { for ( entry = shaders; entry->type != GL_NONE; ++entry ) { glDeleteShader( entry->shader ); entry->shader = 0; } return 0; } glShaderSource( shader, 1, &source, NULL ); delete [] source; glCompileShader( shader ); GLint compiled; glGetShaderiv( shader, GL_COMPILE_STATUS, &compiled ); if ( !compiled ) { #ifdef _DEBUG GLsizei len; glGetShaderiv( shader, GL_INFO_LOG_LENGTH, &len ); GLchar* log = new GLchar[len+1]; glGetShaderInfoLog( shader, len, &len, log ); std::cerr << "Shader compilation failed: " << log << std::endl; delete [] log; #endif /* DEBUG */ return 0; } glAttachShader( program, shader ); ++entry; } #ifdef GL_VERSION_4_1 if ( GLEW_VERSION_4_1 ) { // glProgramParameteri( program, GL_PROGRAM_SEPARABLE, GL_TRUE ); } #endif /* GL_VERSION_4_1 */ glLinkProgram( program ); GLint linked; glGetProgramiv( program, GL_LINK_STATUS, &linked ); if ( !linked ) { #ifdef _DEBUG GLsizei len; glGetProgramiv( program, GL_INFO_LOG_LENGTH, &len ); GLchar* log = new GLchar[len+1]; glGetProgramInfoLog( program, len, &len, log ); std::cerr << "Shader linking failed: " << log << std::endl; delete [] log; #endif /* DEBUG */ for ( entry = shaders; entry->type != GL_NONE; ++entry ) { glDeleteShader( entry->shader ); entry->shader = 0; } return 0; } return program; } //---------------------------------------------------------------------------- #ifdef __cplusplus } #endif // __cplusplus
////////////////////////////////////////////////////////////////////////////// // // --- LoadShaders.h --- // ////////////////////////////////////////////////////////////////////////////// #ifndef __LOAD_SHADERS_H__ #define __LOAD_SHADERS_H__ #ifdef __cplusplus extern "C" { #endif // __cplusplus //---------------------------------------------------------------------------- // // LoadShaders() takes an array of ShaderFile structures, each of which // contains the type of the shader, and a pointer a C-style character // string (i.e., a NULL-terminated array of characters) containing the // entire shader source. // // The array of structures is terminated by a final Shader with the // "type" field set to GL_NONE. // // LoadShaders() returns the shader program value (as returned by // glCreateProgram()) on success, or zero on failure. // typedef struct { GLenum type; const char* filename; GLuint shader; } ShaderInfo; GLuint LoadShaders(ShaderInfo*); //---------------------------------------------------------------------------- #ifdef __cplusplus }; #endif // __cplusplus #endif // __LOAD_SHADERS_H__
#include#include #include #include #include #include "LoadShaders.h" #include "vmath.h" #include "vgl.h" #include
vmath.h
#ifndef __VMATH_H__ #define __VMATH_H__ #define _USE_MATH_DEFINES 1 // Include constants defined in math.h #includenamespace vmath { template inline T radians(T angleInRadians) { return angleInRadians * static_cast (180.0/M_PI); } template class ensure { public: inline ensure() { switch (false) { case false: case cond: break; } } }; template class vecN; template class vecN { public: typedef class vecN my_type; // Default constructor does nothing, just like built-in types inline vecN() { // Uninitialized variable } // Copy constructor inline vecN(const vecN& that) { assign(that); } // Construction from scalar inline vecN(T s) { int n; for (n = 0; n < len; n++) { data[n] = s; } } // Assignment operator inline vecN& operator=(const vecN& that) { assign(that); return *this; } inline vecN operator+(const vecN& that) const { my_type result; int n; for (n = 0; n < len; n++) result.data[n] = data[n] + that.data[n]; return result; } inline vecN& operator+=(const vecN& that) { return (*this = *this + that); } inline vecN operator-() const { my_type result; int n; for (n = 0; n < len; n++) result.data[n] = -data[n]; return result; } inline vecN operator-(const vecN& that) const { my_type result; int n; for (n = 0; n < len; n++) result.data[n] = data[n] - that.data[n]; return result; } inline vecN& operator-=(const vecN& that) { return (*this = *this - that); } inline vecN operator*(const vecN& that) const { my_type result; int n; for (n = 0; n < len; n++) result.data[n] = data[n] * that.data[n]; return result; } inline vecN& operator*=(const vecN& that) { return (*this = *this * that); } inline vecN operator*(const T& that) const { my_type result; int n; for (n = 0; n < len; n++) result.data[n] = data[n] * that; return result; } inline vecN& operator*=(const T& that) { assign(*this * that); return *this; } inline vecN operator/(const vecN& that) const { my_type result; int n; for (n = 0; n < len; n++) result.data[n] = data[n] * that.data[n]; return result; } inline vecN& operator/=(const vecN& that) { assign(*this * that); return *this; } inline vecN operator/(const T& that) const { my_type result; int n; for (n = 0; n < len; n++) result.data[n] = data[n] / that; return result; } inline vecN& operator/(const T& that) { assign(*this / that); } inline T& operator[](int n) { return data[n]; } inline const T& operator[](int n) const { return data[n]; } inline static int size(void) { return len; } inline operator const T* () const { return &data[0]; } protected: T data[len]; inline void assign(const vecN& that) { int n; for (n = 0; n < len; n++) data[n] = that.data[n]; } }; template class Tvec2 : public vecN { public: typedef vecN base; // Uninitialized variable inline Tvec2() {} // Copy constructor inline Tvec2(const base& v) : base(v) {} // vec2(x, y); inline Tvec2(T x, T y) { base::data[0] = x; base::data[1] = y; } }; template class Tvec3 : public vecN { public: typedef vecN base; // Uninitialized variable inline Tvec3() {} // Copy constructor inline Tvec3(const base& v) : base(v) {} // vec3(x, y, z); inline Tvec3(T x, T y, T z) { base::data[0] = x; base::data[1] = y; base::data[2] = z; } // vec3(v, z); inline Tvec3(const Tvec2 & v, T z) { base::data[0] = v[0]; base::data[1] = v[1]; base::data[2] = z; } // vec3(x, v) inline Tvec3(T x, const Tvec2 & v) { base::data[0] = x; base::data[1] = v[0]; base::data[2] = v[1]; } }; template class Tvec4 : public vecN { public: typedef vecN base; // Uninitialized variable inline Tvec4() {} // Copy constructor inline Tvec4(const base& v) : base(v) {} // vec4(x, y, z, w); inline Tvec4(T x, T y, T z, T w) { base::data[0] = x; base::data[1] = y; base::data[2] = z; base::data[3] = w; } // vec4(v, z, w); inline Tvec4(const Tvec2 & v, T z, T w) { base::data[0] = v[0]; base::data[1] = v[1]; base::data[2] = z; base::data[3] = w; } // vec4(x, v, w); inline Tvec4(T x, const Tvec2 & v, T w) { base::data[0] = x; base::data[1] = v[0]; base::data[2] = v[1]; base::data[3] = w; } // vec4(x, y, v); inline Tvec4(T x, T y, const Tvec2 & v) { base::data[0] = x; base::data[1] = y; base::data[2] = v[0]; base::data[3] = v[1]; } // vec4(v1, v2); inline Tvec4(const Tvec2 & u, const Tvec2 & v) { base::data[0] = u[0]; base::data[1] = u[1]; base::data[2] = v[0]; base::data[3] = v[1]; } // vec4(v, w); inline Tvec4(const Tvec3 & v, T w) { base::data[0] = v[0]; base::data[1] = v[1]; base::data[2] = v[2]; base::data[3] = w; } // vec4(x, v); inline Tvec4(T x, const Tvec3 & v) { base::data[0] = x; base::data[1] = v[0]; base::data[2] = v[1]; base::data[3] = v[2]; } }; typedef Tvec2 vec2; typedef Tvec2 ivec2; typedef Tvec2 uvec2; typedef Tvec2 dvec2; typedef Tvec3 vec3; typedef Tvec3 ivec3; typedef Tvec3 uvec3; typedef Tvec3 dvec3; typedef Tvec4 vec4; typedef Tvec4 ivec4; typedef Tvec4 uvec4; typedef Tvec4 dvec4; template static inline const vecN operator * (T x, const vecN & v) { return v * x; } template static inline const Tvec2 operator / (T x, const Tvec2 & v) { return Tvec2 (x / v[0], x / v[1]); } template static inline const Tvec3 operator / (T x, const Tvec3 & v) { return Tvec3 (x / v[0], x / v[1], x / v[2]); } template static inline const Tvec4 operator / (T x, const Tvec4 & v) { return Tvec4 (x / v[0], x / v[1], x / v[2], x / v[3]); } template static inline T dot(const vecN & a, const vecN & b) { int n; T total = T(0); for (n = 0; n < len; n++) { total += a[n] * b[n]; } return total; } template static inline vecN cross(const vecN & a, const vecN & b) { return Tvec3 (a[1] * b[2] - b[1] * a[2], a[2] * b[0] - b[2] * a[0], a[0] * b[1] - b[0] * a[1]); } template static inline T length(const vecN & v) { T result(0); for (int i = 0; i < v.size(); ++i) { result += v[i] * v[i]; } return (T)sqrt(result); } template static inline vecN normalize(const vecN & v) { return v / length(v); } template static inline T distance(const vecN & a, const vecN & b) { return length(b - a); } template class matNM { public: typedef class matNM my_type; typedef class vecN vector_type; // Default constructor does nothing, just like built-in types inline matNM() { // Uninitialized variable } // Copy constructor inline matNM(const matNM& that) { assign(that); } // Construction from element type // explicit to prevent assignment from T explicit inline matNM(T f) { for (int n = 0; n < w; n++) { data[n] = f; } } // Construction from vector inline matNM(const vector_type& v) { for (int n = 0; n < w; n++) { data[n] = v; } } // Assignment operator inline matNM& operator=(const my_type& that) { assign(that); return *this; } inline matNM operator+(const my_type& that) const { my_type result; int n; for (n = 0; n < w; n++) result.data[n] = data[n] + that.data[n]; return result; } inline my_type& operator+=(const my_type& that) { return (*this = *this + that); } inline my_type operator-(const my_type& that) const { my_type result; int n; for (n = 0; n < w; n++) result.data[n] = data[n] - that.data[n]; return result; } inline my_type& operator-=(const my_type& that) { return (*this = *this - that); } // Matrix multiply. // TODO: This only works for square matrices. Need more template skill to make a non-square version. inline my_type operator*(const my_type& that) const { ensure (); my_type result(0); for (int j = 0; j < w; j++) { for (int i = 0; i < h; i++) { T sum(0); for (int n = 0; n < w; n++) { sum += data[n][i] * that[j][n]; } result[j][i] = sum; } } return result; } inline my_type& operator*=(const my_type& that) { return (*this = *this * that); } inline vector_type& operator[](int n) { return data[n]; } inline const vector_type& operator[](int n) const { return data[n]; } inline operator T*() { return &data[0][0]; } inline operator const T*() const { return &data[0][0]; } inline matNM transpose(void) const { matNM result; int x, y; for (y = 0; y < w; y++) { for (x = 0; x < h; x++) { result[x][y] = data[y][x]; } } return result; } static inline my_type identity() { ensure (); my_type result(0); for (int i = 0; i < w; i++) { result[i][i] = 1; } return result; } static inline int width(void) { return w; } static inline int height(void) { return h; } protected: // Column primary data (essentially, array of vectors) vecN data[w]; // Assignment function - called from assignment operator and copy constructor. inline void assign(const matNM& that) { int n; for (n = 0; n < w; n++) data[n] = that.data[n]; } }; /* template class TmatN : public matNM { public: typedef matNM base; typedef TmatN my_type; inline TmatN() {} inline TmatN(const my_type& that) : base(that) {} inline TmatN(float f) : base(f) {} inline TmatN(const vecN & v) : base(v) {} inline my_type transpose(void) { my_type result; int x, y; for (y = 0; y < h; y++) { for (x = 0; x < h; x++) { result[x][y] = data[y][x]; } } return result; } }; */ template class Tmat4 : public matNM { public: typedef matNM base; typedef Tmat4 my_type; inline Tmat4() {} inline Tmat4(const my_type& that) : base(that) {} inline Tmat4(const base& that) : base(that) {} inline Tmat4(const vecN & v) : base(v) {} inline Tmat4(const vecN & v0, const vecN & v1, const vecN & v2, const vecN & v3) { base::data[0] = v0; base::data[1] = v1; base::data[2] = v2; base::data[3] = v3; } }; typedef Tmat4 mat4; typedef Tmat4 imat4; typedef Tmat4 umat4; typedef Tmat4 dmat4; static inline mat4 frustum(float left, float right, float bottom, float top, float n, float f) { mat4 result(mat4::identity()); if ((right == left) || (top == bottom) || (n == f) || (n < 0.0) || (f < 0.0)) return result; result[0][0] = (2.0f * n) / (right - left); result[1][1] = (2.0f * n) / (top - bottom); result[2][0] = (right + left) / (right - left); result[2][1] = (top + bottom) / (top - bottom); result[2][2] = -(f + n) / (f - n); result[2][3]= -1.0f; result[3][2] = -(2.0f * f * n) / (f - n); result[3][3] = 0.0f; return result; } static inline mat4 perspective(float fovy /* in degrees */, float aspect, float n, float f) { float top = n * tan(radians(0.5f*fovy)); // bottom = -top float right = top * aspect; // left = -right return frustum(-right, right, -top, top, n, f); } template static inline Tmat4 lookat(vecN eye, vecN center, vecN up) { const Tvec3 f = normalize(center - eye); const Tvec3 upN = normalize(up); const Tvec3 s = cross(f, upN); const Tvec3 u = cross(s, f); const Tmat4 M = Tmat4 (Tvec4 (s[0], u[0], -f[0], T(0)), Tvec4 (s[1], u[1], -f[1], T(0)), Tvec4 (s[2], u[2], -f[2], T(0)), Tvec4 (T(0), T(0), T(0), T(1))); return M * translate (-eye); } template static inline Tmat4 translate(T x, T y, T z) { return Tmat4 (Tvec4 (1.0f, 0.0f, 0.0f, 0.0f), Tvec4 (0.0f, 1.0f, 0.0f, 0.0f), Tvec4 (0.0f, 0.0f, 1.0f, 0.0f), Tvec4 (x, y, z, 1.0f)); } template static inline Tmat4 translate(const vecN & v) { return translate(v[0], v[1], v[2]); } template static inline Tmat4 scale(T x, T y, T z) { return Tmat4 (Tvec4 (x, 0.0f, 0.0f, 0.0f), Tvec4 (0.0f, y, 0.0f, 0.0f), Tvec4 (0.0f, 0.0f, z, 0.0f), Tvec4 (0.0f, 0.0f, 0.0f, 1.0f)); } template static inline Tmat4 scale(const Tvec4 & v) { return scale(v[0], v[1], v[2]); } template static inline Tmat4 scale(T x) { return Tmat4 (Tvec4 (x, 0.0f, 0.0f, 0.0f), Tvec4 (0.0f, x, 0.0f, 0.0f), Tvec4 (0.0f, 0.0f, x, 0.0f), Tvec4 (0.0f, 0.0f, 0.0f, 1.0f)); } template static inline Tmat4 rotate(T angle, T x, T y, T z) { Tmat4 result; const T x2 = x * x; const T y2 = y * y; const T z2 = z * z; float rads = float(angle) * 0.0174532925f; const float c = cosf(rads); const float s = sinf(rads); const float omc = 1.0f - c; result[0] = Tvec4 (T(x2 * omc + c), T(y * x * omc + z * s), T(x * z * omc - y * s), T(0)); result[1] = Tvec4 (T(x * y * omc - z * s), T(y2 * omc + c), T(y * z * omc + x * s), T(0)); result[2] = Tvec4 (T(x * z * omc + y * s), T(y * z * omc - x * s), T(z2 * omc + c), T(0)); result[3] = Tvec4 (T(0), T(0), T(0), T(1)); return result; } template static inline Tmat4 rotate(T angle, const vecN & v) { return rotate (angle, v[0], v[1], v[2]); } #ifdef min #undef min #endif template static inline T min(T a, T b) { return a < b ? a : b; } #ifdef max #undef max #endif template static inline T max(T a, T b) { return a >= b ? a : b; } template static inline vecN min(const vecN & x, const vecN & y) { vecN t; int n; for (n = 0; n < N; n++) { t[n] = min(x[n], y[n]); } return t; } template static inline vecN max(const vecN & x, const vecN & y) { vecN t; int n; for (n = 0; n < N; n++) { t[n] = max (x[n], y[n]); } return t; } template static inline vecN clamp(const vecN & x, const vecN & minVal, const vecN & maxVal) { return min (max (x, minVal), maxVal); } template static inline vecN smoothstep(const vecN & edge0, const vecN & edge1, const vecN & x) { vecN t; t = clamp((x - edge0) / (edge1 - edge0), vecN (T(0)), vecN (T(1))); return t * t * (vecN (T(3)) - vecN (T(2)) * t); } template static inline matNM matrixCompMult(const matNM & x, const matNM & y) { matNM result; int i, j; for (j = 0; j < M; ++j) { for (i = 0; i < N; ++i) { result[i][j] = x[i][j] * y[i][j]; } } return result; } template static inline vecN operator*(const vecN & vec, const matNM & mat) { int n, m; vecN result(T(0)); for (m = 0; m < M; m++) { for (n = 0; n < N; n++) { result[n] += vec[m] * mat[n][m]; } } return result; } }; #endif /* __VMATH_H__ */
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started