5 #define GL_GLEXT_PROTOTYPES 1
17 static const char *modestr[] = { "GL_POINTS", "glDrawPixels", "textured quad",
23 void reshape(int x, int y);
24 void keyb(unsigned char key, int x, int y);
25 void change_mode(int m);
27 int win_width, win_height;
28 int max_xscroll, max_yscroll;
32 unsigned int img[IMG_W * IMG_H];
34 unsigned int vbo_pos, vbo_col;
36 unsigned int tex, quad, tri;
38 int mode = MODE_POINTS;
40 int have_vbo = 1; /* TODO */
42 unsigned int start_tm;
43 unsigned int num_frames;
46 int main(int argc, char **argv)
48 glutInit(&argc, argv);
49 glutInitWindowSize(800, 600);
50 glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
51 glutCreateWindow("GL pixel drawing methods");
55 glutDisplayFunc(display);
56 glutReshapeFunc(reshape);
57 glutKeyboardFunc(keyb);
64 start_tm = glutGet(GLUT_ELAPSED_TIME);
72 int i, j, xor, r, g, b;
77 for(i=0; i<IMG_H; i++) {
78 for(j=0; j<IMG_W; j++) {
80 r = (xor >> 1) & 0xff;
82 b = (xor << 1) & 0xff;
83 *ptr++ = r | (g << 8) | (b << 16);
87 glPixelStorei(GL_UNPACK_ROW_LENGTH, IMG_W);
89 win_width = glutGet(GLUT_WINDOW_WIDTH);
90 win_height = glutGet(GLUT_WINDOW_HEIGHT);
92 glGenTextures(1, &tex);
93 glBindTexture(GL_TEXTURE_2D, tex);
94 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
95 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
96 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, win_width, win_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
98 varr_sz = win_width * win_height * sizeof *varr * 2;
99 if(!(varr = malloc(varr_sz))) {
100 fprintf(stderr, "failed to allocate vertex array\n");
103 carr_sz = win_width * win_height * sizeof *carr * 3;
104 if(!(carr = malloc(carr_sz))) {
105 fprintf(stderr, "failed to allocate color array\n");
110 for(i=0; i<win_height; i++) {
111 for(j=0; j<win_width; j++) {
119 glGenBuffers(1, &vbo_pos);
120 glBindBuffer(GL_ARRAY_BUFFER, vbo_pos);
121 glBufferData(GL_ARRAY_BUFFER, varr_sz, varr, GL_STATIC_DRAW);
123 glGenBuffers(1, &vbo_col);
124 glBindBuffer(GL_ARRAY_BUFFER, vbo_col);
125 glBufferData(GL_ARRAY_BUFFER, carr_sz, 0, GL_STREAM_DRAW);
128 quad = glGenLists(1);
129 glNewList(quad, GL_COMPILE);
131 glTexCoord2f(0, 0); glVertex2f(0, 0);
132 glTexCoord2f(1, 0); glVertex2f(1, 0);
133 glTexCoord2f(1, 1); glVertex2f(1, 1);
134 glTexCoord2f(0, 1); glVertex2f(0, 1);
139 glNewList(tri, GL_COMPILE);
140 glBegin(GL_TRIANGLES);
141 glTexCoord2f(0, 0); glVertex2f(0, 0);
142 glTexCoord2f(2, 0); glVertex2f(2, 0);
143 glTexCoord2f(0, 2); glVertex2f(0, 2);
153 unsigned int tm = glutGet(GLUT_ELAPSED_TIME);
155 float t = tm / 256.0f;
156 int xoffs = (int)((sin(t) * 0.5f + 0.5f) * max_xscroll);
157 int yoffs = (int)((cos(t) * 0.5f + 0.5f) * max_yscroll);
158 unsigned int *start = img + yoffs * IMG_W + xoffs;
161 glMatrixMode(GL_MODELVIEW);
166 /* draw with points */
168 for(i=0; i<win_height; i++) {
169 for(j=0; j<win_width; j++) {
170 int r = start[j] & 0xff;
171 int g = (start[j] >> 8) & 0xff;
172 int b = (start[j] >> 16) & 0xff;
173 vptr[0] = r / 255.0f;
174 vptr[1] = g / 255.0f;
175 vptr[2] = b / 255.0f;
182 glBindBuffer(GL_ARRAY_BUFFER, vbo_pos);
183 glVertexPointer(2, GL_FLOAT, 0, 0);
184 glBindBuffer(GL_ARRAY_BUFFER, vbo_col);
185 glBufferSubData(GL_ARRAY_BUFFER, 0, carr_sz, carr);
186 glColorPointer(3, GL_FLOAT, 0, 0);
187 glBindBuffer(GL_ARRAY_BUFFER, 0);
189 glVertexPointer(2, GL_FLOAT, 0, varr);
190 glColorPointer(3, GL_FLOAT, 0, carr);
193 glEnableClientState(GL_VERTEX_ARRAY);
194 glEnableClientState(GL_COLOR_ARRAY);
196 glDrawArrays(GL_POINTS, 0, win_width * win_height);
198 glDisableClientState(GL_VERTEX_ARRAY);
199 glDisableClientState(GL_COLOR_ARRAY);
203 /* draw with glDrawPixels */
204 glDrawPixels(win_width, win_height, GL_RGBA, GL_UNSIGNED_BYTE, start);
209 /* draw with textured quad or triangle */
210 glBindTexture(GL_TEXTURE_2D, tex);
211 glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, win_width, win_height, GL_RGBA,
212 GL_UNSIGNED_BYTE, start);
213 glEnable(GL_TEXTURE_2D);
214 glScalef(win_width, win_height, 1);
215 glCallList(mode == MODE_TEXQUAD ? quad : tri);
216 glDisable(GL_TEXTURE_2D);
221 assert(glGetError() == GL_NO_ERROR);
223 tm = glutGet(GLUT_ELAPSED_TIME);
224 interv = tm - start_tm;
225 if(++num_frames == 1000 || interv > 5000) {
226 unsigned int fps = 100000 * num_frames / interv;
227 printf("%s: %.2f fps\n", modestr[mode], fps / 100.0f);
231 if(mode < NUM_MODES - 1) {
232 change_mode(mode + 1);
244 void reshape(int x, int y)
246 glViewport(0, 0, x, y);
248 glMatrixMode(GL_PROJECTION);
250 glOrtho(0, x, 0, y, -1, 1);
254 max_xscroll = IMG_W - win_width;
255 max_yscroll = IMG_H - win_height;
256 if(max_xscroll < 0) max_xscroll = 0;
257 if(max_yscroll < 0) max_yscroll = 0;
260 void keyb(unsigned char key, int x, int y)
267 change_mode((mode + 1) % NUM_MODES);
275 void change_mode(int m)
279 sprintf(title, "GL pixel drawing test: %s\n", modestr[mode]);
280 glutSetWindowTitle(title);