Skip to content

Instantly share code, notes, and snippets.

@krysseltillada
Created April 2, 2016 17:34
Show Gist options
  • Save krysseltillada/39206c0a8b973307a5b59c8691e0466a to your computer and use it in GitHub Desktop.
Save krysseltillada/39206c0a8b973307a5b59c8691e0466a to your computer and use it in GitHub Desktop.
ex 11 vertex array object (vao's) and indexed drawing
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <iostream>
#include <cstdlib>
#include "main.hpp"
void InitWindow(int *const argn, char **const argc) {
glutInit(argn, argc);
glutInitContextVersion(3, 3);
glutInitContextProfile(GLUT_CORE_PROFILE);
glutInitWindowPosition(200, 200);
glutInitWindowSize(800, 600);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow("exercise 11");
if (glewInit())
std::cerr << "cannot initialized the context" << std::endl;
glutDisplayFunc(&Run);
glutKeyboardFunc(&KeyEvent);
glutMainLoop();
}
int main(int argn, char **argc)
{
InitWindow(&argn, argc);
return 0;
}
#version 330
smooth in vec4 vertexOutputColor;
out vec4 fragmentColor;
void main ()
{
fragmentColor = vertexOutputColor;
}
#include "main.hpp"
#include "shader.hpp"
bool ifInit = GL_FALSE;
std::string drawingMethod = "array";
const GLfloat vertexArray[] = {
0.5f, 0.0f, 1.0f, 1.0f,
-0.5f, 0.0f, 1.0f, 1.0f,
0.0f, 0.5f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.0f, 1.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f
};
const GLushort elementArray[] = {
0, 1, 2
};
GLuint vertexBufferObject;
GLuint elementBufferObject;
GLuint vertexArrayObject;
GLuint shaderProgram;
namespace {
void Init() {
glGenVertexArrays(1, &vertexArrayObject);
glGenBuffers(1, &vertexBufferObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexArray), vertexArray, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glGenBuffers(1, &elementBufferObject);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof (elementArray), elementArray, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
shaderProgram = Shader::ShaderUtility::buildProgram({
Shader::ShaderUtility::compileShader(GL_VERTEX_SHADER, Shader::ShaderUtility::loadShaderFile("vertexShader.vert").c_str()),
Shader::ShaderUtility::compileShader(GL_FRAGMENT_SHADER, Shader::ShaderUtility::loadShaderFile("fragmentShader.frag").c_str())
});
glBindVertexArray(vertexArrayObject);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferObject);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void *)0);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (void *)48);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
}
void Display() {
glUseProgram(shaderProgram);
if (drawingMethod == "array") {
glBindVertexArray(vertexBufferObject);
glDrawArrays(GL_TRIANGLES, 0, 3);
glBindVertexArray(0);
}
else if (drawingMethod == "indexed") {
glBindVertexArray(vertexBufferObject);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementBufferObject);
glBindVertexArray(0);
glBindVertexArray(vertexBufferObject);
glDrawElements(GL_TRIANGLES, 3, GL_UNSIGNED_SHORT, (void *)0);
glBindVertexArray(vertexBufferObject);
}
glUseProgram(0);
glutSwapBuffers();
glutPostRedisplay();
}
void Clear() {
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
}
void Run() {
if (!ifInit) {
LOG("press h for array drawing");
LOG("press g for indexed drawing");
Init();
ifInit = GL_TRUE;
}
Display();
Clear();
}
void KeyEvent(unsigned char key, int x, int y) {
switch (key) {
case 'h':
LOG("ARRAY DRAWING");
drawingMethod = "array";
break;
case 'g':
LOG("INDEXED DRAWING");
drawingMethod = "indexed";
break;
default:
break;
}
}
void Resize(int w, int h) {
glViewport(0, 0, static_cast<GLint> (w), static_cast <GLint>(h));
}
#ifndef MAIN_HPP
#define MAIN_HPP
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <string>
#define DEBUG
#ifdef DEBUG
template <typename T>
inline void LOG(const T& v) {
std::cerr << v << std::endl;
}
#endif
namespace {
void Init();
void Display();
void Clear();
}
void Run();
void KeyEvent(unsigned char, int, int);
void Resize(int, int);
#endif
#ifndef SHADER_HEADER
#define SHADER_HEADER
#include <GL/glew.h>
#include <GL/freeglut.h>
#include <memory>
#include <initializer_list>
#include <stdexcept>
#include <string>
#include <iostream>
#include <fstream>
namespace Shader {
class ShaderUtility {
public:
static std::string loadShaderFile(const std::string &fileName) {
std::ifstream readFile;
std::string line, sourceCode;
readFile.open(fileName, std::ifstream::in, std::ifstream::trunc);
if (readFile.is_open()) {
for (; std::getline(readFile, line) ;)
sourceCode += line + '\n';
}
else {}
if (sourceCode[sourceCode.length() - 1] != '\0')
sourceCode.push_back('\0');
return sourceCode;
}
static GLuint compileShader(const GLuint &shaderType, const char *sourceCode) {
GLuint shaderObject = glCreateShader(shaderType);
GLint compileStatus;
glShaderSource(shaderObject, 1, &sourceCode, nullptr);
glCompileShader(shaderObject);
glGetShaderiv(shaderObject, GL_COMPILE_STATUS, &compileStatus);
if (!compileStatus) {
GLint logLength;
std::string shaderTypeStr;
glGetShaderiv(shaderObject, GL_INFO_LOG_LENGTH, &logLength);
std::unique_ptr <GLchar> errLog(new GLchar[logLength + 1]);
glGetShaderInfoLog(shaderObject, logLength + 1, nullptr, errLog.get());
switch (shaderType) {
case GL_VERTEX_SHADER:
shaderTypeStr = "vertex";
break;
case GL_FRAGMENT_SHADER:
shaderTypeStr = "fragment";
break;
default:
break;
}
std::cerr << "error " << shaderTypeStr << " shader " << std::endl
<< errLog.get() << std::endl;
}
return shaderObject;
}
static GLuint buildProgram(std::initializer_list <GLuint> shaderObjectList) {
GLuint programObject = glCreateProgram();
GLint linkStatus;
for (std::initializer_list <GLuint>::iterator it = shaderObjectList.begin();
it != shaderObjectList.end(); ++it)
glAttachShader(programObject, *it);
glLinkProgram(programObject);
glGetProgramiv(programObject, GL_LINK_STATUS, &linkStatus);
if (!linkStatus) {
GLint logLength;
glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &logLength);
std::unique_ptr <GLchar> errLog(new GLchar[logLength + 1]);
glGetProgramInfoLog(programObject, logLength + 1, nullptr, errLog.get());
std::cerr << "LINKING ERROR" << std::endl
<< errLog.get() << std::endl;
}
for (std::initializer_list <GLuint>::iterator it2 = shaderObjectList.begin();
it2 != shaderObjectList.end(); ++it2) {
glDetachShader(programObject, *it2);
glDeleteShader(*it2);
}
return programObject;
}
};
}
#endif
#version 330
layout (location = 0) in vec4 vertexPosition;
layout (location = 1) in vec4 vertexColor;
smooth out vec4 vertexOutputColor;
void main ()
{
gl_Position = vertexPosition;
vertexOutputColor = vertexColor;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment