opengl 显示图片以及保存图片

来源:互联网 发布:c语言入门经典电子版 编辑:程序博客网 时间:2024/06/05 09:54

opengl 的贴图功能是很基本的,不过也难住了我这个新手,所以特意写了一个示例程序,以便以后查阅。


程序很简单,只是在在 x, y 平面画一个框,然后贴上一张图。并且可以保存opengl窗口到图片。


程序:

//本程序的目的是展示贴图和保存图片#include <Windows.h>#include <gl/glut.h>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>using namespace cv;// Rotation amountsstatic GLfloat xRot = 0.0f;static GLfloat yRot = 0.0f;const int height = 600;const int width = 800;static GLbyte TextData[1000*1000*4];static GLuint TexName;static int picrows = 0;static int piccols = 0;void savepic(){GLint viewPort[4] = {0};glGetIntegerv(GL_VIEWPORT, viewPort);int winrows = viewPort[3];int wincols = viewPort[2];GLbyte *colorArr = new GLbyte[winrows*wincols*3];glReadPixels(viewPort[0], viewPort[1], viewPort[2], viewPort[3], GL_RGB, GL_UNSIGNED_BYTE, colorArr);for(int i=0; i<winrows * wincols * 3; i ++) {if(colorArr[i] == -1) { colorArr[i] = 255; }}Mat show = Mat(winrows, wincols, CV_8UC3, Scalar::all(0));for (int i = 0; i< winrows; i++){for (int j = 0; j< wincols; j++){show.at<Vec3b>(winrows-i-1, j) = Vec3b(colorArr[(i*wincols+j)*3+2], colorArr[(i*wincols+j)*3+1], colorArr[(i*wincols+j)*3]);}}delete colorArr;imshow("show", show);waitKey(33);}// Called to draw scenevoid RenderScene(void){// Clear the window with current clearing colorglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Save the matrix state and do the rotationsglPushMatrix();glRotatef(xRot, 1.0f, 0.0f, 0.0f);glRotatef(yRot, 0.0f, 1.0f, 0.0f);//模型glBegin(GL_QUADS);glNormal3f(0.0f, 0.0f, 1.0f);glTexCoord2f(0.0, 1.0);glVertex3f(-1.0, 1.0, 0);glNormal3f(0.0f, 0.0f, 1.0f);glTexCoord2f(0.0, 0.0);glVertex3f(-1.0, -1.0, 0);glNormal3f(0.0f, 0.0f, 1.0f);glTexCoord2f(1.0, 0.0);glVertex3f(1.0, -1.0, 0);glNormal3f(0.0f, 0.0f, 1.0f);glTexCoord2f(1.0, 1.0);glVertex3f(1.0, 1.0, 0);glEnd();// Restore the matrix stateglPopMatrix();// Display the resultsglutSwapBuffers();//savepic();}// This function does any needed initialization on the rendering// context. void SetupRC(){// Black backgroundglClearColor(0.0f, 0.0f, 0.0f, 1.0f );////////////set pixel storage modesglPixelStoref( GL_UNPACK_ALIGNMENT, 1 );glGenTextures( 1, &TexName );glBindTexture( GL_TEXTURE_2D, TexName );glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, piccols,picrows, 0, GL_RGBA, GL_UNSIGNED_BYTE,TextData );//设置s方向纹理重复,为重复设置。glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );//t方向的纹理重复glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );//设置滤波方式为线性滤波// when texture area is large, bilinear filter the first mipmapglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );  // when texture area is small, bilinear filter the closest mipmapglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );//GL_DECAL表示只用纹理颜色,不关心物体表面颜色glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);glEnable(GL_TEXTURE_2D);}/////////////////////////////////////////////////////// Handle arrow keysvoid SpecialKeys(int key, int x, int y){if(key == GLUT_KEY_UP){xRot-= 5.0f;}if(key == GLUT_KEY_DOWN){xRot += 5.0f;}if(key == GLUT_KEY_LEFT)yRot -= 5.0f;if(key == GLUT_KEY_RIGHT)yRot += 5.0f;if(key > 356.0f)xRot = 0.0f;if(key < -1.0f)xRot = 355.0f;if(key > 356.0f)yRot = 0.0f;if(key < -1.0f)yRot = 355.0f;// Refresh the WindowglutPostRedisplay();}//////////////////////////////////////////////////////////// Reset projectionvoid ChangeSize(int w, int h){// Prevent a divide by zeroif(h == 0)h = 1;// Set Viewport to window dimensionsglViewport(0, 0, w, h);// Reset coordinate systemglMatrixMode(GL_PROJECTION);glLoadIdentity();//GLfloat fAspect = (GLfloat) w / (GLfloat) h;//gluPerspective(45.0f, fAspect, 1.0f, 225.0f);glOrtho(-1.3, 1.3, -1.3, 1.3, -10, 10);glMatrixMode(GL_MODELVIEW);glLoadIdentity();}//载入图片void gettex(string name){Mat t = imread(name);piccols = t.cols;picrows = t.rows;assert(picrows<=1000&&piccols<=1000);for (int i = picrows-1; i>= 0; i--){for (int j = 0; j< piccols; j++){TextData[((picrows-1-i)*piccols+j)*4+0] = (GLubyte)t.at<Vec3b>(i, j)[2];TextData[((picrows-1-i)*piccols+j)*4+1] = (GLubyte)t.at<Vec3b>(i, j)[1];TextData[((picrows-1-i)*piccols+j)*4+2] = (GLubyte)t.at<Vec3b>(i, j)[0];TextData[((picrows-1-i)*piccols+j)*4+3] = 255;}}}int main(int argc, char* argv[]){//读取texgettex("test.jpg");glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutInitWindowSize(800,600);glutCreateWindow("pic");glutReshapeFunc(ChangeSize);glutSpecialFunc(SpecialKeys);glutDisplayFunc(RenderScene);SetupRC();glutMainLoop();return 0;}

需要注意的是,当打开savepic开关,并且缩小窗口的时候,会提示错误,目前不太清楚是什么原因。


原因在于保存的时候长宽必须是4的倍数才行。不然会出错。所以,改变窗口大小的话,可以在reshape函数里强制要求长宽被4整除即可。


另外放上一个obj读取的代码,写的很好。不过只能读取点,没有显示。http://download.csdn.net/detail/lcbwlx/6923111

0 0