protected:
const float cameraSpeedFactor = 2.5f;
const float mouseSensitivity = 0.1f;
// Perspective properties
float zNear;
float zFar;
float FoVy;
int width;
int height;
bool isPerspective;
glm::vec3 position;
glm::vec3 forward;
glm::vec3 right;
glm::vec3 up;
glm::vec3 worldUp;
// Euler Angles
float yaw;
float pitch;
bool bFirstMouseMove = true;
float lastX = 0.f, lastY = 0.f;
};
class Shader
{
public:
// constructor generates the shaderStencilTesting on the fly
// ------------------------------------------------------------------------
Shader(const char* vertexPath, const char* fragmentPath)
{
Init(vertexPath, fragmentPath);
}
~Shader()
{
glDeleteProgram(ID);
}
// activate the shaderStencilTesting
// ------------------------------------------------------------------------
void Use() const
{
glUseProgram(ID);
}
unsigned int GetID() const { return ID; }
// MVP
unsigned int loc_model_matrix;
unsigned int loc_view_matrix;
unsigned int loc_projection_matrix;
// utility uniform functions
void SetInt(const std::string& name, int value) const
{
glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
}
void SetFloat(const std::string& name, float value) const
{
glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
}
void SetVec3(const std::string& name, const glm::vec3& value) const
{
glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]);
}
void SetVec3(const std::string& name, float x, float y, float z) const
{
glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z);
}
void SetMat4(const std::string& name, const glm::mat4& mat) const
{
glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE,
&mat[0][0]);
}
private:
void Init(const char* vertexPath, const char* fragmentPath)
{
// 1. retrieve the vertex/fragment source code from filePath
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;
// ensure ifstream objects can throw exceptions:
vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
try {
// open files
vShaderFile.open(vertexPath);
fShaderFile.open(fragmentPath);
std::stringstream vShaderStream, fShaderStream;
// read file's buffer contents into streams
vShaderStream << vShaderFile.rdbuf();
fShaderStream << fShaderFile.rdbuf();
// close file handlers
vShaderFile.close();
fShaderFile.close();
// convert stream into string
vertexCode = vShaderStream.str();
fragmentCode = fShaderStream.str();
}
catch (std::ifstream::failure e) {
std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
}
const char* vShaderCode = vertexCode.c_str();
const char* fShaderCode = fragmentCode.c_str();
// 2. compile shaders
unsigned int vertex, fragment;
// vertex shaderStencilTesting
vertex = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertex, 1, &vShaderCode, NULL);
glCompileShader(vertex);
CheckCompileErrors(vertex, "VERTEX");
// fragment Shader
fragment = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragment, 1, &fShaderCode, NULL);
glCompileShader(fragment);
CheckCompileErrors(fragment, "FRAGMENT");
// shaderStencilTesting Program
ID = glCreateProgram();
glAttachShader(ID, vertex);
glAttachShader(ID, fragment);
glLinkProgram(ID);
CheckCompileErrors(ID, "PROGRAM");
// 3. delete the shaders as they're linked into our program now and no
longer necessery
glDeleteShader(vertex);
glDeleteShader(fragment);
}
// utility function for checking shaderStencilTesting compilation/linking
errors.
// ------------------------------------------------------------------------
void CheckCompileErrors(unsigned int shaderStencilTesting, std::string type)
{
GLint success;
GLchar infoLog[1024];
if (type != "PROGRAM") {
glGetShaderiv(shaderStencilTesting, GL_COMPILE_STATUS, &success);
if (!success) {
glGetShaderInfoLog(shaderStencilTesting, 1024, NULL, infoLog);
std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type <<
"\n" << infoLog << "\n -- --------------------------------------------------- -- "
<< std::endl;
}
}
else {
glGetProgramiv(shaderStencilTesting, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderStencilTesting, 1024, NULL, infoLog);
std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\
n" << infoLog << "\n -- --------------------------------------------------- -- " <<
std::endl;
}
}
}
private:
unsigned int ID;
};
Camera* pCamera = nullptr;
unsigned int CreateTexture(const std::string& strTexturePath)
{
unsigned int textureId = -1;
// load image, create texture and generate mipmaps
int width, height, nrChannels;
stbi_set_flip_vertically_on_load(true); // tell stb_image.h to flip loaded
texture's on the y-axis.
unsigned char* data = stbi_load(strTexturePath.c_str(), &width, &height,
&nrChannels, 0);
if (data) {
GLenum format;
if (nrChannels == 1)
format = GL_RED;
else if (nrChannels == 3)
format = GL_RGB;
else if (nrChannels == 4)
format = GL_RGBA;
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format,
GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
// set the texture wrapping parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
// set texture filtering parameters
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}
else {
std::cout << "Failed to load texture: " << strTexturePath << std::endl;
}
stbi_image_free(data);
return textureId;
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void processInput(GLFWwindow* window);
float height = 0.1f;
float radius = 1.0f;
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (glfwGetKey(window, GLFW_KEY_1) == GLFW_PRESS)
{
height += 0.1f;
}
if (glfwGetKey(window, GLFW_KEY_2) == GLFW_PRESS)
{
height /= 2;
}
if (glfwGetKey(window, GLFW_KEY_EQUAL) == GLFW_PRESS)
{
cubeMovement = Grow;
}
if (glfwGetKey(window, GLFW_KEY_MINUS) == GLFW_PRESS)
{
cubeMovement = Shrink;
}
if (glfwGetKey(window, GLFW_KEY_INSERT) == GLFW_PRESS)
{
radius += 0.1f;
}
if (glfwGetKey(window, GLFW_KEY_DELETE) == GLFW_PRESS)
{
radius -= 0.1f;
}
}