When i try to render OBJ sphere from blender it looks like this:
So i quickly found out that OBJ doesn't contain all information available in v. Then i extended parser to take additional f 1/2/3 1/2/3 1/2/3 data, obviously only the 1's are v indices. I checked variable values with lldb debugger and everything is fine. Here is some code example.
void visualEntityRender(visualEntity *ve){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindBuffer(GL_ARRAY_BUFFER, ve->VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ve->EBO);
glEnableVertexAttribArray(ve->shaderID);
glVertexAttribPointer( ve->shaderID, 3,
GL_FLOAT, GL_FALSE,
0, (void *)0 );
glDrawElements(GL_TRIANGLES, ve->fv_count, GL_UNSIGNED_INT, 0);
}
ve->fv_count contains number fv's from OBJ file. Again i checked everything with debugger and there are no strange numbers.
visualEntity visualEntityInit( char *path ){
visualEntity ve = {
.m4Projection = GLM_MAT4_IDENTITY_INIT,
.m4View = GLM_MAT4_IDENTITY_INIT,
.m4Model = GLM_MAT4_IDENTITY_INIT,
.m4MVP = GLM_MAT4_IDENTITY_INIT
};
ve.Render = &visualEntityRender;
ve.Set = &visualEntityMVPSet;
ve.Update = &visualEntityUpdate;
ve.Destroy = &visualEntityDestroy;
FILE *fp = fopen(path, "r");
if(fp == NULL){
printf("Model load error: %s\n", path);
}
char tmpc[100];
int v_count = 0;
int vt_count = 0;
int vn_count = 0;
int fv_count = 0;
int fvt_count = 0;
int fvn_count = 0;
/* get v,vt and vn data */
while(1){
if( fscanf(fp, "%s", tmpc) == EOF ){
break;
}
if(strcmp(tmpc, "v") == 0){
fscanf(fp, "%f", &ve.v[v_count]);
v_count++;
fscanf(fp, "%f", &ve.v[v_count]);
v_count++;
fscanf(fp, "%f", &ve.v[v_count]);
v_count++;
}
if(strcmp(tmpc, "vt") == 0){
fscanf(fp, "%f", &ve.vt[vt_count]);
vt_count++;
fscanf(fp, "%f", &ve.vt[vt_count]);
vt_count++;
fscanf(fp, "%f", &ve.vt[vt_count]);
vt_count++;
}
if(strcmp(tmpc, "vn") == 0){
fscanf(fp, "%f", &ve.vn[vn_count]);
vn_count++;
fscanf(fp, "%f", &ve.vn[vn_count]);
vn_count++;
fscanf(fp, "%f", &ve.vn[vn_count]);
vn_count++;
}
if(strcmp(tmpc, "f") == 0){
fscanf(fp, "%f/%f/%f", &ve.fv[fv_count], &ve.fvt[fvt_count], &ve.fvn[fvn_count]);
fv_count++; fvt_count++; fvn_count++;
fscanf(fp, "%f/%f/%f", &ve.fv[fv_count], &ve.fvt[fvt_count], &ve.fvn[fvn_count]);
fv_count++; fvt_count++; fvn_count++;
fscanf(fp, "%f/%f/%f", &ve.fv[fv_count], &ve.fvt[fvt_count], &ve.fvn[fvn_count]);
fv_count++; fvt_count++; fvn_count++;
}
}
}
glGenBuffers(1, &ve.VBO);
glBindBuffer(GL_ARRAY_BUFFER, ve.VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(ve.v), ve.v, GL_STATIC_DRAW);
glGenBuffers(1, &ve.EBO); */
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ve.EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(ve.fv), ve.fv, GL_STATIC_DRAW);
ve.v_size = sizeof(GLfloat) * v_count;
ve.vt_size = sizeof(GLfloat) * vt_count;
ve.vn_size = sizeof(GLfloat) * vn_count;
ve.fv_size = sizeof(GLfloat) * fv_count;
ve.fvt_size = sizeof(GLfloat) * fvt_count;
ve.fvn_size = sizeof(GLfloat) * fvn_count;
// TODO, use ve.x_count variables directly in here, discard local x_count;
ve.v_count = v_count;
ve.vt_count = vt_count;
ve.vn_count = vn_count;
ve.fv_count = fv_count;
ve.fvt_count = fvt_count;
ve.fvn_count = fvn_count;
return ve;
}
Parsing code as you can see is pretty straightforward and simple. And this is my main:
visualEntity veCube = visualEntityInit( "sphere.obj" );
veCube.Set(&veCube, glm_rad(45), 4.0f / 3.0f,
0.1f, 100.0f, (vec3){4,3,3}, (vec3){0,0,0}, (vec3){0,1,0});
veCube.Update(&veCube);
veCube.uniformMVPLocation = glGetUniformLocation(shader.program, "MVP");
while(true){
if(SDL_PollEvent(&ev) != 0){
if(ev.key.keysym.sym == SDLK_q){
break;
}
}
glUniformMatrix4fv(veCube.uniformMVPLocation, 1, GL_FALSE, &veCube.m4MVP[0][0]);
veCube.shaderID = vModelPosition;
veCube.Render(&veCube);
SDL_GL_SwapWindow(window);
SDL_Delay(20);
}
When i added glDrawElements in code to try it out i cannot see sphere at all.
