Refactorización completada

parent 42d23246
......@@ -23,6 +23,7 @@ ShaderWindow PAG::GUI::shader = ShaderWindow();
*/
PAG::GUI::GUI() {
background.addListener(&PAG::Renderer::getInstancia());
shader.addListener(&PAG::Renderer::getInstancia());
}
PAG::GUI::~GUI() { }
......@@ -115,3 +116,7 @@ void PAG::GUI::callback_raton(int button, bool pulsado) {
void PAG::GUI::registrarMensaje(std::string texto) {
log.registrarMensaje(texto);
}
void PAG::GUI::deleteShaders() {
shader.deleteShaders();
}
......@@ -43,6 +43,7 @@ namespace PAG {
void callback_raton(int button, bool pulsado);
void registrarMensaje(std::string texto);
void deleteShaders();
};
}
......
......@@ -17,7 +17,8 @@
* El valor es igual al número de argumentos que se pasan en la lista variable.
*/
enum WindowType {
Background = 1
Background = 1,
Shader = 2
};
/**
......
......@@ -10,9 +10,8 @@
#include "Renderer.h"
#include <cstdarg>
#include <fstream>
#include <sstream>
#include "ShaderException.h"
#include "GUI.h"
#include "glad/glad.h"
PAG::Renderer* PAG::Renderer::instancia = nullptr;
......@@ -21,15 +20,7 @@ glm::vec3 PAG::Renderer::color_fondo = glm::vec3(0.6f, 0.6, 0.6f);
PAG::Renderer::Renderer() { }
PAG::Renderer::~Renderer() {
if (idVS != 0) {
glDeleteShader(idVS);
}
if (idFS != 0) {
glDeleteShader(idFS);
}
if (idSP != 0) {
glDeleteProgram(idSP);
}
PAG::GUI::getInstancia().deleteShaders();
if (idVBO != 0) {
glDeleteBuffers(1, &idVBO);
}
......@@ -98,130 +89,6 @@ void PAG::Renderer::refrescar_tamanio_framebuffer(int width, int height) {
}
/**
* Función para crear, compilar y enlazar el shader program
* @param nombre Nombre de los archivos a cargar
* @note Se cargarán los archivos <nombre>-vs.glsl y <nombre>-fs.glsl
* @throws ShaderException Si hay errores durante creaciones, lecturas,
* compilaciones o enlazados de algún shader.
*/
void PAG::Renderer::creaShaderProgram(std::string& nombre) {
std::ifstream lectorArchivos;
// Creando VS
idVS = glCreateShader(GL_VERTEX_SHADER);
if (idVS == 0) {
throw ShaderException(GL_VERTEX_SHADER, CREACION, "");
}
// Leyendo VS
std::string nombreArchivoVS = "";
nombreArchivoVS.append(nombre).append("-vs.glsl");
lectorArchivos.open(nombreArchivoVS);
if(!lectorArchivos.is_open()) {
std::string error = "Couldn't open file ";
error.append(nombreArchivoVS);
throw ShaderException(GL_VERTEX_SHADER, LECTURA, error);
}
std::stringstream ssVS;
ssVS << lectorArchivos.rdbuf();
std::string stringVS = ssVS.str();
lectorArchivos.close();
const GLchar* fuenteVS = stringVS.c_str();
glShaderSource(idVS, 1, &fuenteVS, nullptr);
// Compilando VS
glCompileShader(idVS);
GLint resultadoCompilacion;
glGetShaderiv ( idVS, GL_COMPILE_STATUS, &resultadoCompilacion );
if ( resultadoCompilacion == GL_FALSE )
{ // Ha habido un error en la compilación.
// Para saber qué ha pasado, tenemos que recuperar el mensaje de error de OpenGL
GLint tamMsj = 0;
std::string mensaje = "";
glGetShaderiv ( idVS, GL_INFO_LOG_LENGTH, &tamMsj );
if ( tamMsj > 0 )
{ GLchar* mensajeFormatoC = new GLchar[tamMsj];
GLint datosEscritos = 0;
glGetShaderInfoLog ( idVS, tamMsj, &datosEscritos, mensajeFormatoC );
mensaje.assign ( mensajeFormatoC );
delete[] mensajeFormatoC;
mensajeFormatoC = nullptr;
throw ShaderException(GL_VERTEX_SHADER, LECTURA, mensaje);
}
}
// Creando FS
idFS = glCreateShader(GL_FRAGMENT_SHADER);
if (idFS == 0) {
throw ShaderException(GL_FRAGMENT_SHADER, CREACION, "");
}
// Leyendo FS
std::string nombreArchivoFS = "./";
nombreArchivoFS.append(nombre).append("-fs.glsl");
lectorArchivos.open(nombreArchivoFS);
if(!lectorArchivos.is_open()) {
std::string error = "Couldn't open file ";
error.append(nombreArchivoFS);
throw ShaderException(GL_FRAGMENT_SHADER, LECTURA, error);
}
std::stringstream ssFS;
ssFS << lectorArchivos.rdbuf();
std::string stringFS = ssFS.str();
lectorArchivos.close();
const GLchar* fuenteFS = stringFS.c_str();
glShaderSource(idFS, 1, &fuenteFS, nullptr);
// Compilando FS
glCompileShader(idFS);
glGetShaderiv ( idFS, GL_COMPILE_STATUS, &resultadoCompilacion );
if ( resultadoCompilacion == GL_FALSE )
{ // Ha habido un error en la compilación.
// Para saber qué ha pasado, tenemos que recuperar el mensaje de error de OpenGL
GLint tamMsj = 0;
std::string mensaje = "";
glGetShaderiv ( idFS, GL_INFO_LOG_LENGTH, &tamMsj );
if ( tamMsj > 0 )
{ GLchar* mensajeFormatoC = new GLchar[tamMsj];
GLint datosEscritos = 0;
glGetShaderInfoLog ( idFS, tamMsj, &datosEscritos, mensajeFormatoC );
mensaje.assign ( mensajeFormatoC );
delete[] mensajeFormatoC;
mensajeFormatoC = nullptr;
throw ShaderException(GL_FRAGMENT_SHADER, LECTURA, mensaje);
}
}
// Creando SP
idSP = glCreateProgram();
if(idSP == 0) {
throw ShaderException(0, CREACION, "");
}
glAttachShader(idSP, idVS);
glAttachShader(idSP, idFS);
// Enlazando SP
glLinkProgram(idSP);
GLint resultadoEnlazado = 0;
glGetProgramiv ( idSP, GL_LINK_STATUS, &resultadoEnlazado );
if ( resultadoEnlazado == GL_FALSE )
{ // Ha habido un error y hay que recuperar su descripción, para saber qué ha pasado
GLint tamMsj = 0;
std::string mensaje = "";
glGetProgramiv ( idSP, GL_INFO_LOG_LENGTH, &tamMsj );
if ( tamMsj > 0 )
{ GLchar* mensajeFormatoC = new GLchar[tamMsj];
GLint datosEscritos = 0;
glGetProgramInfoLog ( idSP, tamMsj, &datosEscritos, mensajeFormatoC );
mensaje.assign ( mensajeFormatoC );
delete[] mensajeFormatoC;
mensajeFormatoC = nullptr;
throw ShaderException(0, ENLAZADO, mensaje);
}
}
}
/**
* Función para crear el VAO para el modelo a renderizar.
* @note Está implementado a nivel de código con dos modos:
* Entrelazado y no entrelazado. Ambas son equivalentes.
......@@ -288,12 +155,19 @@ void PAG::Renderer::wakeUp(WindowType t, ...) {
switch (t) {
case Background: {
std::va_list args;
va_start(args, t);
va_start(args, 1);
color_fondo = *(va_arg(args, glm::vec3*));
va_end(args);
glClearColor(color_fondo.r, color_fondo.g, color_fondo.b, 1.0);
break;
}
case Shader: {
std::va_list args;
va_start(args, 1);
idSP = *(va_arg(args, GLuint*));
va_end(args);
break;
}
}
}
......@@ -32,8 +32,6 @@ namespace PAG {
static glm::vec3 color_fondo;
Renderer();
GLuint idVS = 0; // Identificador del Vertex Shader
GLuint idFS = 0; // Identificador del Fragment Shader
GLuint idSP = 0; // Identificador del Shader Program
GLuint idVAO = 0; // Identificador del Vertex Array Object
GLuint idVBO = 0; // Identificador del Vertex Buffer Object
......
......@@ -12,7 +12,14 @@
#include "GUI.h"
#include "ShaderException.h"
bool ShaderWindow::loadShaders() {
/**
* Función para crear, compilar y enlazar el shader program
* @param nombre Nombre de los archivos a cargar
* @note Se cargarán los archivos <nombre>-vs.glsl y <nombre>-fs.glsl
* @throws ShaderException Si hay errores durante creaciones, lecturas,
* compilaciones o enlazados de algún shader.
*/
void ShaderWindow::loadShaders() {
GLuint oldVS = idVS, oldFS = idFS, oldSP = idSP;
std::ifstream lectorArchivos;
......@@ -170,7 +177,9 @@ void ShaderWindow::restoreShader(GLuint& var, GLuint oldId) {
ShaderWindow::ShaderWindow(): currentlyLoaded("NINGUNO"), idVS(0), idFS(0), idSP(0) {}
void ShaderWindow::warnListeners() {
for(int i = 0; i<listeners.size(); i++) {
listeners[i]->wakeUp(Shader, &idSP);
}
}
void ShaderWindow::render() {
......@@ -183,6 +192,7 @@ void ShaderWindow::render() {
if(ImGui::Button("Load")) {
try {
loadShaders();
currentlyLoaded = name;
warnListeners();
} catch(ShaderException ex) {
PAG::GUI::getInstancia().registrarMensaje(ex.getLog());
......@@ -193,3 +203,18 @@ void ShaderWindow::render() {
ImGui::End();
}
void ShaderWindow::deleteShaders() {
if(idVS != 0) {
glDeleteShader(idVS);
idVS = 0;
}
if(idFS != 0) {
glDeleteShader(idFS);
idFS = 0;
}
if(idSP != 0) {
glDeleteProgram(idSP);
idSP = 0;
}
}
......@@ -12,19 +12,24 @@
class ShaderWindow: public GuiElement {
std::string name;
std::string currentlyLoaded;
GLuint idVS;
GLuint idFS;
GLuint idSP;
bool loadShaders();
std::string name; // Texto actualmente en la caja de input
std::string currentlyLoaded; // Nombre del último shader correctamente cargado
GLuint idVS; // Identificador del Vertex Shader
GLuint idFS; // Identificador del Fragment Shader
GLuint idSP; // Identificador del Shader Program
void loadShaders();
void restoreShader(GLuint& var, GLuint oldId);
public:
ShaderWindow();
virtual ~ShaderWindow() = default;
void warnListeners() override;
void render() override;
void deleteShaders();
};
......
......@@ -122,13 +122,6 @@ int main() {
PAG::GUI::getInstancia().registrarMensaje(std::string((const char*)glGetString ( GL_VERSION )));
PAG::GUI::getInstancia().registrarMensaje(std::string((const char*)glGetString ( GL_SHADING_LANGUAGE_VERSION )));
try {
std::string nombre = "pag03";
PAG::Renderer::getInstancia().creaShaderProgram(nombre);
}catch(ShaderException e) {
PAG::GUI::getInstancia().registrarMensaje(e.getLog());
}
PAG::Renderer::getInstancia().creaModelo();
// - Ciclo de eventos de la aplicación. La condición de parada es que la
......
#version 410
in vec4 v_color;
layout (location = 0) out vec4 colorFragmento;
void main() {
colorFragmento = vec4(0.5, 0.5, 0.5, 1.0);
}
#version 410
layout (location = 0) in vec3 posicion;
layout (location = 1) in vec3 color;
out vec4 v_color;
void main() {
v_color = vec4(color, 1.0);
gl_Position = vec4 ( posicion, 1 );
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment