//
// 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;
layout (location = 2) in vec2 aNormal;
out vec3 color;
uniform mat4 mvp;
void main()
{
color = aColor;
gl_Position = mvp * vec4(aPos.x, aPos.y, aPos.z, 1.0);
}
//
//
//
#version 330 core
out vec4 FragColor;
in vec3 color;
void main()
{
FragColor = vec4(color, 1.0f);
}
Infine il file main.cpp che disegna la shape.
//
// main.cpp
//
#include "zxShader.h"
#include <GL/freeglut.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <iostream>
zxShader sha;
unsigned int VBO, EBO, VAO;
float vertices[] = {
0,0,0, 1,0,0, 1,1,0,
0,5,0, 0,1,0, 1,0,0,
5,0,0, 0,0,1, 0,0,0,
5,5,0, 1,1,0, 0,1,0
};
unsigned int indices[] = {
0, 2, 1,
1, 2, 3
};
void axis()
{
glBegin(GL_LINES);
glColor3f(1,0,0);
glVertex3i(0,0,0);
glVertex3i(100,0,0);
glColor3f(0,1,0);
glVertex3i(0,0,0);
glVertex3i(0,100,0);
glColor3f(0,0,1);
glVertex3i(0,0,0);
glVertex3i(0,0,100);
glEnd();
}
void display()
{
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
float W = glutGet(GLUT_WINDOW_WIDTH);
float H = glutGet(GLUT_WINDOW_HEIGHT);
glm::mat4 p = glm::perspective(glm::radians(60.0f), W / H, 0.1f, 100.0f);
glm::mat4 v = glm::lookAt(glm::vec3(0, 0, 10), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
glm::mat4 m = glm::mat4(1.0f);
glm::mat4 mvp = p * v * m;
//glLoadIdentity(); glMultMatrixf(&mvp[0][0]);
sha.start();
sha.uniformMatrix("mvp", 1, false, &mvp[0][0]);
axis();
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
sha.end();
glutSwapBuffers();
}
void elementArrayBuffer()
{
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 9 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(400, 300);
glutCreateWindow("window");
sha.load("shaders/vert.txt", "", "shaders/frag.txt");
elementArrayBuffer();
glutDisplayFunc(display);
glEnable(GL_CULL_FACE);
//glDeleteVertexArrays(1, &VAO);
//glDeleteBuffers(1, &VBO);
//glDeleteBuffers(1, &EBO);
glutMainLoop();
}
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