ff40b1fc7d48202dbe7e0b3c4c87d03ad0d703dc
[ipdf/code.git] / src / objectrenderer.cpp
1 /**
2  * @file objectrenderer.cpp
3  * @brief Implements ObjectRenderer and derived classes
4  */
5
6 #include "objectrenderer.h"
7
8 namespace IPDF
9 {
10
11 /**
12  * ObjectRenderer constructor
13  * Note the ShaderProgram constructor which compiles the shaders for GPU rendering (if they exist)
14  */
15 ObjectRenderer::ObjectRenderer(const ObjectType & type, 
16                 const char * vert_glsl_file, const char * frag_glsl_file, const char * geom_glsl_file)
17                 : m_type(type), m_shader_program(), m_indexes(), m_buffer_builder(NULL)
18 {
19         m_shader_program.InitialiseShaders(vert_glsl_file, frag_glsl_file, geom_glsl_file);
20         m_shader_program.Use();
21         glUniform4f(m_shader_program.GetUniformLocation("colour"), 0,0,0,1); //TODO: Allow different colours
22 }
23
24 /**
25  * Render using GPU
26  */
27 void ObjectRenderer::RenderUsingGPU()
28 {
29         if (!m_shader_program.Valid())
30                 Warn("Shader is invalid (objects are of type %d)", m_type);
31         m_shader_program.Use();
32         m_ibo.Bind();
33         glDrawElements(GL_LINES, m_indexes.size()*2, GL_UNSIGNED_INT, 0);
34 }
35
36 /**
37  * Default implementation for rendering using CPU
38  */
39 void ObjectRenderer::RenderUsingCPU()
40 {
41         Error("Cannot render objects of type %d on CPU", m_type);
42 }
43
44 /**
45  * Prepare index buffers for both CPU and GPU rendering to receive indexes (but don't add any yet!)
46  */
47 void ObjectRenderer::PrepareBuffers(unsigned max_objects)
48 {
49         if (m_buffer_builder != NULL) // We already have a BufferBuilder
50         {
51                 Fatal("Has been called before, without FinaliseBuffers being called since!");
52         }
53         // Empty and reserve the indexes vector (for CPU rendering)
54         m_indexes.clear();
55         m_indexes.reserve(max_objects); //TODO: Can probably make this smaller? Or leave it out? Do we care?
56
57         // Initialise and resize the ibo (for GPU rendering)
58         m_ibo.SetUsage(GraphicsBuffer::BufferUsageStaticDraw);
59         m_ibo.SetType(GraphicsBuffer::BufferTypeIndex);
60         m_ibo.Resize(max_objects * 2 * sizeof(uint32_t));
61         // BufferBuilder is used to construct the ibo
62         m_buffer_builder = new BufferBuilder<uint32_t>(m_ibo.Map(false, true, true), m_ibo.GetSize()); // new matches delete in ObjectRenderer::FinaliseBuffers
63
64 }
65
66 /**
67  * Add object index to the buffers for CPU and GPU rendering
68  */
69 void ObjectRenderer::AddObjectToBuffers(unsigned index)
70 {
71         if (m_buffer_builder == NULL) // No BufferBuilder!
72         {
73                 Fatal("Called without calling PrepareBuffers");
74         }
75         m_buffer_builder->Add(2*index); // ibo for GPU rendering
76         m_buffer_builder->Add(2*index+1);
77         m_indexes.push_back(index); // std::vector of indices for CPU rendering
78 }
79
80 /**
81  * Finalise the index buffers for CPU and GPU rendering
82  */
83 void ObjectRenderer::FinaliseBuffers()
84 {
85         if (m_buffer_builder == NULL) // No BufferBuilder!
86         {
87                 Fatal("Called without calling PrepareBuffers");
88         }
89         // For GPU rendering, UnMap the ibo
90         m_ibo.UnMap();
91         // ... and delete the BufferBuilder used to create it
92         delete m_buffer_builder; // delete matches new in ObjectRenderer::PrepareBuffers
93         m_buffer_builder = NULL;
94         
95         // Nothing is necessary for CPU rendering
96 }
97
98 }

UCC git Repository :: git.ucc.asn.au