Wavefront OBJ import to OpenGL ES 2.0 problems - objective-c

I finally finished building my Wavefront OBJ parser, but still have some issues rendering my test object (cube).
So this is how i have parsed my vertices and indices (faces) into arrays of data. I have ignored textures and normals for now.
Vertices:
v -0.307796 0.00433517 0
v 0.299126 0.00433517 0
v 0.299126 0.00433517 0.48337
v -0.307796 0.00433517 0.48337
v -0.307796 0.364153 0.48337
v 0.299126 0.364153 0.48337
v 0.299126 0.364153 0
v -0.307796 0.364153 0
As:
const Vertex Vertices[] = {
{-0.307796,0.00433517,0},
{0.299126,0.00433517,0},
{0.299126,0.00433517,0.48337},
{-0.307796,0.00433517,0.48337},
{-0.307796,0.364153,0.48337},
{0.299126,0.364153,0.48337},
{0.299126,0.364153,0},
{-0.307796,0.364153,0}
};
Faces:
f 7/1/1 3/2/2 2/3/3
f 3/4/4 7/5/5 6/6/6
f 5/7/7 1/8/8 4/9/9
f 1/10/10 5/11/11 8/12/12
f 7/13/13 1/14/14 8/15/15
f 1/16/16 7/17/17 2/18/18
f 3/19/19 5/20/20 4/21/21
f 5/22/22 3/23/23 6/24/24
f 5/25/25 7/26/26 8/27/27
f 7/28/28 5/29/29 6/30/30
f 3/31/31 1/32/32 2/33/33
f 1/34/34 3/35/35 4/36/36
As:
const GLubyte Indices[] = {
7,1,1, 3,2,2, 2,3,3,
3,4,4, 7,5,5, 6,6,6,
5,7,7, 1,8,8, 4,9,9,
1,10,10, 5,11,11, 8,12,12,
7,13,13, 1,14,14, 8,15,15,
1,16,16, 7,17,17, 2,18,18,
3,19,19, 5,20,20, 4,21,21,
5,22,22, 3,23,23, 6,24,24,
5,25,25, 7,26,26, 8,27,27,
7,28,28, 5,29,29, 6,30,30,
3,31,31, 1,32,32, 2,33,33,
1,34,34, 3,35,35, 4,36,36
};
Indices only as vertex positions:
const GLubyte Indices[] = {
7, 3, 2,
3, 7, 6,
5, 1, 4,
1, 5, 8,
7, 1, 8,
1, 7, 2,
3, 5, 4,
5, 3, 6,
5, 7, 8,
7, 5, 6,
3, 1, 2,
1, 3, 4
};
SetupVBO:
GLuint vertexBuffer;
glGenBuffers(1, &vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW);
GLuint indexBuffer;
glGenBuffers(1, &indexBuffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(Indices), Indices, GL_STATIC_DRAW);
Renderingcode:
glClearColor(0, 104.0/255.0, 55.0/255.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
CC3GLMatrix *modelView = [CC3GLMatrix matrix];
[modelView populateFromTranslation:CC3VectorMake(sin(CACurrentMediaTime()), 0, -7)];
_currentRotation += displayLink.duration * 90;
[modelView rotateBy:CC3VectorMake(_currentRotation, _currentRotation, 0)];
glUniformMatrix4fv(_modelViewUniform, 1, 0, modelView.glMatrix);
// 1
glViewport(0, 0, self.frame.size.width, self.frame.size.height);
// 2
glVertexAttribPointer(_positionSlot, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), 0);
glVertexAttribPointer(_colorSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) (sizeof(float) * 3));
// 3
glDrawElements(GL_TRIANGLES, sizeof(Indices)/sizeof(Indices[0]), GL_UNSIGNED_BYTE, 0);
And the result is pretty much nothing at all, so there must be something that im doing completely wrong.
Furthermore will the indices cause any problems since i have not initialized the normals or texture coords?

The Wavefront obj format says that if you have sequences of 3 in the face definitions then their meaning is:
vertex-index/vertex-texture-index/vector-normal-index
You are reading all of the indices into a single array GLubyte Indices[] and using it as it if was just the indices of the vertices.
If you want to do away with textures and normals, you need to take only the first number of every triplet.
In
f 6/1/1 3/2/2 2/3/3 7/4/4
The face is a quad of vertices of indices [6,3,2,7]. Using the indices array like you have requires that you tell OpenGl that the indices are multiplexed in triplets. It does not look like you do that. It also requires additional buffers for normal and texture coordinates.

Related

Open the depth test, but it doesn't work?

m_Program = new GLProgram;
m_Program->initWithFilenames(“shader/gldemo.vsh”, “shader/gldemo.fsh”);
m_Program->link();
//set uniform locations
m_Program->updateUniforms();
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
//create vbo
glGenBuffers(1, &vertexVBO);
glBindBuffer(GL_ARRAY_BUFFER, vertexVBO);
auto size = Director::getInstance()->getVisibleSize();
float vertercies[] = {
0,0,0.5, //first point
-1, 1,0.5,
-1, -1,0.5,
-0.3,0,0.8,
1, 1,0.8,
1, -1,0.8};
float color[] = { 1, 0,0, 1, 1,0,0, 1, 1, 0, 0, 1,
0, 1,0, 1, 0,1,0, 1, 0, 1, 0, 1};
glBufferData(GL_ARRAY_BUFFER, sizeof(vertercies), vertercies, GL_STATIC_DRAW);
//vertex attribute "a_position"
GLuint positionLocation = glGetAttribLocation(m_Program->getProgram(), "a_position");
glEnableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
//set for color
glGenBuffers(1, &colorVBO);
glBindBuffer(GL_ARRAY_BUFFER, colorVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(color), color, GL_STATIC_DRAW);
GLuint colorLocation = glGetAttribLocation(m_Program->getProgram(), "a_color");
glEnableVertexAttribArray(colorLocation);
glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)0);
//for safty
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//show
glEnable(GL_DEPTH_TEST);
Open the depth test, but it doesn't work?
It can be displayed normally, but I open the depth test, the red triangle Z is set to 0.5, the blue is set to 0.8, but their rendering order has not changed?
Multiple things:
Enabling depth testing does not mean that the depth testing is set correctly. You have to setup it
You have to make sure there is a depth buffer
You have to enable depth writing and depth testing when rendering your primitives
With openGL, you typically need to call those functions in order to have depth testing working:
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
and to enable depth writing:
glDepthMask(GL_TRUE);
And just searching for opengl enable depth testing on google gave me some neat results. You should look on the multiple resources google have in its index.

Nodes inconsistency between 2D and 3D elements in GMSH

I am trying to produce a tetrahedral mesh of a cube. The problem I encounter is that a few nodes that are used to generate the triangular faces are then not used to generate any of the tetrahedral elements. Is there a way to avoid this?
This is the code.
cl__1 = 0.01;
Point(1) = {0, 0, 0, cl__1};
Point(2) = {1, 0, 0, cl__1};
Point(3) = {1, 1, 0, cl__1};
Point(4) = {0, 1, 0, cl__1};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Line Loop(5) = {4, 1, 2, 3};
Plane Surface(6) = {5};
Extrude {0, 0, 1} {
Surface{6};
}
Coherence;
Transfinite Line {1, 2, 3, 4, 9, 10, 11, 8, 18, 22, 13, 14} = 2 Using Progression 1;
Transfinite Surface {19};
Transfinite Surface {23};
Transfinite Surface {27};
Transfinite Surface {15};
Transfinite Surface {28};
Transfinite Surface {6};
Transfinite Volume{1} = {1, 2, 3, 4, 6, 10, 14, 5};
Physical Surface("top") = {28};
Physical Surface("bottom") = {6};
Physical Surface("x_min") = {15};
Physical Surface("x_max") = {23};
Physical Surface("y_min") = {19};
Physical Surface("y_max") = {27};
Physical Volume("bottom_volume") = {1};
Thanks
Jian
The result of that input gives these nodes:
$Nodes
8
1 0 0 0
2 1 0 0
3 1 1 0
4 0 1 0
5 0 1 1
6 0 0 1
7 1 0 1
8 1 1 1
$EndNodes
with these nodes you can define all the triangular faces and the tetrahedral elements that define that mesh (there is no inconsistency in my opinion).

About usage of glVertexAttribPointer

GLfloat m_tex[3][4][2] = {
{ {{1.0, 2.0}, {2.0, 3.0}}, {{0.0, -3.0}, {9.0, 11.0}}, {{23.0, 12.0}, {43.0, 22.0}}, {{15.0, 4.0}, {3.0, 12.0}} },
{ {{13.0, 4.0}, {56.0, 3.0}}, {{5.0, 9.0}, {3.0, 5.0}}, {{3.0, 1.0}, {4.0, 9.0}}, {{5.0, 4.0}, {7.0, 12.0}} },
{ {{3.0, 9.0}, {6.0, 13.0}}, {{8.0, 19.0}, {13.0, 6.0}}, {{3.0, 3.0}, {9.0, 6.0}}, {{35.0, 7.0}, {13.0, 12.0}} }
};
glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, 0, m_tex[0]);
glVertexAttribPointer(Uloc, 2, GL_FLOAT, 0, 0, m_tex[1]);
glVertexAttribPointer(Vloc, 2, GL_FLOAT, 0, 0, m_tex[2]);
I know the meaning of glVertexAttribPointer. It sets the value of m_tex[0] in 2 floats to vertex Yloc but m_tex[0] includes:
{{1.0, 2.0}, {2.0, 3.0}}, {{0.0, -3.0}, {9.0, 11.0}}, {{23.0, 12.0}, {43.0, 22.0}}, {{15.0, 4.0}, {3.0, 12.0}}
So does it take first two ones ? {1.0,2.0}
I am not sure.
Yes, it will take two numbers on each iteration
+-----------------------------------------------------------+
| glVertexAttribPointer(Yloc, 2, GL_FLOAT, 0, 0, m_tex[0]); |
+-----------------------------------------------------------+
| |
take 2 floats each time <+ from this set <-+
[1.0,2.0]
If you change 2 parameter to 3 it will iterate for components[x,y,z]
+-----------------------------------------------------------+
| glVertexAttribPointer(Yloc, 3, GL_FLOAT, 0, 0, m_tex[0]); |
+-----------------------------------------------------------+
| |
take 3 floats each time <+ from this set <-+
[1.0,2.0,2.0]

OpenGLES adding a projection

I'm started to learn a OpenGLES and currently I'm reading this TUTORIAL
I have reached paragraph Adding a Projection and I'm stuck there:
// Add to render, right before the call to glViewport
CC3GLMatrix *projection = [CC3GLMatrix matrix];
float h = 4.0f * self.frame.size.height / self.frame.size.width;
[projection populateFromFrustumLeft:-2 andRight:2 andBottom:-h/2 andTop:h/2 andNear:4 andFar:10];
glUniformMatrix4fv(_projectionUniform, 1, 0, projection.glMatrix);
// Modify vertices so they are within projection near/far planes
const Vertex Vertices[] = {
{{1, -1, -7}, {1, 0, 0, 1}},
{{1, 1, -7}, {0, 1, 0, 1}},
{{-1, 1, -7}, {0, 0, 1, 1}},
{{-1, -1, -7}, {0, 0, 0, 1}}
};
The author uses some variables in populateFromFrustumLeft... and doesn't explain them. I want to understand the logic of variable selection to be able to use this function in future.
Help me plz to understan the logic!

opengl es 2 just clrears the screen to default color value when using multiple VAOs

i'm fairly new to opengl es 2 and since i'm coding IOS apps, i thought id try it!
So I loaded up a default opengl program using the GLKit template in xcode 4 and after fumbling around in the provided code I begun modifying it so that I could draw multiple different kinds of vertex array objects...the problem is only the call to glClearColor seems to produce any results-the whole screen is just grey now:-(
I don't know what is wrong since I checked with many glGetError calls at key places in the code and it always seems to return 0...and I also, to the extent of my small knowledge, follow the steps required to draw with VAOs since when I modified the default code initially to display a plane it worked OK...
So i'm going to be very grateful if you guys could help the newbie!:)
here is a posting of the different relevant parts of the code:
//init VAOs:
glGenVertexArraysOES(NUM_VAO, _vertexArrayIDS);
glGenBuffers(NUM_VAO, _vertexBufferIDS);
glGenBuffers(NUM_VAO, _indexBufferIDS);
//init gl object for player:
//setupGLObject(VAO_PLAYER, gCubicVertexData, gCubicIndices, GL_STATIC_DRAW);
glBindVertexArrayOES(_vertexArrayIDS[VAO_PLAYER]);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferIDS[VAO_PLAYER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubicVertexData), gCubicVertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferIDS[VAO_PLAYER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(gCubicIndices), gCubicIndices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(12));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(24));
//NSLog(#"glError after player init : %d", glGetError());
//init gl object for player wall:
//setupGLObject(VAO_PWALL, gPlayerWallVertexData, gPlayerWallIndices, GL_DYNAMIC_DRAW);
glBindVertexArrayOES(_vertexArrayIDS[VAO_PWALL]);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferIDS[VAO_PWALL]);
glBufferData(GL_ARRAY_BUFFER, sizeof(gPlayerWallVertexData), gPlayerWallVertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferIDS[VAO_PLAYER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(gPlayerWallIndices), gPlayerWallIndices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(12));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(24));
//init gl object for wall/floor plane:
//setupGLObject(VAO_WALL_FLOOR_PLANE, gPlanePyVertexData, gPlanePyIndices, GL_STATIC_DRAW);
glBindVertexArrayOES(_vertexArrayIDS[VAO_WALL_FLOOR_PLANE]);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferIDS[VAO_WALL_FLOOR_PLANE]);
glBufferData(GL_ARRAY_BUFFER, sizeof(gPlanePyVertexData), gPlanePyVertexData, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferIDS[VAO_PLAYER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(gPlanePyIndices), gPlanePyIndices, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(12));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(VertexData), BUFFER_OFFSET(24));
glBindVertexArrayOES(0);
drawing function - glkView:(GLKView *)view drawInRect:(CGRect)rect
for (NSString *currentKey in g_renderables) {
GameObject *currentRenderable = [g_renderables objectForKey:currentKey];
if (currentRenderable.go_type == LC_FLOOR) {
glBindVertexArrayOES(_vertexArrayIDS[VAO_WALL_FLOOR_PLANE]);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, currentRenderable.go_mvm.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
NSLog(#"glError : %d", glGetError());
glDrawElements(GL_TRIANGLE_STRIP, sizeof(gPlanePyIndices)/sizeof(gPlanePyIndices[0]), GL_UNSIGNED_INT, 0);
}
else if (currentRenderable.go_type == LC_WALL) {
glBindVertexArrayOES(_vertexArrayIDS[VAO_WALL_FLOOR_PLANE]);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, currentRenderable.go_mvm.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawElements(GL_TRIANGLE_STRIP, sizeof(gPlanePyIndices)/sizeof(gPlanePyIndices[0]), GL_UNSIGNED_INT, 0);
}
else if (currentRenderable.go_type == LC_PLAYER) {
glBindVertexArrayOES(_vertexArrayIDS[VAO_PLAYER]);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, currentRenderable.go_mvm.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawElements(GL_TRIANGLE_STRIP, sizeof(gCubicIndices)/sizeof(gCubicIndices[0]), GL_UNSIGNED_INT, 0);
}
matrix computations:
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 1000.0f);
for (NSString *currentKey in g_renderables) {
GLKMatrix4 thisMvm = GLKMatrix4Identity;
GameObject *currentRenderable = [g_renderables objectForKey:currentKey];
if (currentRenderable.go_hasVisual) {
thisMvm = GLKMatrix4Translate(thisMvm, currentRenderable.go_origin.x, currentRenderable.go_origin.y, currentRenderable.go_origin.z);
if (currentRenderable.go_type == LC_WALL || currentRenderable.go_type == LC_PLAYER) {
if (currentRenderable.go_type == LC_PLAYER) {
if (currentRenderable.go_orientation == VV_MINUS_X) {
thisMvm = GLKMatrix4RotateY(thisMvm, GLKMathDegreesToRadians(90.0f));
}
else if (currentRenderable.go_orientation == VV_PLUS_X) {
thisMvm = GLKMatrix4RotateY(thisMvm, GLKMathDegreesToRadians(-90.0f));
}
else if (currentRenderable.go_orientation == VV_PLUS_Z) {
thisMvm = GLKMatrix4RotateY(thisMvm, GLKMathDegreesToRadians(180.0f));
}
}
else {
if (currentRenderable.go_orientation == VV_MINUS_X) {
thisMvm = GLKMatrix4RotateZ(thisMvm, GLKMathDegreesToRadians(90.0f));
}
else if (currentRenderable.go_orientation == VV_PLUS_X) {
thisMvm = GLKMatrix4RotateZ(thisMvm, GLKMathDegreesToRadians(-90.0f));
}
else if (currentRenderable.go_orientation == VV_PLUS_Z) {
thisMvm = GLKMatrix4RotateX(thisMvm, GLKMathDegreesToRadians(-90.0f));
}
else if (currentRenderable.go_orientation == VV_MINUS_Z) {
thisMvm = GLKMatrix4RotateX(thisMvm, GLKMathDegreesToRadians(90.0f));
}
}
}
if (currentRenderable.go_type != LC_LINKED_WALL) thisMvm = GLKMatrix4Scale(thisMvm, currentRenderable.width, currentRenderable.height, currentRenderable.depth);
thisMvm = GLKMatrix4Multiply(GLKMatrix4MakeLookAt(g_currentCam.go_origin.x, g_currentCam.go_origin.y, g_currentCam.go_origin.z, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f), thisMvm);
//NSLog(#"%f", thisMvm.m[10]);
thisMvm = GLKMatrix4Multiply(projectionMatrix, thisMvm);
currentRenderable.go_mvm = thisMvm;
}
}
That's it.Please help!!!
I think there is a bit of confusion in the way you understood the glclearcolor.
The main idea is that for every frame you should clear at least the color bit by doing a glclear, it is like cleaning a board after you did your drawings.
The glclearcolor instead instructs OpenGL which color should be used for the whole screen after the clear.
An example of this is the following:
glClearColor(1.0f,0.0f,0.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
This example tells OpenGL to use the red color when a color of the clear of the color_buffer_bit is required.
I hope this helps in some way.