Commit 4b032c7f by Diego Pérez Peña

Merge master y develop p3

parents 000430f2 a41af10a
......@@ -15,9 +15,13 @@ target_include_directories(PAG_p1 PUBLIC glad/include imgui/include )
#find_package(opengl_system)
#find_package(glfw3)
#find_package(glm)
# Then, link your executable or library with the corresponding package targets:
#target_link_libraries(PAG_p1 opengl::opengl)
#target_link_libraries(PAG_p1 glfw)
#target_link_libraries(PAG_p1 glm::glm)
#===========================================
......
......@@ -35,6 +35,11 @@ void LogWindow::render() {
ImGui::SetWindowFontScale ( 1.0f ); // Escalamos el texto si fuera necesario
// Pintamos los controles
ImGui::TextWrapped(log.c_str());
if(autoscroll) {
// Autoscroll hacia abajo
ImGui::SetScrollHereY(1.0f);
}
autoscroll = false;
}
ImGui::End();
}
......@@ -46,4 +51,5 @@ void LogWindow::render() {
*/
void LogWindow::registrarMensaje(std::string texto) {
log.append(texto).append("\n");
autoscroll = true;
}
......@@ -20,6 +20,7 @@
*/
class LogWindow: public GuiElement{
std::string log; ///< String que almacena el registro de mensajes
bool autoscroll = false; ///< Si en el siguiente render se debe hacer autoscroll hasta el final
public:
LogWindow();
virtual ~LogWindow() = default;
......
# Solución a la segunda parte de la práctica 1
# README de las prácticas de PAG
Por Diego Pérez Peña
Para la asignatura Programación de Aplicaciones Gráficas
Índice: [Práctica 1](#práctica-1) [Práctica 2](#práctica-2) [Práctica 3](#práctica-3)
# Práctica 3
Si se quiere regresar al estado de la práctica 3, hacer un git reset a la [**etiqueta p3**](https://gitlab.ujaen.es/dpp00022/PAG_p1/tree/p3).
## Respuestas a las preguntas del guión
**Q1:**
> Si redimensionas la ventana de la aplicación, verás que el triángulo no permanece igual, sino que se deforma al mismo tiempo que la ventana. ¿A qué crees que se debe este comportamiento?
**A1:**<br/>
Esto se debe a la naturaleza del renderizado de OpenGL. Como ya sabemos, en OpenGL no se renderizan ventanas, sino **"viewports"**, que son básicamente espacios reservados para que OpenGL dibuje. Una ventana puede constar solamente de un viewport, pero también puede contener espacios no OpenGL que contengan controles o cualquier otro elemento estático, e incluso varios viewport.
Sabiendo esto, la razón por la que sucede lo anteriormente descrito es porque **OpenGL siempre dibuja la imagen a renderizar en el viewport, ocupando el espacio disponible**. Hay un paso en el que se convierten las coordenadas espaciales, expresadas en el rango [-1, 1], a coordenadas viewport, en el rango [0, {w/h}], siendo w y h el ancho y alto en píxeles del viewport, respectivamente. Por tanto, **al reescalar la ventana, estamos reescalando el viewport con ella**, y por tanto, la misma imagen (nuestro triángulo) se reescala para ocupar este nuevo espacio disponible.
Como colofón, ImGui se mantiene ajeno a este comportamiento porque esta biblioteca porque esta expresa la posición y el tamaño de las ventanas en todo momento en términos de los píxeles de la ventana, y, aunque reescalemos la ventana, los píxeles siempre tendrán el mismo tamaño. La única transformación que causa cambios en el estado de las ventanas ImGui es el desplazamiento de la ventana, ya que estamos desplazando el píxel (0,0) de la ventana al hacer esto.
## Cambios
- Se agregaron las siguientes clases:
- **ShaderException**: Excepción personalizada para los Shaders. Permite especificar rápidamente qué Shader ha dado error y en qué fase del proceso se ha producido el error, además de incluir la información de error generada por OpenGL.
- Se modificaron las siguientes clases Singleton:
- **Renderer**:
- Se agregaron los atributos: `idVS`, `idFS`, `idSP`, `idVAO`, `idVBO`, `idIBO` y `idColor`.
- Se agregó el método `creaShaderProgram(.)`, que crea, carga, compila y enlaza un programa de shaders definido por un nombre.
- Se agregó el método `creaModelo()`, que crea el modelo del triángulo. En el código están incrustados los métodos para especificar la posición y el color de los vértices de forma entrelazada y no entrelazada.
- Se modificó el método `refrescar()` para activar el programa de shaders y renderizar el modelo del triángulo en la ventana.
- Se modificó el destructor para liberar los recursos asociados al Shader Program y al modelo.
- Se modificó el método `inicializar()` para activar el Multisampling.
- Se modificaron las siguientes clases:
- **LogWindow**: Ahora realiza autoscroll hasta abajo al registrar un nuevo mensaje.
- Se agregaron los siguientes archivos
- **pag03-vs.glsl**: Contiene el código fuente del Vertex Shader empleado en esta práctica, el cual lee la posición y el color de cada vértice.
- **pag03-fs.glsl**: Contiene el código fuente del Fragment Shader empleado en esta práctica, el cual devuelve el color correspondiente a cada fragmento.
- Se modificaron los siguientes archivos
- **main.cpp**:
- Se han agregado instrucciones para crear el Shader Program (con captura de excepciones) y para crear el modelo (triángulo).
- Se ha mejorado el bucle de renderizado, de forma que ahora se refresque en tiempo real.
- Se eliminó la impresión de mensajes cuando se refresca o reescala la ventana, se presiona o suelta una tecla o botón del ratón y cuando se hace scroll con la rueda del ratón.
- **CMakeLists.txt** y **conandata.yml**: Se agregó el paquete glm en Windows.
He aquí el UML de la situación actual:
![umlpracticatres.png](https://gitlab.ujaen.es/dpp00022/PAG_p1/raw/master/umlpracticatres.png)
# Práctica 2
Si se quiere regresar al estado de la práctica 2, hacer un git reset a la [**etiqueta p2**](https://gitlab.ujaen.es/dpp00022/PAG_p1/tree/p2).
## Cambios
No se especificaron los cambios en su momento, pero básicamente:
- Se agregaron las clases Singleton:
- **Renderer**: Encargada del renderizado en general de la escena
- **GUI**: Encargada de la gestión de la interfaz de usuario implementada mediante la librería Dear ImGui.
- Se agregaron las clases abstactas:
- **Listener**: Siguiendo el patrón Observador, implementa el comportamiento de una clase que escucha.
- **GuiElement**: Implementa el comportamiento de una ventana de la interfaz de usuario (entre ellas, las alertas a los listeners, siguiendo el patrón Observador).
- Se agregaron las clases:
- **BackgroundWindow**: Ventana de la GUI que contiene un selector de color que cambia el color de fondo.
- **LogWindow**: Ventana de la GUI que contiene un registro de mensajes de la aplicación,
- Se modificaron los siguientes archivos
- **main.cpp**:
- Se sustituyeron varias llamadas a OpenGL por llamadas a Renderer.
- Se eliminó "yPos" y la acción de cambiar el color de fondo al hacer scroll con el ratón.
- Se modificó el bucle de render para renderizar también la GUI.
- Se agregaron llamadas a GUI para imprimir todos los mensajes también en la ventana de log.
- Se agregó compatibilidad con ImGui en los callbacks y la liberación de recursos.
- **CMakeLists.txt**: Se agregó compatibilidad con Linux.
- Se agregó la **biblioteca Dear ImGui**, ahora se halla en la carpeta "imgui".
# Práctica 1
Si se quiere regresar al estado de la práctica 1, hacer un git reset a la [**etiqueta p1**](https://gitlab.ujaen.es/dpp00022/PAG_p1/tree/p1).
## Solución a la segunda parte de la práctica 1
La solución que propongo al problema propuesto sería llamar al método de clase `PAG::Renderer::refrescarVentana()` en la función de C llamada `refresh_window_callback()` que tenemos actualmente en el archivo `main.cpp` de nuestro proyecto de C++. Así, estaríamos encapsulando un método incompatible para la orden `glSetWindowRefreshCallback()` dentro de una función compatible como la que ya hemos mencionado.
Se puede ver que funciona perfectamente porque ya la hemos enlazado sin problemas. Al fin y al cabo, la orden `glSetWindowRefreshCallback()` solo requiere que se le pase una función de C compatible pero, más allá de eso, no comprueba el contenido de `refresh_window_callback()`, simplemente llama a su ejecución lo mismo que haría una llamada directa en el código principal, y mientras el entorno de OpenGL/C++ pueda ejecutar su contenido (cosa que evidentemente puede hacer), no debería haber traba alguna.
......
......@@ -7,17 +7,39 @@
* @brief Implementación de la clase Renderer
*/
#include <GL/gl.h>
#include "Renderer.h"
#include <cstdarg>
#include <GLFW/glfw3.h>
#include <fstream>
#include <sstream>
#include "ShaderException.h"
#include "glad/glad.h"
PAG::Renderer* PAG::Renderer::instancia = nullptr;
glm::vec3 PAG::Renderer::color_fondo = glm::vec3(0.6f, 0.6, 0.6f);
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.
......@@ -43,16 +65,27 @@ void PAG::Renderer::inicializar() {
// - 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.
glEnable ( GL_DEPTH_TEST );
glEnable ( GL_MULTISAMPLE );
}
/**
* @brief Función a llamar cuando se necesite refrescar la ventana.
*
* Esta función limpia los buffers de color y de profundidad de
* OpenGL. No intercambia los buffers.
* OpenGL y renderiza lso modelos asignados con el programa Shader
* asignado. No intercambia los buffers.
*/
void PAG::Renderer::refrescar() {
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 +98,187 @@ 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.
*/
void PAG::Renderer::creaModelo() {
GLfloat vertices[] = { -.5, -.5, 0,
.5, -.5, 0,
.0, .5, 0 };
GLfloat colores[] = { 0.980392, 0.341176, 0.043137,
0.721568, 0.690196, 0.647059,
0.568627, 0.898039, 1.0 };
GLfloat entrelazados[] = { -0.5, -0.5, 0,
0.980392, 0.341176, 0.043137,
0.5, -0.5, 0,
0.721568, 0.690196, 0.647059,
0.0, 0.5, 0,
0.568627, 0.898039, 1.0 };
GLuint indices[] = {0, 1, 2};
glGenVertexArrays(1, &idVAO);
glBindVertexArray(idVAO);
// START NO ENTRELAZADO
/*
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, &idColor);
glBindBuffer(GL_ARRAY_BUFFER, idColor);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 3*sizeof(GLfloat), nullptr);
glBufferData(GL_ARRAY_BUFFER, 9*sizeof(GLfloat), colores, GL_STATIC_DRAW);
*/
// END NO ENTRELAZADO
// START ENTRELAZADO
glGenBuffers(1, &idVBO);
glBindBuffer(GL_ARRAY_BUFFER, idVBO);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), nullptr);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6*sizeof(GLfloat), (GLvoid*)(3*sizeof(float)));
glBufferData(GL_ARRAY_BUFFER, 18*sizeof(GLfloat), entrelazados, GL_STATIC_DRAW);
// END ENTRELAZADO
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.
*
* @param t Clase de ventana que está avisando a este Listener
......
......@@ -11,6 +11,8 @@
#define PAG_P1_RENDERER_H
#include "Listener.h"
#include <glm/vec3.hpp>
#include "glad/glad.h"
#include <string>
/**
* Espacio de nombres para las prácticas de Programación de Aplicaciones
......@@ -30,14 +32,25 @@ 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
GLuint idColor = 0; // Idenfiticador del VBO de color (solo no entrelazada)
GLuint idIBO = 0; // Identificador del Index Buffer Object
public:
virtual ~Renderer();
static Renderer& getInstancia();
void inicializar();
void refrescar();
void refrescar_tamanio_framebuffer(int width, int height);
void creaShaderProgram(std::string& nombre);
void creaModelo();
void wakeUp(WindowType t, ...) override;
};
}
......
/**y
* @file ShaderException.cpp
* @author dpp00022
*
* @date 2025/08/25
*
* @brief Implementación de la clase ShaderException
*/
#include "ShaderException.h"
#include "glad/glad.h"
#include <utility>
/**
* Constructor parametrizado de la clase.
* @param type Tipo de shader que ha causado el error (*)
* @param creating Si el error ha ocurrido durante la creación o no
* @param log Descripción del error
* @note (*) Pasar en type constantes de OpenGL si es Vertex o Fragment Shader
*/
ShaderException::ShaderException(int shaderType, TipoError errorType, std::string log):
shaderType(shaderType), errorType(errorType), log(std::move(log)) {}
/**
* Constructor copia de la clase.
* @param other Excepción que se desea copiar
*/
ShaderException::ShaderException(ShaderException &other):
shaderType(other.shaderType), errorType(other.errorType), log(other.log) {}
/**
* Operador copia de la clase.
* @param other Excepción que se desea copiar
*/
ShaderException & ShaderException::operator=(ShaderException const &other) {
this->shaderType = other.shaderType;
this->errorType = other.errorType;
this->log = other.log;
return *this;
}
/**
* Devuelve un string con el log completo.
*/
std::string ShaderException::getLog() {
std::string aux = "Cannot ";
switch(errorType) {
case CREACION:
aux.append("create ");
break;
case LECTURA:
aux.append("read ");
break;
case COMPILACION:
aux.append("compile ");
break;
case ENLAZADO:
aux.append("link ");
break;
}
if(shaderType == GL_FRAGMENT_SHADER) { aux.append("fragment shader"); }
else if(shaderType == GL_VERTEX_SHADER) { aux.append("vertex shader"); }
else { aux.append("shader program"); }
aux.append(":\n").append(log).append("\n");
return aux;
}
/**
* Mét0do what() de excepción. Solo devuelve la descripción, sin la cabecera.
*/
const char * ShaderException::what() const noexcept {
return log.c_str();
}
/**
* @file ShaderException.h
* @author dpp00022
*
* @date 2025/09/25
*
* @brief Declaración de la clase ShaderException
*/
#ifndef SHADEREXCEPTION_H
#define SHADEREXCEPTION_H
#include <string>
enum TipoError {
CREACION,
LECTURA,
COMPILACION,
ENLAZADO
};
/**
* Clase que representa una excepción personalizada para manejar
* los errores que puedan suceder con los Shaders.
*/
class ShaderException: public std::exception{
int shaderType = 0; ///< Tipo de shader que ha causado el error
TipoError errorType = CREACION; ///< Si el error ha ocurrido durante la creación o no
std::string log; ///< Descripción del error
public:
ShaderException() = default;
ShaderException(int shaderType, TipoError errorType, std::string log);
ShaderException(ShaderException &other);
virtual ~ShaderException() = default;
ShaderException& operator=(ShaderException const& other);
std::string getLog();
const char * what() const noexcept override;
};
#endif //SHADEREXCEPTION_H
......@@ -3,4 +3,5 @@
requirements:
- "glfw/3.3.8"
- "opengl/system"
\ No newline at end of file
- "opengl/system"
- "glm/1.0.1"
\ No newline at end of file
......@@ -3,6 +3,7 @@
#include <GLFW/glfw3.h>
#include "GUI.h"
#include "Renderer.h"
#include "ShaderException.h"
// - Esta función callback será llamada cuando GLFW produzca algún error
void error_callback(int errno, const char* desc) {
......@@ -17,17 +18,12 @@ void error_callback(int errno, const char* desc) {
void refresh_window_callback(GLFWwindow *window) {
// Llamada al mét0do refrescar del Renderer
PAG::Renderer::getInstancia().refrescar();
std::cout << "Refresh callback called" << std::endl;
PAG::GUI::getInstancia().registrarMensaje("Refresh callback called");
}
// - Esta función callback será llamada cada vez que se cambie el tamaño
// del área de dibujo OpenGL.
void framebuffer_size_callback(GLFWwindow *window, int width, int height) {
PAG::Renderer::getInstancia().refrescar_tamanio_framebuffer(width, height);
std::cout << "Resize callback called" << std::endl;
PAG::GUI::getInstancia().registrarMensaje("Resize callback called");
}
// - Esta función callback será llamada cada vez que se pulse una tecla
......@@ -36,25 +32,15 @@ void key_callback(GLFWwindow *window, int key, int scancode, int action, int mod
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
glfwSetWindowShouldClose(window, GLFW_TRUE);
}
std::cout << "Key callback called" << std::endl;
PAG::GUI::getInstancia().registrarMensaje("Key callback called");
}
// - Esta función callback será llamada cada vez que se pulse algún botón
// del ratón sobre el área de dibujo OpenGL.
void mouse_button_callback(GLFWwindow *window, int button, int action, int mods) {
if (action == GLFW_PRESS) {
std::string aux = std::string();
aux.append("Pulsado el botón ").append(std::to_string(button));
std::cout << aux << std::endl;
PAG::GUI::getInstancia().registrarMensaje(aux);
PAG::GUI::getInstancia().callback_raton(button, true);
}
else if (action == GLFW_RELEASE) {
std::string aux = std::string();
aux.append("Soltado el botón ").append(std::to_string(button));
std::cout << aux << std::endl;
PAG::GUI::getInstancia().registrarMensaje(aux);
PAG::GUI::getInstancia().callback_raton(button, false);
}
refresh_window_callback(window);
......@@ -64,14 +50,6 @@ void mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
// del ratón sobre el área de dibujo OpenGL.
void scroll_callback(GLFWwindow *window, double xoffset, double yoffset) {
refresh_window_callback(window);
std::string aux = std::string();
aux.append("Movida la rueda del ratón ").append(std::to_string(xoffset))
.append(" unidades en horizontal y ").append(std::to_string(yoffset))
.append(" unidades en vertical.");
std::cout << aux << std::endl;
PAG::GUI::getInstancia().registrarMensaje(aux);
}
int main() {
......@@ -144,20 +122,29 @@ 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
// ventana principal deba cerrarse. Por ejemplo, si el usuario pulsa el
// botón de cerrar la ventana (la X).
while (!glfwWindowShouldClose(window)) {
PAG::GUI::getInstancia().prepararNuevoFrame();
// Renderizado de figuras OpenGL
refresh_window_callback(window);
PAG::GUI::getInstancia().renderizarNuevoFrame();
// - GLFW usa un doble buffer para que no haya parpadeo. Esta orden
// intercambia el buffer back (en el que se ha estado dibujando) por el
// que se mostraba hasta ahora (front).
glfwSwapBuffers(window);
PAG::GUI::getInstancia().prepararNuevoFrame();
// Renderizado de figuras OpenGL
PAG::GUI::getInstancia().renderizarNuevoFrame();
// - Obtiene y organiza los eventos pendientes, tales como pulsaciones de
// teclas o de ratón, etc. Siempre al final de cada iteración del ciclo
// de eventos y después de glfwSwapBuffers(window);
......
#version 410
in vec4 v_color;
layout (location = 0) out vec4 colorFragmento;
void main() {
colorFragmento = v_color;
}
#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