Use VBO indexing.

This commit is contained in:
Nicolás Ortega Froysa 2018-10-25 17:57:52 +02:00
parent 6e80cc759f
commit eb41b8178c
No known key found for this signature in database
GPG Key ID: FEC70E3BAE2E69BF
7 changed files with 299 additions and 147 deletions

View File

@ -46,9 +46,11 @@ include_directories(
set(SRCS set(SRCS
"src/camera.cpp" "src/camera.cpp"
"src/cube.cpp"
"src/input.cpp" "src/input.cpp"
"src/main.cpp" "src/main.cpp"
"src/shaders.cpp") "src/shaders.cpp"
"src/simulation.cpp")
# Define C++ compiler flags # Define C++ compiler flags
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -Wpedantic -Wfatal-errors -Werror -pedantic-errors -fno-elide-constructors") set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -Wpedantic -Wfatal-errors -Werror -pedantic-errors -fno-elide-constructors")

102
src/cube.cpp Normal file
View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net> All rights reserved.
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "cube.hpp"
#include <cstdlib>
#include <ctime>
cube::cube() {
glGenBuffers(1, &vbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vbuffer);
glBufferData(GL_ARRAY_BUFFER,
vertices.size() * sizeof(GLfloat),
&vertices[0], GL_STATIC_DRAW);
glGenBuffers(1, &ibuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
indices.size() * sizeof(GLuint),
&indices[0], GL_STATIC_DRAW);
srand(static_cast<unsigned int>(time(0)));
for(size_t i = 0; i < vertices.size(); i += 3)
{
colors.push_back(static_cast<float>(rand()) /
static_cast<float>(RAND_MAX));
color_ascending.push_back(rand() % 2 ? true : false);
}
glGenBuffers(1, &cbuffer);
glBindBuffer(GL_ARRAY_BUFFER, cbuffer);
glBufferData(GL_ARRAY_BUFFER,
colors.size() * sizeof(GLfloat),
&colors[0], GL_STATIC_DRAW);
}
cube::~cube() {
glDeleteBuffers(1, &vbuffer);
glDeleteBuffers(1, &ibuffer);
glDeleteBuffers(1, &cbuffer);
}
void cube::render() {
shift_colors();
// setup vertex buffer
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, cbuffer);
glBufferData(GL_ARRAY_BUFFER,
colors.size() * sizeof(GLfloat),
&colors[0], GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibuffer);
glDrawElements(GL_TRIANGLES, indices.size(),
GL_UNSIGNED_INT, nullptr);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
void cube::shift_colors() {
for(size_t i = 0; i < colors.size(); ++i)
{
colors[i] += color_ascending[i] ? color_shift :
-color_shift;
if(colors[i] >= 1.0f)
{
colors[i] = 1.0f;
color_ascending[i] = false;
}
else if(colors[i] <= 0.0f)
{
colors[i] = 0.0f;
color_ascending[i] = true;
}
}
}

78
src/cube.hpp Normal file
View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net> All rights reserved.
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#include <vector>
#include <GL/glew.h>
#include <GL/gl.h>
class cube {
public:
cube();
~cube();
void render();
private:
const float color_shift = 0.0001;
void shift_colors();
// OpenGL buffers
GLuint vbuffer; // vertex buffer
GLuint ibuffer; // index buffer
GLuint cbuffer; // color buffer
// array of vertices
const std::vector<GLfloat> vertices = {
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f
};
// index array to make triangles
// NOTE: multiply the position x3 to get the position
// in the `vertices' array
const std::vector<GLuint> indices = {
0, 1, 2,
1, 3, 2,
2, 3, 7,
2, 7, 6,
2, 6, 4,
2, 4, 0,
0, 5, 1,
0, 4, 5,
1, 5, 3,
3, 5, 7,
6, 7, 5,
6, 5, 4
};
// color control
std::vector<GLfloat> colors;
std::vector<bool> color_ascending;
};

View File

@ -24,47 +24,12 @@
#pragma once #pragma once
#include "input.hpp" #include <SDL2/SDL.h>
#include <GL/gl.h>
#define SCREEN_WIDTH 800 #define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600 #define SCREEN_HEIGHT 600
extern input *in_sys; extern SDL_Window *window;
extern GLuint program_id;
static const GLfloat g_vertex_buffer_data[] = { extern GLuint matrix_id;
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
1.0f,-1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
-1.0f,-1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f,-1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f,-1.0f,
1.0f,-1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f,-1.0f,
-1.0f, 1.0f,-1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,-1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f,-1.0f, 1.0f
};

View File

@ -23,21 +23,18 @@
*/ */
#include <iostream> #include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <GL/glew.h> #include <GL/glew.h>
#include <GL/gl.h> #include <GL/gl.h>
#include <glm/gtc/matrix_transform.hpp>
#include "input.hpp"
#include "globals.hpp" #include "globals.hpp"
#include "shaders.hpp" #include "shaders.hpp"
#include "camera.hpp" #include "simulation.hpp"
input *in_sys; SDL_Window *window;
GLuint program_id;
GLuint matrix_id;
int main() { int main() {
if(SDL_Init(SDL_INIT_VIDEO) < 0) if(SDL_Init(SDL_INIT_VIDEO) < 0)
@ -50,7 +47,7 @@ int main() {
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
SDL_GL_CONTEXT_PROFILE_CORE); SDL_GL_CONTEXT_PROFILE_CORE);
SDL_Window *window = SDL_CreateWindow("OpenGL Tutorial", window = SDL_CreateWindow("OpenGL Tutorial",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_WIDTH, SCREEN_HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN); SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
@ -77,115 +74,22 @@ int main() {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS); glDepthFunc(GL_LESS);
//glEnable(GL_CULL_FACE);
// vertex buffer
GLuint vbuffer;
glGenBuffers(1, &vbuffer);
glBindBuffer(GL_ARRAY_BUFFER, vbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data),
g_vertex_buffer_data, GL_STATIC_DRAW);
srand(static_cast<unsigned int>(time(0)));
GLfloat color_buffer_data[108];
// generate random colors every time
for(int i = 0; i < 108; ++i)
{
color_buffer_data[i] = static_cast<float>(rand()) /
static_cast<float>(RAND_MAX);
}
bool color_ascend[108];
for(int i = 0; i < 108; ++i)
color_ascend[i] = rand() % 2 ? true : false;
// color buffer
GLuint cbuffer;
glGenBuffers(1, &cbuffer);
glBindBuffer(GL_ARRAY_BUFFER, cbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(color_buffer_data),
color_buffer_data, GL_STATIC_DRAW);
// load the shaders into a GLSL program that can be run // load the shaders into a GLSL program that can be run
GLuint program_id = load_shaders("../shaders/vert_shader.glsl", program_id = load_shaders("../shaders/vert_shader.glsl",
"../shaders/frag_shader.glsl"); "../shaders/frag_shader.glsl");
GLuint matrix_id = glGetUniformLocation(program_id, "MVP"); matrix_id = glGetUniformLocation(program_id, "MVP");
// set the clear color to black // set the clear color to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
in_sys = new input(); run();
camera cam;
while(true)
{
cam.update(in_sys);
// clear screen
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program_id);
glm::mat4 mvp;
{
glm::mat4 proj = glm::perspective(glm::radians(45.0f),
static_cast<float>(SCREEN_WIDTH) / static_cast<float>(SCREEN_HEIGHT),
0.1f, 100.0f);
glm::mat4 view = glm::lookAt(
cam.get_pos(), // camera position
glm::vec3(0,0,0), // where the camera is looking
glm::vec3(0,1,0) // which way is vertically up
);
glm::mat4 mod = glm::mat4(1.0f); // identity matrix, object is at origin
mvp = proj * view * mod;
}
glUniformMatrix4fv(matrix_id, 1, GL_FALSE, &mvp[0][0]);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, vbuffer);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
// change colors
for(int i = 0; i < 108; ++i)
{
const float color_delta = 0.0001f;
if(color_ascend[i])
color_buffer_data[i] += color_delta;
else
color_buffer_data[i] -= color_delta;
if(color_buffer_data[i] >= 1.0f)
{
color_buffer_data[i] = 1.0f;
color_ascend[i] = false;
}
else if(color_buffer_data[i] <= 0.0f)
{
color_buffer_data[i] = 0.0f;
color_ascend[i] = true;
}
}
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, cbuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(color_buffer_data),
color_buffer_data, GL_STATIC_DRAW);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, nullptr);
glDrawArrays(GL_TRIANGLES, 0, 12*3);
glDisableVertexAttribArray(0);
SDL_GL_SwapWindow(window);
in_sys->sync_events();
if(in_sys->get_action("quit"))
break;
}
#ifdef DEBUG #ifdef DEBUG
std::cout << "Shutting down..." << std::endl; std::cout << "Shutting down..." << std::endl;
#endif #endif
glDeleteProgram(program_id); glDeleteProgram(program_id);
glDeleteBuffers(1, &cbuffer);
glDeleteBuffers(1, &vbuffer);
SDL_GL_DeleteContext(glcontext); SDL_GL_DeleteContext(glcontext);
SDL_DestroyWindow(window); SDL_DestroyWindow(window);
SDL_Quit(); SDL_Quit();

72
src/simulation.cpp Normal file
View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net> All rights reserved.
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#include "simulation.hpp"
#include <GL/glew.h>
#include <GL/gl.h>
#include <glm/gtc/matrix_transform.hpp>
#include <SDL2/SDL.h>
#include "globals.hpp"
#include "input.hpp"
#include "camera.hpp"
#include "cube.hpp"
void run() {
input in_sys;
camera cam;
cube box;
while(not in_sys.get_action("quit"))
{
cam.update(&in_sys);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glUseProgram(program_id);
glm::mat4 mvp;
{
glm::mat4 proj = glm::perspective(glm::radians(45.0f),
static_cast<float>(SCREEN_WIDTH) / static_cast<float>(SCREEN_HEIGHT),
0.1f, 100.0f);
glm::mat4 view = glm::lookAt(
cam.get_pos(), // camera position
glm::vec3(0,0,0), // where the camera is looking
glm::vec3(0,1,0) // which way is vertically up
);
glm::mat4 mod = glm::mat4(1.0f); // identity matrix, object is at origin
mvp = proj * view * mod;
}
glUniformMatrix4fv(matrix_id, 1, GL_FALSE, &mvp[0][0]);
box.render();
SDL_GL_SwapWindow(window);
in_sys.sync_events();
}
}

29
src/simulation.hpp Normal file
View File

@ -0,0 +1,29 @@
/*
* Copyright (C) 2018 Ortega Froysa, Nicolás <nortega@themusicinnoise.net> All rights reserved.
* Author: Ortega Froysa, Nicolás <nortega@themusicinnoise.net>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
#pragma once
#include <GL/glew.h>
void run();