Advertisement
Guest User

Context.cpp

a guest
Aug 23rd, 2013
60
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.89 KB | None | 0 0
  1. #include "Context.hpp"
  2. #include <GL/glew.h>
  3. #include <fstream>
  4. #include <sstream>
  5. #include <string>
  6. #include <memory>
  7. #include <vector>
  8. #include <utility>
  9.  
  10. Context::Context(size_t triangles) :
  11.     m_programId(),
  12.     m_vertexArrayId(),
  13.     m_vertexShaderId(),
  14.     m_fragmentShaderId(),
  15.     m_vertexBufferId(),
  16.     m_triangles(triangles)
  17. {}
  18.  
  19. Context::~Context()
  20. {}
  21.  
  22. Context::Context(const Context& other) :
  23.     m_programId(other.m_programId),
  24.     m_vertexArrayId(other.m_vertexArrayId),
  25.     m_vertexShaderId(other.m_vertexShaderId),
  26.     m_fragmentShaderId(other.m_fragmentShaderId),
  27.     m_vertexBufferId(other.m_vertexBufferId),
  28.     m_triangles(other.m_triangles)
  29. {
  30. }
  31.  
  32. Context& Context::operator=(const Context& other)
  33. {
  34.     m_programId = other.m_programId;
  35.     m_vertexArrayId = other.m_vertexArrayId;
  36.     m_vertexShaderId = other.m_vertexShaderId;
  37.     m_fragmentShaderId = other.m_fragmentShaderId;
  38.     m_vertexBufferId = other.m_vertexBufferId;
  39.     m_triangles = other.m_triangles;
  40.     return *this;
  41. }
  42.  
  43. // Delegating constructors ;(
  44. Context::Context(Context&& other) :
  45.     m_programId(other.m_programId),
  46.     m_vertexArrayId(other.m_vertexArrayId),
  47.     m_vertexShaderId(other.m_vertexShaderId),
  48.     m_fragmentShaderId(other.m_fragmentShaderId),
  49.     m_vertexBufferId(other.m_vertexBufferId),
  50.     m_triangles(other.m_triangles)
  51. {}
  52.  
  53. Context& Context::operator=(Context&& other)
  54. {
  55.     (*this) = other; // here 'other' is an lvalue
  56.     return *this;
  57. }
  58.  
  59. std::string readfile(const char* fileName) {
  60.     std::ifstream shaderStream(fileName, std::ios::in);
  61.    
  62.     if (!shaderStream.is_open())
  63.     {
  64.         throw std::runtime_error("Couldn't open file");
  65.     }
  66.  
  67.     std::stringstream buffer;
  68.     buffer << shaderStream.rdbuf();
  69.     return buffer.str();
  70. }
  71.  
  72. void Context::init()
  73. {
  74.     initProgram();
  75.     initVbo();
  76.     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  77. }
  78.  
  79. void Context::draw()
  80. {
  81.     glClear(GL_COLOR_BUFFER_BIT);
  82.    
  83.     // As far as I've tested and checked with ref. the only OpenGL call I
  84.     // really need to do is the glDrawArrays() - the rest can be safely put in
  85.     // the init() method.
  86.     glUseProgram(m_programId);
  87.     glBindVertexArray(m_vertexArrayId);
  88.  
  89.     glEnableVertexAttribArray(0);
  90.     glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);
  91.     glVertexAttribPointer(
  92.         0, // attribute index
  93.         3, // elements per vertex
  94.         GL_FLOAT, // type
  95.         GL_FALSE, // never for floats
  96.         0, // stride
  97.         (void*)0 // array buffer offset
  98.     );
  99.  
  100.     glDrawArrays(
  101.         GL_TRIANGLES,
  102.         0,              // Start from the first index
  103.         3 * m_triangles // Draw 3 indices
  104.     );
  105.  
  106.     glDisableVertexAttribArray(0);
  107.     glBindBuffer(GL_ARRAY_BUFFER, 0);
  108.     glBindVertexArray(0);
  109.     glUseProgram(0);
  110. }
  111.  
  112. void Context::initProgram()
  113. {
  114.     m_programId = glCreateProgram();
  115.    
  116.     m_vertexShaderId = glCreateShader(GL_VERTEX_SHADER);
  117.     const auto vertexSource = readfile("vs.glsl");
  118.     const char* shaders[] = { vertexSource.c_str() };
  119.     glShaderSource(m_vertexShaderId, 1, shaders, nullptr);
  120.     glCompileShader(m_vertexShaderId);
  121.  
  122.     GLint compilationStatus;
  123.     glGetShaderiv(m_vertexShaderId, GL_COMPILE_STATUS, &compilationStatus);
  124.     if (compilationStatus != GL_TRUE) {
  125.         GLint infoLength;
  126.         glGetShaderiv(m_vertexShaderId, GL_INFO_LOG_LENGTH, &infoLength);
  127.  
  128.         auto logBuffer = std::unique_ptr<char>(new char[infoLength]);
  129.         glGetShaderInfoLog(m_vertexShaderId, infoLength, nullptr, logBuffer.get());
  130.  
  131.         throw std::runtime_error(logBuffer.get());
  132.     }
  133.  
  134.     glAttachShader(m_programId, m_vertexShaderId);
  135.    
  136.     m_fragmentShaderId = glCreateShader(GL_FRAGMENT_SHADER);
  137.     const auto fragmentSource = readfile("ps.glsl");
  138.     const char* shaders2[] = { fragmentSource.c_str() };
  139.     glShaderSource(m_fragmentShaderId, 1, shaders2, nullptr);
  140.     glCompileShader(m_fragmentShaderId);
  141.  
  142.     GLint compilationStatus2;
  143.     glGetShaderiv(m_fragmentShaderId, GL_COMPILE_STATUS, &compilationStatus2);
  144.     if (compilationStatus2 != GL_TRUE) {
  145.         GLint infoLength;
  146.         glGetShaderiv(m_fragmentShaderId, GL_INFO_LOG_LENGTH, &infoLength);
  147.  
  148.         auto logBuffer = std::unique_ptr<char>(new char[infoLength]);
  149.         glGetShaderInfoLog(m_fragmentShaderId, infoLength, nullptr, logBuffer.get());
  150.  
  151.         throw std::runtime_error(logBuffer.get());
  152.     }
  153.  
  154.     glAttachShader(m_programId, m_fragmentShaderId);
  155.    
  156.     glLinkProgram(m_programId);
  157.  
  158.     GLint linkStatus;
  159.     glGetProgramiv(m_programId, GL_LINK_STATUS, &linkStatus);
  160.     if (linkStatus != GL_TRUE) {
  161.         throw std::runtime_error("Couldn't link the program");
  162.     }
  163. }
  164.  
  165. void Context::initVbo()
  166. {
  167.     glGenBuffers(1, &m_vertexBufferId);
  168.     glBindBuffer(GL_ARRAY_BUFFER, m_vertexBufferId);
  169.  
  170.     const float verArr[] = {
  171.         -1.0f, -1.0f, 0.0f,
  172.         1.0f, -1.0f, 0.0f,
  173.         0.0f,  1.0f, 0.0f,
  174.     };
  175.  
  176.     std::vector<float> vertices;
  177.     vertices.reserve(m_triangles * 9);
  178.     for (int v = 0; v < m_triangles; ++v)
  179.     {
  180.         vertices.insert(vertices.end(), std::begin(verArr), std::end(verArr));
  181.     }
  182.  
  183.     glBufferData(
  184.         GL_ARRAY_BUFFER,
  185.         vertices.size() * sizeof(float),
  186.         vertices.data(),
  187.         GL_STATIC_DRAW
  188.     );
  189.  
  190.     glBindBuffer(GL_ARRAY_BUFFER, 0);
  191.  
  192.     glGenVertexArrays(1, &m_vertexArrayId);
  193. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement