ok

img

Triangolo GLSL

Definiamo prima i file per gli shaders:
//
// 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.
Nello script è esemplificato come si usano VAO, VBO, glDrawElements e attributi.
Il VAO è una sorta di contenitore generale che permette di raggruppare vari VBO e inviarli al vertex shader.
Gli attributi permettono di distinguere i vari gruppi di dati (vertici, colori, texture, normali, ecc) e identificarli nel vertex shader.
//
// 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();
}

Biografia

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.

facebook instagram youtube
HTML5 Template create by Cosimo Saccone 2022

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