mirror of
https://github.com/JoeyDeVries/LearnOpenGL.git
synced 2026-01-30 20:13:22 +08:00
Spheres model matrix generation fix
Fix of integer division resulting in some spheres being rendered at same position. Removed redundant float cast as all operands are being promoted to double anyways.
This commit is contained in:
@@ -1,373 +1,376 @@
|
|||||||
#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__
|
||||||
// glfw window creation
|
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // uncomment this statement to fix compilation on OS X
|
||||||
// --------------------
|
#endif
|
||||||
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
|
|
||||||
glfwMakeContextCurrent(window);
|
// glfw window creation
|
||||||
if (window == NULL)
|
// --------------------
|
||||||
{
|
GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
|
||||||
std::cout << "Failed to create GLFW window" << std::endl;
|
glfwMakeContextCurrent(window);
|
||||||
glfwTerminate();
|
if (window == NULL)
|
||||||
return -1;
|
{
|
||||||
}
|
std::cout << "Failed to create GLFW window" << std::endl;
|
||||||
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
glfwTerminate();
|
||||||
glfwSetCursorPosCallback(window, mouse_callback);
|
return -1;
|
||||||
glfwSetScrollCallback(window, scroll_callback);
|
}
|
||||||
|
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
|
||||||
// tell GLFW to capture our mouse
|
glfwSetCursorPosCallback(window, mouse_callback);
|
||||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
glfwSetScrollCallback(window, scroll_callback);
|
||||||
|
|
||||||
// glad: load all OpenGL function pointers
|
// tell GLFW to capture our mouse
|
||||||
// ---------------------------------------
|
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;
|
// ---------------------------------------
|
||||||
return -1;
|
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
|
||||||
}
|
{
|
||||||
|
std::cout << "Failed to initialize GLAD" << std::endl;
|
||||||
// configure global opengl state
|
return -1;
|
||||||
// -----------------------------
|
}
|
||||||
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.setVec3("albedo", 0.5f, 0.0f, 0.0f);
|
Shader shader("1.1.pbr.vs", "1.1.pbr.fs");
|
||||||
shader.setFloat("ao", 1.0f);
|
|
||||||
|
shader.use();
|
||||||
// lights
|
shader.setVec3("albedo", 0.5f, 0.0f, 0.0f);
|
||||||
// ------
|
shader.setFloat("ao", 1.0f);
|
||||||
glm::vec3 lightPositions[] = {
|
|
||||||
glm::vec3(-10.0f, 10.0f, 10.0f),
|
// 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 lightColors[] = {
|
glm::vec3(-10.0f, -10.0f, 10.0f),
|
||||||
glm::vec3(300.0f, 300.0f, 300.0f),
|
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),
|
||||||
int nrRows = 7;
|
glm::vec3(300.0f, 300.0f, 300.0f),
|
||||||
int nrColumns = 7;
|
glm::vec3(300.0f, 300.0f, 300.0f)
|
||||||
float spacing = 2.5;
|
};
|
||||||
|
int nrRows = 7;
|
||||||
// initialize static shader uniforms before rendering
|
int nrColumns = 7;
|
||||||
// --------------------------------------------------
|
float spacing = 2.5;
|
||||||
glm::mat4 projection = glm::perspective(camera.Zoom, (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
|
|
||||||
shader.use();
|
// initialize static shader uniforms before rendering
|
||||||
shader.setMat4("projection", projection);
|
// --------------------------------------------------
|
||||||
|
glm::mat4 projection = glm::perspective(glm::radians(camera.Zoom), (float)SCR_WIDTH / (float)SCR_HEIGHT, 0.1f, 100.0f);
|
||||||
// render loop
|
shader.use();
|
||||||
// -----------
|
shader.setMat4("projection", projection);
|
||||||
while (!glfwWindowShouldClose(window))
|
|
||||||
{
|
// render loop
|
||||||
// per-frame time logic
|
// -----------
|
||||||
// --------------------
|
while (!glfwWindowShouldClose(window))
|
||||||
float currentFrame = glfwGetTime();
|
{
|
||||||
deltaTime = currentFrame - lastFrame;
|
// per-frame time logic
|
||||||
lastFrame = currentFrame;
|
// --------------------
|
||||||
|
float currentFrame = glfwGetTime();
|
||||||
// input
|
deltaTime = currentFrame - lastFrame;
|
||||||
// -----
|
lastFrame = currentFrame;
|
||||||
processInput(window);
|
|
||||||
|
// input
|
||||||
// render
|
// -----
|
||||||
// ------
|
processInput(window);
|
||||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
// render
|
||||||
|
// ------
|
||||||
shader.use();
|
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||||
glm::mat4 view = camera.GetViewMatrix();
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
shader.setMat4("view", view);
|
|
||||||
shader.setVec3("camPos", camera.Position);
|
shader.use();
|
||||||
|
glm::mat4 view = camera.GetViewMatrix();
|
||||||
// render rows*column number of spheres with varying metallic/roughness values scaled by rows and columns respectively
|
shader.setMat4("view", view);
|
||||||
glm::mat4 model;
|
shader.setVec3("camPos", camera.Position);
|
||||||
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
|
||||||
shader.setFloat("metallic", (float)row / (float)nrRows);
|
glm::mat4 model;
|
||||||
for (unsigned int col = 0; col < nrColumns; ++col)
|
for (unsigned int row = 0; row < nrRows; ++row)
|
||||||
{
|
{
|
||||||
// we clamp the roughness to 0.025 - 1.0 as perfectly smooth surfaces (roughness of 0.0) tend to look a bit off
|
shader.setFloat("metallic", (float)row / (float)nrRows);
|
||||||
// on direct lighting.
|
for (unsigned int col = 0; col < nrColumns; ++col)
|
||||||
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
|
||||||
model = glm::mat4();
|
// on direct lighting.
|
||||||
model = glm::translate(model, glm::vec3(
|
shader.setFloat("roughness", glm::clamp((float)col / (float)nrColumns, 0.05f, 1.0f));
|
||||||
(float)(col - (nrColumns / 2)) * spacing,
|
|
||||||
(float)(row - (nrRows / 2)) * spacing,
|
model = glm::mat4();
|
||||||
0.0f
|
model = glm::translate(model, glm::vec3(
|
||||||
));
|
(col - (nrColumns / 2.)) * spacing,
|
||||||
shader.setMat4("model", model);
|
(row - (nrRows / 2.)) * spacing,
|
||||||
renderSphere();
|
0.0f
|
||||||
}
|
));
|
||||||
}
|
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.
|
|
||||||
for (unsigned int i = 0; i < sizeof(lightPositions) / sizeof(lightPositions[0]); ++i)
|
// 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
|
||||||
glm::vec3 newPos = lightPositions[i] + glm::vec3(sin(glfwGetTime() * 5.0) * 5.0, 0.0, 0.0);
|
// keeps the codeprint small.
|
||||||
newPos = lightPositions[i];
|
for (unsigned int i = 0; i < sizeof(lightPositions) / sizeof(lightPositions[0]); ++i)
|
||||||
shader.setVec3("lightPositions[" + std::to_string(i) + "]", newPos);
|
{
|
||||||
shader.setVec3("lightColors[" + std::to_string(i) + "]", lightColors[i]);
|
glm::vec3 newPos = lightPositions[i] + glm::vec3(sin(glfwGetTime() * 5.0) * 5.0, 0.0, 0.0);
|
||||||
|
newPos = lightPositions[i];
|
||||||
model = glm::mat4();
|
shader.setVec3("lightPositions[" + std::to_string(i) + "]", newPos);
|
||||||
model = glm::translate(model, newPos);
|
shader.setVec3("lightColors[" + std::to_string(i) + "]", lightColors[i]);
|
||||||
model = glm::scale(model, glm::vec3(0.5f));
|
|
||||||
shader.setMat4("model", model);
|
model = glm::mat4();
|
||||||
renderSphere();
|
model = glm::translate(model, newPos);
|
||||||
}
|
model = glm::scale(model, glm::vec3(0.5f));
|
||||||
|
shader.setMat4("model", model);
|
||||||
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
|
renderSphere();
|
||||||
// -------------------------------------------------------------------------------
|
}
|
||||||
glfwSwapBuffers(window);
|
|
||||||
glfwPollEvents();
|
// glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
|
||||||
}
|
// -------------------------------------------------------------------------------
|
||||||
|
glfwSwapBuffers(window);
|
||||||
// glfw: terminate, clearing all previously allocated GLFW resources.
|
glfwPollEvents();
|
||||||
// ------------------------------------------------------------------
|
}
|
||||||
glfwTerminate();
|
|
||||||
return 0;
|
// glfw: terminate, clearing all previously allocated GLFW resources.
|
||||||
}
|
// ------------------------------------------------------------------
|
||||||
|
glfwTerminate();
|
||||||
// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
|
return 0;
|
||||||
// ---------------------------------------------------------------------------------------------------------
|
}
|
||||||
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)
|
// ---------------------------------------------------------------------------------------------------------
|
||||||
glfwSetWindowShouldClose(window, true);
|
void processInput(GLFWwindow *window)
|
||||||
|
{
|
||||||
float cameraSpeed = 2.5 * deltaTime;
|
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
|
||||||
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
glfwSetWindowShouldClose(window, true);
|
||||||
camera.ProcessKeyboard(FORWARD, deltaTime);
|
|
||||||
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
float cameraSpeed = 2.5 * deltaTime;
|
||||||
camera.ProcessKeyboard(BACKWARD, deltaTime);
|
if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS)
|
||||||
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
camera.ProcessKeyboard(FORWARD, deltaTime);
|
||||||
camera.ProcessKeyboard(LEFT, deltaTime);
|
if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS)
|
||||||
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
camera.ProcessKeyboard(BACKWARD, deltaTime);
|
||||||
camera.ProcessKeyboard(RIGHT, deltaTime);
|
if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS)
|
||||||
}
|
camera.ProcessKeyboard(LEFT, deltaTime);
|
||||||
|
if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS)
|
||||||
// glfw: whenever the window size changed (by OS or user resize) this callback function executes
|
camera.ProcessKeyboard(RIGHT, deltaTime);
|
||||||
// ---------------------------------------------------------------------------------------------
|
}
|
||||||
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
|
// ---------------------------------------------------------------------------------------------
|
||||||
// height will be significantly larger than specified on retina displays.
|
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
|
||||||
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;
|
{
|
||||||
lastY = ypos;
|
if (firstMouse)
|
||||||
firstMouse = false;
|
{
|
||||||
}
|
lastX = xpos;
|
||||||
|
lastY = ypos;
|
||||||
float xoffset = xpos - lastX;
|
firstMouse = false;
|
||||||
float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
|
}
|
||||||
|
|
||||||
lastX = xpos;
|
float xoffset = xpos - lastX;
|
||||||
lastY = ypos;
|
float yoffset = lastY - ypos; // reversed since y-coordinates go from bottom to top
|
||||||
|
|
||||||
camera.ProcessMouseMovement(xoffset, yoffset);
|
lastX = xpos;
|
||||||
}
|
lastY = ypos;
|
||||||
|
|
||||||
// glfw: whenever the mouse scroll wheel scrolls, this callback is called
|
camera.ProcessMouseMovement(xoffset, yoffset);
|
||||||
// ----------------------------------------------------------------------
|
}
|
||||||
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)
|
||||||
|
{
|
||||||
// renders (and builds at first invocation) a sphere
|
camera.ProcessMouseScroll(yoffset);
|
||||||
// -------------------------------------------------
|
}
|
||||||
unsigned int sphereVAO = 0;
|
|
||||||
unsigned int indexCount;
|
// renders (and builds at first invocation) a sphere
|
||||||
void renderSphere()
|
// -------------------------------------------------
|
||||||
{
|
unsigned int sphereVAO = 0;
|
||||||
if (sphereVAO == 0)
|
unsigned int indexCount;
|
||||||
{
|
void renderSphere()
|
||||||
glGenVertexArrays(1, &sphereVAO);
|
{
|
||||||
|
if (sphereVAO == 0)
|
||||||
unsigned int vbo, ebo;
|
{
|
||||||
glGenBuffers(1, &vbo);
|
glGenVertexArrays(1, &sphereVAO);
|
||||||
glGenBuffers(1, &ebo);
|
|
||||||
|
unsigned int vbo, ebo;
|
||||||
std::vector<glm::vec3> positions;
|
glGenBuffers(1, &vbo);
|
||||||
std::vector<glm::vec2> uv;
|
glGenBuffers(1, &ebo);
|
||||||
std::vector<glm::vec3> normals;
|
|
||||||
std::vector<unsigned int> indices;
|
std::vector<glm::vec3> positions;
|
||||||
|
std::vector<glm::vec2> uv;
|
||||||
const unsigned int X_SEGMENTS = 64;
|
std::vector<glm::vec3> normals;
|
||||||
const unsigned int Y_SEGMENTS = 64;
|
std::vector<unsigned int> indices;
|
||||||
const float PI = 3.14159265359;
|
|
||||||
for (unsigned int y = 0; y <= Y_SEGMENTS; ++y)
|
const unsigned int X_SEGMENTS = 64;
|
||||||
{
|
const unsigned int Y_SEGMENTS = 64;
|
||||||
for (unsigned int x = 0; x <= X_SEGMENTS; ++x)
|
const float PI = 3.14159265359;
|
||||||
{
|
for (unsigned int y = 0; y <= Y_SEGMENTS; ++y)
|
||||||
float xSegment = (float)x / (float)X_SEGMENTS;
|
{
|
||||||
float ySegment = (float)y / (float)Y_SEGMENTS;
|
for (unsigned int x = 0; x <= X_SEGMENTS; ++x)
|
||||||
float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
{
|
||||||
float yPos = std::cos(ySegment * PI);
|
float xSegment = (float)x / (float)X_SEGMENTS;
|
||||||
float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
float ySegment = (float)y / (float)Y_SEGMENTS;
|
||||||
|
float xPos = std::cos(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
||||||
positions.push_back(glm::vec3(xPos, yPos, zPos));
|
float yPos = std::cos(ySegment * PI);
|
||||||
uv.push_back(glm::vec2(xSegment, ySegment));
|
float zPos = std::sin(xSegment * 2.0f * PI) * std::sin(ySegment * PI);
|
||||||
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)
|
}
|
||||||
{
|
|
||||||
if (!oddRow) // even rows: y == 0, y == 2; and so on
|
bool oddRow = false;
|
||||||
{
|
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);
|
{
|
||||||
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
|
for (int x = 0; x <= X_SEGMENTS; ++x)
|
||||||
}
|
{
|
||||||
}
|
indices.push_back(y * (X_SEGMENTS + 1) + x);
|
||||||
else
|
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
|
||||||
{
|
}
|
||||||
for (int x = X_SEGMENTS; x >= 0; --x)
|
}
|
||||||
{
|
else
|
||||||
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
|
{
|
||||||
indices.push_back(y * (X_SEGMENTS + 1) + x);
|
for (int x = X_SEGMENTS; x >= 0; --x)
|
||||||
}
|
{
|
||||||
}
|
indices.push_back((y + 1) * (X_SEGMENTS + 1) + x);
|
||||||
oddRow = !oddRow;
|
indices.push_back(y * (X_SEGMENTS + 1) + x);
|
||||||
}
|
}
|
||||||
indexCount = indices.size();
|
}
|
||||||
|
oddRow = !oddRow;
|
||||||
std::vector<float> data;
|
}
|
||||||
for (int i = 0; i < positions.size(); ++i)
|
indexCount = indices.size();
|
||||||
{
|
|
||||||
data.push_back(positions[i].x);
|
std::vector<float> data;
|
||||||
data.push_back(positions[i].y);
|
for (int i = 0; i < positions.size(); ++i)
|
||||||
data.push_back(positions[i].z);
|
{
|
||||||
if (uv.size() > 0)
|
data.push_back(positions[i].x);
|
||||||
{
|
data.push_back(positions[i].y);
|
||||||
data.push_back(uv[i].x);
|
data.push_back(positions[i].z);
|
||||||
data.push_back(uv[i].y);
|
if (uv.size() > 0)
|
||||||
}
|
{
|
||||||
if (normals.size() > 0)
|
data.push_back(uv[i].x);
|
||||||
{
|
data.push_back(uv[i].y);
|
||||||
data.push_back(normals[i].x);
|
}
|
||||||
data.push_back(normals[i].y);
|
if (normals.size() > 0)
|
||||||
data.push_back(normals[i].z);
|
{
|
||||||
}
|
data.push_back(normals[i].x);
|
||||||
}
|
data.push_back(normals[i].y);
|
||||||
glBindVertexArray(sphereVAO);
|
data.push_back(normals[i].z);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
}
|
||||||
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
|
}
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
glBindVertexArray(sphereVAO);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
glBindBuffer(GL_ARRAY_BUFFER, vbo);
|
||||||
float stride = (3 + 2 + 3) * sizeof(float);
|
glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), &data[0], GL_STATIC_DRAW);
|
||||||
glEnableVertexAttribArray(0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
|
||||||
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), &indices[0], GL_STATIC_DRAW);
|
||||||
glEnableVertexAttribArray(1);
|
float stride = (3 + 2 + 3) * sizeof(float);
|
||||||
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, (void*)(3 * sizeof(float)));
|
glEnableVertexAttribArray(0);
|
||||||
glEnableVertexAttribArray(2);
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0);
|
||||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, stride, (void*)(5 * sizeof(float)));
|
glEnableVertexAttribArray(1);
|
||||||
}
|
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, stride, (void*)(3 * sizeof(float)));
|
||||||
|
glEnableVertexAttribArray(2);
|
||||||
glBindVertexArray(sphereVAO);
|
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, stride, (void*)(5 * sizeof(float)));
|
||||||
glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);
|
}
|
||||||
}
|
|
||||||
|
glBindVertexArray(sphereVAO);
|
||||||
// utility function for loading a 2D texture from file
|
glDrawElements(GL_TRIANGLE_STRIP, indexCount, GL_UNSIGNED_INT, 0);
|
||||||
// ---------------------------------------------------
|
}
|
||||||
unsigned int loadTexture(char const * path)
|
|
||||||
{
|
// utility function for loading a 2D texture from file
|
||||||
unsigned int textureID;
|
// ---------------------------------------------------
|
||||||
glGenTextures(1, &textureID);
|
unsigned int loadTexture(char const * path)
|
||||||
|
{
|
||||||
int width, height, nrComponents;
|
unsigned int textureID;
|
||||||
unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
|
glGenTextures(1, &textureID);
|
||||||
if (data)
|
|
||||||
{
|
int width, height, nrComponents;
|
||||||
GLenum format;
|
unsigned char *data = stbi_load(path, &width, &height, &nrComponents, 0);
|
||||||
if (nrComponents == 1)
|
if (data)
|
||||||
format = GL_RED;
|
{
|
||||||
else if (nrComponents == 3)
|
GLenum format;
|
||||||
format = GL_RGB;
|
if (nrComponents == 1)
|
||||||
else if (nrComponents == 4)
|
format = GL_RED;
|
||||||
format = GL_RGBA;
|
else if (nrComponents == 3)
|
||||||
|
format = GL_RGB;
|
||||||
glBindTexture(GL_TEXTURE_2D, textureID);
|
else if (nrComponents == 4)
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
format = GL_RGBA;
|
||||||
glGenerateMipmap(GL_TEXTURE_2D);
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textureID);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, data);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||||
stbi_image_free(data);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
}
|
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;
|
}
|
||||||
stbi_image_free(data);
|
else
|
||||||
}
|
{
|
||||||
|
std::cout << "Texture failed to load at path: " << path << std::endl;
|
||||||
return textureID;
|
stbi_image_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return textureID;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user