pgl
PrimitiveOpenGL3Dprimitivelibrary
pgl.h
Go to the documentation of this file.
1 
22 #ifndef PGL_PGL_H_
23 #define PGL_PGL_H_
24 
25 #include "math.h"
26 
27 #include <GL/gl.h>
28 
29 #include <memory>
30 #include <vector>
31 #include <fstream>
32 #include <iostream>
33 
34 // GLFW-compatible defines
35 #define PGL_RELEASE 0
36 #define PGL_PRESS 1
37 #define PGL_REPEAT 2
38 
39 #define PGL_MOUSE_BUTTON_LEFT 0
40 #define PGL_MOUSE_BUTTON_RIGHT 1
41 #define PGL_MOUSE_BUTTON_MIDDLE 2
42 
43 namespace pgl {
44 
129 class Node
130 {
131  public:
132  std::vector<Node*> children;
133 
134  public:
135  virtual ~Node()
136  {
137  for (size_t ii=0; ii != children.size(); ++ii)
138  delete children[ii];
139  children.clear();
140  }
141 
143  virtual void draw()
144  {
145  for (size_t ii=0; ii != children.size(); ++ii)
146  children[ii]->draw();
147  }
148 
159  template<class T>
160  T* attach(T *child)
161  {
162  children.push_back(child);
163  return child;
164  }
165 };
166 
174 class Object : public Node
175 {
176  public:
178 
179  public:
185  Object() : transform({0, 0, 0}, {0, 0, 0}) { }
186 
188  virtual void draw()
189  {
190  glPushMatrix();
191  glMultMatrixd(transform.data);
192  Node::draw();
193  glPopMatrix();
194  }
195 };
196 
203 class Scene : public Node
204 {
205  public:
207 
208  public:
209  Scene() : color(0, 0, 0) { }
210 
212  virtual void draw()
213  {
214  glClearColor(color.x, color.y, color.z, 1);
215  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
216 
217  Node::draw();
218  }
219 };
220 
224 class Camera
225 {
226  public:
229  double fovy;
230 
231  public:
239  Camera(Scene *_scene, double _fovy = 0.92) : scene(_scene), fovy(_fovy) { }
240 
242  void draw()
243  {
244  int dims[4];
245  glGetIntegerv(GL_VIEWPORT, dims);
246  double aspect = dims[2]/(double)dims[3];
247 
248  double f = 1/tan(fovy/2);
249  double near = 1, far = 100;
250 
251  double matrix[] = {f/aspect, 0., 0., 0.,
252  0., f, 0., 0.,
253  0., 0., (far+near)/(near-far), -1.,
254  0., 0., 2*far*near/(near-far), 0.};
255 
256  glMatrixMode(GL_PROJECTION);
257  glLoadMatrixd(matrix);
258 
259  GLfloat pos[] = {0, 0, 1, 0};
260  glLightfv(GL_LIGHT0, GL_POSITION, pos);
261 
262  glMatrixMode(GL_MODELVIEW);
263  glLoadMatrixd(transform.data);
264 
265  scene->draw();
266  }
267 };
268 
275 {
276  public:
278 
279  public:
280  Controller(Camera *_camera) : camera(_camera) { }
281  virtual ~Controller() { }
282 
284  virtual void click(int button, int action, int mods, double xpos, double ypos) = 0;
285 
287  virtual void scroll(double xoffset, double yoffset) = 0;
288 
290  virtual void motion(double xpos, double ypos) = 0;
291 };
292 
299 class Texture
300 {
301  protected:
302  typedef std::shared_ptr<GLuint> GLuintPtr;
303 
304  public:
305  int width = 0,
306  height = 0;
307 
308  protected:
309  GLuintPtr texture_ = 0;
310 
311  public:
312  Texture() { }
313 
315  Texture(int width, int height, unsigned char *data, bool interpolate=false)
316  {
317  make(width, height, data, interpolate);
318  }
319 
321  Texture(const std::string &file, bool interpolate=true)
322  {
323  std::ifstream ifs(file);
324  std::string magic;
325 
326  ifs >> magic;
327  if (magic != "P6")
328  {
329  std::cerr << file << " is not a valid binary PPM" << std::endl;
330  return;
331  }
332 
333  int _width = readint(ifs);
334  int _height = readint(ifs);
335  int maxval = readint(ifs);
336 
337  if (maxval != 255)
338  {
339  std::cerr << file << ": pixel format not supported" << std::endl;
340  return;
341  }
342 
343  unsigned char *data = new unsigned char[_width*_height*3];
344 
345  ifs.read((char*)data, _width*_height*3);
346  if (!ifs.good())
347  {
348  std::cerr << file << " is truncated" << std::endl;
349  return;
350  }
351 
352  make(_width, _height, data, interpolate);
353 
354  delete[] data;
355  }
356 
357  ~Texture()
358  {
359  // Delete OpenGL texture when last reference goes out of scope.
360  if (texture_.use_count() == 1)
361  glDeleteTextures(1, texture_.get());
362  }
363 
365  operator bool() const
366  {
367  return texture_ != 0;
368  }
369 
371  void bind() const
372  {
373  glBindTexture(GL_TEXTURE_2D, *texture_);
374  }
375 
376  protected:
377  void make(int _width, int _height, unsigned char *data, bool interpolate)
378  {
379  width = _width;
380  height = _height;
381  texture_ = GLuintPtr(new GLuint);
382 
383  glGenTextures(1, texture_.get());
384  glBindTexture(GL_TEXTURE_2D, *texture_);
385  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
386  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, interpolate?GL_LINEAR:GL_NEAREST);
387  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, interpolate?GL_LINEAR:GL_NEAREST);
388  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
389  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
390  glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, (void*)data);
391  }
392 
393  void eatcomments(std::ifstream &ifs)
394  {
395  char c;
396  do
397  {
398  c = ifs.get();
399  if (c == '#')
400  {
401  char buffer[256];
402  ifs.getline(buffer, 256);
403  }
404  } while (isspace(c) || c == '#');
405 
406  ifs.putback(c);
407  }
408 
410  int readint(std::ifstream &ifs)
411  {
412  int val;
413 
414  eatcomments(ifs);
415  ifs >> val;
416  eatcomments(ifs);
417 
418  return val;
419  }
420 };
421 
423 class Checkerboard4x4 : public Texture
424 {
425  public:
427  {
428  const unsigned char m = 255;
429  unsigned char data[] = {0,0,0,m,m,m,0,0,0,m,m,m,
430  m,m,m,0,0,0,m,m,m,0,0,0,
431  0,0,0,m,m,m,0,0,0,m,m,m,
432  m,m,m,0,0,0,m,m,m,0,0,0};
433 
434  make(4, 4, data, false);
435  }
436 };
437 
438 }
439 
440 #include "primitive.h"
441 #include "controller.h"
442 
443 #endif // PGL_PGL_H_
Camera(Scene *_scene, double _fovy=0.92)
Specifies the Scene to draw, as well as the vertical field of view.
Definition: pgl.h:239
Transform transform
Position and orientation.
Definition: pgl.h:177
Texture(int width, int height, unsigned char *data, bool interpolate=false)
Loads texture data from existing RGB array. Data can be discarded afterwards.
Definition: pgl.h:315
Vector3 color
Background color.
Definition: pgl.h:206
std::vector< Node * > children
Sub-objects.
Definition: pgl.h:132
virtual void draw()
Draw children relative to this object.
Definition: pgl.h:188
Object()
Default constructor.
Definition: pgl.h:185
Camera * camera
Camera to move.
Definition: pgl.h:277
Node in the scene graph.
Definition: pgl.h:129
Texture.
Definition: pgl.h:299
Definition: controller.h:27
virtual void draw()
Draw scene.
Definition: pgl.h:212
Transform transform
Camera position.
Definition: pgl.h:227
Camera controller.
Definition: pgl.h:274
virtual void draw()
Draw children.
Definition: pgl.h:143
3-component vector.
Definition: math.h:43
double fovy
Vertical field of view.
Definition: pgl.h:229
Checkerboard texture.
Definition: pgl.h:423
void bind() const
Use this texture as the current OpenGL 2D texture.
Definition: pgl.h:371
void draw()
Draw Scene from this camera&#39;s perspective.
Definition: pgl.h:242
int readint(std::ifstream &ifs)
Read integer value from PPM file, ignoring comments and whitespace.
Definition: pgl.h:410
Texture(const std::string &file, bool interpolate=true)
Loads texture from Portable Pixmap (PPM) file.
Definition: pgl.h:321
Homogeneous coordinate transform.
Definition: math.h:164
Root node of the scene graph.
Definition: pgl.h:203
Object in a scene.
Definition: pgl.h:174
T * attach(T *child)
Add child to list of sub-objects.
Definition: pgl.h:160
Scene * scene
Scene to draw.
Definition: pgl.h:228
Defines camera position and frustum.
Definition: pgl.h:224