Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Context.hpp"
- #include <GL/glew.h>
- #include <fstream>
- #include <sstream>
- #include <string>
- #include <memory>
- #include <vector>
- #include <utility>
- Context::Context(size_t triangles) :
- m_programId(),
- m_vertexArrayId(),
- m_vertexShaderId(),
- m_fragmentShaderId(),
- m_vertexBufferId(),
- m_triangles(triangles)
- {}
- Context::~Context()
- {}
- Context::Context(const Context& other) :
- m_programId(other.m_programId),
- m_vertexArrayId(other.m_vertexArrayId),
- m_vertexShaderId(other.m_vertexShaderId),
- m_fragmentShaderId(other.m_fragmentShaderId),
- m_vertexBufferId(other.m_vertexBufferId),
- m_triangles(other.m_triangles)
- {
- }
- Context& Context::operator=(const Context& other)
- {
- m_programId = other.m_programId;
- m_vertexArrayId = other.m_vertexArrayId;
- m_vertexShaderId = other.m_vertexShaderId;
- m_fragmentShaderId = other.m_fragmentShaderId;
- m_vertexBufferId = other.m_vertexBufferId;
- m_triangles = other.m_triangles;
- return *this;
- }
- // Delegating constructors ;(
- Context::Context(Context&& other) :
- m_programId(other.m_programId),
- m_vertexArrayId(other.m_vertexArrayId),
- m_vertexShaderId(other.m_vertexShaderId),
- m_fragmentShaderId(other.m_fragmentShaderId),
- m_vertexBufferId(other.m_vertexBufferId),
- m_triangles(other.m_triangles)
- {}
- Context& Context::operator=(Context&& other)
- {
- (*this) = other; // here 'other' is an lvalue
- return *this;
- }
- std::string readfile(const char* fileName) {
- std::ifstream shaderStream(fileName, std::ios::in);
- if (!shaderStream.is_open())
- {
- throw std::runtime_error("Couldn't open file");
- }
- std::stringstream buffer;
- buffer << shaderStream.rdbuf();
- return buffer.str();
- }
- void Context::init()
- {
- initProgram();
- initVbo();
- glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
- }
- void Context::draw()
- {
- glClear(GL_COLOR_BUFFER_BIT);
- // As far as I've tested and checked with ref. the only OpenGL call I
- // really need to do is the glDrawArrays() - the rest can be safely put in
- // the init() method.
- glUseProgram(m_programId);
- glBindVertexArray(m_vertexArrayId);
- glEnableVertexAttribArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);
- glVertexAttribPointer(
- 0, // attribute index
- 3, // elements per vertex
- GL_FLOAT, // type
- GL_FALSE, // never for floats
- 0, // stride
- (void*)0 // array buffer offset
- );
- glDrawArrays(
- GL_TRIANGLES,
- 0, // Start from the first index
- 3 * m_triangles // Draw 3 indices
- );
- glDisableVertexAttribArray(0);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindVertexArray(0);
- glUseProgram(0);
- }
- void Context::initProgram()
- {
- m_programId = glCreateProgram();
- m_vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
- const auto vertexSource = readfile("vs.glsl");
- const char* shaders[] = { vertexSource.c_str() };
- glShaderSource(m_vertexShaderId, 1, shaders, nullptr);
- glCompileShader(m_vertexShaderId);
- GLint compilationStatus;
- glGetShaderiv(m_vertexShaderId, GL_COMPILE_STATUS, &compilationStatus);
- if (compilationStatus != GL_TRUE) {
- GLint infoLength;
- glGetShaderiv(m_vertexShaderId, GL_INFO_LOG_LENGTH, &infoLength);
- auto logBuffer = std::unique_ptr<char>(new char[infoLength]);
- glGetShaderInfoLog(m_vertexShaderId, infoLength, nullptr, logBuffer.get());
- throw std::runtime_error(logBuffer.get());
- }
- glAttachShader(m_programId, m_vertexShaderId);
- m_fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
- const auto fragmentSource = readfile("ps.glsl");
- const char* shaders2[] = { fragmentSource.c_str() };
- glShaderSource(m_fragmentShaderId, 1, shaders2, nullptr);
- glCompileShader(m_fragmentShaderId);
- GLint compilationStatus2;
- glGetShaderiv(m_fragmentShaderId, GL_COMPILE_STATUS, &compilationStatus2);
- if (compilationStatus2 != GL_TRUE) {
- GLint infoLength;
- glGetShaderiv(m_fragmentShaderId, GL_INFO_LOG_LENGTH, &infoLength);
- auto logBuffer = std::unique_ptr<char>(new char[infoLength]);
- glGetShaderInfoLog(m_fragmentShaderId, infoLength, nullptr, logBuffer.get());
- throw std::runtime_error(logBuffer.get());
- }
- glAttachShader(m_programId, m_fragmentShaderId);
- glLinkProgram(m_programId);
- GLint linkStatus;
- glGetProgramiv(m_programId, GL_LINK_STATUS, &linkStatus);
- if (linkStatus != GL_TRUE) {
- throw std::runtime_error("Couldn't link the program");
- }
- }
- void Context::initVbo()
- {
- glGenBuffers(1, &m_vertexBufferId);
- glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);
- const float verArr[] = {
- -1.0f, -1.0f, 0.0f,
- 1.0f, -1.0f, 0.0f,
- 0.0f, 1.0f, 0.0f,
- };
- std::vector<float> vertices;
- vertices.reserve(m_triangles * 9);
- for (int v = 0; v < m_triangles; ++v)
- {
- vertices.insert(vertices.end(), std::begin(verArr), std::end(verArr));
- }
- glBufferData(
- GL_ARRAY_BUFFER,
- vertices.size() * sizeof(float),
- vertices.data(),
- GL_STATIC_DRAW
- );
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glGenVertexArrays(1, &m_vertexArrayId);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement