问题:glBufferData上的分段错误。
关于libs&输入数据:
3ds file contains a few models.
GLEW - 1.11.0
GLFW - 3.0.4
GLM - 0.9.5.4
ASSIMP - 3.1.1
OS - Windows 7 x64 lastest PS
GPU: nvidia 770
输出:
Wersja OpenGL: 4.4.0
Kompilacja shadera...
Compiling shader : vert.vs
- Success
Compiling shader : frag.fs
- Success
Ustawianie Model - Widok - Projekcja...
Wczytywanie wczeťniej wygenerowanych obiektˇw...
Ladowanie Mesha nr.0...
Rozmiary - 2 | 108 | 108
a
b
c
这是代码:
Mesh_Loader.cpp
GLfloat **vertexData, **normalData, **colorsData_buffer;
GLushort** indexData;
/** Bufory */
GLuint* vertexBuffer, *colorBuffer, *indexBuffer;
int mesh_size = 0;
unsigned int* count_of_vertex; //Licznik ile vertex-ów na danym meshie jest
int* count_of_index; //Licznik indeksów
unsigned int suma_vertexow = 0; //Suma wszystkich vertexow... normalnie się powinno to inaczej obejść. Ale kij.
const struct aiFace* tmp_face;
int tmp_index = 0;
//[...]
bool mesh_load(const std::string& Filename)
{
Assimp::Importer Importer;
const aiScene* pScene = Importer.ReadFile(Filename.c_str(), aiProcess_Triangulate | aiProcess_GenSmoothNormals | aiProcess_FlipUVs);
/** Sprawdzenie czy wczytał scene */
if (pScene) {
init_from_scene(pScene);
return true;
}
else
{
std::cout << "Wystąpił błąd podczas wczytywania: " << Importer.GetErrorString() << std::endl;
return false;
}
}
void pre_reserve_memory(const aiMesh* paiMesh, int cur_poz)
{
count_of_index[cur_poz] = 0;
for (unsigned int i = 0; i < paiMesh->mNumFaces; i++) {
tmp_face = &paiMesh->mFaces[i];
count_of_index[cur_poz] += tmp_face->mNumIndices;
}
indexData[cur_poz] = new GLushort[count_of_index[cur_poz]];
}
void init_from_scene(const aiScene* pScene)
{
mesh_size = pScene->mNumMeshes;
//Pre Rezerwacja miejsca
vertexData = new GLfloat*[mesh_size];
colorsData_buffer = new GLfloat*[mesh_size];
normalData = new GLfloat*[mesh_size];
indexData = new GLushort*[mesh_size];
//Buffory
vertexBuffer = new GLuint[mesh_size];
colorBuffer = new GLuint[mesh_size];
indexBuffer = new GLuint[mesh_size];
count_of_vertex = new unsigned int[mesh_size];
count_of_index = new int[mesh_size];
for (unsigned int i = 0; i < pScene->mNumMeshes; i++)
{
pre_reserve_memory(pScene->mMeshes[i], i);
// [...]
przepare_mesh(pScene->mMeshes[i], vertexData[i], colorsData_buffer[i], normalData[i], indexData[i], &count_of_vertex[i]);
}
}
void przepare_mesh(const aiMesh* paiMesh, GLfloat* vertexData, GLfloat* colorsData_buffer, GLfloat* normalData, GLushort* indexData, unsigned int* count_of_vertex)
{
int counter;
vertexData = (GLfloat *)&paiMesh->mVertices;
colorsData_buffer = (GLfloat *)&paiMesh->mColors;
normalData = (GLfloat *)&paiMesh->mNormals;
*count_of_vertex = paiMesh->mNumVertices;
for (unsigned int i = 0; i < paiMesh->mNumFaces; i++) {
tmp_face = &paiMesh->mFaces[i];
for (unsigned int j = 0; j < tmp_face->mNumIndices; j++)
{
counter = i + j;
indexData[counter] = tmp_face->mIndices[j];
}
}
}
/** TODO: RE-LIGHTING, MOUSE */
void render_scene()
{
glLinkProgram(program); // jak skompilowalem kod to moge go polaczyc z bibliotekami - linkowanie
glUseProgram(program); // od tego momentu wszystko co zrobie bedzie uzywac tego programu (tej kombinacji shaderow)
glClearColor(0.0f, 0.0f, 0.4f, 0.0f); // ustala kolor wyczyszczonego okna
glEnable(GL_CULL_FACE); // wewnetrzne flagi opengl
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/** Model - View - Projection */
glm::mat4 Model = glm::mat4(1.0f); // tworzenie macierzy obiektu
glm::mat4 View = glm::lookAt(glm::vec3(0.0f, 2.0f, -5.0f), glm::vec3(), glm::vec3(0.0f, 1.0f, 0.0f)); // widoku
glm::mat4 Projection = glm::perspective(60.0f, 16.0f / 9.0f, 0.1f, 1000.0f); // projekcji
glm::mat4 MVP; // zmienna na pozniej
GLuint MVPUniformLoc = glGetUniformLocation(program, "MVP"); // daje wskaznik gdzie MVP znajduje sie w pamieci
/** Addresy Pamięci */
GLuint positionAttribLoc = glGetAttribLocation(program, "position"); // wytlumaczenie cpu jak sie dostac do adresu pamieci gpu
GLuint colorAttribLoc = glGetAttribLocation(program, "color");
/** tworzenie tablicy przechowujacej vertexy */
GLuint vertexArrayObject;
glGenVertexArrays(1, &vertexArrayObject);
glBindVertexArray(vertexArrayObject);
for (int i = 0; i < mesh_size; i++)
{
suma_vertexow += count_of_vertex[i];
glGenBuffers(1, &vertexBuffer[i]);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[i]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(GLfloat)* count_of_vertex[i]), vertexData[i], GL_STATIC_DRAW); //Problem Area
if (colorsData_buffer[i] != NULL)
{
glGenBuffers(1, &colorBuffer[i]);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer[i]);
glBufferData(GL_ARRAY_BUFFER, (sizeof(GLfloat) * count_of_vertex[i]), colorsData_buffer[i], GL_DYNAMIC_DRAW);
}
glGenBuffers(1, &indexBuffer[i]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer[i]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, (sizeof(GLushort)* count_of_index[i]), indexData[i], GL_DYNAMIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL);
glEnableVertexAttribArray(positionAttribLoc); // atrybuty wskazinikow (bufory)
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer[i]);
glVertexAttribPointer(
positionAttribLoc, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
NORMALIZED, // normalized?
0, // stride - wierzcholki oznaczajace pozycje sa w tym buforze jeden za drugim (odstep miedzy kolejnymi wierzcholkami)
(GLvoid*)0 // array buffer offset - w ktorym miejscu bufora zaczyna sie inf o wierzcholkach
);
glBindBuffer(GL_ARRAY_BUFFER, NULL);
if (colorsData_buffer[i] != NULL)
{
glEnableVertexAttribArray(colorAttribLoc);
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer[i]);
glVertexAttribPointer(
colorAttribLoc, // attribute. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
NORMALIZED, // normalized?
0, // stride
(GLvoid*)0 // array buffer offset
);
}
glBindBuffer(GL_ARRAY_BUFFER, NULL);
}
//[...]
}
Mesh_Loader - &gt;通过来自3DS文件的assimp.importer数据加载 并提取有关每个网格的索引,颜色,顶点,法线的数据
function render - &gt;加载有关索引,颜色,顶点,法线的数据
但是当它将数据加载到缓冲区时会引起一些问题&#34; glBufferData&#34; 段错误
Additioanl_func.cpp 负载着色器和附件的额外功能;鼠标回调
哪里有问题?
答案 0 :(得分:3)
我不认为这是一个OpenGL问题。代码只是使用未初始化的指针。如果用于任何事情,这可能会导致崩溃。它恰好是传递给glBufferData()
。
通过使用vertexData
,它被声明为指向GLfloat
的指针:
GLfloat **vertexData;
然后分配:
vertexData = new GLfloat*[mesh_size];
vertexData
现在指向mesh_size
指针GLfloat
。请注意,这些指针未初始化。
然后将这些指针作为参数传递给函数:
przepare_mesh(..., vertexData[i], ...);
在函数内部,然后为函数参数赋值(我正在重命名原始代码中的参数,以避免在我的解释中出现名称混淆):
void przepare_mesh(..., GLfloat* vertices, ...)
{
...
vertices = (GLfloat *)&paiMesh->mVertices;
由于指针是按值传递给函数的,因此该赋值仅更改参数的本地值,并且不为最初传入的指针设置值。因此vertexData[i]
仍将是未初始化的当这个函数返回时。
稍后,vertexData[i]
被用作glBufferData()
的参数,并导致崩溃,因为它未初始化。
解决此问题的最简单方法是将函数参数的声明更改为引用:
void przepare_mesh(..., GLfloat*& vertices, ...)
一旦参数是引用,在函数内部为它赋值将改变调用者传入的指针的值。
代码中还有其他相同问题的情况,我只是用第一个来说明问题。