Code:
#include "OpenGLSB.h"
#include "GLTools.h"
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)
#define TEXTURE_BACK 0
#define TEXTURE_MASK 1
#define TEXTURE_SPRITE 2
#define TEXTURE_COUNT 3
GLuint textures[TEXTURE_COUNT];
const char *szTextureFiles[TEXTURE_COUNT] = { "back.tga", "mask.tga", "sprite.tga" };
void RenderScene(void);
void ResizeScene(GLint w, GLint h);
void SetupRC(void);
void ReleaseRC(void);
void TimerFunc(GLint value);
void GetInput(void);
int main(void) {
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
glutInitWindowPosition(150, 150);
glutInitWindowSize(SCREEN_WIDTH, SCREEN_HEIGHT);
glutCreateWindow("OpenGL Console");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ResizeScene);
glutTimerFunc(33, TimerFunc, 0);
SetupRC();
glutMainLoop();
ReleaseRC();
return 0;
}
void SetupRC(void) {
GLubyte *pBytes = NULL;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
GLint i;
glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glShadeModel(GL_SMOOTH);
// Load Textures
glGenTextures(TEXTURE_COUNT, textures);
for (i = 0; i < TEXTURE_COUNT; i++) {
// Bind to next texture object
glBindTexture(GL_TEXTURE_2D, textures[i]);
// Load texture, set filter and wrap modes.
pBytes = gltLoadTGA(szTextureFiles[i], &iWidth, &iHeight, &iComponents, &eFormat);
if (pBytes != NULL) {
gluBuild2DMipmaps(GL_TEXTURE_2D, iComponents, iWidth, iHeight, eFormat, GL_UNSIGNED_BYTE, pBytes);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
free(pBytes); // Free origional texture data.
} else {
printf("Error reading file.\n");
}
}
}
void ReleaseRC(void) {
glDeleteTextures(TEXTURE_COUNT, textures);
}
void ResizeScene(GLint w, GLint h) {
if (h == 0)
h = 1;
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-400.0, 400.0, -300.0, 300.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void TimerFunc(GLint value) {
GetInput();
glutPostRedisplay();
glutTimerFunc(33, TimerFunc, 0);
}
void GetInput(void) {
if (KEYDOWN(VK_ESCAPE))
exit(0);
}
void RenderScene(void) {
static GLint frame = 0;
static GLfloat x = 0.0f;
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_BACK]);
glBegin(GL_QUADS);
// Lower-left
glTexCoord2f(-1.0f, -1.0f);
glVertex2f(-400.0f, -300.0f);
// Lower-right
glTexCoord2f(1.0f, -1.0f);
glVertex2f(400.0f, -300.0f);
// Upper-right
glTexCoord2f(1.0f, 1.0f);
glVertex2f(400.0f, 300.0f);
// Upper-left
glTexCoord2f(-1.0f, 1.0f);
glVertex2f(-400.0f, 300.0f);
glEnd();
// Mask Sprite
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR, GL_ZERO);
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_MASK]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, frame*0.5f); glVertex3f(-25.0f+x, -25.0f, 0.0f); // <11-2>
glTexCoord2f(1.0f, frame*0.5f); glVertex3f(25.0f+x, -25.0f, 0.0f); // <11-3>
glTexCoord2f(1.0f, frame*0.5f+0.5f); glVertex3f(25.0f+x, 25.0f, 0.0f); // <11-4>
glTexCoord2f(0.0f, frame*0.5f+0.5f); glVertex3f(-25.0f+x, 25.0f, 0.0f); // <11-5>
glEnd();
// Sprite
glBlendFunc(GL_ONE, GL_ONE);
glBindTexture(GL_TEXTURE_2D, textures[TEXTURE_SPRITE]);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, frame*0.5f); glVertex3f(-25.0f+x, -25.0f, 0.0f); // <14-2>
glTexCoord2f(1.0f, frame*0.5f); glVertex3f(25.0f+x, -25.0f, 0.0f); // <14-3>
glTexCoord2f(1.0f, frame*0.5f+0.5f); glVertex3f(25.0f+x, 25.0f, 0.0f); // <14-4>
glTexCoord2f(0.0f, frame*0.5f+0.5f); glVertex3f(-25.0f+x, 25.0f, 0.0f); // <14-5>
glEnd();
glDisable(GL_BLEND);
if (frame == 0)
frame = 1;
else
frame = 0;
x += 0.025f;
if(x>6.0f) x=-5.0f;
glutSwapBuffers();
}