I am trying to figure out index buffers. I read the MSDN & another thread on it [ Struggling With Vertex And Index Buffers In Direct3D ].
I thought I got it, but in practice, I could not get it to work. I was trying to make a square.
I have 6 vertices:
SimpleVertex vertices[]={ // {Position, Color}
{XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT4(0.8f, 0.2f, 6.0f, 1.0f)}, // top left
{XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT4(0.8f, 0.2f, 6.0f, 1.0f)}, // bottom right
{XMFLOAT3(-0.5f, -0.5f, 0.5f), XMFLOAT4(0.8f, 0.2f, 6.0f, 1.0f)}, // bottom left
{XMFLOAT3(-0.5f, 0.5f, 0.5f), XMFLOAT4(0.8f, 0.2f, 6.0f, 1.0f)}, // top left
{XMFLOAT3(0.5f, 0.5f, 0.5f), XMFLOAT4(0.8f, 0.2f, 6.0f, 1.0f)}, // top right
{XMFLOAT3(0.5f, -0.5f, 0.5f), XMFLOAT4(0.8f, 0.2f, 6.0f, 1.0f)}, // bottom right
};
& an array of indices:
unsigned short indices[]={
0,3,2, // a d c
0,1,3, // a b d
// a---b
// | \ |
// c---d
}
but that does not display anything. If I change the indices to 0,1,2,3,4,5, it works [defeats the point of the index though].
Anyone know what is wrong with the way I think of indices?
Oops, took me a while after I posted to figure out my problem.
1] I listed the vertices as if I was going to draw it manually. I should have had just 4 vertices [not 6].
The index connects the dots; 1st 3 indices make 1st triangle, 2nd 3 make 2nd triangle.
2] I thought the numbers in the index array represented sides on a shape I imagined [not sure how that even works :P]. They actually represent the position in the array of vertices.
Hope this helps others.
Related
I want to draw object within ar but got unexpected result - gl mashine think that i see object from another side (or from inside).
Here image what i want to draw (taken from separate project)
And here - what i got when try to draw this object in my ar (inside of the sphere)
So I guess that problem is that because I put object inside sphere and adjust position of obj using base mat from sphere obj.
Camera positioned in the center of the sphere - so for this obj I use same mat - just scale/rotate/translate it.
This is how I calculate projection mat
CGRect viewFrame = self.frame;
if (!CGSizeEqualToSize(self.newSize, CGSizeZero){
size = self.newSize;
}
CGFloat aspect = viewFrame.size.width / viewFrame.size.height;
CGFloat scale = self.interractor.scale;
CGFloat FOVY = DEGREES_TO_RADIANS(self.viewScale) / scale;
CGFloat cameraDistanse = -(1.0 / [Utilities FarZ]);
GLKMatrix4 cameraTranslation = GLKMatrix4MakeTranslation(0, 0, cameraDistanse);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(FOVY, aspect, NearZ, [Utilities FarZ]);
projectionMatrix = GLKMatrix4Multiply(projectionMatrix, cameraTranslation);
//and also here added some code for modifying, but I skip it here
For this obj I just calculate new scale and position of obj - looks like it's correct because I able to see obj and change his position etc, so skip this part.
In the second project where I got correct result of displaying obj I calculate projection mat in similar way, but with a little bit less calculation:
float aspect = self.glView.frame.size.width / self.glView.frame.size.height;
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.01f, 100);
//scale
//rotate
//translate
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, projectionMatrix);
GLfloat scale = 0.5 *_scale;
GLKMatrix4 scaleMatrix = GLKMatrix4MakeScale(scale, scale, scale);
modelViewMatrix = GLKMatrix4Translate(modelViewMatrix, _positionX, _positionY, -5);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotationX, 0.0f, 1.0f, 0.0f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotationY, 1.0f, 0.0f, 0.0f);
modelViewMatrix = GLKMatrix4Multiply(scaleMatrix, modelViewMatrix);
In first project (correct one) I also use
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glDisable(GL_CULL_FACE);
In second with few obj - depend from obj that I want to draw:
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
//call sphere draw
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
//call obj draw
glEnable(GL_SCISSOR_TEST);
So as I sad before, I guess that the problem is that openGL "think" that we are looking to obj from another side, but I'm not sure. And if i'm right how can i fix this? Or whats done incorrect?
Update
#codetiger I check ur suggestions:
1) Wrong face winding order - recheck it again and try to inverse order, also try to build same model in another project (all works perfect) - result i guess that order is ok;
2) Wrong Culling - check all combinations of
glDisable / glEnable with argument GL_CULL_FACE
glCullFace with argument GL_FRONT, GL_BACK or GL_FRONT_AND_BACK
glFrontFace with argument GL_CW or GL_CCW
What i see - a little bit change but i see still incorrect obj (or wrong side or partial obj etc)
3) vertices are flipped - try to flip them, as result - even worse than before
4) try to combine this 3 suggestion one with another - result not acceptable
The following code draws only a green box, when I am expecting both a green and red box.
If I don't have the second glClear() statement, the red box appears.
This leads me to conclude, since I have the scissor box outside the bounds of the red box, that the glClear() statement is not respecting the scissor box.
Can anyone help me understand what is going on?
glEnable(GL_SCISSOR_TEST);
int x, y, w, h;
x = 0;
y = 0;
w = 700;
h = 700;
glViewport(x,y,w,h);
glScissor(x,y,w,h);
glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
x = 0;
y = 750;
w = 700;
h = 700;
glViewport(x,y,w,h);
glScissor(x,y,w,h);
glClearColor(0.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
So I managed to figure this out myself. I had to "reset" the scissor box at the end of the draw call. i.e.:
glScissor(0,0,viewPixelWidth, viewPixelHeight);
What was happening was that when the renderbuffer was being presented, the scissor box was being applied again, therefore everything outside the latest scissor box was not copied.
I am reading sample code GLVideoFrame from WWDC2010. In this sample, it has code like below:
static const GLfloat squareVertices[] = {
-0.5f, -0.33f,
0.5f, -0.33f,
-0.5f, 0.33f,
0.5f, 0.33f,
};
...
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, (GLfloat)(sinf(transY)/2.0f), 0.0f);
transY += 0.075f;
...
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
Notice that this code does not call any function like glFrustum or glOrtho for openGL projection setting.
By only calling gLoadIdentity(), what will be the "default" view volume?
it wil be a perspective project or orthographic projection?
edited:
to be more specific,
is the view volume a cube that "ranging from -1 to 1 in all three axes" ?
OpenGL assumes that after the ModelView and Projection transform, all visible elements are in clip space (or NDC space); it uses the cube [-1;+1]^3. The matrices contents is entirely your responsibility. Since you load the identity matrix, there is no Projection at all.
Here I created one simple OpenGLES iPad sample.
//----------------------------------------
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustumf(-1, 1, -1, 1, 0, 20);
glMatrixMode(GL_MODELVIEW);
static const GLfloat squareVertices[] = {
-0.5f, -0.33f,1.6,
0.5f, -0.33f,1.6,
-0.5f, 0.33f,1.6,
0.5f, 0.33f,1.6
};
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
. . . . . . .
. . . . . . .
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
//----------------------------------------
I used gluLookAt in mac sample, but it is not found in iPad. What is the basic mistake in above code? why square is not visible?
if I change z value in vertex array then works fine.
static const GLfloat squareVertices[] = {
-0.5f, -0.33f,0.5,
0.5f, -0.33f,0.5,
-0.5f, 0.33f,0.5,
0.5f, 0.33f,0.5
};
I thought z value range should be 0-20, here 1.6, its in range. I don't like to change vertex value now. Help me to set glFrustumf.
The near and far values passed to glFrustum are not absolute coordinates in object space. They are the distances from the camera to the near and far planes. That means that you can't say that a z coordinate of 1.6 is necessarily in your frustum unless you know where the camera position is and what direction it is pointing in.
For example if your camera is at (0,0,-19) pointed at the origin and you pass 0 and 20 to glFrustum for near and far then in object space the near plane is at -19 (-19+0) and the far plane is at 1 (-19+20). In such a case the square with z=1.6 would be past the far plane but the one with z=0.5 would be inside the frustum. Similarly if your camera was at (0,0,1) with the same values for glFrustum then in object space the near plane would be at 1 and the far would be at -19 so 0.5 would be in and 1.6 would be out.
I'm learning how to use OpenGL ES 2.0 on iOS. Right now I want to just do some basic 2D animation (e.g. move a rectangle around the screen and change its size). I've started out with the project template for OpenGL ES provided by Apple in Xcode. My drawing code looks like this:
static GLfloat squareVertices[] = {
-0.5f, -0.33f,
0.5f, -0.33f,
-0.5f, 0.33f,
0.5f, 0.33f
};
// Update attribute values.
glVertexAttribPointer(VERTEX_ATTR, 2, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(VERTEX_ATTR);
glVertexAttribPointer(COLOR_ATTR, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors);
glEnableVertexAttribArray(COLOR_ATTR);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 5);
Now this will draw a nice rectangle in the middle of the screen. But if I start to change the rectangle by adding the following code, it starts to look funky:
squareVertices[5] -= .001;
squareVertices[7] -= .001;
It is as if part of the rectangle is attached to the center of the screen. I am completely new to OpenGL ES so I'm sure my problem is obvious. I also assume this has something to do with OpenGL ES being a 3D graphics library and I'm trying to treat it as a 2D space. So my question is: What is the best way to draw and animate 2D objects in OpenGL ES 2.0? I've seen some stuff online for OpenGL ES 1.1, but that is not much help to me. Are their special techniques for 2D drawing in OpenGL ES 2.0, or is there some sort of 2D drawing mode?
Any guidance would be greatly appreciated.
#macinjosh: This is a response to your updated question for those who are interested in the answer. I'm guessing you've gained further knowledge since Dec '10 when you posted!
OpenGL vertices are in 3D, not 2D. To be completely truthful, they're actually in 4D since they include a 'w' component as well, but for now just consider that as value 1.0 like a homogenous vector.
Due to their 3D-ness, unless you add a 'z' component in a shader you must specify one as a vertex attribute.
Because you have a '3' as the third parameter of glVertexAttribPointer. I believe you can set it to 2 but I haven't tried this in GL. My guess is the missing z axis would be filled in internally as '0' (but again, try it and see!). Internally, it's probably all going to be 4 float vectors with the 4th ('w') parameter used for homogeneous matrix multiplication gubbins.
If you're doing this on a mobile device you may also wish to look into fixed point maths (faster on some devices that don't have a floating point co-pro) and also Vertex Buffer Objects, which are more efficient on many machines. Also, a fixed vertex format such as used by
glInterleavedArrays(format_code, stride, data)
may prove to be more efficient as the device may have optimized code paths for whatever 'format_code' you decide to go with.
I'm new with OpenGL, but vertex doesn't require 3 float, one every axis : X,Y,Z?
So, the first vertex array will be :
( -0.50f, -0.33f, 0.50f)
( -0.33f, -0.50f, 0.33f)
( 0.50f, 0.33f, ?????)
the second will be :
( -0.50f, -0.33f, 0.00f )
( 0.50f, -0.33f, 0.00f )
( -0.50f, 0.33f, 0.00f )
( 0.50f, 0.33f, 0.00f )
After some playing around I changed the drawing code to this:
static GLfloat squareVertices[12] = {
-0.5f, -0.33f, 0.0,
0.5f, -0.33f, 0.0,
-0.5f, 0.33f, 0.0,
0.5f, 0.33f, 0.0
};
// Update attribute values.
glVertexAttribPointer(VERTEX_ATTR, 3, GL_FLOAT, 0, 0, squareVertices);
glEnableVertexAttribArray(VERTEX_ATTR);
glVertexAttribPointer(COLOR_ATTR, 4, GL_UNSIGNED_BYTE, 1, 0, squareColors);
glEnableVertexAttribArray(COLOR_ATTR);
squareVertices[7] -= .001;
squareVertices[10] -= .001;
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
Adding the third 0.0 float to each vertex seemed to do the trick. I am unclear on why this is so if any one could shed some light I would apreciate it.