0% found this document useful (0 votes)
104 views

Laboratorio #8 - OpenGL - Programacion Grafica 2024

Uploaded by

Eddy Rivas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
104 views

Laboratorio #8 - OpenGL - Programacion Grafica 2024

Uploaded by

Eddy Rivas
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 14

En este laboratorio se incorpora el uso de la vista de la cámara a un modelo 3D.

Además, se agrega la
manipulación del teclado, así como el mouse para la manipulación de la cámara, la cual básicamente
representa el eje Z. Quedando el proyecto en Visual Community de la siguiente manera:
Para este laboratorio, los siguientes archivos fueron agregados y Main.cpp fue modificado para la
interacción de la camera por medio de teclado primeramente y luego la incorporación del mouse.

default.vert
#version 330 core

// Positions/Coordinates
layout (location = 0) in vec3 aPos;
// Colors
layout (location = 1) in vec3 aColor;
// Texture Coordinates
layout (location = 2) in vec2 aTex;

// Outputs the color for the Fragment Shader


out vec3 color;
// Outputs the texture coordinates to the fragment shader
out vec2 texCoord;

uniform mat4 camMatrix;

void main()
{
// Outputs the positions/coordinates of all vertices
gl_Position = camMatrix * vec4(aPos, 1.0);
// Assigns the colors from the Vertex Data to "color"
color = aColor;
// Assigns the texture coordinates from the Vertex Data to "texCoord"
texCoord = aTex;
}

Camera.h
#ifndef CAMERA_CLASS_H
#define CAMERA_CLASS_H

#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<glm/glm.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>
#include<glm/gtx/rotate_vector.hpp>
#include<glm/gtx/vector_angle.hpp>

#include"shaderClass.h"

class Camera
{
public:
glm::vec3 Position;
glm::vec3 Orientation = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 Up = glm::vec3(0.0f, 1.0f, 0.0f);

int width;
int height;

float speed = 0.1f;


float sensitivity = 100.0f;

Camera(int width, int height, glm::vec3 position);

void Matrix(float FOVdeg, float nearPlane, float farPlane, Shader& shader,


const char* uniform);
void Inputs(GLFWwindow* window);

};

#endif // !CAMERA_CLASS_H

Camera.cpp
#include"Camara.h"

Camera::Camera(int width, int height, glm::vec3 position)


{
Camera::width = width;
Camera::height = height;
Position = position;
}

void Camera::Matrix(float FOVdeg, float nearPlane, float farPlane, Shader& shader, const
char* uniform)
{
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);

view = glm::lookAt(Position, Position + Orientation, Up);


projection = glm::perspective(glm::radians(FOVdeg), (float)(width / height),
nearPlane, farPlane);

glUniformMatrix4fv(glGetUniformLocation(shader.ID, uniform), 1, GL_FALSE,


glm::value_ptr(projection * view));
}

void Camera::Inputs(GLFWwindow* window)


{
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
{
Position += speed * Orientation;
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
{
Position += speed * glm::normalize(glm::cross(Orientation, Up));
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
{
Position += speed * -Orientation;
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
{
Position -= speed * glm::normalize(glm::cross(Orientation, Up));
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
{
Position += speed * Up;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
{
Position += speed * -Up;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
{
speed= 0.4f;
}
else if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_RELEASE)
{
speed = 0.1f;
}
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
{
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);

double mouseX;
double mouseY;
glfwGetCursorPos(window, &mouseX, &mouseY);

}
else if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_RELEASE)
{
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}

IMPORTANTE: CADA CAPTURA DE PANTALLA REPRESENTA EL MOVIMIENTO PRESIONANDO LAS TECLAS “A,
S,D,W,CONTROL IZQUIERDO, BARRA ESPACIADORA”
Si al archivo Camera.cpp le agregamos la funcionalidad del uso del mouse para la manipulación de la
cámara que representa el eje z para los ojos del usuario, nos quedaría de la siguiente manera:

Camera.cpp
#include"Camara.h"

Camera::Camera(int width, int height, glm::vec3 position)


{
Camera::width = width;
Camera::height = height;
Position = position;
}

void Camera::Matrix(float FOVdeg, float nearPlane, float farPlane, Shader& shader, const
char* uniform)
{
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);

view = glm::lookAt(Position, Position + Orientation, Up);


projection = glm::perspective(glm::radians(FOVdeg), (float)(width / height),
nearPlane, farPlane);

glUniformMatrix4fv(glGetUniformLocation(shader.ID, uniform), 1, GL_FALSE,


glm::value_ptr(projection * view));
}

void Camera::Inputs(GLFWwindow* window)


{
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
{
Position += speed * Orientation;
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
{
Position += speed * glm::normalize(glm::cross(Orientation, Up));
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
{
Position += speed * -Orientation;
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
{
Position -= speed * glm::normalize(glm::cross(Orientation, Up));
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
{
Position += speed * Up;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
{
Position += speed * -Up;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
{
speed= 0.4f;
}
else if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_RELEASE)
{
speed = 0.1f;
}
if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
{
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);

double mouseX;
double mouseY;
glfwGetCursorPos(window, &mouseX, &mouseY);

float rotx = sensitivity * (float)(mouseY - (height / 2)) / height;


float roty = sensitivity * (float)(mouseX - (height / 2)) / height;

glm::vec3 newOrientation = glm::rotate(Orientation, glm::radians(-rotx),


glm::normalize(glm::cross(Orientation, Up)));

if (!((glm::angle(newOrientation, Up) <= glm::radians(5.0f)) or


(glm::angle(newOrientation, -Up) <= glm::radians(5.0f))))
{
Orientation = newOrientation;
}

Orientation = glm::rotate(Orientation, glm::radians(-roty), Up);

glfwSetCursorPos(window, (width / 2), (height / 2));

}
else if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_RELEASE)
{
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
}

Por lo tanto, agregando la función “clic” para posicionar el cursor del mouse en la ventana, los archivos
Camara.h y Camera.cpp quedan finalmente de la siguiente manera.

Camara.h
#ifndef CAMERA_CLASS_H
#define CAMERA_CLASS_H

#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<glm/glm.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>
#include<glm/gtx/rotate_vector.hpp>
#include<glm/gtx/vector_angle.hpp>

#include"shaderClass.h"

class Camera
{
public:
// Stores the main vectors of the camera
glm::vec3 Position;
glm::vec3 Orientation = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 Up = glm::vec3(0.0f, 1.0f, 0.0f);

// Prevents the camera from jumping around when first clicking left click
bool firstClick = true;

// Stores the width and height of the window


int width;
int height;

// Adjust the speed of the camera and it's sensitivity when looking around
float speed = 0.1f;
float sensitivity = 100.0f;

// Camera constructor to set up initial values


Camera(int width, int height, glm::vec3 position);

// Updates and exports the camera matrix to the Vertex Shader


void Matrix(float FOVdeg, float nearPlane, float farPlane, Shader& shader, const
char* uniform);
// Handles camera inputs
void Inputs(GLFWwindow* window);
};
#endif

Camera.cpp

#include"Camara.h"

Camera::Camera(int width, int height, glm::vec3 position)


{
Camera::width = width;
Camera::height = height;
Position = position;
}

void Camera::Matrix(float FOVdeg, float nearPlane, float farPlane, Shader& shader, const
char* uniform)
{
// Initializes matrices since otherwise they will be the null matrix
glm::mat4 view = glm::mat4(1.0f);
glm::mat4 projection = glm::mat4(1.0f);

// Makes camera look in the right direction from the right position
view = glm::lookAt(Position, Position + Orientation, Up);
// Adds perspective to the scene
projection = glm::perspective(glm::radians(FOVdeg), (float)width / height,
nearPlane, farPlane);

// Exports the camera matrix to the Vertex Shader


glUniformMatrix4fv(glGetUniformLocation(shader.ID, uniform), 1, GL_FALSE,
glm::value_ptr(projection * view));
}

void Camera::Inputs(GLFWwindow* window)


{
// Handles key inputs
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
{
Position += speed * Orientation;
}
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
{
Position += speed * -glm::normalize(glm::cross(Orientation, Up));
}
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
{
Position += speed * -Orientation;
}
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
{
Position += speed * glm::normalize(glm::cross(Orientation, Up));
}
if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS)
{
Position += speed * Up;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS)
{
Position += speed * -Up;
}
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS)
{
speed = 0.4f;
}
else if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_RELEASE)
{
speed = 0.1f;
}

// Handles mouse inputs


if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS)
{
// Hides mouse cursor
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);

// Prevents camera from jumping on the first click


if (firstClick)
{
glfwSetCursorPos(window, (width / 2), (height / 2));
firstClick = false;
}

// Stores the coordinates of the cursor


double mouseX;
double mouseY;
// Fetches the coordinates of the cursor
glfwGetCursorPos(window, &mouseX, &mouseY);

// Normalizes and shifts the coordinates of the cursor such that they begin
in the middle of the screen
// and then "transforms" them into degrees
float rotX = sensitivity * (float)(mouseY - (height / 2)) / height;
float rotY = sensitivity * (float)(mouseX - (width / 2)) / width;

// Calculates upcoming vertical change in the Orientation


glm::vec3 newOrientation = glm::rotate(Orientation, glm::radians(-rotX),
glm::normalize(glm::cross(Orientation, Up)));

// Decides whether or not the next vertical Orientation is legal or not


if (abs(glm::angle(newOrientation, Up) - glm::radians(90.0f)) <=
glm::radians(85.0f))
{
Orientation = newOrientation;
}

// Rotates the Orientation left and right


Orientation = glm::rotate(Orientation, glm::radians(-rotY), Up);

// Sets mouse cursor to the middle of the screen so that it doesn't end up
roaming around
glfwSetCursorPos(window, (width / 2), (height / 2));
}
else if (glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT) == GLFW_RELEASE)
{
// Unhides cursor since camera is not looking around anymore
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
// Makes sure the next time the camera looks around it doesn't jump
firstClick = true;
}
}

Main.cpp
#include<iostream>
#include<glad/glad.h>
#include<GLFW/glfw3.h>
#include<stb/stb_image.h>
#include<glm/glm.hpp>
#include<glm/gtc/matrix_transform.hpp>
#include<glm/gtc/type_ptr.hpp>

#include"Texture.h"
#include"shaderClass.h"
#include"VAO.h"
#include"VBO.h"
#include"EBO.h"
#include"Camara.h"

const unsigned int width = 800;


const unsigned int height = 800;

//Coordenadas de Vertices
GLfloat vertices[] =
{
// COORDENADAS COLORES COORDENADAS
PARA LA TEXTURE
-0.5f, 0.0f, 0.5f, 0.83f, 0.70f, 0.44f, 0.0f, 0.0f,
-0.5f, 0.0f, -0.5f, 0.83f, 0.70f, 0.44f, 5.0f, 0.0f,
0.5f, 0.0f, -0.5f, 0.83f, 0.70f, 0.44f, 0.0f, 0.0f,
0.5f, 0.0f, 0.5f, 0.83f, 0.70f, 0.44f, 5.0f, 0.0f,
0.0f, 0.8f, 0.0f, 0.92f, 0.86f, 0.76f, 2.5f, 5.0f
};

// Indices for vertices order


GLuint indices[] =
{
0, 1, 2,
0, 2, 3,
0, 1, 4,
1, 2, 4,
2, 3, 4,
3, 0, 4

};

int main()
{
// Initialize GLFW
glfwInit();

// Tell GLFW what version of OpenGL we are using


// In this case we are using OpenGL 3.3
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
// Tell GLFW we are using the CORE profile
// So that means we only have the modern functions
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

// Create a GLFWwindow object of 800 by 800 pixels


GLFWwindow* window = glfwCreateWindow(width, height, "Incorporando la
funcionalidad de la Camara en OpenGL", NULL, NULL);
// Error check if the window fails to create
if (window == NULL)
{
std::cout << "Failed to create GLFW window" << std::endl;
glfwTerminate();
return -1;
}
// Introduce the window into the current context
glfwMakeContextCurrent(window);

//Load GLAD so it configures OpenGL


gladLoadGL();
// Specify the viewport of OpenGL in the Window
// In this case the viewport goes from x = 0, y = 0, to x = 800, y = 800
glViewport(0, 0, width, height);
// Generates Shader object using shaders defualt.vert and default.frag
Shader shaderProgram("default.vert", "default.frag");

// Generates Vertex Array Object and binds it


VAO VAO1;
VAO1.Bind();

// Generates Vertex Buffer Object and links it to vertices


VBO VBO1(vertices, sizeof(vertices));
// Generates Element Buffer Object and links it to indices
EBO EBO1(indices, sizeof(indices));

// Links VBO attributes such as coordinates and colors to VAO


VAO1.LinkAttrib(VBO1, 0, 3, GL_FLOAT, 8 * sizeof(float), (void*)0);
VAO1.LinkAttrib(VBO1, 1, 3, GL_FLOAT, 8 * sizeof(float), (void*)(3 *
sizeof(float)));
VAO1.LinkAttrib(VBO1, 2, 2, GL_FLOAT, 8 * sizeof(float), (void*)(6 *
sizeof(float)));

// Unbind all to prevent accidentally modifying them


VAO1.Unbind();
VBO1.Unbind();
EBO1.Unbind();

//Gets ID of uniform called "scale"


//GLuint uniID = glGetUniformLocation(shaderProgram.ID, "scale");

//Texture

int widthImg, heightImg, numColCh;


stbi_set_flip_vertically_on_load(true);
unsigned char* bytes = stbi_load("dog.png", &widthImg, &heightImg, &numColCh, 0);
//Texture dog("dog.png", GL_TEXTURE_2D, GL_TEXTURE0, GL_RGBA, GL_UNSIGNED_BYTE);
//dog.texUnit(shaderProgram, "tex0", 0);

GLuint texture;
glGenTextures(1, &texture);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, texture);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);


glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

//Para ubicar la textura


glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, widthImg, heightImg, 0, GL_RGB,
GL_UNSIGNED_BYTE, bytes);
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB,
GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);

//stbi_image_free(bytes);
glBindTexture(GL_TEXTURE_2D, 0);

GLuint tex0Uni = glGetUniformLocation(shaderProgram.ID, "tex0");


shaderProgram.Activate();
glUniform1i(tex0Uni, 0);

//Variables para controlar la rotacion


//float rotation = 0.0f;
//double prevTime = glfwGetTime();

glEnable(GL_DEPTH_TEST);

Camera camera(width, height, glm::vec3(0.0f, 0.0f, 2.0f));

// Main while loop


while (!glfwWindowShouldClose(window))
{
// Specify the color of the background
glClearColor(0.07f, 0.13f, 0.17f, 1.0f);
// Clean the back buffer and assign the new color to it
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
// Tell OpenGL which Shader Program we want to use
shaderProgram.Activate();

camera.Inputs(window);
camera.Matrix(45.0f, 0.1f, 100.0f, shaderProgram, "camMatrix");

//Control de la Rotation de la Piramide con la textura incorporada por


medio de la funcion del tiempo.
//double crntTime = glfwGetTime();
//if (crntTime - prevTime >= 1/60)
//{

//rotation += 0.5f;
//prevTime = crntTime;

//}

//Inicializacion de las matrices para ser utilizadas


//glm::mat4 model = glm::mat4(1.0f);
//glm::mat4 view = glm::mat4(1.0f);
//glm::mat4 proj = glm::mat4(1.0f);

//Asignamos diferentes transformaciones a las matrices que tenemos


previamente declaradas
//Para controlar la rotacion de la piramide
//model = glm::rotate(model, glm::radians(rotation), glm::vec3(0.0f, 1.0f,
0.0f));

//Para establecer la matriz de traslacion


//view = glm::translate(view, glm::vec3(0.0f, -0.5f, -2.0f));

//Para establecer la proyeccion en perspectiva


//proj = glm::perspective(glm::radians(45.05f), (float)(width / height),
0.1f, 100.0f);//Posicion de la Camara

//Entradas de las matrices para ser usadas en el Vertex Shader


//int modelLoc = glGetUniformLocation(shaderProgram.ID, "model");
//glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));

//int viewLoc = glGetUniformLocation(shaderProgram.ID, "view");


//glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));

//int projLoc = glGetUniformLocation(shaderProgram.ID, "proj");


//glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(proj));

// Assigns a value to the uniform


shaderProgram.Activate();
//Assigns a value to the uniform
//glUniform1f(uniID, 0.5f);
glBindTexture(GL_TEXTURE_2D, texture);
// Bind the VAO so OpenGL knows to use it
VAO1.Bind();
// Draw primitives, number of indices, datatype of indices, index of
indices
glDrawElements(GL_TRIANGLES, sizeof(indices)/sizeof(int), GL_UNSIGNED_INT,
0);
// Swap the back buffer with the front buffer
glfwSwapBuffers(window);
// Take care of all GLFW events
glfwPollEvents();
}

// Delete all the objects we've created


VAO1.Delete();
VBO1.Delete();
EBO1.Delete();
glDeleteTextures(1, &texture);
shaderProgram.Delete();
// Delete window before ending the program
glfwDestroyWindow(window);
// Terminate GLFW before ending the program
glfwTerminate();
return 0;
}

You might also like