#include <GL/glew.h>
#include
<GL/freeglut.h>
#include <iostream>
GLuint pboID[2];
GLuint textureID;
const int IMAGE_WIDTH = 1024;
const int IMAGE_HEIGHT = 800;
const
int CHANNEL_COUNT = 4;
const int DATA_SIZE = IMAGE_WIDTH * IMAGE_HEIGHT
* CHANNEL_COUNT;
GLubyte * imageData = 0;
float cameraAngleX;
float cameraAngleY;
float
cameraDistance = -5.0;
bool mouseLeftDown;
bool mouseRightDown;
float
LastXPos;
float LastYPos;
void
InitGL()
{
glEnable(GL_TEXTURE_2D);
glShadeModel(GL_SMOOTH);
glClearColor(0.0,
0.0, 0.0, 1.0);
glGenTextures(1,
&textureID);
glBindTexture(GL_TEXTURE_2D,
textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D,
GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, IMAGE_WIDTH,
IMAGE_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid
*)(imageData));
glBindTexture(GL_TEXTURE_2D, 0);
glGenBuffers(2,
pboID);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
pboID[0]);
glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0,
GL_STREAM_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
pboID[1]);
glBufferData(GL_PIXEL_UNPACK_BUFFER, DATA_SIZE, 0,
GL_STREAM_DRAW);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
0);
}
void UpdatePixels(GLubyte* dst, int size)
{
static int color = 0;
if(!dst)
return;
int* ptr = (int*)dst;
for(int i = 0; i <
IMAGE_HEIGHT; ++i)
{
for(int j = 0;
j < IMAGE_WIDTH; ++j)
{
*ptr = color;
ptr++;
}
color += 257;
}
++color;
}
void PaintGL()
{
static int index = 0;
int
nextIndex = 0;
index = (index + 1) % 2;
nextIndex =
(index + 1) % 2;
glBindTexture(GL_TEXTURE_2D,
textureID);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
pboID[index]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, IMAGE_WIDTH,
IMAGE_HEIGHT, GL_BGRA, GL_UNSIGNED_BYTE,
0);
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
pboID[nextIndex]);
glBufferData(GL_PIXEL_UNPACK_BUFFER,
DATA_SIZE, 0, GL_STREAM_DRAW);
GLubyte * ptr = (GLubyte
*)glMapBuffer(GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY);
if
(ptr)
{
UpdatePixels(ptr,
DATA_SIZE);
glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER);
}
glBindBuffer(GL_PIXEL_UNPACK_BUFFER,
0);
glClear(GL_COLOR_BUFFER_BIT |
GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(0, 0, cameraDistance);
glRotatef(cameraAngleX, 1, 0, 0);
glRotatef(cameraAngleY, 0, 1, 0);
glBindTexture(GL_TEXTURE_2D, textureID);
glColor4f(1, 1, 1, 1);
glBegin(GL_QUADS);
glNormal3f(0, 0, 1);
glTexCoord2f(0.0f,
0.0f); glVertex3f(-1.0f, -1.0f, 0.0f);
glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,
0.0f);
glTexCoord2f(1.0f, 1.0f); glVertex3f(
1.0f, 1.0f, 0.0f);
glTexCoord2f(0.0f,
1.0f); glVertex3f(-1.0f, 1.0f, 0.0f);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
glPopMatrix();
glutSwapBuffers();
}
void ResizeGL(int w, int h)
{
if (h == 0)
h
= 1;
glViewport(0, 0, w,
h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0,
w/h, 1.0,
100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mouse(int button, int state, int x, int y)
{
if (button == GLUT_LEFT_BUTTON && state ==
GLUT_DOWN)
{
mouseLeftDown =
true;
LastXPos = x;
LastYPos = y;
}
if (button == GLUT_RIGHT_BUTTON && state ==
GLUT_UP)
{
mouseRightDown =
true;
}
}
void mouseMotion(int x, int
y)
{
if (mouseLeftDown)
{
cameraAngleX += GLfloat(y - LastYPos)/GLfloat(20.0);
cameraAngleY += GLfloat(x - LastXPos)/GLfloat(20.0);
LastYPos = y;
LastXPos = x;
}
}
int main(int argc, char ** argv)
{
glutInit(&argc,
argv);
glutInitDisplayMode(GLUT_DOUBLE |
GLUT_RGBA);
glutInitWindowSize(1024,
800);
glutCreateWindow("PBO");
GLenum res =
glewInit();
if (res !=
GLEW_OK)
{
std::cout <<
glewGetErrorString(res) << std::endl;
return
EXIT_FAILURE;
}
InitGL();
glutDisplayFunc(PaintGL);
glutReshapeFunc(ResizeGL);
glutMouseFunc(mouse);
glutMotionFunc(mouseMotion);
glutMainLoop();
glDeleteBuffers(2,
pboID);
glDeleteTextures(1, &textureID);
delete []
imageData;
return EXIT_SUCCESS;
}