对上篇文章增加了纹理逐步绘制的功能
#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;
static float scale = 0.1;
//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,-5);
glRotatef(angle,1,1,0);
glScalef(scale,scale,scale);
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);
GLfloat* mapBuffer = 0,*textureBuffer = 0;
for (int i=0; i<rectCnt; ++i)
{
glBindBuffer(GL_ARRAY_BUFFER, vbo[Index_Vertex]);
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);
glBindBuffer(GL_ARRAY_BUFFER,vbo[Index_Texture_Coord]);
textureBuffer = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
for (int i=0; i<8; ++i)
if(textureBuffer[i] != 0)
textureBuffer[i] = scale;
glUnmapBuffer(GL_ARRAY_BUFFER);
glDrawArrays(GL_TRIANGLE_FAN, 0,4);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glutSwapBuffers();
}
void idle()
{
angle += 1.0;
angle %= 360;
scale += 0.002;
if (scale>=1)
scale = 0.1;
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;
}