Aller au contenu principal

Exemple

Afin que vous ayez une idée claire de ce à quoi ressemble un code minimal OpenGL 3 qui affiche un triangle coloré, voici l'exemple du triangle coloré version GL 3+ ! Pas la peine de lire dans le détail à nouveau, vous aurez les TPs pour vous y faire x)

#include <p6/p6.h>

int main()
{
auto ctx = p6::Context{};

const char* vertexShaderSource = R"STR(
#version 330
layout(location = 0) in vec3 iVertexPosition;
layout(location = 1) in vec3 iVertexColor;
out vec3 FragColor;

void main() {
FragColor = iVertexColor;
gl_Position = vec4(iVertexPosition, 1.f);
}
)STR";

const char* fragmentShaderSource = R"STR(
#version 330
in vec3 FragColor;
out vec4 oFragColor;

void main() {
oFragColor = vec4(FragColor, 1.f);
}
)STR";

GLuint vbo, vao;

glGenBuffers(1, &vbo);

glBindBuffer(GL_ARRAY_BUFFER, vbo);

GLfloat vertices[] = {
-0.5, -0.5, /* Position */ 1., 0., 0., /* Couleur */ // Premier vertex
0.5, -0.5, /* Position */ 0., 1., 0., /* Couleur */ // Deuxième vertex
0., 0.5, /* Position */ 0., 0., 1. /* Couleur */ // Troisème vertex
};

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);

glGenVertexArrays(1, &vao);

glBindVertexArray(vao);

glBindBuffer(GL_ARRAY_BUFFER, vbo);

glEnableVertexAttribArray(0);
glVertexAttribPointer(
0,
2,
GL_FLOAT,
GL_FALSE,
5 * sizeof(GLfloat),
0);

glEnableVertexAttribArray(1);
glVertexAttribPointer(
1,
3,
GL_FLOAT,
GL_FALSE,
5 * sizeof(GLfloat),
(void*)(2 * sizeof(GLfloat)));

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray(0);

GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);

glShaderSource(vertexShader, 1, &vertexShaderSource, 0);

glCompileShader(vertexShader);

GLint compileStatus;

glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus == GL_FALSE)
{
GLint logLength;
glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &logLength);

char* log = new char[logLength];

glGetShaderInfoLog(vertexShader, logLength, 0, log);
std::cerr << "Vertex Shader error:" << log << std::endl;
std::cerr << vertexShaderSource << std::endl;

delete[] log;
return 2;
}

GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

glShaderSource(fragmentShader, 1, &fragmentShaderSource, 0);

glCompileShader(fragmentShader);

glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compileStatus);
if (compileStatus == GL_FALSE)
{
GLint logLength;
glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &logLength);

char* log = new char[logLength];

glGetShaderInfoLog(fragmentShader, logLength, 0, log);
std::cerr << "Fragment Shader error:" << log << std::endl;
std::cerr << fragmentShaderSource << std::endl;

delete[] log;
return 2;
}

GLuint program;

program = glCreateProgram();

glAttachShader(program, vertexShader);
glAttachShader(program, fragmentShader);

glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);

glLinkProgram(program);

GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (linkStatus == GL_FALSE)
{
GLint logLength;
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength);

char* log = new char[logLength];

glGetProgramInfoLog(program, logLength, 0, log);
std::cerr << "Program link error:" << log << std::endl;

delete[] log;
return 2;
}

glUseProgram(program);

ctx.update = [&]() {
glBindVertexArray(vao);

glDrawArrays(GL_TRIANGLES, 0 /* Pas d'offset au début du VBO */, 3);

glBindVertexArray(0);
};

ctx.start();

glDeleteProgram(program);
glDeleteVertexArrays(1, &vao);
glDeleteBuffers(1, &vbo);
return 0;
}