opengl vbo纹理
我仍然是vbo的初学者,我想渲染collada模型。从cae文件中分别获取顶点、法线和纹理以及顶点、法线和纹理的索引的所有必要信息后,我将它们作为模型对象放在内存中。剩下的问题是如何使用vbo和纹理渲染此对象。我通过获取顶点和索引,然后在vbo渲染中应用DrawleElement,成功地渲染了对象。但是,当我尝试渲染纹理时,使用“显示列表”正确渲染纹理时失败,这是因为我通过每个三角形,并根据顶点索引和纹理索引正确应用顶点和纹理坐标。因此,如何应用vbo中对象中的纹理索引,以便正确渲染纹理 这是项目的代码:opengl vbo纹理,opengl,object,buffer,textures,vertex,Opengl,Object,Buffer,Textures,Vertex,我仍然是vbo的初学者,我想渲染collada模型。从cae文件中分别获取顶点、法线和纹理以及顶点、法线和纹理的索引的所有必要信息后,我将它们作为模型对象放在内存中。剩下的问题是如何使用vbo和纹理渲染此对象。我通过获取顶点和索引,然后在vbo渲染中应用DrawleElement,成功地渲染了对象。但是,当我尝试渲染纹理时,使用“显示列表”正确渲染纹理时失败,这是因为我通过每个三角形,并根据顶点索引和纹理索引正确应用顶点和纹理坐标。因此,如何应用vbo中对象中的纹理索引,以便正确渲染纹理 这是项
#include "bmp.h"
struct mdl_vert
{
float x,y,z;
};
struct mdl_normal
{
float x,y,z;
};
struct mdl_texCoord
{
float u,v;
};
struct mdl_capacity
{
int vertsSize,indicesSize,normalsSize,texCoordsSize;
};
struct mdl_indices
{
int *vertIndices;
int *normalIndices;
int *texIndices;
};
class Group
{
public:
mdl_capacity capacity;
mdl_vert *verts;
mdl_normal *normals;
mdl_texCoord *texCoords;
mdl_indices indices;
char grp_name[64];
Group()
{
capacity.texCoordsSize=0;
capacity.normalsSize=0;
capacity.indicesSize=0;
capacity.vertsSize=0;
verts=NULL;
normals=NULL;
texCoords=NULL;
indices.vertIndices=NULL;
indices.normalIndices=NULL;
indices.texIndices=NULL;
for(int i=0;i<64;i++)
grp_name[i]='\0';
}
};
class Model
{
public:
char tex_name[512];
std::string Name;
Group **groups;
int groupsSize;
}
#define VBO_BUFFER_SIZE 4
struct GroupObject
{
GLuint *buffer;
};
class ModelObject
{
private:
GLuint displayList;
GroupObject *groupBuffer;
bool isLoaded;
GLuint tex;
float ang,iniRotX,iniRotY,iniRotZ;
Model *mdl;
bool Hide;
AUX_RGBImageRec* m_pTextureImage; // Heightmap Data
public:
ModelObject(Model* mdl)
{
this->mdl=mdl;
Redraw();
}
void Redraw()
{
Hide=false;
ang=-0;
iniRotX=1;
iniRotY=0;
iniRotZ=0;
if(displayList!=-1)
displayList=-1;
groupBuffer=NULL;
}
void BuildTexture(int i)
{
if(mdl->groups[i]->capacity.texCoordsSize>0)
{
try
{
m_pTextureImage = auxDIBImageLoad( mdl->tex_name ); // Utilize GLaux's Bitmap Load Routine
glGenTextures( 1, &tex ); // Get An Open ID
glBindTexture( GL_TEXTURE_2D, tex ); // Bind The Texture
glTexImage2D( GL_TEXTURE_2D, 0, 3, m_pTextureImage->sizeX, m_pTextureImage->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, m_pTextureImage->data );
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
// Free The Texture Data
if( m_pTextureImage )
{
if( m_pTextureImage->data )
free( m_pTextureImage->data );
free( m_pTextureImage );
}
}
catch(std::exception &ex)
{
}
}
}
void BuildVBO()
{
int index=0;
groupBuffer=new GroupObject[mdl->groupsSize];
for(int i=0;i<mdl->groupsSize;i++)
{
BuildTexture(i);
groupBuffer[i].buffer=new GLuint[VBO_BUFFER_SIZE];
// Generate And Bind The Vertex Buffer
glGenBuffersARB( 1, &groupBuffer[i].buffer[0] ); // Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[0] ); // Bind The Buffer
glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.vertsSize*sizeof(mdl_vert), mdl->groups[i]->verts, GL_STATIC_DRAW_ARB );
// Generate And Bind The Normal Buffer
glGenBuffersARB( 1, &groupBuffer[i].buffer[1] ); // Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[1] ); // Bind The Buffer
glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.normalsSize*sizeof(mdl_normal), mdl->groups[i]->normals, GL_STATIC_DRAW_ARB );
// Generate And Bind The Texture Buffer
glGenBuffersARB( 1, &groupBuffer[i].buffer[2] ); // Get A Valid Name
glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[2] ); // Bind The Buffer
glBufferDataARB( GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.texCoordsSize*sizeof(mdl_texCoord), mdl->groups[i]->texCoords, GL_STATIC_DRAW_ARB );
// Generate And Bind The Index Buffer
glGenBuffersARB(1, &groupBuffer[i].buffer[3]);
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[3]);
glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mdl->groups[i]->capacity.indicesSize*sizeof(unsigned int), mdl->groups[i]->indices.vertIndices, GL_STATIC_DRAW_ARB);
}
}
void render()
{
if(!Hide)
{
if(Drawer.vboSupported())
{
if(groupBuffer==NULL)
BuildVBO();
glRotatef(ang,iniRotX,iniRotY,iniRotZ);
for(int i=0;i<mdl->groupsSize;i++)
{
// Enable Pointers
glEnableClientState( GL_VERTEX_ARRAY ); // Disable Vertex Arrays
glEnableClientState( GL_NORMAL_ARRAY ); // Enable Normal Arrays
glEnableClientState( GL_TEXTURE_COORD_ARRAY ); // Enable Texture Coord Arrays
glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[0] );
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[1] );
glNormalPointer(GL_FLOAT,0, BUFFER_OFFSET(0));
glClientActiveTexture(GL_TEXTURE0);
glBindBufferARB( GL_ARRAY_BUFFER_ARB, groupBuffer[i].buffer[2] );
glTexCoordPointer(2,GL_FLOAT,0,BUFFER_OFFSET(0));
glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER, groupBuffer[i].buffer[3]);
glIndexPointer(GL_UNSIGNED_INT,0,BUFFER_OFFSET(0));
glDrawElements( GL_TRIANGLES, mdl->groups[i]->capacity.indicesSize,GL_UNSIGNED_INT, 0); // Draw All Of The Triangles At Once
// Disable Pointers
glDisableClientState( GL_VERTEX_ARRAY ); // Disable Vertex Arrays
glDisableClientState( GL_NORMAL_ARRAY ); // Enable Normal Arrays
glDisableClientState( GL_TEXTURE_COORD_ARRAY ); // Enable Texture Coord Arrays
}
glRotatef(-ang,iniRotX,iniRotY,iniRotZ);
}
else
{
if(this->displayList==-1)
{
displayList = glGenLists(1);
glNewList(displayList,GL_COMPILE_AND_EXECUTE);
glRotatef(ang,iniRotX,iniRotY,iniRotZ);
for(int j=0;j<mdl->groupsSize;j++)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex);
// Enable Pointers
BuildTexture(j);
//glColor3f(((float)(rand()%256)/256.0f),((float)(rand()%256)/256.0f),((float)(rand()%256)/256.0f));
for(int i=0;i<mdl->groups[j]->capacity.indicesSize;i+=3)
{
int iv1=mdl->groups[j]->indices.vertIndices[i];
int in1=mdl->groups[j]->indices.normalIndices[i];
int it1=mdl->groups[j]->indices.texIndices[i];
int iv2=mdl->groups[j]->indices.vertIndices[i+1];
int in2=mdl->groups[j]->indices.normalIndices[i+1];
int it2=mdl->groups[j]->indices.texIndices[i+1];
int iv3=mdl->groups[j]->indices.vertIndices[i+2];
int in3=mdl->groups[j]->indices.normalIndices[i+2];
int it3=mdl->groups[j]->indices.texIndices[i+2];
glBegin(GL_TRIANGLES);
glTexCoord2f(mdl->groups[j]->texCoords[it1].u,mdl->groups[j]->texCoords[it1].v);
glNormal3f(mdl->groups[j]->normals[in1].x,mdl->groups[j]->normals[in1].y,mdl->groups[j]->normals[in1].z);
glVertex3f(mdl->groups[j]->verts[iv1].x,mdl->groups[j]->verts[iv1].y,mdl->groups[j]->verts[iv1].z);
glTexCoord2f(mdl->groups[j]->texCoords[it2].u,mdl->groups[j]->texCoords[it2].v);
glNormal3f(mdl->groups[j]->normals[in2].x,mdl->groups[j]->normals[in2].y,mdl->groups[j]->normals[in2].z);
glVertex3f(mdl->groups[j]->verts[iv2].x,mdl->groups[j]->verts[iv2].y,mdl->groups[j]->verts[iv2].z);
glTexCoord2f(mdl->groups[j]->texCoords[it3].u,mdl->groups[j]->texCoords[it3].v);
glNormal3f(mdl->groups[j]->normals[in3].x,mdl->groups[j]->normals[in3].y,mdl->groups[j]->normals[in3].z);
glVertex3f(mdl->groups[j]->verts[iv3].x,mdl->groups[j]->verts[iv3].y,mdl->groups[j]->verts[iv3].z);
glEnd();
}
glDisable(GL_TEXTURE_2D);
}
glRotatef(-ang,iniRotX,iniRotY,iniRotZ);
glEndList();
glCallList(displayList);
}
else
glCallList(displayList);
}
}
}
#包括“bmp.h”
结构mdl_垂直
{
浮动x,y,z;
};
结构mdl_正常
{
浮动x,y,z;
};
结构mdl_texCoord
{
浮动u,v;
};
结构mdl_容量
{
int VERTSIZE、indicesSize、NORMASIZE、texCoordsSize;
};
结构mdl_索引
{
int*垂直方向;
int*正常指数;
int*tex指数;
};
班级
{
公众:
mdl_容量;
mdl_vert*verts;
mdl_法线*法线;
mdl_texCoord*texCoords;
mdl_指数;
字符grp_名称[64];
组()
{
容量.texCoordsSize=0;
容量.normalsSize=0;
容量。指示大小=0;
容量.vertsize=0;
verts=NULL;
法线=空;
texCoords=NULL;
索引。vertIndices=NULL;
索引。normalindex=NULL;
index.texindex=NULL;
对于(int i=0;imdl=mdl;
重画();
}
作废重画()
{
隐藏=假;
ang=-0;
iniRotX=1;
iniRotY=0;
iniRotZ=0;
如果(显示列表!=-1)
displayList=-1;
groupBuffer=NULL;
}
void BuildTexture(int i)
{
如果(mdl->groups[i]->capacity.texCoordsSize>0)
{
尝试
{
m_pTextureImage=auxDIBImageLoad(mdl->tex_name);//利用GLaux的位图加载例程
glGenTextures(1,&tex);//获取打开的ID
glBindTexture(GL_TEXTURE_2D,tex);//绑定纹理
glTexImage2D(GL_纹理_2D,0,3,m_纹理图像->尺寸,m_纹理图像->尺寸,0,GL_RGB,GL_无符号字节,m_纹理图像->数据);
glTexParameteri(GL_纹理2D、GL_纹理最小过滤器、GL_线性);
glTexParameteri(GL_纹理2D、GL_纹理MAG_过滤器、GL_线性);
//释放纹理数据
如果(m_pTextureImage)
{
如果(m_pTextureImage->data)
免费(图片->数据);
免费(m_pTextureImage);
}
}
捕获(标准::异常和例外)
{
}
}
}
void BuildVBO()
{
int指数=0;
groupBuffer=newgroupobject[mdl->groupsSize];
对于(int i=0;igroupsSize;i++)
{
建筑结构(一);
groupBuffer[i].buffer=new GLuint[VBO_buffer_SIZE];
//生成并绑定顶点缓冲区
glGenBuffersARB(1,&groupBuffer[i].buffer[0]);//获取有效名称
glBindBufferARB(GL_ARRAY_BUFFER_ARB,groupBuffer[i].BUFFER[0]);//绑定缓冲区
glBufferDataARB(GL\U ARRAY\U BUFFER\U ARB,mdl->groups[i]->capacity.vertsSize*sizeof(mdl\U vert),mdl->groups[i]->verts,GL\U STATIC\U DRAW\U ARB);
//生成并绑定普通缓冲区
glGenBuffersARB(1,&groupBuffer[i].buffer[1]);//获取有效名称
glBindBufferARB(GL_ARRAY_BUFFER_ARB,groupBuffer[i].BUFFER[1]);//绑定缓冲区
glBufferDataARB(GL\U数组\U缓冲区\U ARB,mdl->组[i]->容量。normalize*sizeof(mdl\U normal),mdl->组[i]->法线,GL\U静态\U绘制\U ARB);
//生成并绑定纹理缓冲区
glGenBuffersARB(1,&groupBuffer[i].buffer[2]);//获取有效名称
glBindBufferARB(GL_ARRAY_BUFFER_ARB,groupBuffer[i].BUFFER[2]);//绑定缓冲区
glBufferDataARB(GL_ARRAY_BUFFER_ARB,mdl->groups[i]->capacity.texCoordsSize*sizeof(mdl_texCoord),mdl->groups[i]->texCoords,GL_STATIC\u DRAW\u ARB);
//生成并绑定索引缓冲区
glGenBuffersARB(1,&groupBuffer[i].buffer[3]);
glBindBufferARB(GL_元素数组缓冲区ARB,groupBuffer[i].BUFFER[3]);
glBufferDataARB(GL\u ELEMENT\u ARRAY\u BUFFER\u ARB,mdl->groups[i]->capacity.indicatize*sizeof(unsigned int),mdl->groups[i]->index.vertIndices,GL\u STATIC\u DRAW\u ARB);
}
}
void render()
{
如果(!隐藏)
{
if(Drawer.vboSupported())
{
if(groupBuffer==NULL)
BuildVBO();
glRotatef(ang、iniRotX、iniRotY、iniRotZ);
对于(int i=0;igroupsSize;i++)
{
//启用指针
glEnableClientState(GL_顶点_数组);//禁用顶点数组
glEnableClientState(GL_NORMAL_数组);//启用NORMAL数组
格伦
struct Trinity {
int iv, in, it;
bool operator <(const Trinity &t) const // implement less-than operator as required by std::map
{
return iv < t.iv || (iv == t.iv && (in < t.in || (in == t.in && it < t.it)));
}
};
#include <map>
#include <vector>
for(int j=0;j<mdl->groupsSize;j++) { // for each object ...
int next_index = 0; // next index to be assigned
std::map<int, Trinity> index_map; // map of collada indices to OpenGL indices
std::vector<int> new_indices; // new indices that can be used for drawing with OpenGL
std::vector<float> new_positions, new_texcoords, new_normals; // other arrays
for(int i=0;i<mdl->groups[j]->capacity.indicesSize;i++) { // for each vertex ...
Trinity t;
t.iv = mdl->groups[j]->indices.vertIndices[i];
t.in = mdl->groups[j]->indices.normalIndices[i];
t.it = mdl->groups[j]->indices.texIndices[i];
// go through all the vertices' indices
int index;
if(index_map.find(t) != index_map.end())
index = index_map[t]; // we already saw this combination of indices, reuse it
else {
index = next_index; // this is new; assign a new index
++ next_index;
index_map[t] = index; // store the index in the map
new_positions.push_back(mdl->groups[j]->verts[t.iv].x);
new_positions.push_back(mdl->groups[j]->verts[t.iv].y);
new_positions.push_back(mdl->groups[j]->verts[t.iv].z);
new_texcoords.push_back(mdl->groups[j]->texCoords[t.it].u);
new_texcoords.push_back(mdl->groups[j]->texCoords[t.it].v);
new_normals.push_back(mdl->groups[j]->normals[t.in].x);
new_normals.push_back(mdl->groups[j]->normals[t.in].y);
new_normals.push_back(mdl->groups[j]->normals[t.in].z);
// add this particular combination of coordinates at the end of the buffers
}
// translate the combination of iv, in, it to a single index
new_indices.push_back(index);
// store it in the array
}
// object data ready to pass to VBOs
}