本来打算全部用顶点缓冲来实现的,但是发现我使用的是二维纹理,这样是不行滴,所以只能是用glVertex来暂时对应纹理坐标,下篇打算直接使用3D纹理贴图
// beauty_cube.cpp : 定义控制台应用程序的入口点。
//
#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 = malloc(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);
//glPixelStorei(GL_UNPACK_ALIGNMENT,4);
glEnable(GL_DEPTH_TEST);
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_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
void* bmpData = NULL;
int width=0, height=0, totals=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);
glBindTexture(GL_TEXTURE_2D, 0);
//校验结果
assert(glGetError() == GLEW_NO_ERROR);
//顶点
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},
};
//纹理坐标
GLfloat txtCoords[][2]=
{
{1,0},
{1,1},
{0,1},
{0,0},
{0,0},
{0,1},
{1,1},
{1,0},
};
//面索引
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},
};
//VBO buffers
glGenBuffers(3,vbo);
//顶点
glBindBuffer(GL_ARRAY_BUFFER, vbo[Index_Vertex]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs), vertexs, 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);
//顶点索引
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[Index_Vertex_Element_Array]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
GLenum errorInfo = glGetError();
assert(glGetError() == GLEW_NO_ERROR);
}
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();
//gluLookAt(0,0,5, 0, 0, 0, 0, 1,0);
glTranslatef(0,0,-3);
glRotatef(angle,1,1,0);
glBindTexture(GL_TEXTURE_2D, txtID);
glBegin(GL_QUADS);
{
glTexCoord2f(0,0); glVertex3f(-1,-1,1);
glTexCoord2f(1,0); glVertex3f(1,-1,1);
glTexCoord2f(1,1); glVertex3f(1,1,1);
glTexCoord2f(0,1); glVertex3f(-1,1,1);
glTexCoord2f(1,0); glVertex3f(-1,-1,-1);
glTexCoord2f(1,1); glVertex3f(-1,1,-1);
glTexCoord2f(0,1); glVertex3f(1,1,-1);
glTexCoord2f(0,0); glVertex3f(1,-1,-1);
glTexCoord2f(0,1); glVertex3f(-1,1,-1);
glTexCoord2f(0,0); glVertex3f(-1,1,1);
glTexCoord2f(1,0); glVertex3f(1,1,1);
glTexCoord2f(1,1); glVertex3f(1,1,-1);
glTexCoord2f(1,1); glVertex3f(-1,-1,-1);
glTexCoord2f(0,1); glVertex3f(1,-1,-1);
glTexCoord2f(0,0); glVertex3f(1,-1,1);
glTexCoord2f(1,0); glVertex3f(-1,-1,1);
glTexCoord2f(1,0); glVertex3f(1,-1,-1);
glTexCoord2f(1,1); glVertex3f(1,1,-1);
glTexCoord2f(0,1); glVertex3f(1,1,1);
glTexCoord2f(0,0); glVertex3f(1,-1,1);
glTexCoord2f(0,0); glVertex3f(-1,-1,-1);
glTexCoord2f(1,0); glVertex3f(-1,-1,1);
glTexCoord2f(1,1); glVertex3f(-1,1,1);
glTexCoord2f(0,1); glVertex3f(-1,1,-1);
}
glEnd();
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[Index_Vertex_Element_Array]);
//glDrawElements(GL_QUADS,24,GL_UNSIGNED_BYTE,0);
//glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
//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},
//};
//glDrawElements(GL_QUADS, sizeof(indices), GL_UNSIGNED_BYTE, indices);
//int offset = 0;
//GLubyte *curPos = NULL;
//for(int i=0; i<sizeof(indices)/4; ++i)
//{
// curPos = &indices[0][0]+4*i;
// glBindBuffer(GL_ARRAY_BUFFER,vbo[Index_Texture_Coord]);
// GLfloat* bufferData = (GLfloat*)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE);
// for (int j=0; j<4; ++j)
// {
// offset = curPos[j] % 4;
// switch (offset)
// {
// case 0:
// bufferData[j*2] = 0;
// bufferData[j*2+1] = 0;
// break;
// case 1:
// bufferData[j*2] = 0;
// bufferData[j*2+1] = 1;
// break;
// case 2:
// bufferData[j*2] = 1;
// bufferData[j*2+1] = 1;
// break;
// case 3:
// bufferData[j*2] = 1;
// bufferData[j*2+1] = 0;
// break;
// default:
// break;
// }
// }
// glUnmapBuffer(GL_ARRAY_BUFFER);
// glDrawElements(GL_QUADS, 4, GL_UNSIGNED_BYTE, curPos);
//
//}
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;
}