OpenGL Instanced rendering example

You can read about it at many places. Probably the red book and http://ogldev.atspace.co.uk/www/tutorial33/tutorial33.html are one of the best sources. However, there is a lot of information in the red book and the example which is given is not too clear. You just see something rendered and you may have not cover transformations yet or you do not know how to load some model from some file.
In Ogldev you have to read a lot of other tutorials to get aquainted what happens and the tutorial mostly modifies previously written code (the one about loading models with Assimp).
Also, it may be a bit hard to follow since a lot of other stuff is happening as well like texture mapping, etc.

#define GLM_FORCE_RADIANS
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <iostream>
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include "../common/Shader.hpp"
#include "../common/ShaderProgram.hpp"
using namespace glm;
using namespace std;

/*
    checks whether there are errors and prints them
*/
void checkForOpenglErrors() {
    GLenum glErr;
    while ((glErr = glGetError()) != GL_NO_ERROR) {
        std::cerr << "OpenGL error: " << glErr << std::endl;
    }
}

/*
    vertices of a pyramid
*/
GLfloat vertices[] = {
    -1,0,2,
    1,0,2,
    1,0,0,
    -1,0,0,
    0,1,1
};

/*
    indices to represent all of the faces (triangles) of the pyramid
*/
GLushort indices[] = {
    0,1,4,
    1,2,4,
    2,3,4,
    3,0,4
};

/*
    colors for each pyramid instance rendered
*/
GLfloat colors[] = {
    1,0,0,
    0,1,0,
    0,0,1
};

/* Vertex array */
GLuint VAO;

/* Buffers bind to vertex array */
#define NUM_BUFFERS 4
GLuint buffers[NUM_BUFFERS];


/* Locations of buffers in array */
#define POSITION_BUFFER 0
#define INDEX_BUFFER 1
#define COLOR_BUFFER 2
#define TRANS_BUFFER 3

/* Locations of attributes in vertex shader */
#define POSITION_ATTR_LOC 0
#define COLOR_ATTR_LOC 1
#define TRANS_ATTR_LOC 2

void init() {
    /* create aand use shader program */
    ShaderProgram program = ShaderProgram(Shader("shader.vert", GL_VERTEX_SHADER),
     Shader("shader.frag", GL_FRAGMENT_SHADER));
    glUseProgram(program.getProgram());

    /* generate the needed vertex array so that we can use later when rendering */
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    /* generate buffers needed for the pyramid */
    glGenBuffers(NUM_BUFFERS, buffers);

    /* buffer to store vertices */
    glBindBuffer(GL_ARRAY_BUFFER, buffers[POSITION_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glEnableVertexAttribArray(POSITION_ATTR_LOC);
    glVertexAttribPointer(POSITION_ATTR_LOC, 3, GL_FLOAT, GL_FALSE, 0, 0);

    /* index buffer */
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDEX_BUFFER]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    /* buffer for the colors of each pyramid */
    glBindBuffer(GL_ARRAY_BUFFER, buffers[COLOR_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(colors), colors, GL_STATIC_DRAW);
    glVertexAttribPointer(COLOR_ATTR_LOC, 3, GL_FLOAT, GL_FALSE, 0, 0);
    // set change per instance -> every instance will have a new entry from the array buffer
    glVertexAttribDivisor(COLOR_ATTR_LOC, 1);
    glEnableVertexAttribArray(COLOR_ATTR_LOC);

    /*
        create just translate transformations for each pyramid -> 3 pyramids
    */
    mat4 transf[] = {
        translate(mat4(1.0f), vec3(-4.0f, -3.0f, -14.0f)),
        translate(mat4(1.0f), vec3(3.0f, -1.0f, -17.0f)),
        translate(mat4(1.0f), vec3(2.0f, -2.0f, -9.0f))
    };
    glBindBuffer(GL_ARRAY_BUFFER, buffers[TRANS_BUFFER]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(transf), transf, GL_STATIC_DRAW);

    /*
        set the attrib location and enable it. since we have a 4x4 matrix we have
        4 columns of vectors of length 4.
    */
    for (int i = 0; i < 4; ++i) {
        glVertexAttribPointer(TRANS_ATTR_LOC+i, 4, GL_FLOAT, GL_FALSE, sizeof(mat4), (GLvoid *)(i*sizeof(vec4)));
        glVertexAttribDivisor(TRANS_ATTR_LOC+i, 1);
        glEnableVertexAttribArray(TRANS_ATTR_LOC+i);
    }

    // done with VAO
    // unbind
    glBindVertexArray(0);

    /*
        create projection transformation and update the uniform
    */
    GLint projectionLoc = glGetUniformLocation(program.getProgram(), "projection");
    mat4 projection = perspective(45.0f, 4.0f / 3.0f, 0.1f, 100.0f);
    glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, &projection[0][0]);
}

void display() {
    checkForOpenglErrors();

    glClear(GL_COLOR_BUFFER_BIT);

    /* bind and draw */
    glBindVertexArray(VAO);

    /* sizeof(indices) / sizeof(GLushort) will return number of elements in the array */
    glDrawElementsInstanced(GL_TRIANGLES, sizeof(indices) / sizeof(GLushort), GL_UNSIGNED_SHORT, NULL, 3);

    glFlush();

}

int main(int argc, char ** argv)
{

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_RGBA);
    glutInitWindowSize(512, 512);
    glutInitContextVersion(4,3); // freeglut required
    glutInitContextProfile(GLUT_CORE_PROFILE);
    glutCreateWindow("");
    glewExperimental=GL_TRUE;

    if (glewInit()) {
        cerr << "Problem initializing glew" << endl;
        exit(EXIT_FAILURE);
    }

    init();

    glutDisplayFunc(display);

    glutMainLoop();

    return 0;
}

Vertex shader:

#version 430 core

layout (location = 0) in vec3 position;

// per-instance attribute
layout (location = 1) in vec3 color;

// per-instance transformation
layout (location = 2) in mat4 trans;

uniform mat4 projection;


out vec4 col;

void main() {
    gl_Position = projection * trans * vec4(position, 1.0f);
    col = vec4(color, 1.0f);
}

Fragment shader

#version 430 core


in vec4 col;
out vec4 color;

void main() {
    color = col;
}

Error compiling opengl code under Linux

If you have a NVidia card, you are using Linux and trying to compile something using Opengl, then you might have run into the following error:

Inconsistency detected by ld.so: dl-version.c: 224: _dl_check_map_versions: Assertion `needed != ((void *)0)' failed!

This most probably happen to incosistency between NVidia and Mesa drivers for your card. It would be best to choose to use the NVidia drivers in most cases.
Go to directory usr/lib/nvidia-***
It could be nvidia-***-update or something like that. There should be a libGL.so file there. You have to link it to your code. Remove -lGL from the other linker options.

След весело прекарване на празниците отново с много ангажименти

За много години на всички познати!
Весело си прекарах през цялата зимна ваканция! В общи линии си починах добре!
Очакват се доста ангажименти поне до към края Април като работа с клиенти и подготвяне за 3-4 състезания. На ~21 Януари ще има състезания по информатика C/C++. След това почвам да работя по един проект за клиент и след това почвам по проекта за 2те състезания по уеб програмиране – националното по информационни системи в категория Уеб Приложения и Webloz. Дочувам, че имало и някакво състезания в Монтана, по-късно във Варна. Ще се ходи тази година предполагам. По информатика ще съм в B група. Не съм много добре подготвен, но ако отида на областен това ще е успех за мен!

Сдобих се с две нови книги за c++

Вчера си купих две книги със задачи на c++. Съответно има решени задачи и след това няколко сходни задачи, които да се решат. Напоследък съм доста надъхан да решавам разни задачки на c++ като се пробвам и на разни от национални състезания и от международни, но една голяма част са ми над нивото и съответно не мога да се справя с тях. Двете книги са:
– Сборник От Задачи По Програмиране На C++ 1 част

– Сборник От Задачи По Програмиране на C++ 2 част – обектно ориентирано програмиране

Тъй като вече не намирам нещо, което да не знам и да не мога да направя на език php, реших да почна нещо ново и доста по-сложно като c++ за да видя и другата страна на програмирането. Btw написах и свой php framework, а съвсем скоро с един колега ще пуснем сайт за обяви. :)

Защо се занимавам с програмиране

Под програмиране разбирайте писане на приложения (системи,сайтове) на php, java, c++ и другите сходни на тези езици.
Компютрите са ми любимото занимание от много време насам. Помня първия си компютър, помня как бях жаден за знания, помня как бях вманиачен да се науча да правя сайтове още когато бях втори клас. Впоследствие игрите завлядяха моето съзнание и бях станал типичното геймърче, което цикли dota, cs и другите игри, които бяха популярни преди време (донякъде и днес). Единственото, което правих пред компютъра, беше да играя игри. Впоследствие в края на осми клас един приятел ме зариби доста към уеб дизайна така да се каже макар и след време да се отказах да правя дизайнчета и да насоча своето време и внимание изцяло към програмирането (както споменах php, java, c++). Почнах да уча от официални източници четейки документации на функции и въведения на езика, както и учих от сайтове, които предлагат уроци (videotutorials-bg.com, nau4i.me и други, но чуждостранни източници).
Не мога да опиша защо точно се занимавам с програмиране – просто ми харесва, а и така трябва да е – развива логическата мисъл, винаги ще има работа за теб, защото IT секторът е супер развит дори в България. Т.е. ако знаеш някой от топ езиците като php, java, c/c++ то гладен няма да останеш :)
Нямаше голяма аргументация на това защо се занимавам с програмиране, но пък и причините за такова нещо не могат да са чак толкова много :)