initial glcxx development

This commit is contained in:
Josh Holtrop 2015-06-11 00:01:59 -04:00
commit f8af892c0d
9 changed files with 329 additions and 0 deletions

8
include/glcxx.hpp Normal file
View File

@ -0,0 +1,8 @@
#ifndef GLCXX_HPP
#define GLCXX_HPP
#include "glcxx/Buffer.hpp"
#include "glcxx/Program.hpp"
#include "glcxx/Shader.hpp"
#endif

30
include/glcxx/Buffer.hpp Normal file
View File

@ -0,0 +1,30 @@
#ifndef GLCXX_BUFFER_HPP
#define GLCXX_BUFFER_HPP
#include "glcxx/gl.hpp"
namespace glcxx
{
class Buffer
{
public:
Buffer();
~Buffer();
void create(GLenum target, GLenum usage, const void *ptr, size_t sz);
GLuint id() const { return m_id; }
void bind() const { glBindBuffer(m_target, m_id); }
bool valid() const { return m_id > 0u; }
protected:
GLuint m_id;
GLenum m_target;
};
};
#endif

19
include/glcxx/Error.hpp Normal file
View File

@ -0,0 +1,19 @@
#ifndef GLCXX_ERROR_HPP
#define GLCXX_ERROR_HPP
#include <stdexcept>
namespace glcxx
{
class Error : public std::runtime_error
{
public:
Error(const std::string & msg) : std::runtime_error(msg)
{
};
};
};
#endif

73
include/glcxx/Program.hpp Normal file
View File

@ -0,0 +1,73 @@
#ifndef GLCXX_PROGRAM_HPP
#define GLCXX_PROGRAM_HPP
#include <initializer_list>
#include <memory>
#include "glcxx/Shader.hpp"
namespace glcxx
{
class Program
{
public:
Program();
~Program();
GLuint id() const { return m_id; }
void use() const { glUseProgram(m_id); }
bool valid() const { return m_id > 0u; }
template <typename... Shaders>
void create(Shaders... shaders)
{
allocate();
_create(shaders...);
}
void attach_shader(const Shader & shader) const
{
glAttachShader(m_id, shader.id());
}
void attach_shader(std::unique_ptr<Shader> shader) const
{
glAttachShader(m_id, shader->id());
}
void attach_shader(std::shared_ptr<Shader> shader) const
{
glAttachShader(m_id, shader->id());
}
void bind_attribute(const char * name, GLuint index) const
{
glBindAttribLocation(m_id, index, name);
}
template <typename... Args>
void bind_attributes(const char * name, GLuint index, Args... args) const
{
bind_attribute(name, index);
bind_attributes(args...);
}
protected:
void allocate();
void _create() const;
template <typename T, typename... Shaders>
void _create(T shader, Shaders... args) const
{
attach_shader(shader);
_create(args...);
}
GLuint m_id;
};
};
#endif

26
include/glcxx/Shader.hpp Normal file
View File

@ -0,0 +1,26 @@
#ifndef GLCXX_SHADER_HPP
#define GLCXX_SHADER_HPP
#include "glcxx/gl.hpp"
namespace glcxx
{
class Shader
{
public:
Shader();
~Shader();
void create(GLenum shaderType, const char *source);
GLuint id() const { return m_id; }
bool valid() const { return m_id > 0u; }
protected:
GLuint m_id;
};
};
#endif

10
include/glcxx/gl.hpp Normal file
View File

@ -0,0 +1,10 @@
#ifndef GLCXX_GL_HPP
#define GLCXX_GL_HPP
#ifdef GLCXX_GL_INCLUDE
#include GLCXX_GL_INCLUDE
#else
#include "GL/gl.h"
#endif
#endif

30
src/glcxx/Buffer.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "glcxx/Buffer.hpp"
#include "glcxx/Error.hpp"
namespace glcxx
{
Buffer::Buffer()
{
m_id = 0u;
}
Buffer::~Buffer()
{
if (m_id > 0u)
{
glDeleteBuffers(1, &m_id);
}
}
void Buffer::create(GLenum target, GLenum usage, const void *ptr, size_t sz)
{
m_target = target;
glGenBuffers(1, &m_id);
if (m_id == 0u)
{
throw Error("Failed to allocate an OpenGL buffer");
}
bind();
glBufferData(target, sz, ptr, usage);
}
}

64
src/glcxx/Program.cpp Normal file
View File

@ -0,0 +1,64 @@
#include "glcxx/Program.hpp"
#include "glcxx/Error.hpp"
#include <string>
namespace glcxx
{
Program::Program()
{
m_id = 0u;
}
Program::~Program()
{
if (m_id > 0u)
{
glDeleteProgram(m_id);
}
}
void Program::allocate()
{
m_id = glCreateProgram();
if (m_id == 0u)
{
throw Error("Failed to allocate an OpenGL program");
}
}
void Program::_create() const
{
glLinkProgram(m_id);
GLint link_status;
glGetProgramiv(m_id, GL_LINK_STATUS, &link_status);
if (link_status != GL_TRUE)
{
std::string message = "Failed to link program";
GLint log_length = 0;
glGetProgramiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0)
{
char *log = new char[log_length];
glGetProgramInfoLog(m_id, log_length, &log_length, log);
message += "\n";
message += log;
message += "\n";
delete[] log;
}
throw Error(message);
}
}
#if 0
for (;;)
{
const char *uniform_name = va_arg(va, const char *);
if (uniform_name == NULL)
break;
GLint loc = glGetUniformLocation(m_id, uniform_name);
m_uniform_locations.push_back(loc);
m_uniform_location_names[uniform_name] = loc;
}
#endif
}

69
src/glcxx/Shader.cpp Normal file
View File

@ -0,0 +1,69 @@
#include "glcxx/Shader.hpp"
#include "glcxx/Error.hpp"
#include <string>
namespace glcxx
{
Shader::Shader()
{
m_id = 0u;
}
Shader::~Shader()
{
if (m_id > 0u)
{
glDeleteShader(m_id);
}
}
void Shader::create(GLenum shaderType, const char *source)
{
GLint status;
m_id = glCreateShader(shaderType);
if (m_id == 0u)
{
throw Error("Failed to allocate an OpenGL shader");
}
glShaderSource(m_id, 1, &source, NULL);
glCompileShader(m_id);
glGetShaderiv(m_id, GL_COMPILE_STATUS, &status);
if (status == GL_TRUE)
{
return;
}
std::string message = "Error compiling ";
switch (shaderType)
{
case GL_VERTEX_SHADER:
message += "vertex";
break;
case GL_FRAGMENT_SHADER:
message += "fragment";
break;
default:
message += "unknown";
break;
}
message += " shader";
GLint log_length;
glGetShaderiv(m_id, GL_INFO_LOG_LENGTH, &log_length);
if (log_length > 0)
{
char * log = new char[log_length];
glGetShaderInfoLog(m_id, log_length, &log_length, log);
message += "\nShader Log:\n";
message += log;
message += "\n";
delete[] log;
}
glDeleteShader(m_id);
throw Error(message);
}
}