add a cube that rotates.
This commit is contained in:
parent
f22087afc1
commit
642e913275
1 changed files with 285 additions and 194 deletions
479
src/main.cc
479
src/main.cc
|
@ -10,14 +10,6 @@
|
||||||
#include "utilities.hh"
|
#include "utilities.hh"
|
||||||
#include "image.hh"
|
#include "image.hh"
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
|
||||||
void process_input(GLFWwindow* window);
|
|
||||||
void key_pressed(GLFWwindow *window, int key, int scancode, int action, int mods);
|
|
||||||
int check_shader_compilation_status(unsigned int shaderId);
|
|
||||||
|
|
||||||
bool wireframe;
|
|
||||||
bool rectangleToggled;
|
|
||||||
|
|
||||||
struct GlRenderObjects {
|
struct GlRenderObjects {
|
||||||
unsigned int vertexBufferObject;
|
unsigned int vertexBufferObject;
|
||||||
unsigned int vertexArrayObject;
|
unsigned int vertexArrayObject;
|
||||||
|
@ -30,6 +22,290 @@ struct GlRenderObjects {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum state {
|
||||||
|
CUBE,
|
||||||
|
RECTANGLE,
|
||||||
|
TRIANGLE
|
||||||
|
};
|
||||||
|
|
||||||
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
|
||||||
|
void process_input(GLFWwindow* window);
|
||||||
|
void key_pressed(GLFWwindow *window, int key, int scancode, int action, int mods);
|
||||||
|
int check_shader_compilation_status(unsigned int shaderId);
|
||||||
|
void createTexture(uint* textureInt, const char* path, GLenum imageType, GLenum minFilter, GLenum magFilter);
|
||||||
|
GlRenderObjects cube();
|
||||||
|
GlRenderObjects triangle();
|
||||||
|
GlRenderObjects rectangle();
|
||||||
|
|
||||||
|
bool wireframe;
|
||||||
|
bool rectangleToggled;
|
||||||
|
state currentState = CUBE;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
glfwInit();
|
||||||
|
|
||||||
|
// These brackets are a RAII (Resource Acquisition Is Initialization) pattern,
|
||||||
|
// which means these brackets are its own "scope" which means stack allocated memory
|
||||||
|
// and heap allocated memory wrapped in a smart pointer like unique_ptr will be cleaned
|
||||||
|
// up after you go out of scope.
|
||||||
|
{
|
||||||
|
// Set OpenGL version to 3.3.
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||||
|
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||||
|
|
||||||
|
// Set OpenGL to use the Core profile.
|
||||||
|
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||||
|
|
||||||
|
// Create a OpenGL window with the 800x600 resolution and with the title "OpenGL Sussy Window".
|
||||||
|
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Sussy Window", nullptr, nullptr);
|
||||||
|
|
||||||
|
// Fail if the window is failed to create.
|
||||||
|
if (window == nullptr) {
|
||||||
|
std::cout << "Failed to create GLFW window." << std::endl;
|
||||||
|
glfwTerminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
|
||||||
|
// Tell OpenGL the size of the rendering window. We're telling it right now that its 800x600.
|
||||||
|
glViewport(0, 0, 800, 600);
|
||||||
|
|
||||||
|
// Register a callback for window size changes.
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
|
|
||||||
|
std::string currentPath = utilities::getCurrentPath();
|
||||||
|
|
||||||
|
// Create a shader class.
|
||||||
|
Shader shader(std::format("{}/vertex.glsl", currentPath).c_str(), std::format("{}/fragment.glsl", currentPath).c_str());
|
||||||
|
|
||||||
|
GlRenderObjects cubeRenderObjs = cube();
|
||||||
|
GlRenderObjects triangleRenderObjs = triangle();
|
||||||
|
GlRenderObjects rectangleRenderObjs = rectangle();
|
||||||
|
|
||||||
|
unsigned int texture1, texture2;
|
||||||
|
|
||||||
|
createTexture(&texture1, "container.jpg", GL_RGB, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
|
||||||
|
createTexture(&texture2, "awesomeface.png", GL_RGBA, GL_LINEAR, GL_LINEAR);
|
||||||
|
|
||||||
|
// activate the shader
|
||||||
|
shader.activate();
|
||||||
|
|
||||||
|
// tell the shader what texture unit the textures are on
|
||||||
|
shader.setInt("texture1", 0);
|
||||||
|
shader.setInt("texture2", 1);
|
||||||
|
|
||||||
|
// glm::mat4 trans = glm::mat4(1.0f);
|
||||||
|
// trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
|
||||||
|
// trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
|
||||||
|
|
||||||
|
// Create a render loop, which keeps the program open until glfw tells the loop that the window should close.
|
||||||
|
while (!glfwWindowShouldClose(window)) {
|
||||||
|
// Process input.
|
||||||
|
process_input(window);
|
||||||
|
// Set a callback to trigger whenever a key is pressed.
|
||||||
|
glfwSetKeyCallback(window, key_pressed);
|
||||||
|
|
||||||
|
// Set the GL state to use this color when clearing the screen.
|
||||||
|
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
||||||
|
// Clear the screen and use the color from the state.
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
|
||||||
|
// assign texture1 to the GL_TEXTURE0 texture unit.
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture1);
|
||||||
|
|
||||||
|
// assign texture1 to the GL_TEXTURE1 texture unit.
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texture2);
|
||||||
|
|
||||||
|
shader.activate();
|
||||||
|
|
||||||
|
// the model matrix. this rotates the plane on the x axis by -55 degrees.
|
||||||
|
glm::mat4 model(1.0f);
|
||||||
|
model = glm::rotate(model, (float)glfwGetTime() * glm::radians(50.0f), glm::vec3(0.5f, 1.0f, 0.0f));
|
||||||
|
|
||||||
|
// the view matrix. this moves the "camera" back by 3 units.
|
||||||
|
glm::mat4 view(1.0f);
|
||||||
|
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
|
||||||
|
|
||||||
|
// the projection matrix. the fov is 45 degrees. the aspect is 800/600 (4:3). the near plane is 0.1 units. the far plane is 100 units.
|
||||||
|
glm::mat4 projection;
|
||||||
|
projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
|
||||||
|
|
||||||
|
// create the identity matrix
|
||||||
|
glm::mat4 trans(1);
|
||||||
|
// translate it by this vector3
|
||||||
|
trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
|
||||||
|
// rotate by the z axis with the angle being controlled by time
|
||||||
|
trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
|
||||||
|
|
||||||
|
shader.setMat4("model", model);
|
||||||
|
shader.setMat4("view", view);
|
||||||
|
shader.setMat4("projection", projection);
|
||||||
|
|
||||||
|
switch (currentState) {
|
||||||
|
case CUBE:
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
glBindVertexArray(cubeRenderObjs.vertexArrayObject);
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 36);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
break;
|
||||||
|
case RECTANGLE:
|
||||||
|
glBindVertexArray(rectangleRenderObjs.vertexArrayObject);
|
||||||
|
// Draw 6 elements (indices) that are unsigned ints.
|
||||||
|
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
break;
|
||||||
|
case TRIANGLE:
|
||||||
|
// Bind the state to use the vertexArrayObject object so OpenGL knows what to do with the verticies.
|
||||||
|
glBindVertexArray(triangleRenderObjs.vertexArrayObject);
|
||||||
|
// Draw the verticies with the first index being 0 and the size of the vertex being 3 floats.
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This swaps completely drawn frames from the "second buffer" to the front one which is displayed on the screen.
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
// Check if any events are triggered.
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glfwTerminate();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
|
||||||
|
// Tell OpenGL the size of the rendering window.
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void process_input(GLFWwindow* window) {
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||||
|
glfwSetWindowShouldClose(window, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void key_pressed(GLFWwindow *window, int key, int scancode, int action, int mods) {
|
||||||
|
// If the W key is pressed, toggle wireframe mode.
|
||||||
|
if (key == GLFW_KEY_W && action == GLFW_PRESS) {
|
||||||
|
if (!wireframe) {
|
||||||
|
// Render polygons in wireframe mode.
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
wireframe = true;
|
||||||
|
} else {
|
||||||
|
// Render polygons in fill mode.
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
wireframe = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (key == GLFW_KEY_R && action == GLFW_PRESS) {
|
||||||
|
currentState = RECTANGLE;
|
||||||
|
} else if (key == GLFW_KEY_T && action == GLFW_PRESS) {
|
||||||
|
currentState = TRIANGLE;
|
||||||
|
} else if (key == GLFW_KEY_C && action == GLFW_PRESS) {
|
||||||
|
currentState = CUBE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int check_shader_compilation_status(unsigned int shaderId) {
|
||||||
|
int success;
|
||||||
|
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success);
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createTexture(uint* textureInt, const char* path, GLenum imageType, GLenum minFilter, GLenum magFilter) {
|
||||||
|
// Create a texture ID and assign it to the textureInt pointer.
|
||||||
|
glGenTextures(1, textureInt);
|
||||||
|
// Bind that texture to the GL_TEXTURE_2D state.
|
||||||
|
glBindTexture(GL_TEXTURE_2D, *textureInt);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
|
||||||
|
|
||||||
|
Image texture(utilities::getCurrentPath(path));
|
||||||
|
if (texture.data) {
|
||||||
|
// Read the texture data and assign it to the GL texture.
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, imageType, texture.width, texture.height, 0, imageType, GL_UNSIGNED_BYTE, texture.data);
|
||||||
|
// Generate a mipmap of the texture data.
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
} else {
|
||||||
|
std::cout << "Failed to load texture." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlRenderObjects cube() {
|
||||||
|
float vertices[] = {
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 0.0f,
|
||||||
|
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 1.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
|
||||||
|
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
0.5f, -0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
-0.5f, -0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
|
||||||
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f,
|
||||||
|
0.5f, 0.5f, -0.5f, 1.0f, 1.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
0.5f, 0.5f, 0.5f, 1.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, 0.5f, 0.0f, 0.0f,
|
||||||
|
-0.5f, 0.5f, -0.5f, 0.0f, 1.0f
|
||||||
|
};
|
||||||
|
|
||||||
|
unsigned int vertexArrayObject, vertexBufferObject;
|
||||||
|
glGenVertexArrays(1, &vertexArrayObject);
|
||||||
|
glGenBuffers(1, &vertexBufferObject);
|
||||||
|
glBindVertexArray(vertexArrayObject);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
return {vertexBufferObject, vertexArrayObject, 0};
|
||||||
|
}
|
||||||
|
|
||||||
GlRenderObjects triangle() {
|
GlRenderObjects triangle() {
|
||||||
// An array of verticies containing data for a triangle.
|
// An array of verticies containing data for a triangle.
|
||||||
float vertices[] = {
|
float vertices[] = {
|
||||||
|
@ -72,7 +348,7 @@ GlRenderObjects triangle() {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
return {vertexArrayObject, vertexArrayObject, 0};
|
return {vertexBufferObject, vertexArrayObject, 0};
|
||||||
}
|
}
|
||||||
|
|
||||||
GlRenderObjects rectangle() {
|
GlRenderObjects rectangle() {
|
||||||
|
@ -128,188 +404,3 @@ GlRenderObjects rectangle() {
|
||||||
|
|
||||||
return {vertexBufferObject, vertexArrayObject, elementBufferObject};
|
return {vertexBufferObject, vertexArrayObject, elementBufferObject};
|
||||||
}
|
}
|
||||||
|
|
||||||
void createTexture(uint* textureInt, const char* path, GLenum imageType, GLenum minFilter, GLenum magFilter) {
|
|
||||||
// Create a texture ID and assign it to the textureInt pointer.
|
|
||||||
glGenTextures(1, textureInt);
|
|
||||||
// Bind that texture to the GL_TEXTURE_2D state.
|
|
||||||
glBindTexture(GL_TEXTURE_2D, *textureInt);
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, magFilter);
|
|
||||||
|
|
||||||
Image texture(utilities::getCurrentPath(path));
|
|
||||||
if (texture.data) {
|
|
||||||
// Read the texture data and assign it to the GL texture.
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, imageType, texture.width, texture.height, 0, imageType, GL_UNSIGNED_BYTE, texture.data);
|
|
||||||
// Generate a mipmap of the texture data.
|
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
} else {
|
|
||||||
std::cout << "Failed to load texture." << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
glfwInit();
|
|
||||||
|
|
||||||
// These brackets are a RAII (Resource Acquisition Is Initialization) pattern,
|
|
||||||
// which means these brackets are its own "scope" which means stack allocated memory
|
|
||||||
// and heap allocated memory wrapped in a smart pointer like unique_ptr will be cleaned
|
|
||||||
// up after you go out of scope.
|
|
||||||
{
|
|
||||||
// Set OpenGL version to 3.3.
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
|
||||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
|
||||||
|
|
||||||
// Set OpenGL to use the Core profile.
|
|
||||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
|
||||||
|
|
||||||
// Create a OpenGL window with the 800x600 resolution and with the title "OpenGL Sussy Window".
|
|
||||||
GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Sussy Window", nullptr, nullptr);
|
|
||||||
|
|
||||||
// Fail if the window is failed to create.
|
|
||||||
if (window == nullptr) {
|
|
||||||
std::cout << "Failed to create GLFW window." << std::endl;
|
|
||||||
glfwTerminate();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwMakeContextCurrent(window);
|
|
||||||
|
|
||||||
// Tell OpenGL the size of the rendering window. We're telling it right now that its 800x600.
|
|
||||||
glViewport(0, 0, 800, 600);
|
|
||||||
|
|
||||||
// Register a callback for window size changes.
|
|
||||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
|
||||||
|
|
||||||
std::string currentPath = utilities::getCurrentPath();
|
|
||||||
|
|
||||||
// Create a shader class.
|
|
||||||
Shader shader(std::format("{}/vertex.glsl", currentPath).c_str(), std::format("{}/fragment.glsl", currentPath).c_str());
|
|
||||||
|
|
||||||
GlRenderObjects triangleRenderObjs = triangle();
|
|
||||||
GlRenderObjects rectangleRenderObjs = rectangle();
|
|
||||||
|
|
||||||
unsigned int texture1, texture2;
|
|
||||||
|
|
||||||
createTexture(&texture1, "container.jpg", GL_RGB, GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR);
|
|
||||||
createTexture(&texture2, "awesomeface.png", GL_RGBA, GL_LINEAR, GL_LINEAR);
|
|
||||||
|
|
||||||
// activate the shader
|
|
||||||
shader.activate();
|
|
||||||
|
|
||||||
// tell the shader what texture unit the textures are on
|
|
||||||
shader.setInt("texture1", 0);
|
|
||||||
shader.setInt("texture2", 1);
|
|
||||||
|
|
||||||
// glm::mat4 trans = glm::mat4(1.0f);
|
|
||||||
// trans = glm::rotate(trans, glm::radians(90.0f), glm::vec3(0.0, 0.0, 1.0));
|
|
||||||
// trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
|
|
||||||
|
|
||||||
// Create a render loop, which keeps the program open until glfw tells the loop that the window should close.
|
|
||||||
while (!glfwWindowShouldClose(window)) {
|
|
||||||
// Process input.
|
|
||||||
process_input(window);
|
|
||||||
// Set a callback to trigger whenever a key is pressed.
|
|
||||||
glfwSetKeyCallback(window, key_pressed);
|
|
||||||
|
|
||||||
// Set the GL state to use this color when clearing the screen.
|
|
||||||
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
|
|
||||||
// Clear the screen and use the color from the state.
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
// assign texture1 to the GL_TEXTURE0 texture unit.
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture1);
|
|
||||||
|
|
||||||
// assign texture1 to the GL_TEXTURE1 texture unit.
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture2);
|
|
||||||
|
|
||||||
shader.activate();
|
|
||||||
|
|
||||||
// the model matrix. this rotates the plane on the x axis by -55 degrees.
|
|
||||||
glm::mat4 model(1.0f);
|
|
||||||
model = glm::rotate(model, glm::radians(-55.0f), glm::vec3(1.0f, 0.0f, 0.0f));
|
|
||||||
|
|
||||||
// the view matrix. this moves the "camera" back by 3 units.
|
|
||||||
glm::mat4 view(1.0f);
|
|
||||||
view = glm::translate(view, glm::vec3(0.0f, 0.0f, -3.0f));
|
|
||||||
|
|
||||||
// the projection matrix. the fov is 45 degrees. the aspect is 800/600 (4:3). the near plane is 0.1 units. the far plane is 100 units.
|
|
||||||
glm::mat4 projection;
|
|
||||||
projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
|
|
||||||
|
|
||||||
// create the identity matrix
|
|
||||||
glm::mat4 trans(1);
|
|
||||||
// translate it by this vector3
|
|
||||||
trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
|
|
||||||
// rotate by the z axis with the angle being controlled by time
|
|
||||||
trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
|
|
||||||
|
|
||||||
shader.setMat4("model", model);
|
|
||||||
shader.setMat4("view", view);
|
|
||||||
shader.setMat4("projection", projection);
|
|
||||||
|
|
||||||
if (!rectangleToggled) {
|
|
||||||
// Bind the state to use the vertexArrayObject object so OpenGL knows what to do with the verticies.
|
|
||||||
glBindVertexArray(triangleRenderObjs.vertexArrayObject);
|
|
||||||
// Draw the verticies with the first index being 0 and the size of the vertex being 3 floats.
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, 3);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
} else {
|
|
||||||
glBindVertexArray(rectangleRenderObjs.vertexArrayObject);
|
|
||||||
// Draw 6 elements (indices) that are unsigned ints.
|
|
||||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This swaps completely drawn frames from the "second buffer" to the front one which is displayed on the screen.
|
|
||||||
glfwSwapBuffers(window);
|
|
||||||
// Check if any events are triggered.
|
|
||||||
glfwPollEvents();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glfwTerminate();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
|
|
||||||
// Tell OpenGL the size of the rendering window.
|
|
||||||
glViewport(0, 0, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void process_input(GLFWwindow* window) {
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
|
||||||
glfwSetWindowShouldClose(window, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int check_shader_compilation_status(unsigned int shaderId) {
|
|
||||||
int success;
|
|
||||||
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success);
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
void key_pressed(GLFWwindow *window, int key, int scancode, int action, int mods) {
|
|
||||||
// If the W key is pressed, toggle wireframe mode.
|
|
||||||
if (key == GLFW_KEY_W && action == GLFW_PRESS) {
|
|
||||||
if (!wireframe) {
|
|
||||||
// Render polygons in wireframe mode.
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
|
||||||
wireframe = true;
|
|
||||||
} else {
|
|
||||||
// Render polygons in fill mode.
|
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
||||||
wireframe = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Flip a boolean indicating the rectangle should be rendered.
|
|
||||||
if (key == GLFW_KEY_R && action == GLFW_PRESS) {
|
|
||||||
rectangleToggled = !rectangleToggled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue