OpenGL基于帧缓存FBO的离屏渲染

时间:2021-10-06 05:08:02
#include <GL/glew.h>  //最好放在glut.h前面包含
#include <GL/glut.h>
#include <cv.h>
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;


#pragma comment( lib, "glew32.lib"  )
#pragma comment( lib, "glew32s.lib" )
#pragma comment( lib, "glut32.lib"  )


const int WIDTH  = 600;
const int HEIGHT = 600;

const double xMax =  10;
const double xMin = -10;
const double yMax =  10;
const double yMin = -10;
const double nearDist = 0;
const double farDist  = 100;


const double camPosX = 0;
const double camPosY = 0;
const double camPosZ = 0;
const double lookAtX = 0;
const double lookAtY = 0;
const double lookAtZ = -1;
const double upX     = 0;
const double upY     = 1;
const double upZ     = 0;


void main() {


//////////////////////
// Create a window. //
//////////////////////


//glutInit( &argc, argv );
glutCreateWindow( "RTT window" );  //完成OpenGL初始化,但是窗口并没有显示,要调用glutMainLoop才显示
//glutInitWindowSize( WIDTH, HEIGHT );
glewInit(); 


//////////////////////////////////
// Check th framebuffer status. //
//////////////////////////////////


GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );


switch( status ) {


case GL_FRAMEBUFFER_COMPLETE_EXT:
cout<<"GL_FRAMEBUFFER_COMPLETE_EXT!: SUCCESS"<<endl<<endl;
break;


case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
cout<<"GL_FRAMEBUFFER_UNSUPPORTED_EXT!: ERROR"<<endl;
exit(0);
break;


default:
exit(0);


}
// ID numbers for buffers.
GLuint fbo; // for 'frame buffer object'
GLuint rbo; // for 'render buffer object'

// ID numbers for textures.
GLuint renderTarget;
GLuint textureID;  //外部加载ID号

// Create buffers.
glGenFramebuffersEXT(  1, &fbo );
glGenRenderbuffersEXT( 1, &rbo );

// Create textures.
glGenTextures( 1, &renderTarget );
glBindTexture( GL_TEXTURE_2D, renderTarget );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, WIDTH, HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL );

// Set the render target.
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, fbo );
glBindRenderbufferEXT( GL_RENDERBUFFER_EXT, rbo );
glRenderbufferStorageEXT( GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, WIDTH, HEIGHT ); //

glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );

glFramebufferTexture2DEXT( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, renderTarget, 0 );
glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rbo );

//sphere texture
IplImage* imgBGR = cvLoadImage("test1.jpg"); //通过opengcv从磁盘加载图
IplImage* imgRGB = cvCreateImage(cvGetSize(imgBGR), 8, 3);
cvCvtColor(imgBGR,imgRGB,CV_BGR2RGB);

int width  = imgRGB->width;
int height = imgRGB->height; 

glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 

glTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE,imgRGB->imageData); //已存入显存

cvReleaseImage(&imgBGR);
cvReleaseImage(&imgRGB);

///////////////////
// Render scene. //
///////////////////

// Set the render states.
glEnable( GL_DEPTH_TEST );
glDepthMask( 1 );
glDepthFunc( GL_LEQUAL );

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);

glEnable(GL_LINE_SMOOTH);
glLineWidth(1.0);


// Draw on the buffer.
glClearColor( 0.f, 0.f, 0.f, 1.f );
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glViewport( 0, 0, WIDTH, HEIGHT );  // Viewport transformation

glMatrixMode( GL_PROJECTION );      // Projection transformation
glLoadIdentity();
//glOrtho( xMin, xMax, yMin, yMax, nearDist, farDist );
gluPerspective(90, (float)WIDTH/(float)HEIGHT, 0.1, 100);

glMatrixMode( GL_MODELVIEW );       // Viewing transformation
glLoadIdentity();
gluLookAt( camPosX, camPosY, camPosZ, lookAtX, lookAtY, lookAtZ, upX, upY, upZ );


//glColor3f(1,1,1); // yellow 这里是画四边形
//glTranslatef( 0, 0, -60 );
//glBegin( GL_QUADS );
//glVertex3f( xMin, yMin, 0 );
//glVertex3f( xMax, yMin, 0 );
//glVertex3f( xMax, yMax, 0 );
//glVertex3f( xMin, yMax, 0 );
//glEnd();


GLUquadricObj* quadratic= gluNewQuadric(); //画带纹理的球
gluQuadricDrawStyle(quadratic, GLU_FILL);
gluQuadricNormals(quadratic, GLU_SMOOTH);
gluQuadricTexture(quadratic, GL_TRUE);
glPushMatrix(); 
glColor3f(1.0f,1.0f,1.0f); 
glTranslatef(0.0f,0.0f,0.0f);
glBindTexture(GL_TEXTURE_2D,textureID); 
glEnable(GL_TEXTURE_2D); 


glRotatef(90.0f,1.0f,0.0f,0.0f);
glRotatef(-23.5f,0.0f,0.0f,1.0f);


gluSphere(quadratic,1,180,180); 
glDisable(GL_TEXTURE_2D);
glPopMatrix(); 


///////////////////////
// Read from buffer. //
///////////////////////
unsigned char *color = new unsigned char[WIDTH*HEIGHT*4];
float         *depth = new float[WIDTH*HEIGHT];;


glReadBuffer( GL_COLOR_ATTACHMENT0_EXT );
glReadPixels( 0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE, color );
IplImage* image = cvCreateImage(cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 4);
IplImage* imageRGB = cvCreateImage(cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 4);
IplImage* imageFlip = cvCreateImage(cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 4);
image->imageData = (char*)color;
//cvCvtColor(image,imgRGB,CV_BGRA2BGR);
//cvFlip(imageRGB,imageFlip,1);
cvSaveImage("C:\\temp.jpg", image); //保存
cvReleaseImage(&image);
//cvReleaseImage(&imageRGB);
//cvReleaseImage(&imageFlip);

cout<<"Color values from color buffer:"<<endl;
cout<<"("<<(int)color[8]<<","<<(int)color[9]<<","<<(int)color[10]<<","<<(int)color[11]<<") ("
<<(int)color[12]<<","<<(int)color[13]<<","<<(int)color[14]<<","<<(int)color[15]<<")"<<endl;
cout<<"("<<(int)color[0]<<","<<(int)color[1]<<","<<(int)color[2]<<","<<(int)color[3]<<") ("
<<(int)color[4]<<","<<(int)color[5]<<","<<(int)color[6]<<","<<(int)color[7]<<")"<<endl<<endl;

glReadBuffer( GL_DEPTH_ATTACHMENT_EXT );
glReadPixels( 0, 0, WIDTH, HEIGHT, GL_DEPTH_COMPONENT, GL_FLOAT, depth );

cout<<"Depth values from z-buffer:"<<endl;
cout<<depth[2]<<" "<<depth[3]<<endl;
cout<<depth[0]<<" "<<depth[1]<<endl;

delete[] color;
delete[] depth;
/////////////////////
// Release mmemory //
/////////////////////
// Delete textures;
glDeleteTextures( 1, &renderTarget );

// Delete buffers.
glDeleteFramebuffersEXT(  1, &fbo );
glDeleteRenderbuffersEXT( 1, &rbo );

// Return to rendering to the main framebuffer instead of 'fbo'.
glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );


}