Guión implementado, ejercicio 2 en proceso

parent 058cdcb3
Showing with 172 additions and 4 deletions
...@@ -7,17 +7,37 @@ ...@@ -7,17 +7,37 @@
* @brief Implementación de la clase Renderer * @brief Implementación de la clase Renderer
*/ */
#include <GL/gl.h>
#include "Renderer.h" #include "Renderer.h"
#include <cstdarg> #include <cstdarg>
#include <GLFW/glfw3.h> #include <iostream>
#include <string>
#include "glad/glad.h"
PAG::Renderer* PAG::Renderer::instancia = nullptr; PAG::Renderer* PAG::Renderer::instancia = nullptr;
glm::vec3 PAG::Renderer::color_fondo = glm::vec3(0.6f, 0.6, 0.6f); glm::vec3 PAG::Renderer::color_fondo = glm::vec3(0.6f, 0.6, 0.6f);
PAG::Renderer::Renderer() { } PAG::Renderer::Renderer() { }
PAG::Renderer::~Renderer() { } PAG::Renderer::~Renderer() {
if (idVS != 0) {
glDeleteShader(idVS);
}
if (idFS != 0) {
glDeleteShader(idFS);
}
if (idSP != 0) {
glDeleteProgram(idSP);
}
if (idVBO != 0) {
glDeleteBuffers(1, &idVBO);
}
if (idIBO != 0) {
glDeleteBuffers(1, &idIBO);
}
if (idVAO != 0) {
glDeleteVertexArrays(1, &idVAO);
}
}
/** /**
* Devuelve la instancia única de la clase. * Devuelve la instancia única de la clase.
...@@ -43,6 +63,7 @@ void PAG::Renderer::inicializar() { ...@@ -43,6 +63,7 @@ void PAG::Renderer::inicializar() {
// - Le decimos a OpenGL que tenga en cuenta la profundidad a la hora de dibujar. // - Le decimos a OpenGL que tenga en cuenta la profundidad a la hora de dibujar.
// No tiene por qué ejecutarse en cada paso por el ciclo de eventos. // No tiene por qué ejecutarse en cada paso por el ciclo de eventos.
glEnable ( GL_DEPTH_TEST ); glEnable ( GL_DEPTH_TEST );
glEnable ( GL_MULTISAMPLE );
} }
/** /**
...@@ -53,6 +74,15 @@ void PAG::Renderer::inicializar() { ...@@ -53,6 +74,15 @@ void PAG::Renderer::inicializar() {
*/ */
void PAG::Renderer::refrescar() { void PAG::Renderer::refrescar() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Activar geometría y shader program
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glUseProgram(idSP);
// Iniciar el rendering
glBindVertexArray(idVAO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idIBO);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_INT, nullptr);
} }
/** /**
...@@ -65,6 +95,131 @@ void PAG::Renderer::refrescar_tamanio_framebuffer(int width, int height) { ...@@ -65,6 +95,131 @@ void PAG::Renderer::refrescar_tamanio_framebuffer(int width, int height) {
} }
/** /**
* Función para crear, compilar y enlazar el shader program
* @note No se incluye ninguna comprobación de errores
*/
void PAG::Renderer::creaShaderProgram() {
std::string miVertexShader =
"#version 410\n"
"layout (location = 0) in vec3 posicion;\n"
"void main()\n"
"{ gl_Position = vec4 ( posicion, 1 );\n"
"}\n";
std::string miFragmentShader =
"#version 410\n"
"out vec4 colorFragmento;\n"
"void main()\n"
"{ colorFragmento = vec4 ( 1.0, .4, .2, 1.0 );\n"
"}\n";
idVS = glCreateShader(GL_VERTEX_SHADER);
if (idVS == 0) {
std::cout << "Cannot create vertex shader object." << std::endl;
return;
}
const GLchar* fuenteVS = miVertexShader.c_str();
glShaderSource(idVS, 1, &fuenteVS, nullptr);
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 std::runtime_error(mensaje);
}
}
idFS = glCreateShader(GL_FRAGMENT_SHADER);
if (idFS == 0) {
std::cout << "Cannot create fragment shader object." << std::endl;
// TODO: Cambiar por excepción
return;
}
const GLchar* fuenteFS = miFragmentShader.c_str();
glShaderSource(idFS, 1, &fuenteFS, nullptr);
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 std::runtime_error(mensaje);
}
}
idSP = glCreateProgram();
if(idSP == 0) {
std::cout << "Cannot create shader program" << std::endl;
return;
}
glAttachShader(idSP, idVS);
glAttachShader(idSP, idFS);
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;
std::cout << "Cannot link shader program" << std::endl;
std::cout << mensaje << std::endl;
}
}
}
/**
* Función para crear el VAO para el modelo a renderizar
* @note No se incluye ninguna comprobación de errores
*/
void PAG::Renderer::creaModelo() {
GLfloat vertices[] = { -.5, -.5, 0,
.5, -.5, 0,
.0, .5, 0 };
GLuint indices[] = {0, 1, 2};
glGenVertexArrays(1, &idVAO);
glBindVertexArray(idVAO);
glGenBuffers(1, &idVBO);
glBindBuffer(GL_ARRAY_BUFFER, idVBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), nullptr);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &idIBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, idIBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, 3*sizeof(GLuint), indices, GL_STATIC_DRAW);
}
/**
* Función que implementa el mét0do de actualización del Renderer. * Función que implementa el mét0do de actualización del Renderer.
* *
* @param t Clase de ventana que está avisando a este Listener * @param t Clase de ventana que está avisando a este Listener
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define PAG_P1_RENDERER_H #define PAG_P1_RENDERER_H
#include "Listener.h" #include "Listener.h"
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include "glad/glad.h"
/** /**
* Espacio de nombres para las prácticas de Programación de Aplicaciones * Espacio de nombres para las prácticas de Programación de Aplicaciones
...@@ -30,14 +31,24 @@ namespace PAG { ...@@ -30,14 +31,24 @@ namespace PAG {
static glm::vec3 color_fondo; static glm::vec3 color_fondo;
Renderer(); 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
GLuint idIBO = 0; // Identificador del Index Buffer Object
public: public:
virtual ~Renderer(); virtual ~Renderer();
static Renderer& getInstancia(); static Renderer& getInstancia();
void inicializar(); void inicializar();
void refrescar(); void refrescar();
void refrescar_tamanio_framebuffer(int width, int height); void refrescar_tamanio_framebuffer(int width, int height);
void creaShaderProgram();
void creaModelo();
void wakeUp(WindowType t, ...) override; void wakeUp(WindowType t, ...) override;
}; };
} }
......
...@@ -120,6 +120,8 @@ int main() { ...@@ -120,6 +120,8 @@ int main() {
PAG::GUI::getInstancia().registrarMensaje(std::string((const char*)glGetString ( GL_VERSION ))); PAG::GUI::getInstancia().registrarMensaje(std::string((const char*)glGetString ( GL_VERSION )));
PAG::GUI::getInstancia().registrarMensaje(std::string((const char*)glGetString ( GL_SHADING_LANGUAGE_VERSION ))); PAG::GUI::getInstancia().registrarMensaje(std::string((const char*)glGetString ( GL_SHADING_LANGUAGE_VERSION )));
PAG::Renderer::getInstancia().creaShaderProgram();
PAG::Renderer::getInstancia().creaModelo();
// - Ciclo de eventos de la aplicación. La condición de parada es que la // - Ciclo de eventos de la aplicación. La condición de parada es que la
// ventana principal deba cerrarse. Por ejemplo, si el usuario pulsa el // ventana principal deba cerrarse. Por ejemplo, si el usuario pulsa el
......
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