#pragma comment(lib, "glew32.lib")
#pragma comment(lib, "freeglut.lib")
#include "windows.h"
#include <stdio.h>
#include <gl/glew.h>
#include <gl/glut.h>
int windowWidth = 0;
int windowHeight = 0;
const int TexWidth = 500;
const int TexHeight = 500;
int colorBitLen = 32;
bool leftMouseDown = false;
float mouseX, mouseY;
float cameraAngleX, cameraAngleY;
float xRot, yRot;
GLubyte buff[TexWidth * TexHeight * 4] = {0};
GLuint textureID;
GLuint frameBufferID;
GLuint renderBufferID;
void drawCube()
{
glBindTexture(GL_TEXTURE_2D, textureID);
glColor4f(1, 1, 1, 1);
glBegin(GL_QUADS);
//Front
glNormal3d(0, 0, 1);
glVertex3d(-1, -1, 1); glTexCoord2d(0, 0);
glVertex3d(1, -1, 1); glTexCoord2d(1, 0);
glVertex3d(1, 1, 1); glTexCoord2d(1, 1);
glVertex3d(-1, 1, 1); glTexCoord2d(0, 1);
Back
//glNormal3d(0, 0, -1);
//glVertex3d(1, -1, -1); glTexCoord2d(0, 0);
//glVertex3d(-1, -1, -1); glTexCoord2d(1, 0);
//glVertex3d(-1, 1, -1); glTexCoord2d(1, 1);
//glVertex3d(1, 1, -1); glTexCoord2d(0, 1);
Left
//glNormal3d(-1, 0, 0);
//glVertex3d(-1, -1, -1); glTexCoord2d(0, 0);
//glVertex3d(-1, -1, 1); glTexCoord2d(1, 0);
//glVertex3d(-1, 1, 1); glTexCoord2d(1, 1);
//glVertex3d(-1, 1, -1); glTexCoord2d(0, 1);
Right
//glNormal3d(1, 0, 0);
//glVertex3d(1, -1, 1); glTexCoord2d(0, 0);
//glVertex3d(1, -1, -1); glTexCoord2d(1, 0);
//glVertex3d(1, 1, -1); glTexCoord2d(1, 1);
//glVertex3d(1, 1, 1); glTexCoord2d(0, 1);
Top
//glNormal3d(0, 1, 0);
//glVertex3d(-1, 1, 1); glTexCoord2d(0, 0);
//glVertex3d(1, 1, 1); glTexCoord2d(1, 0);
//glVertex3d(1, 1, -1); glTexCoord2d(1, 1);
//glVertex3d(-1, 1, -1); glTexCoord2d(0, 1);
Bottom
//glNormal3d(0, -1, 0);
//glVertex3d(1, -1, 1); glTexCoord2d(0, 0);
//glVertex3d(-1, -1, 1); glTexCoord2d(1, 0);
//glVertex3d(-1, -1, -1); glTexCoord2d(1, 1);
//glVertex3d(1, -1, -1); glTexCoord2d(0, 1);
glEnd();
glBindTexture(GL_TEXTURE_2D, 0);
}
void ChangeSize(int w, int h)
{
windowWidth = w;
windowHeight = h;
if (h == 0)
h = 1;
}
void savePixelData(GLubyte *data, int size) {
FILE* pFile;
fopen_s(&pFile, "C:\\Users\\bluda\\Desktop\\test.bmp", "wt");
if (!pFile) { fprintf(stderr, "error \n"); exit(-1); }
BITMAPFILEHEADER hdr;
BITMAPINFOHEADER infoHdr;
infoHdr.biSize = sizeof(BITMAPINFOHEADER);
infoHdr.biWidth = TexWidth;
infoHdr.biHeight = TexHeight;
infoHdr.biPlanes = 1;
infoHdr.biBitCount = colorBitLen;
infoHdr.biCompression = 0;
infoHdr.biSizeImage = size;
infoHdr.biXPelsPerMeter = 0;
infoHdr.biYPelsPerMeter = 0;
infoHdr.biClrUsed = 0;
infoHdr.biClrImportant = 0;
hdr.bfType = 0x4D42;
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = 54;
hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + size);
fwrite(&hdr, 1, sizeof(BITMAPFILEHEADER), pFile);
fwrite(&infoHdr, 1, sizeof(BITMAPINFOHEADER), pFile);
fwrite(data, 1, size, pFile);
fclose(pFile);
printf("color data saved! \n");
}
void renderToImg() {
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID);
glReadPixels(0, 0, TexWidth, TexHeight, GL_RGBA, GL_UNSIGNED_BYTE, buff);
savePixelData(buff, TexWidth * TexHeight * 4);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
#define BMP_Header_Length 54
void SetupRC()
{
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_2D, textureID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, TexWidth, TexHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glGenRenderbuffers(1, &renderBufferID);
glBindRenderbuffer(GL_RENDERBUFFER, renderBufferID);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, TexWidth, TexHeight);
glBindRenderbuffer(GL_RENDERBUFFER, 0);
glGenFramebuffers(1, &frameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureID, 0);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)
{
fprintf(stderr, "GLEW Error: %s\n", "FRAME BUFFER STATUS Error!");
return;
}
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
}
void RenderScene(void)
{
//设置渲染到纹理的视口和投影矩阵
glViewport(0, 0, TexWidth, TexHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (float)(TexWidth) / TexHeight, 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//渲染到纹理
glBindFramebuffer(GL_FRAMEBUFFER, frameBufferID);
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1, 0, 1);
glPushMatrix();
glTranslated(0, 0.0, -10);
glRotated(xRot, 1, 0, 0);
glRotated(yRot, 0, 1, 0);
glutSolidTeapot(1.0);
// 加载图片
glPopMatrix();
//切换到窗口系统的帧缓冲区
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glViewport(0, 0, windowWidth, windowHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0f, (float)(windowWidth) / windowHeight, 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClearColor(0.2, 0.3, 0.4, 0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glTranslated(0, 0, -5);
glRotated(cameraAngleY*0.5, 1, 0, 0);
glRotated(cameraAngleX*0.5, 0, 1, 0);
glColor3d(1.0, 1.0, 1.0);
drawCube();
glutSwapBuffers();
}
void MouseFuncCB(int button, int state, int x, int y)
{
mouseX = x;
mouseY = y;
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
leftMouseDown = true;
}
else if (state == GLUT_UP)
{
leftMouseDown = false;
}
}
if (button == GLUT_RIGHT_BUTTON)
{
if (state == GLUT_DOWN)
{
}
else if (state == GLUT_UP)
{
renderToImg();
}
}
}
void MouseMotionFuncCB(int x, int y)
{
if (leftMouseDown)
{
cameraAngleX += (x - mouseX);
cameraAngleY += (y - mouseY);
mouseX = x;
mouseY = y;
}
glutPostRedisplay();
}
void TimerFuncCB(int value)
{
xRot += 2;
yRot += 3;
glutPostRedisplay();
glutTimerFunc(33, TimerFuncCB, 1);
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize(TexWidth, TexHeight);
glutCreateWindow("OpenGL");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
glutMouseFunc(MouseFuncCB);
glutMotionFunc(MouseMotionFuncCB);
glutTimerFunc(33, TimerFuncCB, 1);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
SetupRC();
glutMainLoop();
return 0;
}
这个是离屏渲染的图片
这个是窗口种
按鼠标右键 保存图片。