#define ALLEGRO_UNSTABLE
#include <stdio.h>
#include <math.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_opengl.h>
#include "common.c"
* on red background onto a texture, then draws a quad with that texture.
*/
GLuint tex, fbo;
bool no_fbo = false;
static void draw_opengl(void)
{
double secs = al_get_time();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
* it with the framebuffer extension.
*/
if (!tex) {
unsigned char *pixels = malloc(256 * 256 * 4);
int x, y;
for (y = 0; y < 256; y++) {
for (x = 0; x < 256; x++) {
unsigned char r = x, g = y, b = 0, a = 255;
pixels[y * 256 * 4 + x * 4 + 0] = r;
pixels[y * 256 * 4 + x * 4 + 1] = g;
pixels[y * 256 * 4 + x * 4 + 2] = b;
pixels[y * 256 * 4 + x * 4 + 3] = a;
}
}
glGenTextures(1, &tex);
glBindTexture(GL_TEXTURE_2D, tex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 256, 256, 0, GL_RGBA,
GL_UNSIGNED_INT_8_8_8_8_REV, pixels);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
free(pixels);
}
if (!fbo && !no_fbo) {
if (al_get_opengl_extension_list()->ALLEGRO_GL_EXT_framebuffer_object) {
glGenFramebuffersEXT(1, &fbo);
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
GL_TEXTURE_2D, tex, 0);
if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) !=
GL_FRAMEBUFFER_COMPLETE_EXT) {
no_fbo = true;
}
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
else {
no_fbo = true;
}
}
if (fbo && !no_fbo) {
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo);
glPushAttrib(GL_VIEWPORT_BIT | GL_TRANSFORM_BIT);
glViewport(0, 0, 256, 256);
glClearColor(1, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, 256, 256, 0, -1, 1);
glDisable(GL_TEXTURE_2D);
glColor3f(1, 1, 0);
glTranslatef(128, 128 + sin(secs * ALLEGRO_PI * 2 * 2) * 20, 0);
glBegin(GL_TRIANGLES);
glVertex2f(0, -100);
glVertex2f(100, 0);
glVertex2f(-100, 0);
glEnd();
glPopMatrix();
glPopAttrib();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
}
glClearColor(0, 0, 1, 1);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glTranslatef(320, 240, 0);
glRotatef(secs * 360 / 4, 0, 0, 1);
glColor3f(1, 1, 1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex2f(-100, -100);
glTexCoord2f(1, 0); glVertex2f(+100, -100);
glTexCoord2f(1, 1); glVertex2f(+100, +100);
glTexCoord2f(0, 1); glVertex2f(-100, +100);
glEnd();
}
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display;
ALLEGRO_EVENT_QUEUE *queue;
ALLEGRO_EVENT event;
int frames = 0;
double start;
(void)argc;
(void)argv;
if (!al_init()) {
abort_example("Could not init Allegro.\n");
}
open_log();
al_install_keyboard();
al_set_new_display_flags(ALLEGRO_OPENGL);
display = al_create_display(640, 480);
if (!display) {
abort_example("Could not create display.\n");
}
queue = al_create_event_queue();
al_register_event_source(queue, al_get_keyboard_event_source());
al_register_event_source(queue, al_get_display_event_source(display));
start = al_get_time();
while (true) {
if (!al_is_event_queue_empty(queue)) {
while (al_get_next_event(queue, &event)) {
switch (event.type) {
case ALLEGRO_EVENT_DISPLAY_CLOSE:
goto done;
case ALLEGRO_EVENT_KEY_DOWN:
if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
goto done;
break;
}
}
}
draw_opengl();
al_flip_display();
frames++;
}
done:
log_printf("%.1f FPS\n", frames / (al_get_time() - start));
al_destroy_event_queue(queue);
al_destroy_display(display);
close_log(true);
return 0;
}