Yeah it's broken
[ipdf/code.git] / src / view.cpp
1 #include "view.h"
2
3 #include "SDL_opengl.h"
4
5 using namespace IPDF;
6 using namespace std;
7
8 void View::Translate(Real x, Real y)
9 {
10         x *= m_bounds.w;
11         y *= m_bounds.h;
12         m_bounds.x += x;
13         m_bounds.y += y;
14         Debug("View Bounds => %s", m_bounds.Str().c_str());
15         if (!m_use_gpu_transform)
16         {
17                 m_buffer_dirty = true;
18         }
19         m_bounds_dirty = true;
20 }
21
22 void View::ScaleAroundPoint(Real x, Real y, Real scaleAmt)
23 {
24         // x and y are coordinates in the window
25         // Convert to local coords.
26         x *= m_bounds.w;
27         y *= m_bounds.h;
28         x += m_bounds.x;
29         y += m_bounds.y;
30         
31         //Debug("Mouse wheel event %f %f %f\n", Float(x), Float(y), Float(scaleAmt));
32         
33         Real top = y - m_bounds.y;
34         Real left = x - m_bounds.x;
35         
36         top *= scaleAmt;
37         left *= scaleAmt;
38         
39         m_bounds.x = x - left;
40         m_bounds.y = y - top;
41         m_bounds.w *= scaleAmt;
42         m_bounds.h *= scaleAmt;
43         Debug("View Bounds => %s", m_bounds.Str().c_str());
44         if (!m_use_gpu_transform)
45                 m_buffer_dirty = true;
46         m_bounds_dirty = true;
47 }
48
49 Rect View::TransformToViewCoords(const Rect& inp) const
50 {
51         Rect out;
52         out.x = (inp.x - m_bounds.x) / m_bounds.w;
53         out.y = (inp.y - m_bounds.y) / m_bounds.h;
54
55         out.w = inp.w / m_bounds.w;
56         out.h = inp.h / m_bounds.h;
57         return out;
58 }
59
60 void View::DrawGrid()
61 {
62         // Draw some grid lines at fixed pixel positions
63         glMatrixMode(GL_PROJECTION);
64         glLoadIdentity();
65         glOrtho(0.0, 1.0, 1.0, 0.0, -1.f, 1.f);
66         glMatrixMode(GL_MODELVIEW);
67         glLoadIdentity();
68
69         glColor4f(0.9,0.9,0.9,0.1);
70         const float num_lines = 50.0;
71         for (float i = 0; i < num_lines; ++i)
72         {
73                 glBegin(GL_LINES);
74                 glVertex2f(i*(1.0/num_lines), 0.0);
75                 glVertex2f(i*(1.0/num_lines), 1.0);
76                 glEnd();
77                 glBegin(GL_LINES);
78                 glVertex2f(0.0,i*(1.0/num_lines));
79                 glVertex2f(1.0,i*(1.0/num_lines));
80                 glEnd();
81         
82         }
83 }
84
85 void glPrimitiveRestartIndex(GLuint index);
86
87 void View::Render(int width, int height)
88 {
89         if (width != m_cached_display.GetWidth() || height != m_cached_display.GetHeight())
90         {
91                 m_cached_display.Create(width, height);
92                 m_bounds_dirty = true;
93         }
94
95         if (!m_bounds_dirty)
96         {
97                 m_cached_display.UnBind();
98                 m_cached_display.Blit();
99                 return;
100         }
101         m_cached_display.Bind();
102         m_cached_display.Clear();
103         
104         glMatrixMode(GL_PROJECTION);
105         glLoadIdentity();
106         if (m_use_gpu_transform)
107         {
108                 glOrtho(Float(m_bounds.x), Float(m_bounds.x)+Float(m_bounds.w), Float(m_bounds.y) + Float(m_bounds.h), Float(m_bounds.y), -1.f, 1.f);
109         }
110         else
111         {
112                 glOrtho(0,1,1,0,-1,1);
113         }
114
115         if (m_buffer_dirty)
116                 ReRender();
117
118         glMatrixMode(GL_MODELVIEW);
119         glLoadIdentity();
120         if (m_colour.a < 1.0f)
121         {
122                 glEnable(GL_BLEND);
123                 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
124         }
125         glColor4f(m_colour.r, m_colour.g, m_colour.b, m_colour.a);
126         m_vertex_buffer.Bind();
127         m_index_buffer.Bind();
128         glEnable(GL_PRIMITIVE_RESTART);
129         glPrimitiveRestartIndex(0xFFFFFFFF);
130         glVertexPointer(2, GL_FLOAT, 0, 0);
131         glEnableClientState(GL_VERTEX_ARRAY);
132         glDrawElements(GL_TRIANGLE_STRIP, m_rendered_filled * 5, GL_UNSIGNED_INT, 0);
133         glDrawElements(GL_LINE_LOOP, m_rendered_outline*5, GL_UNSIGNED_INT,(void*)(sizeof(uint32_t)*m_rendered_filled*5));
134         glDisable(GL_PRIMITIVE_RESTART);
135         if (m_colour.a < 1.0f)
136         {
137                 glDisable(GL_BLEND);
138         }
139         m_cached_display.UnBind();
140         m_cached_display.Blit();
141
142 }
143
144 void View::ReRender()
145 {
146         static bool debug_output_done = false;
147         if (!debug_output_done)
148         {
149                 //m_document.DebugDumpObjects();
150                 debug_output_done = true;
151
152                 m_vertex_buffer.SetType(GraphicsBuffer::BufferTypeVertex);
153                 m_index_buffer.SetUsage(GraphicsBuffer::BufferUsageStaticDraw);
154                 m_index_buffer.SetType(GraphicsBuffer::BufferTypeIndex);
155
156                 m_vertex_buffer.Upload(m_document.ObjectCount() * 8 * sizeof(float), NULL);
157                 m_index_buffer.Upload(m_document.ObjectCount() * 5 * sizeof(uint32_t), NULL);
158         }
159         m_rendered_filled = m_rendered_outline = 0;
160         
161         if (m_use_gpu_transform)
162         {
163                 m_vertex_buffer.SetUsage(GraphicsBuffer::BufferUsageStaticDraw);
164         }
165         else
166         {
167                 m_vertex_buffer.SetUsage(GraphicsBuffer::BufferUsageDynamicDraw);
168         }
169
170
171         //DrawGrid(); // Draw the gridlines
172
173
174
175         float *vertexData = (float*)m_vertex_buffer.Map(false, true, true);
176         uint32_t *indexData = (uint32_t*)m_index_buffer.Map(false, true, true);
177
178         uint32_t currentIndex = 0;
179         for (unsigned id = 0; id < m_document.ObjectCount(); ++id)
180         {
181                 if (m_document.m_objects.types[id] != RECT_FILLED)
182                         continue;
183                 Rect obj_bounds;
184                 if (m_use_gpu_transform)
185                 {
186                         obj_bounds = m_document.m_objects.bounds[id];
187                 }
188                 else
189                 {
190                         obj_bounds = TransformToViewCoords(m_document.m_objects.bounds[id]);
191                 }
192                 *vertexData = Float(obj_bounds.x); vertexData++;
193                 *vertexData = Float(obj_bounds.y); vertexData++;
194                 *vertexData = Float(obj_bounds.x) + Float(obj_bounds.w); vertexData++;
195                 *vertexData = Float(obj_bounds.y); vertexData++;
196                 *vertexData = Float(obj_bounds.x) + Float(obj_bounds.w); vertexData++;
197                 *vertexData = Float(obj_bounds.y) + Float(obj_bounds.h); vertexData++;
198                 *vertexData = Float(obj_bounds.x); vertexData++;
199                 *vertexData = Float(obj_bounds.y) + Float(obj_bounds.h); vertexData++;
200
201                 *indexData = currentIndex; indexData++;
202                 *indexData = currentIndex+1; indexData++;
203                 *indexData = currentIndex+3; indexData++;
204                 *indexData = currentIndex+2; indexData++;
205                 *indexData = 0xFFFFFFFF; // Primitive restart.
206                 indexData++;
207                 currentIndex += 4;
208                 m_rendered_filled++;
209
210         }
211         
212         for (unsigned id = 0; id < m_document.ObjectCount(); ++id)
213         {
214                 if (m_document.m_objects.types[id] != RECT_OUTLINE)
215                         continue;
216                 Rect obj_bounds;
217                 if (m_use_gpu_transform)
218                 {
219                         obj_bounds = m_document.m_objects.bounds[id];
220                 }
221                 else
222                 {
223                         obj_bounds = TransformToViewCoords(m_document.m_objects.bounds[id]);
224                 }
225                 *vertexData = Float(obj_bounds.x); vertexData++;
226                 *vertexData = Float(obj_bounds.y); vertexData++;
227                 *vertexData = Float(obj_bounds.x) + Float(obj_bounds.w); vertexData++;
228                 *vertexData = Float(obj_bounds.y); vertexData++;
229                 *vertexData = Float(obj_bounds.x) + Float(obj_bounds.w); vertexData++;
230                 *vertexData = Float(obj_bounds.y) + Float(obj_bounds.h); vertexData++;
231                 *vertexData = Float(obj_bounds.x); vertexData++;
232                 *vertexData = Float(obj_bounds.y) + Float(obj_bounds.h); vertexData++;
233
234                 *indexData = currentIndex; indexData++;
235                 *indexData = currentIndex+1; indexData++;
236                 *indexData = currentIndex+2; indexData++;
237                 *indexData = currentIndex+3; indexData++;
238                 *indexData = 0xFFFFFFFF; // Primitive restart.
239                 indexData++;
240                 currentIndex += 4;
241                 m_rendered_outline++;
242         }
243         m_vertex_buffer.UnMap();
244         m_index_buffer.UnMap();
245
246         m_bounds_dirty = false;
247
248 }

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