2.2 Uniforms

https://www.khronos.org/opengl/wiki/Uniform_(GLSL)


Complete Source Code:

Download


Graphics.cpp

#include "Graphics.h"

#include <glm/glm.hpp>

#include <glm/gtc/type_ptr.hpp>

#include <iostream>

#include <vector>

#include "Shader.h"

using namespace std;

using namespace glm;

struct Vertex {

vec3 Position;

vec4 Color;

Vertex(const vec3& position, const vec4& color)

: Position(position), Color(color)

{}

};

uvec2 framebuffersize(0, 0);

GLuint program = 0;

GLuint vertexshader = 0;

GLuint fragmentshader = 0;

GLuint vertexarray = 0;

GLuint vertexbuffer = 0;

bool Graphics::Initialize(unsigned int width, unsigned int height)

{

/* set view port */

Resize(width, height);

/* general settings */

glClearColor(0.3f, 0.3f, 0.3f, 0.0f); /* background gray */

/* create all objects */

program = glCreateProgram();

vertexshader = glCreateShader(GL_VERTEX_SHADER);

fragmentshader = glCreateShader(GL_FRAGMENT_SHADER);

glGenVertexArrays(1, &vertexarray);

glGenBuffers(1, &vertexbuffer);

/* shader source */

string vertexshader_source(

"#version 450 core\n"

"in layout (location = 0) vec3 in_position;"

"in layout (location = 1) vec4 in_color;"

"uniform layout (location = 2) vec3 position_offset = vec3(0, 0, 0);"

"smooth out vec4 color;"

"void main() {"

"gl_Position = vec4(position_offset + in_position, 1);"

"color = in_color;"

"}"

);

string fragmentshader_source(

"#version 450 core\n"

"smooth in vec4 color;"

"out layout (location = 0) vec4 out_color;"

"void main() {"

"out_color = color;"

"}"

);

/* compile shaders */

if (!CompileShader(vertexshader, vertexshader_source))

return false;

if (!CompileShader(fragmentshader, fragmentshader_source))

return false;

/* link program */

list<GLuint> shaderlist;

shaderlist.push_back(vertexshader);

shaderlist.push_back(fragmentshader);

if (!LinkProgram(program, shaderlist))

return false;

/* setup vertexarray */

glBindVertexArray(vertexarray);

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, Position)));

glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), reinterpret_cast<void*>(offsetof(Vertex, Color)));

glBindBuffer(GL_ARRAY_BUFFER, 0);

glEnableVertexAttribArray(0);

glEnableVertexAttribArray(1);

glBindVertexArray(0);

/* setup vertexbuffer */

vector<Vertex> vertices;

vertices.push_back(Vertex(vec3(0, 0, 0), vec4(1, 0, 0, 1)));

vertices.push_back(Vertex(vec3(1, 0, 0), vec4(0, 1, 0, 1)));

vertices.push_back(Vertex(vec3(0, 1, 0), vec4(0, 0, 1, 1)));

glBindBuffer(GL_ARRAY_BUFFER, vertexbuffer);

glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * vertices.size(), vertices.data(), GL_STATIC_DRAW);

glBindBuffer(GL_ARRAY_BUFFER, 0);

/* successfully initialized */

return true;

}

void Graphics::CleanUp()

{

/* destroy all objects */

glDeleteProgram(program);

glDeleteShader(vertexshader);

glDeleteShader(fragmentshader);

glDeleteVertexArrays(1, &vertexarray);

glDeleteBuffers(1, &vertexbuffer);

}

void Graphics::Render()

{

/* set value for "vec4 position_offset" in vertex shader */

GLint location = 2;

static float x = 0.0f; x += 0.05f;

vec3 position_offset = vec3(sin(x), 0, 0);

glProgramUniform3fv(program, location, 1, value_ptr(position_offset));

/* clear framebuffer */

glClear(GL_COLOR_BUFFER_BIT);

/* draw triangle */

glUseProgram(program);

glBindVertexArray(vertexarray);

glDrawArrays(GL_TRIANGLES, 0, 3);

glBindVertexArray(0);

glUseProgram(0);

CheckForGLError();

}

void Graphics::Resize(unsigned int width, unsigned int height)

{

framebuffersize = uvec2(width, height);

glViewport(0, 0, width, height);

}

GLContextInfo Graphics::GetContextInfos()

{

GLContextInfo infos;

glGetIntegerv(GL_MAJOR_VERSION, &infos.Version.Major);

glGetIntegerv(GL_MINOR_VERSION, &infos.Version.Minor);

infos.Version.Driver = (const char*)glGetString(GL_VERSION);

infos.Vendor = (const char*)glGetString(GL_VENDOR);

infos.Renderer = (const char*)glGetString(GL_RENDERER);

infos.Version.ShadingLanguage = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);

GLint numberofextensions = 0;

glGetIntegerv(GL_NUM_EXTENSIONS, &numberofextensions);

for (int i = 0; i < numberofextensions; i++)

infos.SupportedExtensions.push_back((const char*)glGetStringi(GL_EXTENSIONS, i));

GLint numberofsupportedglslversions = 0;

glGetIntegerv(GL_NUM_SHADING_LANGUAGE_VERSIONS, &numberofsupportedglslversions);

for (int i = 0; i < numberofsupportedglslversions; i++)

infos.SupportedGLSLVersions.push_back((const char*)glGetStringi(GL_SHADING_LANGUAGE_VERSION, i));

return infos;

}

void Graphics::CheckForGLError()

{

for (GLenum error; (error = glGetError()) != GL_NO_ERROR;)

{

cout << "OpenGL Error: \t";

if (error == GL_INVALID_ENUM)

cout << "GL_INVALID_ENUM";

if (error == GL_INVALID_VALUE)

cout << "GL_INVALID_VALUE";

if (error == GL_INVALID_OPERATION)

cout << "GL_INVALID_OPERATION";

if (error == GL_STACK_OVERFLOW)

cout << "GL_STACK_OVERFLOW";

if (error == GL_STACK_UNDERFLOW)

cout << "GL_STACK_UNDERFLOW";

if (error == GL_OUT_OF_MEMORY)

cout << "GL_OUT_OF_MEMORY";

if (error == GL_INVALID_FRAMEBUFFER_OPERATION)

cout << "GL_INVALID_FRAMEBUFFER_OPERATION";

if (error == GL_CONTEXT_LOST)

cout << "GL_CONTEXT_LOST";

cout << (char)7 << endl; /*play sound*/

cin.get();

}

}