Refactored texture usage

This commit is contained in:
Daniel 2023-07-31 13:42:13 +02:00
parent 350aef4871
commit a89e820bd8
2 changed files with 59 additions and 56 deletions

View File

@ -8,13 +8,15 @@
#include <string> #include <string>
#include "shaders/Shader.h" #include "shaders/Shader.h"
#include "textures/Texture2D.h"
#include "util/stb_image.h" #include "util/stb_image.h"
// Continue: https://learnopengl.com/Getting-started/Coordinate-Systems // Continue: https://learnopengl.com/Getting-started/Coordinate-Systems
// Chapter: More Cubes! // Chapter: More Cubes!
// //
// TODO: look at project->properties->VC++ Directories-> change everything to the Environment var // TODO: look at project->properties->VC++ Directories-> change everything to the Environment var
// For the "real" Nebulix Engine setup everything so it can be compiled/used with VSCode/CLion and not just VS (so basically having an "external" folder which has open gl, GLAD, etc. in it or something like this) // For the "real" Nebulix Engine setup everything so it can be compiled/used with VSCode/CLion and not just VS
// (so basically having an "external" folder which has open gl, GLAD, GLM, stb_image etc. in it or something like this)
// //
// HOW TO redirect error output to file // HOW TO redirect error output to file
@ -42,6 +44,12 @@ void ProcessInput(GLFWwindow* window)
glfwSetWindowShouldClose(window, true); glfwSetWindowShouldClose(window, true);
} }
void Configure()
{
stbi_set_flip_vertically_on_load(true); // because an image has 0 at top of y axis and opengl expects it to be on the botton, so if this is omitted, the image will be flipped
glEnable(GL_DEPTH_TEST);
}
int main() int main()
{ {
glfwInit(); glfwInit();
@ -70,6 +78,8 @@ int main()
OnWindowResize(window, WINDOW_WIDTH, WINDOW_HEIGHT); OnWindowResize(window, WINDOW_WIDTH, WINDOW_HEIGHT);
glfwSetFramebufferSizeCallback(window, OnWindowResize); glfwSetFramebufferSizeCallback(window, OnWindowResize);
Configure();
float vertices[] = { // object coordinates, uv-coordinates float vertices[] = { // object coordinates, uv-coordinates
-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, 0.0f,
@ -116,23 +126,8 @@ int main()
GLuint faces[]{ GLuint faces[]{
0, 1, 3, 0, 1, 3,
1, 2, 3, 1, 2, 3
};
4, 5, 6,
5, 6, 7,
8, 9, 10,
9, 10, 11,
12, 13, 14,
13, 14, 15,
16, 17, 18,
17, 18, 19,
20, 21, 22,
21, 22, 23
}; // 23
// VBO == all verticies; EBO == connection of vertices (faces) and is optional although it is a bit more efficient than using VBOs; // VBO == all verticies; EBO == connection of vertices (faces) and is optional although it is a bit more efficient than using VBOs;
// VAO == collection of VBOs/EBOs used for rendering // VAO == collection of VBOs/EBOs used for rendering
@ -152,7 +147,7 @@ int main()
// position attribute // position attribute
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
// uv-coordinates (or more general the third vertex attribute) // uv-coordinates (or more general the third vertex attribute which can be anything not just uv-coordinates)
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float))); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
// I could unbind the VAO, but this is usually not needed because when creating a new VAO we need to bind that to change it anyway, so there shouldn't be a problem // I could unbind the VAO, but this is usually not needed because when creating a new VAO we need to bind that to change it anyway, so there shouldn't be a problem
@ -173,35 +168,8 @@ int main()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// TEXTURES // TEXTURES
stbi_set_flip_vertically_on_load(true); // because an image has 0 at top of y axis and opengl expects it to be on the botton, so if this is omitted, the image will be flipped Texture2D containerImage("images/container.jpg");
int width, height, nrChannels; Texture2D faceImage("images/awesomeface.png", 0, GL_RGBA);
unsigned char* image = stbi_load("images/container.jpg", &width, &height, &nrChannels, 0);
if (!image)
{
std::cerr << "ERROR::IO::LOAD_TEXTURE";
stbi_image_free(image);
return -1; // it would be better to just use a default error image instead and make the error message a warning message instead
}
unsigned int textureID_container;
glGenTextures(1, &textureID_container);
glBindTexture(GL_TEXTURE_2D, textureID_container);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(image);
image = stbi_load("images/awesomeface.png", &width, &height, &nrChannels, 0);
if (!image)
{
std::cerr << "ERROR::IO::LOAD_TEXTURE";
stbi_image_free(image);
return -1; // it would be better to just use a default error image instead and make the error message a warning message instead
}
unsigned int textureID_face;
glGenTextures(1, &textureID_face);
glBindTexture(GL_TEXTURE_2D, textureID_face);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(image);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
//glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
@ -214,7 +182,6 @@ int main()
viewMatrix = glm::translate(viewMatrix, vec3(0, 0, -3.0f)); viewMatrix = glm::translate(viewMatrix, vec3(0, 0, -3.0f));
mat4 projectionMatrix = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f); mat4 projectionMatrix = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);
glEnable(GL_DEPTH_TEST);
float timeLastFrame = glfwGetTime(); float timeLastFrame = glfwGetTime();
// main loop // main loop
while(!glfwWindowShouldClose(window)) while(!glfwWindowShouldClose(window))
@ -235,10 +202,8 @@ int main()
shader->SetMatrix("viewMatrix", viewMatrix); shader->SetMatrix("viewMatrix", viewMatrix);
shader->SetMatrix("projectionMatrix", projectionMatrix); shader->SetMatrix("projectionMatrix", projectionMatrix);
glActiveTexture(GL_TEXTURE0); // before binding texture, activate correct textre Unit (some drivers might show nothing if this is omitted) containerImage.BindTexture();
glBindTexture(GL_TEXTURE_2D, textureID_container); faceImage.BindTexture(GL_TEXTURE0 + 1); // GL_TEXTURE0 + 1 == GL_TEXTURE1, this means looping over multiple units is easily possible
glActiveTexture(GL_TEXTURE0 + 1); // GL_TEXTURE0 + 1 == GL_TEXTURE1, this means looping over multiple units is easily possible
glBindTexture(GL_TEXTURE_2D, textureID_face);
glBindVertexArray(vertexArrayObject); glBindVertexArray(vertexArrayObject);
//glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // for EBOs //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // for EBOs

View File

@ -1,11 +1,49 @@
#pragma once #pragma once
#include <glad/glad.h>
#include <string>
#include "../util/stb_image.h"
#include "../exceptions/IOException.h"
// Maybe make a base "Texture" class and make a Texture2D and Texture3D child class. look into what would make more sense // Maybe make a base "Texture" class and make a Texture2D and Texture3D child class. look into what would make more sense
class Texture2D class Texture2D
{ {
public: public:
Texture2D(); // maybe add a parameter for configuring mipmapping
~Texture2D(); Texture2D(std::string pathToTexture, int desiredColourChannels = 0, GLenum fileFormat = GL_RGB)
{
unsigned char* image = stbi_load(pathToTexture.c_str(), &width, &height, &nrChannels, desiredColourChannels);
if (!image)
{
stbi_image_free(image);
throw Nebulix::IOException("ERROR::FILE::IO::LOAD_TEXTURE"); // it would be better to just use a default error image instead and make the error message a warning message
}
glGenTextures(1, &textureId);
glBindTexture(GL_TEXTURE_2D, textureId);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, fileFormat, GL_UNSIGNED_BYTE, image);
glGenerateMipmap(GL_TEXTURE_2D);
stbi_image_free(image);
}
~Texture2D()
{
glDeleteTextures(1, &textureId);
}
/// <summary>
/// Activate and bind this texture to use it
/// </summary>
/// <param name="texture">The texture unit of this texture. For example GL_TEXTURE0 (default)</param>
void BindTexture(GLenum textureUnit = GL_TEXTURE0)
{
// TODO: add the interpolation configuration. Make as properties which have default settings kinda like Unity
glActiveTexture(textureUnit); // before binding texture, activate correct textre Unit (some drivers might show nothing if this is omitted)
glBindTexture(GL_TEXTURE_2D, textureId);
}
int GetWidth() { return width; }
int GetHeight() { return height; }
int GetNrChannels() { return nrChannels; }
private: private:
GLuint textureId;
int width, height, nrChannels;
}; };