summaryrefslogtreecommitdiffstats
path: root/copy_experiments/gl_copies.c
blob: 4d6de1f4a64fdcf8c4a661b90af6942d56e9756c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
// Built off the Triangle and Checkered Triangle OpenGL examples by Ray Toal
// (https://cs.lmu.edu/~ray/notes/openglexamples/)
#include <stdio.h>

#include <GL/glut.h>

#define red {0xff, 0x00, 0x00}
#define yellow {0xff, 0xff, 0x00}
#define magenta {0xff, 0, 0xff}

GLubyte* texture;

const unsigned side = 1024*10; // 30 MiB

// Clears the current window and draws a triangle.
void display() {

  // Set every pixel in the frame buffer to the current clear color.
  glClear(GL_COLOR_BUFFER_BIT);

  // Re-upload the texture on every frame
  glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, side, side, GL_RGB, GL_UNSIGNED_BYTE, texture);

  // Drawing is done by specifying a sequence of vertices.  The way these
  // vertices are connected (or not connected) depends on the argument to
  // glBegin.  GL_POLYGON constructs a filled polygon.
  glBegin(GL_POLYGON);
  glTexCoord2f(0.5, side); glVertex3f(-0.6, -0.75, 0.5);
  glTexCoord2f(0.0, 0.0); glVertex3f(0.6, -0.75, 0);
  glTexCoord2f(side, 0.0); glVertex3f(0, 0.75, 0);
  glEnd();

  // Flush drawing command buffer to make drawing happen as soon as possible.
  glFlush();

  // Request a redraw on the next loop
  glutPostRedisplay();
}

// Initializes GLUT, the display mode, and main window; registers callbacks;
// enters the main event loop.
int main(int argc, char** argv) {
  // No arguments are accepted
  if (argc != 1) {
    fprintf(stderr, "Usage: %s\n", argv[0]);
    return 1;
  }

  // 30 MiB image
  texture = malloc(side*side*3u);

  // Add a checkered pattern to the texture
  for (unsigned i = 0; i < side*side; i++) {
    if (i % 2 == 0) { // Yellow
      texture[i*3] = 0xff;
      texture[i*3+1] = 0xff;
    } else // Red
      texture[i*3] = 0xff;
  }

  // Use a single buffered window in RGB mode (as opposed to a double-buffered
  // window or color-index mode).
  glutInit(&argc, argv);
  glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

  // Position window at (80,80)-(480,380) and give it a title.
  glutInitWindowPosition(80, 80);
  glutInitWindowSize(400, 300);
  glutCreateWindow("A Simple Triangle");

  // Tell GLUT that whenever the main window needs to be repainted that it
  // should call the function display().
  glutDisplayFunc(display);

  glEnable(GL_TEXTURE_2D);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glTexImage2D(GL_TEXTURE_2D,
               0,                    // level 0
               3,                    // use only R, G, and B components
               side, side,           // texture has 2x2 texels
               0,                    // no border
               GL_RGB,               // texels are in RGB format
               GL_UNSIGNED_BYTE,     // color components are unsigned bytes
               texture);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

  // Tell GLUT to start reading and processing events.  This function
  // never returns; the program only exits when the user closes the main
  // window or kills the process.
  glutMainLoop();
}