您的位置:首页 > 其它

使用二维纹理贴图,从24位位图加载,用vertex方式绘制

2013-09-04 17:10 435 查看
本来打算全部用顶点缓冲来实现的,但是发现我使用的是二维纹理,这样是不行滴,所以只能是用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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: