PBO

#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;
}

PBO

上一篇:Riskified Ltd.宣布首次公开发行的定价


下一篇:像玩魔兽一样编程——谈VS2010键盘流