Revert "Spheres model matrix generation fix"

This reverts commit d702e0c6bf.
This commit is contained in:
Erik
2018-04-10 12:39:42 +03:00
parent d702e0c6bf
commit e511ca603d

View File

@@ -1,376 +1,373 @@
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <stb_image.h> #include <stb_image.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp> #include <glm/gtc/type_ptr.hpp>
#include <learnopengl/filesystem.h> #include <learnopengl/filesystem.h>
#include <learnopengl/shader.h> #include <learnopengl/shader.h>
#include <learnopengl/camera.h> #include <learnopengl/camera.h>
#include <learnopengl/model.h> #include <learnopengl/model.h>
#include <iostream> #include <iostream>
void framebuffer_size_callback(GLFWwindow* window, int width, int height); void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void mouse_callback(GLFWwindow* window, double xpos, double ypos); void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset); void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void processInput(GLFWwindow *window); void processInput(GLFWwindow *window);
unsigned int loadTexture(const char *path); unsigned int loadTexture(const char *path);
void renderSphere(); void renderSphere();
// settings // settings
const unsigned int SCR_WIDTH = 1280; const unsigned int SCR_WIDTH = 1280;
const unsigned int SCR_HEIGHT = 720; const unsigned int SCR_HEIGHT = 720;
// camera // camera
Camera camera(glm::vec3(0.0f, 0.0f, 3.0f)); Camera camera(glm::vec3(0.0f, 0.0f, 3.0f));
float lastX = 800.0f / 2.0; float lastX = 800.0f / 2.0;
float lastY = 600.0 / 2.0; float lastY = 600.0 / 2.0;
bool firstMouse = true; bool firstMouse = true;
// timing // timing
float deltaTime = 0.0f; float deltaTime = 0.0f;
float lastFrame = 0.0f; float lastFrame = 0.0f;
int main() int main()
{ {
// glfw: initialize and configure // glfw: initialize and configure
// ------------------------------ // ------------------------------
glfwInit(); glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_SAMPLES, 4); glfwWindowHint(GLFW_SAMPLES, 4);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
//glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
#ifdef __APPLE__
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X // glfw window creation
#endif // --------------------
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
// glfw window creation glfwMakeContextCurrent(window);
// -------------------- if (window == NULL)
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL); {
glfwMakeContextCurrent(window); std::cout << "Failed to create GLFW window" << std::endl;
if (window == NULL) glfwTerminate();
{ return -1;
std::cout << "Failed to create GLFW window" << std::endl; }
glfwTerminate(); glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
return -1; glfwSetCursorPosCallback(window, mouse_callback);
} glfwSetScrollCallback(window, scroll_callback);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
glfwSetCursorPosCallback(window, mouse_callback); // tell GLFW to capture our mouse
glfwSetScrollCallback(window, scroll_callback); glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// tell GLFW to capture our mouse // glad: load all OpenGL function pointers
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); // ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
// glad: load all OpenGL function pointers {
// --------------------------------------- std::cout << "Failed to initialize GLAD" << std::endl;
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) return -1;
{ }
std::cout << "Failed to initialize GLAD" << std::endl;
return -1; // configure global opengl state
} // -----------------------------
glEnable(GL_DEPTH_TEST);
// configure global opengl state
// ----------------------------- // build and compile shaders
glEnable(GL_DEPTH_TEST); // -------------------------
Shader shader("1.1.pbr.vs", "1.1.pbr.fs");
// build and compile shaders
// ------------------------- shader.use();
Shader shader("1.1.pbr.vs", "1.1.pbr.fs"); shader.setVec3("albedo", 0.5f, 0.0f, 0.0f);
shader.setFloat("ao", 1.0f);
shader.use();
shader.setVec3("albedo", 0.5f, 0.0f, 0.0f); // lights
shader.setFloat("ao", 1.0f); // ------
glm::vec3 lightPositions[] = {
// lights glm::vec3(-10.0f, 10.0f, 10.0f),
// ------ glm::vec3( 10.0f, 10.0f, 10.0f),
glm::vec3 lightPositions[] = { glm::vec3(-10.0f, -10.0f, 10.0f),
glm::vec3(-10.0f, 10.0f, 10.0f), glm::vec3( 10.0f, -10.0f, 10.0f),
glm::vec3( 10.0f, 10.0f, 10.0f), };
glm::vec3(-10.0f, -10.0f, 10.0f), glm::vec3 lightColors[] = {
glm::vec3( 10.0f, -10.0f, 10.0f), glm::vec3(300.0f, 300.0f, 300.0f),
}; glm::vec3(300.0f, 300.0f, 300.0f),
glm::vec3 lightColors[] = { glm::vec3(300.0f, 300.0f, 300.0f),
glm::vec3(300.0f, 300.0f, 300.0f), glm::vec3(300.0f, 300.0f, 300.0f)
glm::vec3(300.0f, 300.0f, 300.0f), };
glm::vec3(300.0f, 300.0f, 300.0f), int nrRows = 7;
glm::vec3(300.0f, 300.0f, 300.0f) int nrColumns = 7;
}; float spacing = 2.5;
int nrRows = 7;
int nrColumns = 7; // initialize static shader uniforms before rendering
float spacing = 2.5; // --------------------------------------------------
glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
// initialize static shader uniforms before rendering shader.use();
// -------------------------------------------------- shader.setMat4("projection", projection);
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
shader.use(); // render loop
shader.setMat4("projection", projection); // -----------
while (!glfwWindowShouldClose(window))
// render loop {
// ----------- // per-frame time logic
while (!glfwWindowShouldClose(window)) // --------------------
{ float currentFrame = glfwGetTime();
// per-frame time logic deltaTime = currentFrame - lastFrame;
// -------------------- lastFrame = currentFrame;
float currentFrame = glfwGetTime();
deltaTime = currentFrame - lastFrame; // input
lastFrame = currentFrame; // -----
processInput(window);
// input
// ----- // render
processInput(window); // ------
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
// render glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// ------
glClearColor(0.1f, 0.1f, 0.1f, 1.0f); shader.use();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glm::mat4 view = camera.GetViewMatrix();
shader.setMat4("view", view);
shader.use(); shader.setVec3("camPos", camera.Position);
glm::mat4 view = camera.GetViewMatrix();
shader.setMat4("view", view); // render rows*column number of spheres with varying metallic/roughness values scaled by rows and columns respectively
shader.setVec3("camPos", camera.Position); glm::mat4 model;
for (unsigned int row = 0; row < nrRows; ++row)
// render rows*column number of spheres with varying metallic/roughness values scaled by rows and columns respectively {
glm::mat4 model; shader.setFloat("metallic", (float)row / (float)nrRows);
for (unsigned int row = 0; row < nrRows; ++row) for (unsigned int col = 0; col < nrColumns; ++col)
{ {
shader.setFloat("metallic", (float)row / (float)nrRows); // we clamp the roughness to 0.025 - 1.0 as perfectly smooth surfaces (roughness of 0.0) tend to look a bit off
for (unsigned int col = 0; col < nrColumns; ++col) // on direct lighting.
{ shader.setFloat("roughness", glm::clamp((float)col / (float)nrColumns, 0.05f, 1.0f));
// we clamp the roughness to 0.025 - 1.0 as perfectly smooth surfaces (roughness of 0.0) tend to look a bit off
// on direct lighting. model = glm::mat4();
shader.setFloat("roughness", glm::clamp((float)col / (float)nrColumns, 0.05f, 1.0f)); model = glm::translate(model, glm::vec3(
(float)(col - (nrColumns / 2)) * spacing,
model = glm::mat4(); (float)(row - (nrRows / 2)) * spacing,
model = glm::translate(model, glm::vec3( 0.0f
(col - (nrColumns / 2.)) * spacing, ));
(row - (nrRows / 2.)) * spacing, shader.setMat4("model", model);
0.0f renderSphere();
)); }
shader.setMat4("model", model); }
renderSphere();
} // render light source (simply re-render sphere at light positions)
} // this looks a bit off as we use the same shader, but it'll make their positions obvious and
// keeps the codeprint small.
// render light source (simply re-render sphere at light positions) for (unsigned int i = 0; i < sizeof(lightPositions) / sizeof(lightPositions[0]); ++i)
// this looks a bit off as we use the same shader, but it'll make their positions obvious and {
// keeps the codeprint small. glm::vec3 newPos = lightPositions[i] + glm::vec3(sin(glfwGetTime() * 5.0) * 5.0, 0.0, 0.0);
for (unsigned int i = 0; i < sizeof(lightPositions) / sizeof(lightPositions[0]); ++i) newPos = lightPositions[i];
{ shader.setVec3("lightPositions[" + std::to_string(i) + "]", newPos);
glm::vec3 newPos = lightPositions[i] + glm::vec3(sin(glfwGetTime() * 5.0) * 5.0, 0.0, 0.0); shader.setVec3("lightColors[" + std::to_string(i) + "]", lightColors[i]);
newPos = lightPositions[i];
shader.setVec3("lightPositions[" + std::to_string(i) + "]", newPos); model = glm::mat4();
shader.setVec3("lightColors[" + std::to_string(i) + "]", lightColors[i]); model = glm::translate(model, newPos);
model = glm::scale(model, glm::vec3(0.5f));
model = glm::mat4(); shader.setMat4("model", model);
model = glm::translate(model, newPos); renderSphere();
model = glm::scale(model, glm::vec3(0.5f)); }
shader.setMat4("model", model);
renderSphere(); // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
} // -------------------------------------------------------------------------------
glfwSwapBuffers(window);
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.) glfwPollEvents();
// ------------------------------------------------------------------------------- }
glfwSwapBuffers(window);
glfwPollEvents(); // glfw: terminate, clearing all previously allocated GLFW resources.
} // ------------------------------------------------------------------
glfwTerminate();
// glfw: terminate, clearing all previously allocated GLFW resources. return 0;
// ------------------------------------------------------------------ }
glfwTerminate();
return 0; // process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
} // ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly {
// --------------------------------------------------------------------------------------------------------- if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
void processInput(GLFWwindow *window) glfwSetWindowShouldClose(window, true);
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) float cameraSpeed = 2.5 * deltaTime;
glfwSetWindowShouldClose(window, true); if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
camera.ProcessKeyboard(FORWARD, deltaTime);
float cameraSpeed = 2.5 * deltaTime; if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) camera.ProcessKeyboard(BACKWARD, deltaTime);
camera.ProcessKeyboard(FORWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) camera.ProcessKeyboard(LEFT, deltaTime);
camera.ProcessKeyboard(BACKWARD, deltaTime); if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) camera.ProcessKeyboard(RIGHT, deltaTime);
camera.ProcessKeyboard(LEFT, deltaTime); }
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
camera.ProcessKeyboard(RIGHT, deltaTime); // glfw: whenever the window size changed (by OS or user resize) this callback function executes
} // ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
// glfw: whenever the window size changed (by OS or user resize) this callback function executes {
// --------------------------------------------------------------------------------------------- // make sure the viewport matches the new window dimensions; note that width and
void framebuffer_size_callback(GLFWwindow* window, int width, int height) // height will be significantly larger than specified on retina displays.
{ glViewport(0, 0, width, height);
// make sure the viewport matches the new window dimensions; note that width and }
// height will be significantly larger than specified on retina displays.
glViewport(0, 0, width, height);
} // glfw: whenever the mouse moves, this callback is called
// -------------------------------------------------------
void mouse_callback(GLFWwindow* window, double xpos, double ypos)
// glfw: whenever the mouse moves, this callback is called {
// ------------------------------------------------------- if (firstMouse)
void mouse_callback(GLFWwindow* window, double xpos, double ypos) {
{ lastX = xpos;
if (firstMouse) lastY = ypos;
{ firstMouse = false;
lastX = xpos; }
lastY = ypos;
firstMouse = false; float xoffset = xpos - lastX;
} float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
float xoffset = xpos - lastX; lastX = xpos;
float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top lastY = ypos;
lastX = xpos; camera.ProcessMouseMovement(xoffset, yoffset);
lastY = ypos; }
camera.ProcessMouseMovement(xoffset, yoffset); // glfw: whenever the mouse scroll wheel scrolls, this callback is called
} // ----------------------------------------------------------------------
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
// glfw: whenever the mouse scroll wheel scrolls, this callback is called {
// ---------------------------------------------------------------------- camera.ProcessMouseScroll(yoffset);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset) }
{
camera.ProcessMouseScroll(yoffset); // renders (and builds at first invocation) a sphere
} // -------------------------------------------------
unsigned int sphereVAO = 0;
// renders (and builds at first invocation) a sphere unsigned int indexCount;
// ------------------------------------------------- void renderSphere()
unsigned int sphereVAO = 0; {
unsigned int indexCount; if (sphereVAO == 0)
void renderSphere() {
{ glGenVertexArrays(1, &sphereVAO);
if (sphereVAO == 0)
{ unsigned int vbo, ebo;
glGenVertexArrays(1, &sphereVAO); glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
unsigned int vbo, ebo;
glGenBuffers(1, &vbo); std::vector<glm::vec3> positions;
glGenBuffers(1, &ebo); std::vector<glm::vec2> uv;
std::vector<glm::vec3> normals;
std::vector<glm::vec3> positions; std::vector<unsigned int> indices;
std::vector<glm::vec2> uv;
std::vector<glm::vec3> normals; const unsigned int X_SEGMENTS = 64;
std::vector<unsigned int> indices; const unsigned int Y_SEGMENTS = 64;
const float PI = 3.14159265359;
const unsigned int X_SEGMENTS = 64; for (unsigned int y = 0; y <= Y_SEGMENTS; ++y)
const unsigned int Y_SEGMENTS = 64; {
const float PI = 3.14159265359; for (unsigned int x = 0; x <= X_SEGMENTS; ++x)
for (unsigned int y = 0; y <= Y_SEGMENTS; ++y) {
{ float xSegment = (float)x / (float)X_SEGMENTS;
for (unsigned int x = 0; x <= X_SEGMENTS; ++x) float ySegment = (float)y / (float)Y_SEGMENTS;
{ float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
float xSegment = (float)x / (float)X_SEGMENTS; float yPos = std::cos(ySegment * PI);
float ySegment = (float)y / (float)Y_SEGMENTS; float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
float yPos = std::cos(ySegment * PI); positions.push_back(glm::vec3(xPos, yPos, zPos));
float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI); uv.push_back(glm::vec2(xSegment, ySegment));
normals.push_back(glm::vec3(xPos, yPos, zPos));
positions.push_back(glm::vec3(xPos, yPos, zPos)); }
uv.push_back(glm::vec2(xSegment, ySegment)); }
normals.push_back(glm::vec3(xPos, yPos, zPos));
} bool oddRow = false;
} for (int y = 0; y < Y_SEGMENTS; ++y)
{
bool oddRow = false; if (!oddRow) // even rows: y == 0, y == 2; and so on
for (int y = 0; y < Y_SEGMENTS; ++y) {
{ for (int x = 0; x <= X_SEGMENTS; ++x)
if (!oddRow) // even rows: y == 0, y == 2; and so on {
{ indices.push_back(y * (X_SEGMENTS + 1) + x);
for (int x = 0; x <= X_SEGMENTS; ++x) indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
{ }
indices.push_back(y * (X_SEGMENTS + 1) + x); }
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x); else
} {
} for (int x = X_SEGMENTS; x >= 0; --x)
else {
{ indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
for (int x = X_SEGMENTS; x >= 0; --x) indices.push_back(y * (X_SEGMENTS + 1) + x);
{ }
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x); }
indices.push_back(y * (X_SEGMENTS + 1) + x); oddRow = !oddRow;
} }
} indexCount = indices.size();
oddRow = !oddRow;
} std::vector<float> data;
indexCount = indices.size(); for (int i = 0; i < positions.size(); ++i)
{
std::vector<float> data; data.push_back(positions[i].x);
for (int i = 0; i < positions.size(); ++i) data.push_back(positions[i].y);
{ data.push_back(positions[i].z);
data.push_back(positions[i].x); if (uv.size() > 0)
data.push_back(positions[i].y); {
data.push_back(positions[i].z); data.push_back(uv[i].x);
if (uv.size() > 0) data.push_back(uv[i].y);
{ }
data.push_back(uv[i].x); if (normals.size() > 0)
data.push_back(uv[i].y); {
} data.push_back(normals[i].x);
if (normals.size() > 0) data.push_back(normals[i].y);
{ data.push_back(normals[i].z);
data.push_back(normals[i].x); }
data.push_back(normals[i].y); }
data.push_back(normals[i].z); glBindVertexArray(sphereVAO);
} glBindBuffer(GL_ARRAY_BUFFER, vbo);
} glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
glBindVertexArray(sphereVAO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW); float stride = (3 + 2 + 3) * sizeof(float);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); glEnableVertexAttribArray(0);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0);
float stride = (3 + 2 + 3) * sizeof(float); glEnableVertexAttribArray(1);
glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, (void*)(3 * sizeof(float)));
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0); glEnableVertexAttribArray(2);
glEnableVertexAttribArray(1); glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, stride, (void*)(5 * sizeof(float)));
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, (void*)(3 * sizeof(float))); }
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, stride, (void*)(5 * sizeof(float))); glBindVertexArray(sphereVAO);
} glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);
}
glBindVertexArray(sphereVAO);
glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0); // utility function for loading a 2D texture from file
} // ---------------------------------------------------
unsigned int loadTexture(char const * path)
// utility function for loading a 2D texture from file {
// --------------------------------------------------- unsigned int textureID;
unsigned int loadTexture(char const * path) glGenTextures(1, &textureID);
{
unsigned int textureID; int width, height, nrComponents;
glGenTextures(1, &textureID); unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
if (data)
int width, height, nrComponents; {
unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0); GLenum format;
if (data) if (nrComponents == 1)
{ format = GL_RED;
GLenum format; else if (nrComponents == 3)
if (nrComponents == 1) format = GL_RGB;
format = GL_RED; else if (nrComponents == 4)
else if (nrComponents == 3) format = GL_RGBA;
format = GL_RGB;
else if (nrComponents == 4) glBindTexture(GL_TEXTURE_2D, textureID);
format = GL_RGBA; glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glGenerateMipmap(GL_TEXTURE_2D); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); stbi_image_free(data);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); }
else
stbi_image_free(data); {
} std::cout << "Texture failed to load at path: " << path << std::endl;
else stbi_image_free(data);
{ }
std::cout << "Texture failed to load at path: " << path << std::endl;
stbi_image_free(data); return textureID;
} }
return textureID;
}