对上一篇的改良,使用三角形来进行快速绘制
#include "stdafx.h" #include <iostream> #include <fstream> #include <cassert> #include <gl/glew.h> #include <gl/glut.h> #pragma comment(lib, "glew32.lib") using namespace std; static GLuint txtID = 0; static GLuint vbo[3] = {0}; static int angle = 0; //Vbo索引 static enum { Index_Vertex = 0, Index_Texture_Coord, Index_Vertex_Element_Array, }; //修改为始终绘制三角形 void readBitmp24(const std::string& filename, void* &ptr, int &width, int &height, int& totals) { fstream in(filename.c_str(), ios_base::in|ios_base::binary); if (!in) { ptr = NULL; return; } in.seekg(0x12); //18个字节开始读取宽度和高度 in.read((char*)&width, sizeof(int)); in.read((char*)&height,sizeof(int)); //BMP的每行按照4个字节对齐 int realWidth = width; int lineLength = width*3; while (lineLength % 4 != 0) ++lineLength; totals = lineLength * height; ptr = new char[totals]; in.seekg(0x36); //54开始是数据,按照行读取 in.read((char*)ptr, totals); //将BGR模式转换为RGB模式 char *startPos = NULL,*curPos = NULL; for (int i=0; i<height; ++i) { curPos = ((char*)ptr+i*lineLength); for (int j=0; j<realWidth;++j) { std::swap(curPos[0], curPos[2]); curPos += 3; } } in.close(); } void init() { glClearColor(0,0,0,0); glClearDepth(1.0); glPixelStorei(GL_UNPACK_ALIGNMENT,4); glEnable(GL_DEPTH_TEST); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glBlendFunc(GL_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); glGenTextures(1, &txtID); assert(txtID); glBindTexture(GL_TEXTURE_2D, txtID); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); //void* oldData = NULL; void* bmpData = NULL; int width=0, height=0, totals=0,depth=0; readBitmp24("e:/test.bmp",bmpData,width, height,totals); assert(bmpData);//客户端数据,暂时不释放 glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, bmpData); GLenum ffff = glGetError(); glBindTexture(GL_TEXTURE_2D, 0); //校验结果 assert(glGetError() == GLEW_NO_ERROR); GLfloat txtCoords[][2]= { {0,0}, {0,1}, {1,1}, {1,0}, }; GLfloat vertex[12] = {0}; //VBO buffers glGenBuffers(3,vbo); //顶点 glBindBuffer(GL_ARRAY_BUFFER, vbo[Index_Vertex]); glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*12, vertex, GL_STATIC_DRAW); glVertexPointer(3, GL_FLOAT, 0, 0); glEnableClientState(GL_VERTEX_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); //纹理坐标 glBindBuffer(GL_ARRAY_BUFFER, vbo[Index_Texture_Coord]); glBufferData(GL_ARRAY_BUFFER, sizeof(txtCoords), txtCoords, GL_STATIC_DRAW); glTexCoordPointer(2, GL_FLOAT, 0, 0); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, 0); GLenum errorInfo = glGetError(); assert(glGetError() == GLEW_NO_ERROR); delete[] bmpData; } void reshape(int width, int height) { glViewport(0, 0, width, height); float factor = width*1.0/height; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, factor, 1, 10); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void display() { glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0,0,-3); glRotatef(angle,1,1,0); glColor4f(1,1,1,0.8); //顶点 static GLfloat vertexs[][3] = { {-1, -1, -1}, {-1, 1, -1}, {1, 1, -1}, {1, -1, -1}, {-1, -1, 1}, {-1, 1, 1}, {1, 1, 1}, {1, -1, 1}, }; //面索引 static GLubyte indices[][4] ={ {3,2,1,0}, {7,6,2,3}, {4,5,6,7}, {0,1,5,4}, {5,1,2,6}, {0,4,7,3}, }; static const int rectCnt = sizeof(indices)/4; glBindTexture(GL_TEXTURE_2D, txtID); glBindBuffer(GL_ARRAY_BUFFER, vbo[Index_Vertex]); GLfloat* mapBuffer = 0; for (int i=0; i<rectCnt; ++i) { mapBuffer = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); for (int j=0; j<4; ++j) { mapBuffer[j*3] = vertexs[indices[i][j]] [0]; mapBuffer[j*3+1] = vertexs[indices[i][j]] [1]; mapBuffer[j*3+2] = vertexs[indices[i][j]] [2]; } glUnmapBuffer(GL_ARRAY_BUFFER); glDrawArrays(GL_TRIANGLE_FAN, 0,4); } glBindBuffer(GL_ARRAY_BUFFER, 0); glutSwapBuffers(); } void idle() { angle += 1; angle %= 360; glutPostRedisplay(); } int _tmain(int argc, _TCHAR* argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA|GLUT_DEPTH); glutInitWindowPosition(100, 100); glutInitWindowSize(600,600); glutCreateWindow("Texture2D"); GLenum error = glewInit(); assert(error == GLEW_NO_ERROR); init(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutIdleFunc(idle); glutMainLoop(); return 0; }