// // shader.h // #ifndef zxShader_h #define zxShader_h #include <gl/glew.h> #include <gl/freeglut.h> #include <string> class zxShader { private: GLuint program; GLuint vertexShader; GLuint geometryShader; GLuint fragmentShader; char *open(std::string filename); GLuint shader(int type, std::string filename); bool link(); bool init(); public: zxShader(); ~zxShader(); bool load(std::string vert, std::string geom, std::string frag); void start(); void end(); GLint attributeVariable(const char *var); void attribute(const char *var, float *a); void uniform1f(const char *var, float a); void uniform2f(const char *var, float a, float b); void uniform3f(const char *var, float a, float b, float c); void uniform4f(const char *var, float a, float b, float c, float d); void uniform1fv(const char *var, int size, float *a); void uniform2fv(const char *var, int size, float *a); void uniform3fv(const char *var, int size, float *a); void uniform4fv(const char *var, int size, float *a); void uniform1i(const char *var, int a); void uniform2i(const char *var, int a, int b); void uniform3i(const char *var, int a, int b, int c); void uniform4i(const char *var, int a, int b, int c, int d); void uniform1iv(const char *var, int size, int *a); void uniform2iv(const char *var, int size, int *a); void uniform3iv(const char *var, int size, int *a); void uniform4iv(const char *var, int size, int *a); void uniformMatrix(const char *var, unsigned short size, bool p, float *m); GLint uniformVariable(const char *var); }; #endif
// // shader.cpp // #include <iostream> #include "zxShader.h" #include <fstream> zxShader::zxShader() { } zxShader::~zxShader() { glDeleteShader(this->vertexShader); glDeleteShader(this->geometryShader); glDeleteShader(this->fragmentShader); glDeleteProgram(this->program); } char *zxShader::open(std::string filename) { FILE *file; char *content = NULL; int count = 0; if(filename != "") { file = fopen(filename.c_str(), "rt"); if(file != NULL) { fseek(file, 0, SEEK_END); count = ftell(file); rewind(file); if(count > 0) { content = new char[count + 1]; count = fread(content, sizeof(char), count, file); content[count] = '\0'; } fclose(file); } } return content; } bool zxShader::init() { if(glewInit() != GLEW_OK) { fprintf(stderr, "glew not initialized\n"); return false; } else { this->vertexShader = 0; this->geometryShader = 0; this->fragmentShader = 0; return true; } } GLuint zxShader::shader(int type, std::string filename) { if(filename != "") { GLuint s[3] = {GL_VERTEX_SHADER, GL_GEOMETRY_SHADER, GL_FRAGMENT_SHADER}; int success; char infoLog[512]; GLuint shader = glCreateShader(s[type]); char *script = this->open(filename); glShaderSource(shader, 1, (const GLchar **)&script, NULL); delete [] script; glCompileShader(shader); glGetShaderiv(shader, GL_COMPILE_STATUS, &success); if(success) { return shader; } else { std::string w[3] = {"VERTEX", "GEOMETRY", "FRAGMENT"}; glGetShaderInfoLog(shader, 512, NULL, infoLog); std::cout << "ERROR::" << w[type] << "::COMPILATION_FAILED\n" << infoLog << std::endl; return 0; } } else { return 0; } } bool zxShader::link() { int success; char infoLog[512]; this->program = glCreateProgram(); if(this->vertexShader != 0){glAttachShader(this->program, this->vertexShader);} if(this->geometryShader != 0){glAttachShader(this->program, this->geometryShader);} if(this->fragmentShader != 0){glAttachShader(this->program, this->fragmentShader);} glLinkProgram(this->program); glGetProgramiv(this->program, GL_LINK_STATUS, &success); if(!success) { glGetProgramInfoLog(this->program, 512, NULL, infoLog); std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl; } } bool zxShader::load(std::string vert, std::string geom, std::string frag) { bool r = false; if(this->init()) { this->vertexShader = this->shader(0, vert); this->geometryShader = this->shader(1, geom); this->fragmentShader = this->shader(2, frag); if(this->link()) { r = true; } } return r; } void zxShader::start() { glUseProgram(this->program); } void zxShader::end() { glUseProgram(0); } void zxShader::uniform1f(const char *var, float a) { glUniform1f(glGetUniformLocation(this->program, var), a); } void zxShader::uniform2f(const char *var, float a, float b) { glUniform2f(glGetUniformLocation(this->program, var), a, b); } void zxShader::uniform3f(const char *var, float a, float b, float c) { glUniform3f(glGetUniformLocation(this->program, var), a, b, c); } void zxShader::uniform4f(const char *var, float a, float b, float c, float d) { glUniform4f(glGetUniformLocation(this->program, var), a, b, c, d); } void zxShader::uniform1fv(const char *var, int size, float *a) { glUniform1fv(glGetUniformLocation(this->program, var), size, a); } void zxShader::uniform2fv(const char *var, int size, float *a) { glUniform2fv(glGetUniformLocation(this->program, var), size, a); } void zxShader::uniform3fv(const char *var, int size, float *a) { glUniform3fv(glGetUniformLocation(this->program, var), size, a); } void zxShader::uniform4fv(const char *var, int size, float *a) { glUniform4fv(glGetUniformLocation(this->program, var), size, a); } void zxShader::uniform1i(const char *var, int a) { glUniform1i(glGetUniformLocation(this->program, var), a); } void zxShader::uniform2i(const char *var, int a, int b) { glUniform2i(glGetUniformLocation(this->program, var), a, b); } void zxShader::uniform3i(const char *var, int a, int b, int c) { glUniform3i(glGetUniformLocation(this->program, var), a, b, c); } void zxShader::uniform4i(const char *var, int a, int b, int c, int d) { glUniform4i(glGetUniformLocation(this->program, var), a, b, c, d); } void zxShader::uniform1iv(const char *var, int size, int *a) { glUniform1iv(glGetUniformLocation(this->program, var), size, a); } void zxShader::uniform2iv(const char *var, int size, int *a) { glUniform2iv(glGetUniformLocation(this->program, var), size, a); } void zxShader::uniform3iv(const char *var, int size, int *a) { glUniform3iv(glGetUniformLocation(this->program, var), size, a); } void zxShader::uniform4iv(const char *var, int size, int *a) { glUniform4iv(glGetUniformLocation(this->program, var), size, a); } void zxShader::attribute(const char *var, float *a) { glVertexAttrib1fv(glGetAttribLocation(this->program, var), a); } void zxShader::uniformMatrix(const char *var, unsigned short size, bool p, float *m) { glUniformMatrix4fv(glGetUniformLocation(this->program, var), size, p, m); } GLint zxShader::uniformVariable(const char *var) { return glGetUniformLocation(this->program, var); } GLint zxShader::attributeVariable(const char *var) { return glGetAttribLocation(this->program, var); }nella cartella shaders inseriamo due file txt con gli script GLSL.
// // vert.txt // #version 330 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec3 aColor; out vec3 color; uniform mat4 mvp; void main() { color = aColor; gl_Position = mvp * vec4(aPos, 1.0); } // // // #version 330 core out vec4 FragColor; in vec3 color; void main() { FragColor = vec4(color, 1.0f); }Aggiungiamo anche delle classi per il calcolo delle matrici (visto che non si usano più le funzioni proprie a opengl) e due files per la definizione di variabili globali.
// // zxMath.h // #ifndef zxMath_h #define zxMath_h #include <math.h> namespace zxMath { float abs(float x); class vec2 { public: float x, y; vec2(); vec2(float x, float y); void set(float x, float y); void show(); }; class vec3 { public: float x, y, z; vec3(); vec3(float x, float y, float z); void set(float x, float y, float z); void show(); }; class vec4 { public: float x, y, z, a; vec4(); vec4(float x, float y, float z, float a); void set(float x, float y, float z, float a); void show(); }; class mat2 { public: float m[4]; mat2(); mat2(float a, float b, float c, float d); mat2(vec2 A, vec2 B); void set(float a, float b, float c, float d); void set(vec2 A, vec2 B); void show(); }; class mat3 { public: float m[9]; mat3(); mat3(float a, float b, float c, float d, float e, float f, float g, float h, float i); mat3(vec3 A, vec3 B, vec3 C); void set(float a, float b, float c, float d, float e, float f, float g, float h, float i); void set(vec3 A, vec3 B, vec3 C); void show(); }; class mat4 { public: float m[16]; mat4(); mat4(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p); mat4(vec4 A, vec4 B, vec4 C, vec4 D); void set(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p); void set(vec4 A, vec4 B, vec4 C, vec4 D); void show(); }; vec2 cross(vec2 A, vec2 B); vec3 cross(vec3 A, vec3 B); vec4 cross(vec4 A, vec4 B); float det(mat2 A); float det(mat3 A); float det(mat4 A); float dot(vec2 A, vec2 B); float dot(vec3 A, vec3 B); float dot(vec4 A, vec4 B); float magnitude(vec2 A); float magnitude(vec3 A); float magnitude(vec4 A); vec2 normalize(vec2 A); vec3 normalize(vec3 A); vec4 normalize(vec4 A); mat3 product(mat3 A, mat3 B); mat4 product(mat4 A, mat4 B); mat4 transpose(mat4 A); mat4 inverse(mat4 A); mat4 perspective(float fovy, float aspect, float near, float far); mat4 lookAt(vec3 E, vec3 C, vec3 U); mat4 defaultCamera(vec3 E, vec3 C); mat4 modelViewProjection(mat4 M, mat4 V, mat4 P); mat4 ortho(float left, float right, float bottom, float top); mat4 ortho(float left, float right, float bottom, float top, float near, float far); mat3 rotate(mat3 M, float a); mat4 rotate(mat4 M, float a, zxMath::vec3 b); mat3 translate(mat3 M, zxMath::vec2 t); mat4 translate(mat4 M, zxMath::vec3 t); mat2 toMat2(mat3 A); mat2 toMat2(mat4 A); mat3 toMat3(mat2 A); mat3 toMat3(mat4 A); mat4 toMat4(mat2 A); mat4 toMat4(mat3 A); }; #endif // // zxMath.cpp // #include "zxMath.h" #include <iostream> float zxMath::abs(float x) { if(x < 0) { x *= -1.0f; } return x; } zxMath::vec2::vec2() { this->set(0.0f, 0.0f); } zxMath::vec2::vec2(float x, float y) { this->set(x, y); } void zxMath::vec2::set(float x, float y) { this->x = x; this->y = y; } void zxMath::vec2::show() { std::cout << this->x << "\t" << this->y << "\n"; } zxMath::vec3::vec3() { this->set(0.0f, 0.0f, 0.0f); } zxMath::vec3::vec3(float x, float y, float z) { this->set(x, y, z); } void zxMath::vec3::set(float x, float y, float z) { this->x = x; this->y = y; this->z = z; } void zxMath::vec3::show() { std::cout << this->x << "\t" << this->y << "\t" << this->z << "\n"; } zxMath::vec4::vec4() { this->set(0.0f, 0.0f, 0.0f, 0.0f); } zxMath::vec4::vec4(float x, float y, float z, float a) { this->set(x, y, z, a); } void zxMath::vec4::set(float x, float y, float z, float a) { this->x = x; this->y = y; this->z = z; this->a = a; } void zxMath::vec4::show() { std::cout << this->x << "\t" << this->y << "\t" << this->z << "\t" << a << "\n"; } zxMath::mat2::mat2() { this->set(1.0f, 0.0f, 0.0f, 1.0f); } zxMath::mat2::mat2(float a, float b, float c, float d) { this->set(a, b, c, d); } zxMath::mat2::mat2(zxMath::vec2 A, zxMath::vec2 B) { this->set(A, B); } void zxMath::mat2::set(float a, float b, float c, float d) { this->m[0] = a; this->m[1] = b; this->m[2] = c; this->m[3] = d; } void zxMath::mat2::set(zxMath::vec2 A, zxMath::vec2 B) { this->m[0] = A.x; this->m[1] = A.y; this->m[2] = B.x; this->m[3] = B.y; } void zxMath::mat2::show() { std::cout << this->m[0] << "\t" << this->m[1] << "\n"; std::cout << this->m[2] << "\t" << this->m[3] << "\n"; } zxMath::mat3::mat3() { this->set(1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f); } zxMath::mat3::mat3(float a, float b, float c, float d, float e, float f, float g, float h, float i) { this->set(a, b, c, d, e, f, g, h, i); } zxMath::mat3::mat3(zxMath::vec3 A, zxMath::vec3 B, zxMath::vec3 C) { this->set(A, B, C); } void zxMath::mat3::set(float a, float b, float c, float d, float e, float f, float g, float h, float i) { this->m[0] = a; this->m[1] = b; this->m[2] = c; this->m[3] = d; this->m[4] = e; this->m[5] = f; this->m[6] = g; this->m[7] = h; this->m[8] = i; } void zxMath::mat3::set(zxMath::vec3 A, zxMath::vec3 B, zxMath::vec3 C) { this->m[0] = A.x; this->m[1] = A.y; this->m[2] = A.z; this->m[3] = B.x; this->m[4] = B.y; this->m[5] = B.z; this->m[6] = C.x; this->m[7] = C.y; this->m[8] = C.z; } void zxMath::mat3::show() { std::cout << this->m[0] << "\t" << this->m[1] << "\t" <<this->m[2] << "\t" << "\n"; std::cout << this->m[3] << "\t" << this->m[4] << "\t" <<this->m[5] << "\t" << "\n"; std::cout << this->m[6] << "\t" << this->m[7] << "\t" <<this->m[8] << "\t" << "\n"; } zxMath::mat4::mat4() { this->set(1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); } zxMath::mat4::mat4(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p) { this->set(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p); } zxMath::mat4::mat4(zxMath::vec4 A, zxMath::vec4 B, zxMath::vec4 C, zxMath::vec4 D) { this->set(A, B, C, D); } void zxMath::mat4::set(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p) { this->m[ 0] = a; this->m[ 1] = b; this->m[ 2] = c; this->m[ 3] = d; this->m[ 4] = e; this->m[ 5] = f; this->m[ 6] = g; this->m[ 7] = h; this->m[ 8] = i; this->m[ 9] = j; this->m[10] = k; this->m[11] = l; this->m[12] = m; this->m[13] = n; this->m[14] = o; this->m[15] = p; } void zxMath::mat4::set(zxMath::vec4 A, zxMath::vec4 B, zxMath::vec4 C, zxMath::vec4 D) { this->m[ 0] = A.x; this->m[ 1] = A.y; this->m[ 2] = A.z; this->m[ 3] = A.a; this->m[ 4] = B.x; this->m[ 5] = B.y; this->m[ 6] = B.z; this->m[ 7] = B.a; this->m[ 8] = C.x; this->m[ 9] = C.y; this->m[10] = C.z; this->m[11] = C.a; this->m[12] = D.x; this->m[13] = D.y; this->m[14] = D.z; this->m[15] = D.a; } void zxMath::mat4::show() { std::cout << this->m[ 0] << "\t" << this->m[ 1] << "\t" << this->m[ 2] << "\t" << this->m[ 3] << "\n"; std::cout << this->m[ 4] << "\t" << this->m[ 5] << "\t" << this->m[ 6] << "\t" << this->m[ 7] << "\n"; std::cout << this->m[ 8] << "\t" << this->m[ 9] << "\t" << this->m[10] << "\t" << this->m[11] << "\n"; std::cout << this->m[12] << "\t" << this->m[13] << "\t" << this->m[14] << "\t" << this->m[15] << "\n"; } zxMath::vec2 zxMath::cross(zxMath::vec2 A, zxMath::vec2 B) { zxMath::vec2 R(A.x * B.y - A.y * B.x, 0.0f); return R; } zxMath::vec3 zxMath::cross(zxMath::vec3 A, zxMath::vec3 B) { zxMath::vec3 R(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x); return R; } zxMath::vec4 zxMath::cross(zxMath::vec4 A, zxMath::vec4 B) { vec4 R(A.y * B.z - A.z * B.y, A.z * B.x - A.x * B.z, A.x * B.y - A.y * B.x, 0.0f); return R; } float zxMath::det(zxMath::mat2 A) { float r = A.m[0] * A.m[3] - A.m[1] * A.m[2]; return r; } float zxMath::det(zxMath::mat3 A) { float r = A.m[ 0] * A.m[ 4] * A.m[ 8] + A.m[ 1] * A.m[ 5] * A.m[ 6] + A.m[ 2] * A.m[ 3] * A.m[ 7] - A.m[ 6] * A.m[ 4] * A.m[ 2] - A.m[ 7] * A.m[ 5] * A.m[ 0] - A.m[ 8] * A.m[ 3] * A.m[ 1]; return r; } float zxMath::det(zxMath::mat4 A) { zxMath::mat3 J(A.m[ 1], A.m[ 2], A.m[ 3], A.m[ 5], A.m[ 6], A.m[ 7], A.m[ 9], A.m[10], A.m[11]); zxMath::mat3 K(A.m[ 0], A.m[ 2], A.m[ 3], A.m[ 4], A.m[ 6], A.m[ 7], A.m[ 8], A.m[10], A.m[11]); zxMath::mat3 L(A.m[ 0], A.m[ 1], A.m[ 3], A.m[ 4], A.m[ 5], A.m[ 7], A.m[ 8], A.m[ 9], A.m[11]); zxMath::mat3 M(A.m[ 0], A.m[ 1], A.m[ 2], A.m[ 4], A.m[ 5], A.m[ 6], A.m[ 8], A.m[ 9], A.m[10]); float d = - A.m[12] * zxMath::det(J) + A.m[13] * zxMath::det(K) - A.m[14] * zxMath::det(L) + A.m[15] * zxMath::det(M); return d; } float zxMath::dot(zxMath::vec2 A, zxMath::vec2 B) { return A.x * B.x + A.y * B.y; } float zxMath::dot(zxMath::vec3 A, zxMath::vec3 B) { return A.x * B.x + A.y * B.y + A.z * B.z; } float zxMath::dot(zxMath::vec4 A, zxMath::vec4 B) { return A.x * B.x + A.y * B.y + A.z * B.z + A.a * B.a; } float zxMath::magnitude(zxMath::vec2 A) { return sqrt(A.x * A.x + A.y * A.y); } float zxMath::magnitude(zxMath::vec3 A) { return sqrt(A.x * A.x + A.y * A.y + A.z * A.z); } float zxMath::magnitude(zxMath::vec4 A) { float r = sqrt(A.x * A.x + A.y * A.y + A.z * A.z); return r; } zxMath::vec2 zxMath::normalize(zxMath::vec2 A) { float d = zxMath::magnitude(A); zxMath::vec2 R(A.x / d, A.y / d); return R; } zxMath::vec3 zxMath::normalize(zxMath::vec3 A) { float d = zxMath::magnitude(A); zxMath::vec3 R(A.x / d, A.y / d, A.z / d); return R; } zxMath::vec4 zxMath::normalize(zxMath::vec4 A) { float d = zxMath::magnitude(A); zxMath::vec4 R(A.x / d, A.y / d, A.z / d, 0); return R; } zxMath::mat3 zxMath::product(zxMath::mat3 A, zxMath::mat3 B) { zxMath::mat3 R( A.m[0] * B.m[0] + A.m[1] * B.m[3] + A.m[2] * B.m[6], A.m[0] * B.m[1] + A.m[1] * B.m[4] + A.m[2] * B.m[7], A.m[0] * B.m[2] + A.m[1] * B.m[5] + A.m[2] * B.m[8], A.m[3] * B.m[0] + A.m[4] * B.m[3] + A.m[5] * B.m[6], A.m[3] * B.m[1] + A.m[4] * B.m[4] + A.m[5] * B.m[7], A.m[3] * B.m[2] + A.m[4] * B.m[5] + A.m[5] * B.m[8], A.m[6] * B.m[0] + A.m[7] * B.m[3] + A.m[8] * B.m[6], A.m[6] * B.m[1] + A.m[7] * B.m[4] + A.m[8] * B.m[7], A.m[6] * B.m[2] + A.m[7] * B.m[5] + A.m[8] * B.m[8] ); return R; } zxMath::mat4 zxMath::product(zxMath::mat4 A, zxMath::mat4 B) { zxMath::mat4 R( A.m[ 0] * B.m[ 0] + A.m[ 1] * B.m[ 4] + A.m[ 2] * B.m[ 8] + A.m[ 3] * B.m[12], A.m[ 0] * B.m[ 1] + A.m[ 1] * B.m[ 5] + A.m[ 2] * B.m[ 9] + A.m[ 3] * B.m[13], A.m[ 0] * B.m[ 2] + A.m[ 1] * B.m[ 6] + A.m[ 2] * B.m[10] + A.m[ 3] * B.m[14], A.m[ 0] * B.m[ 3] + A.m[ 1] * B.m[ 7] + A.m[ 2] * B.m[11] + A.m[ 3] * B.m[15], A.m[ 4] * B.m[ 0] + A.m[ 5] * B.m[ 4] + A.m[ 6] * B.m[ 8] + A.m[ 7] * B.m[12], A.m[ 4] * B.m[ 1] + A.m[ 5] * B.m[ 5] + A.m[ 6] * B.m[ 9] + A.m[ 7] * B.m[13], A.m[ 4] * B.m[ 2] + A.m[ 5] * B.m[ 6] + A.m[ 6] * B.m[10] + A.m[ 7] * B.m[14], A.m[ 4] * B.m[ 3] + A.m[ 5] * B.m[ 7] + A.m[ 6] * B.m[11] + A.m[ 7] * B.m[15], A.m[ 8] * B.m[ 0] + A.m[ 9] * B.m[ 4] + A.m[10] * B.m[ 8] + A.m[11] * B.m[12], A.m[ 8] * B.m[ 1] + A.m[ 9] * B.m[ 5] + A.m[10] * B.m[ 9] + A.m[11] * B.m[13], A.m[ 8] * B.m[ 2] + A.m[ 9] * B.m[ 6] + A.m[10] * B.m[10] + A.m[11] * B.m[14], A.m[ 8] * B.m[ 3] + A.m[ 9] * B.m[ 7] + A.m[10] * B.m[11] + A.m[11] * B.m[15], A.m[12] * B.m[ 0] + A.m[13] * B.m[ 4] + A.m[14] * B.m[ 8] + A.m[15] * B.m[12], A.m[12] * B.m[ 1] + A.m[13] * B.m[ 5] + A.m[14] * B.m[ 9] + A.m[15] * B.m[13], A.m[12] * B.m[ 2] + A.m[13] * B.m[ 6] + A.m[14] * B.m[10] + A.m[15] * B.m[14], A.m[12] * B.m[ 3] + A.m[13] * B.m[ 7] + A.m[14] * B.m[11] + A.m[15] * B.m[15] ); return R; } zxMath::mat4 zxMath::transpose(zxMath::mat4 A) { mat4 R( A.m[ 0], A.m[ 4], A.m[ 8], A.m[12], A.m[ 1], A.m[ 5], A.m[ 9], A.m[13], A.m[ 2], A.m[ 6], A.m[10], A.m[14], A.m[ 3], A.m[ 7], A.m[11], A.m[15]); return R; } zxMath::mat4 zxMath::inverse(zxMath::mat4 A) { float det = zxMath::det(A), d[16]; zxMath::mat4 R; if(det != 0.0f) { for(unsigned short n = 0; n < 16; n++) { zxMath::mat3 B; unsigned short p = n % 4, q = n / 4, i = 0; for(unsigned short j = 0; j < 16; j++) { if(j % 4 != p && j / 4 != q) { B.m[i] = A.m[j]; i++; } } d[n] = pow(-1.0f, p + q + 2.0f) * zxMath::det(B) / det; } R.set(d[0], d[4], d[8], d[12], d[1], d[5], d[9], d[13], d[2], d[6], d[10], d[14], d[3], d[7], d[11], d[15]); } else { std::cout << "matrix does not have an inverse. Determinant is zero.\n"; } return R; } zxMath::mat4 zxMath::perspective(float fovy, float aspect, float near, float far) { float f = 1.0f / tan(fovy * .0174533f / 2.0f); zxMath::mat4 R( f / aspect, 0.0f, 0.0f, 0.0f, 0.0f, f, 0.0f, 0.0f, 0.0f, 0.0f, (far + near) / (near - far), -1.0f, 0.0f, 0.0f, (2.0f * far * near) / (near - far), 0.0f); return R; } zxMath::mat4 zxMath::ortho(float left, float right, float bottom, float top) { return zxMath::ortho(left, right, bottom, top, -1.0f, 1.0f); } zxMath::mat4 zxMath::ortho(float left, float right, float bottom, float top, float near, float far) { zxMath::mat4 R( 2.0f / (right - left), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / (far - near), 0.0f, -(right + left) / (right - left), -(top + bottom) / (top - bottom), -(far + near) / (far - near), 1.0f ); return R; } zxMath::mat4 zxMath::lookAt(zxMath::vec3 E, zxMath::vec3 C, zxMath::vec3 U) { zxMath::vec3 L = zxMath::normalize(zxMath::vec3(C.x - E.x, C.y - E.y, C.z - E.z)); zxMath::vec3 S = zxMath::normalize(zxMath::cross(L, U)); zxMath::vec3 V = zxMath::cross(S, L); L.x *= -1.0f; L.y *= -1.0f; L.z *= -1.0f; zxMath::mat4 R( vec4(S.x, V.x, L.x, 0.0f), vec4(S.y, V.y, L.y, 0.0f), vec4(S.z, V.z, L.z, 0.0f), vec4(-dot(S, E), -dot(V, E), -dot(L, E), 1.0f)); return R; } zxMath::mat3 zxMath::rotate(zxMath::mat3 M, float a) { float c = cos(a * .0174533f); float s = sin(a * .0174533f); zxMath::mat3 R( c, -s, 0.0f, s, c, 0.0f, 0.0f, 0.0f, 1.0f ); return zxMath::product(M, R); } zxMath::mat3 zxMath::translate(zxMath::mat3 M, zxMath::vec2 t) { zxMath::mat3 R( 1.0f, 0.0f, t.x, 0.0f, 1.0f, t.y, 0.0f, 0.0f, 1.0f ); return zxMath::product(M, R); } zxMath::mat4 zxMath::rotate(zxMath::mat4 M, float a, zxMath::vec3 b) { float c = cos(a * .0174533f); float s = sin(a * .0174533f); zxMath::mat4 R( c + b.x * b.x * (1.0f - c), b.x * b.y * (1.0f - c) - b.z * s, b.x * b.z * (1.0f - c) + b.y * s, 0.0f, b.x * b.y * (1.0f - c) + b.z * s, c + b.y * b.y * (1.0f - c), b.y * b.z * (1.0f - c) - b.x * s, 0.0f, b.x * b.z * (1.0f - c) - b.y * s, b.y * b.z * (1.0f - c) + b.x * s, c + b.z * b.z * (1.0f - c), 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); return zxMath::product(M, R); } zxMath::mat4 zxMath::translate(zxMath::mat4 M, zxMath::vec3 t) { M.m[ 3] = t.x; M.m[ 7] = t.y; M.m[11] = t.z; return M; } zxMath::mat4 zxMath::modelViewProjection(zxMath::mat4 M, zxMath::mat4 V, zxMath::mat4 P) { return zxMath::product(zxMath::product(M, V), P); } zxMath::mat4 zxMath::defaultCamera(zxMath::vec3 E, zxMath::vec3 C) { zxMath::vec3 U(0.0f, 0.0f, 1.0f); return zxMath::lookAt(E, C, U); } zxMath::mat2 zxMath::toMat2(zxMath::mat3 A) { return zxMath::mat2(A.m[0], A.m[1], A.m[3], A.m[4]); } zxMath::mat2 zxMath::toMat2(zxMath::mat4 A) { return zxMath::mat2(A.m[0], A.m[1], A.m[4], A.m[5]); } zxMath::mat3 zxMath::toMat3(zxMath::mat2 A) { return zxMath::mat3(A.m[0], A.m[1], 0.0f, A.m[2], A.m[3], 0.0f, 0.0f, 0.0f, 1.0f); } zxMath::mat3 zxMath::toMat3(zxMath::mat4 A) { return zxMath::mat3(A.m[0], A.m[1], A.m[2], A.m[4], A.m[5], A.m[6], A.m[8], A.m[9], A.m[10]); } zxMath::mat4 zxMath::toMat4(zxMath::mat2 A) { return zxMath::mat4(A.m[0], A.m[1], 0.0f, 0.0f, A.m[2], A.m[3], 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); } zxMath::mat4 zxMath::toMat4(zxMath::mat3 A) { return zxMath::mat4(A.m[0], A.m[1], A.m[2], 0.0f, A.m[3], A.m[4], A.m[5], 0.0f, A.m[6], A.m[7], A.m[8], 0.0f, 0.0f, 0.0f, 0.0f, 1.0f); } // // zxGlobal.h // #ifndef zxGlobal_h #define zxGlobal_h #include "zxWindow.h" #include <vector> struct mouse { int button; int state; int x, y; }; extern std::vector <zxWindow*> WINDOW; extern mouse MOUSE; extern float TIME; #endif // // zxGlobal.cpp // #include "zxGlobal.h" std::vector <zxWindow*> WINDOW; mouse MOUSE; float TIME;La classe zxContent costituisce una classe vuota. I suoi metodi possono essere ridefiniti per passare contenuti grafici alla finestra.
// // zxContent // #ifndef zxContent_h #define zxContent_h class zxContent { public: zxContent(); ~zxContent(); virtual void init(); virtual void display(); }; #endif // // zxContent.cpp // #include "zxContent.h" zxContent::zxContent() { } zxContent::~zxContent() { } void zxContent::init() { } void zxContent::display() { }Quindi la classe che gestisce la finestra vera e propria.
// // zxWindow.h // #ifndef zxWindow_h #define zxWindow_h #include <string> #include <gl/glew.h> #include <gl/freeglut.h> #include "zxContent.h" class zxWindow { private: static bool ini; static unsigned int ID; unsigned int id; std::string title; zxContent *content; static void display(); static void mouse(int button, int state, int x, int y); static void motion(int x, int y); static void passive(int x, int y); void create(int x, int y, unsigned int width, unsigned int height, std::string title, zxContent *content); static void init(); public: zxWindow(zxContent *content); zxWindow(int x, int y, unsigned int width, unsigned int height, std::string title, zxContent *content); zxWindow(unsigned int width, unsigned int height, zxContent *content); ~zxWindow(); unsigned int getId(); int getX(); int getY(); unsigned int getWidth(); unsigned int getHeight(); void getPosition(int (&position)[2]); void getSize(unsigned int (&size)[2]); std::string getTitle(); unsigned int getScreenWidth(); unsigned int getScreenHeight(); void getScreenSize(unsigned int (&screen)[2]); void setX(int x); void setY(int y); void setWidth(unsigned int width); void setHeight(unsigned int height); void setPosition(int x, int y); void setSize(unsigned int width, unsigned int height); void setTitle(std::string title); void setContent(zxContent *content); static void timer(int id); static void mainLoop(); }; #endif // // zxWindow.cpp // #include <iostream> #include "zxWindow.h" #include "zxGlobal.h" bool zxWindow::ini = false; zxWindow::zxWindow(zxContent *content) { this->create(0, 0, 200, 200, "window", content); } zxWindow::zxWindow(int x, int y, unsigned int width, unsigned int height, std::string title, zxContent *content) { this->create(x, y, width, height, title, content); } zxWindow::zxWindow(unsigned int width, unsigned int height, zxContent *content) { this->create(0, 0, width, height, "window", content); } zxWindow::~zxWindow() { } void zxWindow::create(int x, int y, unsigned int width, unsigned int height, std::string title, zxContent *content) { zxWindow::init(); this->content = content; WINDOW.push_back(this); this->title = title; glutInitWindowPosition(x, y); glutInitWindowSize(width, height); this->id = glutCreateWindow(title.c_str()); if(glewInit() != GLEW_OK) { std::cout << "GLEW not initialized\n"; } glutDisplayFunc(zxWindow::display); //glutIdleFunc(zxWindow::display); glutMouseFunc(zxWindow::mouse); glutMotionFunc(zxWindow::motion); glutPassiveMotionFunc(zxWindow::passive); this->content->init(); glutTimerFunc(30, this->timer, 0); } void zxWindow::init() { if(!zxWindow::ini) { int argc = 0; char **argv; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); zxWindow::ini = true; //glutLeaveMainLoop(); } } void zxWindow::display() { int id = glutGetWindow(); WINDOW[id - 1]->content->display(); } void zxWindow::mouse(int button, int state, int x, int y) { MOUSE.button = button; MOUSE.state = state; MOUSE.x = x; MOUSE.y = y; glutPostRedisplay(); } void zxWindow::motion(int x, int y) { MOUSE.x = x; MOUSE.y = y; glutPostRedisplay(); } void zxWindow::passive(int x, int y) { MOUSE.x = x; MOUSE.y = y; glutPostRedisplay(); } unsigned int zxWindow::getId() { return this->id; } int zxWindow::getX() { return glutGet(GLUT_WINDOW_X); } int zxWindow::getY() { return glutGet(GLUT_WINDOW_Y); } unsigned int zxWindow::getWidth() { return glutGet(GLUT_WINDOW_WIDTH); } unsigned int zxWindow::getHeight() { return glutGet(GLUT_WINDOW_HEIGHT); } void zxWindow::getPosition(int (&position)[2]) { position[0] = glutGet(GLUT_WINDOW_X); position[1] = glutGet(GLUT_WINDOW_Y); } void zxWindow::getSize(unsigned int (&size)[2]) { size[0] = glutGet(GLUT_WINDOW_WIDTH); size[1] = glutGet(GLUT_WINDOW_HEIGHT); } std::string zxWindow::getTitle() { return this->title; } unsigned int zxWindow::getScreenWidth() { return glutGet(GLUT_SCREEN_WIDTH); } unsigned int zxWindow::getScreenHeight() { return glutGet(GLUT_SCREEN_HEIGHT); } void zxWindow::getScreenSize(unsigned int (&screen)[2]) { screen[0] = glutGet(GLUT_SCREEN_WIDTH); screen[1] = glutGet(GLUT_SCREEN_HEIGHT); } void zxWindow::setX(int x) { } void zxWindow::setY(int y) { } void zxWindow::setWidth(unsigned int width) { } void zxWindow::setHeight(unsigned int height) { } void zxWindow::setPosition(int x, int y) { } void zxWindow::setSize(unsigned int width, unsigned int height) { } void zxWindow::setTitle(std::string title) { this->title = title; glutSetWindowTitle(title.c_str()); } void zxWindow::setContent(zxContent *content) { this->content = content; } void zxWindow::mainLoop() { glutMainLoop(); } void zxWindow::timer(int id) { glutPostRedisplay(); glutTimerFunc(30, zxWindow::timer, 0); }Infine il file main.cpp che disegna la shape.
// // main.cpp // #include <iostream> #include "zxWindow.h" #include "zxShader.h" #include "zxMath.h" #include "zxGlobal.h" zxShader *shader; GLuint VAO, VBO, EBO; float rad = .0174533; class myContent:public zxContent { public: void init() { TIME = 0; // definizione dei vertici di un pentagono regolare float ver[] = { // 3 valori per il vertice e 3 per il colore cos(0.0f * rad) * 30.0f+100, sin(0.0f * rad) * 30.0f+100, 0, 1,0,1, cos(72.0f * rad) * 30.0f+100, sin(72.0f * rad) * 30.0f+100, 0, 1,1,0, cos(144.0f * rad) * 30.0f+100, sin(144.0f * rad) * 30.0f+100, 0, 0,1,1, cos(216.0f * rad) * 30.0f+100, sin(216.0f * rad) * 30.0f+100, 0, 0,1,0, cos(288.0f * rad) * 30.0f+100, sin(288.0f * rad) * 30.0f+100, 0, 1,0,0 }; unsigned int ind[] = { 0, 1, 3, 1, 2, 3, 4, 0, 3 }; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 30, ver, GL_STATIC_DRAW); // dimensioni dell'array ver glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int) * 9, ind, GL_STATIC_DRAW); // dimensioni dell'array ind glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)0); // i primi 3 valori su 6 sono il vertice glEnableVertexAttribArray(0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void*)(3 * sizeof(float))); // i secondi 3 valori rappresentano il colore glEnableVertexAttribArray(1); shader = new zxShader(); shader->load("shaders/vert.txt", "", "shaders/frag.txt"); } void display() { unsigned int W = WINDOW[0]->getWidth(), H = WINDOW[0]->getHeight(); glViewport(0, 0, W, H); zxMath::mat4 P = zxMath::ortho(0.0f, (float)W, (float)H, 0.0f, 0.0f, 1.0f); //zxMath::mat4 P = zxMath::perspective(45.0f, (float)W / (float)H, .1f, 100.0f); //zxMath::mat4 V = zxMath::lookAt(zxMath::vec3(0,-10,0), zxMath::vec3(0,0,0), zxMath::vec3(0,0,1)); zxMath::mat4 V = zxMath::mat4(); zxMath::mat4 M = zxMath::mat4(); M = zxMath::rotate(M, TIME, zxMath::vec3(0,0,1)); zxMath::mat4 MVP = zxMath::modelViewProjection(M, V, P); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // shader->start(); shader->uniformMatrix("MVP", 1, false, MVP.m); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0); // 3 vertici * 3 triangoli shader->stop(); // TIME++; glutSwapBuffers(); } }; int main() { zxContent *content = new myContent(); zxWindow *win1 = new zxWindow(100, 100, 500, 500, "prova1", content); zxWindow *win2 = new zxWindow(150, 150, 200, 200, "prova2", content); // nelle due finestre (indipendenti) gira la stessa routine content->display zxWindow::mainLoop(); }E' possibile scaricare tutto il pacchetto dal seguente link:
Mi chiamo Cosimo Saccone e sono un programmatore napoletano di 44 anni con oltre 35 anni di esperienza nella programmazione (BASIC, Assembly). Realizzo progetti e programmi utilizzando i principali e più diffusi linguaggi (C, C++, PHP, Javascript, HTML) e software per la grafica (Photoshop, Illustrator, 3dsMax). Anche se la grafica rappresenta il mio principale settore di interesse, non disdegno il lavoro di back-end e di organizzazione dati e sono attento agli aspetti di efficienza e di risparmio delle risorse tipica della programmazione di basso livello (specie nel settore della grafica 3d). Realizzo siti internet, applicativi desktop e servizi di vario tipo. Ho una buona conoscenza della libreria OpenGL per lo sviluppo di applicazioni 3d interattive in C/C++. Cerco di adottare uno stile di programmazione fortemente ordinato e modulare. Possiedo, inoltre, una buona capacità di elaborazione della documentazione. Ho vari hobbies tra cui la pittura, la ginnastica e le lunghe passeggiate in solitudine.
Al fine di migliorare l’esperienza di navigazione sul nostro sito noi di cosimosaccone.com e i nostri partner selezionati elaboriamo i dati personali, compreso l’indirizzo IP e le pagine visitate, in relazione alla tua navigazione nei contenuti del sito, per i seguenti scopi:
Accesso alle informazioni
Dati precisi di geolocalizzazione
Misurazione del pubblico
Pubblicità e contenuti personalizzati
Ti ricordiamo che il termine cookie si riferisce a una porzione di dati inviati al tuo browser da un web server. Il cookie viene memorizzato sul tuo dispositivo e riconosciuto dal sito web che lo ha inviato in ogni navigazione successiva. Se vuoi saperne di più e compiere una scelta diversa, come il rifiuto del trattamento dei tuoi dati personali, clicca qui sulla nostra privacy policy. Potrai sempre modificare le tue scelte e impostare i singolo cookies selezionando il bottone qui sotto.
OK