Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <GL/glew.h>
- #include <SDL2/SDL.h>
- #include <glm/glm.hpp>
- #include <glm/gtc/matrix_transform.hpp>
- #include <cstdio>
- #define SKIP 1
- inline void glError(const char *file, int line) {
- GLenum err;
- while((err = glGetError()) != GL_NO_ERROR){
- char error[128];
- switch(err) {
- case GL_INVALID_ENUM: snprintf(error, sizeof(error), "%s", "INVALID_ENUM"); break;
- case GL_INVALID_VALUE: snprintf(error, sizeof(error), "%s", "INVALID_VALUE"); break;
- case GL_INVALID_OPERATION: snprintf(error, sizeof(error), "%s", "INVALID_OPERATION"); break;
- case GL_OUT_OF_MEMORY: snprintf(error, sizeof(error), "%s", "OUT_OF_MEMORY"); break;
- case GL_INVALID_FRAMEBUFFER_OPERATION: snprintf(error, sizeof(error), "%s", "INVALID_FRAMEBUFFER_OPERATION"); break;
- default: snprintf(error, sizeof(error), "%s", "UNKNOWN_ERROR"); break;
- }
- fprintf(stderr, "GL%s - %s: %d\n", error, file, line);
- }
- }
- static inline void validateShader(GLuint shader){
- const unsigned int BUFFER_SIZE = 512;
- char buffer[BUFFER_SIZE];
- //memset(buffer, 0, BUFFER_SIZE);
- GLsizei length = 0;
- glGetShaderInfoLog(shader, BUFFER_SIZE, &length, buffer);
- if(length>0){
- printf("Shader %d compile error: %s\n", shader, buffer);
- }
- }
- static inline bool validateProgram(GLuint program){
- const GLsizei BUFFER_SIZE = 512;
- GLchar buffer[BUFFER_SIZE];
- memset(buffer, 0, BUFFER_SIZE);
- GLsizei length = 0;
- glGetProgramInfoLog(program, BUFFER_SIZE, &length, buffer);
- if(length>0){
- printf("Program %d link error: %s\n", program, buffer);
- }
- glValidateProgram(program);
- GLint status;
- glGetProgramiv(program, GL_VALIDATE_STATUS, &status);
- if(status == GL_FALSE){
- printf("Error validating program %d.\n", program);
- return false;
- }
- return true;
- }
- struct Vertex{
- glm::vec3 p, n;
- };
- static const glm::vec3 vs[] = {
- glm::vec3( 1.0, -1.0, -1.0),
- glm::vec3( 1.0, -1.0, 1.0),
- glm::vec3(-1.0, -1.0, 1.0),
- glm::vec3(-1.0, -1.0, -1.0),
- glm::vec3( 1.0, 1.0, -1.0),
- glm::vec3( 1.0, 1.0, 1.0),
- glm::vec3(-1.0, 1.0, 1.0),
- glm::vec3(-1.0, 1.0, -1.0)
- };
- static const glm::vec3 ns[] = {
- glm::vec3( 0.0, -1.0, 0.0),
- glm::vec3( 0.0, 1.0, 0.0),
- glm::vec3( 1.0, 0.0, 0.0),
- glm::vec3( 0.0, 0.0, 1.0),
- glm::vec3(-1.0, 0.0, 0.0),
- glm::vec3( 0.0, 0.0, -1.0)
- };
- static const Vertex cube_vertices[] = {
- Vertex{vs[0], ns[0]}, Vertex{vs[1], ns[0]}, Vertex{vs[2], ns[0]},
- Vertex{vs[0], ns[0]}, Vertex{vs[2], ns[0]}, Vertex{vs[3], ns[0]},
- Vertex{vs[4], ns[1]}, Vertex{vs[7], ns[1]}, Vertex{vs[6], ns[1]},
- Vertex{vs[4], ns[1]}, Vertex{vs[6], ns[1]}, Vertex{vs[5], ns[1]},
- Vertex{vs[0], ns[2]}, Vertex{vs[4], ns[2]}, Vertex{vs[5], ns[2]},
- Vertex{vs[0], ns[2]}, Vertex{vs[5], ns[2]}, Vertex{vs[1], ns[2]},
- Vertex{vs[1], ns[3]}, Vertex{vs[5], ns[3]}, Vertex{vs[6], ns[3]},
- Vertex{vs[1], ns[3]}, Vertex{vs[6], ns[3]}, Vertex{vs[2], ns[3]},
- Vertex{vs[2], ns[4]}, Vertex{vs[6], ns[4]}, Vertex{vs[7], ns[4]},
- Vertex{vs[2], ns[4]}, Vertex{vs[7], ns[4]}, Vertex{vs[3], ns[4]},
- Vertex{vs[4], ns[5]}, Vertex{vs[0], ns[5]}, Vertex{vs[3], ns[5]},
- Vertex{vs[4], ns[5]}, Vertex{vs[3], ns[5]}, Vertex{vs[7], ns[5]}
- };
- int main(int argc, char* argv[]){
- if(SDL_Init(SDL_INIT_VIDEO) < 0){
- SDL_Quit();
- return 0;
- }
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
- SDL_Window* window = SDL_CreateWindow(
- "test",
- SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
- 600, 600,
- SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN
- );
- if(!window){
- SDL_Quit();
- return 0;
- }
- SDL_GLContext context = SDL_GL_CreateContext(window);
- glewExperimental = GL_TRUE;
- GLenum err = glewInit();
- if(GLEW_OK != err){
- SDL_Quit();
- return 0;
- }
- glError(__FILE__, __LINE__);
- SDL_GL_SetSwapInterval(1);
- //--Setup model matrices
- int n_instances = 4096;
- glm::mat4 modelMatrices[n_instances];
- for(int i = 0, idx = 0; i < 16; ++i){
- for(int j = 0; j < 16; ++j){
- for(int k = 0; k < 16; ++k, ++idx){
- modelMatrices[idx] = glm::translate(
- glm::mat4(1.0), 2.2f * glm::vec3(i, j, -k) - 1.1f * 16.0f * glm::vec3(1.0, 1.0, -1.0)
- );
- }
- }
- }
- //--Upload cube vertices
- GLuint cube_vbo;
- glGenBuffers(1, &cube_vbo);
- glBindBuffer(GL_ARRAY_BUFFER, cube_vbo);
- glBufferData(GL_ARRAY_BUFFER, 12 * 3 * sizeof(Vertex), cube_vertices, GL_STATIC_DRAW);
- //--Upload model matrix
- GLuint mm_vbo;
- glGenBuffers(1, &mm_vbo);
- glBindBuffer(GL_ARRAY_BUFFER, mm_vbo);
- glBufferData(GL_ARRAY_BUFFER, n_instances * sizeof(glm::mat4), modelMatrices, GL_STATIC_DRAW);
- //--Setup vertex format
- GLuint vao;
- glGenVertexArrays(1, &vao);
- glBindVertexArray(vao);
- int va_idx = 0;
- glEnableVertexAttribArray(va_idx);
- glVertexAttribFormat(va_idx, 3, GL_FLOAT, GL_FALSE, 0);
- glVertexAttribBinding(va_idx, 0);
- ++va_idx;
- #if SKIP == 1
- ++va_idx;
- #endif
- glEnableVertexAttribArray(va_idx);
- glVertexAttribFormat(va_idx, 3, GL_FLOAT, GL_FALSE, sizeof(glm::vec3));
- glVertexAttribBinding(va_idx, 0);
- ++va_idx;
- for(int i = 0; i < 4; i++){ //Model Matrices
- glEnableVertexAttribArray(va_idx);
- glVertexAttribFormat(va_idx, 4, GL_FLOAT, GL_FALSE, sizeof(float) * i * 4);
- glVertexAttribBinding(va_idx, 1);
- ++va_idx;
- }
- glVertexAttribDivisor(1, 1);
- glBindVertexArray(0);
- //--Setup shaders
- GLuint shader;
- GLint loc_projectionMatrix, loc_mvMatrix;
- {
- const char* vs_source =
- "#version 330 core\n"
- "layout(location = 0) in vec3 in_position;\n"
- #if SKIP == 1
- "layout(location = 2) in vec3 in_normal;\n"
- "layout(location = 3) in mat4 modelMatrix;\n"
- #else
- "layout(location = 1) in vec3 in_normal;\n"
- "layout(location = 2) in mat4 modelMatrix;\n"
- #endif
- "uniform mat4 projectionMatrix;\n"
- "uniform mat4 mvMatrix;\n"
- "smooth out vec3 normal;\n"
- "void main(void){\n"
- " normal = mat3(transpose(inverse(mvMatrix * modelMatrix))) * in_normal;\n"
- " gl_Position = projectionMatrix * mvMatrix * modelMatrix * vec4(in_position, 1.0);\n"
- "}\n";
- GLuint vs = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vs, 1, &vs_source, 0);
- glCompileShader(vs);
- validateShader(vs);
- const char* fs_source =
- "#version 330 core\n"
- "smooth in vec3 normal;\n"
- "layout(location = 0) out vec4 color;\n"
- "void main(void){\n"
- " color = vec4(normal, 1.0);\n"
- "}\n";
- GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
- glShaderSource(fs, 1, &fs_source, 0);
- glCompileShader(fs);
- validateShader(fs);
- shader = glCreateProgram();
- glAttachShader(shader, vs);
- glAttachShader(shader, fs);
- glLinkProgram(shader);
- glDetachShader(shader, vs);
- glDetachShader(shader, fs);
- glDeleteShader(vs);
- glDeleteShader(fs);
- if(!validateProgram(shader)){
- glDeleteBuffers(1, &cube_vbo);
- glDeleteVertexArrays(1, &vao);
- glDeleteProgram(shader);
- SDL_GL_DeleteContext(context);
- SDL_DestroyWindow(window);
- SDL_Quit();
- return 0;
- }
- loc_projectionMatrix = glGetUniformLocation(shader, "projectionMatrix");
- loc_mvMatrix = glGetUniformLocation(shader, "mvMatrix");
- }
- glm::mat4 projectionMatrix = glm::perspective(glm::radians(60.0), 1.0, 10.0, 300.0);
- glm::mat4 viewMatrix = glm::lookAt(glm::vec3(0.0, 0.0, 80.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));
- //--Setup uniforms
- glUseProgram(shader);
- {
- glUniformMatrix4fv(loc_projectionMatrix, 1, GL_FALSE, &projectionMatrix[0][0]);
- glUniformMatrix4fv(loc_mvMatrix, 1, GL_FALSE, &viewMatrix[0][0]);
- }
- glUseProgram(0);
- bool quit = false;
- SDL_Event event;
- glClearColor(0.0, 0.0, 0.0, 1.0);
- glViewport(0, 0, 600, 600);
- glEnable(GL_CULL_FACE);
- glCullFace(GL_BACK);
- glEnable(GL_DEPTH_TEST);
- glBindVertexArray(vao);
- glm::mat4 mvMatrix = viewMatrix;
- while(!quit){
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- glUseProgram(shader);
- mvMatrix = glm::rotate(mvMatrix, glm::radians(0.4f), glm::vec3(0.0, 1.0, 1.0));
- glUniformMatrix4fv(loc_mvMatrix, 1, GL_FALSE, &mvMatrix[0][0]);
- glBindVertexBuffer(0, cube_vbo, 0, sizeof(Vertex));
- glBindVertexBuffer(1, mm_vbo, 0, sizeof(glm::mat4));
- glDrawArraysInstanced(GL_TRIANGLES, 0, 12 * 3, n_instances);
- glUseProgram(0);
- while(SDL_PollEvent(&event) != 0){
- if(event.type == SDL_QUIT) quit = true;
- }
- SDL_GL_SwapWindow(window);
- }
- glBindVertexArray(0);
- glDeleteBuffers(1, &cube_vbo);
- glDeleteVertexArrays(1, &vao);
- SDL_GL_DeleteContext(context);
- SDL_DestroyWindow(window);
- SDL_Quit();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement