I am new in iOS OpenGL ES. And I created an OpenGL project "OpenGl Game" in Xcode 5. Then I build and run, there are 2 cubes rotating around. I read the code and do not understand why there is 2 cubes instead of 1?
Here is the code related to the cubes:
- (void)update{
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -4.0f);
baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _rotation, 0.0f, 1.0f, 0.0f);
// Compute the model view matrix for the object rendered with GLKit
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, -1.5f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
self.effect.transform.modelviewMatrix = modelViewMatrix;
// Compute the model view matrix for the object rendered with ES2
modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, 1.5f);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _rotation, 1.0f, 1.0f, 1.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
_rotation += self.timeSinceLastUpdate * 0.5f;
}
It seems that GLKit and ES2 renders a cube respectively, but I don't know why?
The "OpenGL Game" template creates a program that renders 2 cubes into the GLKView. One of those cubes is rendered using the GLKit analogs of the old OpenGL ES 1.1 fixed function pipeline, the other cube is rendered through an ES 2.0 pipeline using the fragment and vertex shaders included in the template.
I think they do both so you have a working starting point for whichever pipeline you choose to use. For my current ES 2.0 project I simply stripped out all of the code relating to the ES1.1 cube and built on the code provided for the 2.0 pipeline. If you were porting some existing ES 1.1 code into GLKit you might do the opposite and remove all the stuff relating to the ES 2.0 cube.
Related
Basically, I am trying to build some effect like that on iOS with GLSL.
http://threejs.org/examples/#webgl_kinect
With what I know, the first step should be create one vertex for each pixel, and then map each vertex with pixel. If this step done, I can adjust the z position of vertex in vertexShader with some logic, then accomplish this effect.
The problem is too slow,such as the front camera is 2MP, there will be 2M vertices in the array.
static const GLfloat squareVertices[] = {
-1.0f, -1.0f, // bottom left
1.0f, -1.0f, // bottom right
-1.0f, 1.0f, // top left
1.0f, 1.0f, // top right
};
static const float textureVertices[] = {
0.0f, 0.0f, // bottom left
1.0f, 0.0f, // bottom right
0.0f, 1.0f, // top left
1.0f, 1.0f, // top right
};
glVertexAttribPointer( ATTRIB_VERTEX, 2, GL_FLOAT, 0, 0, squareVertices );
glEnableVertexAttribArray( ATTRIB_VERTEX );
glVertexAttribPointer( ATTRIB_TEXTUREPOSITON, 2, GL_FLOAT, 0, 0, textureVertices );
glEnableVertexAttribArray( ATTRIB_TEXTUREPOSITON );
Are there any GL api can do this easily and fast?
I am guessing the key might be in THREE.BufferGeometry() and THREE.Points()
How did three.js made that?
I am working on the app where i am developing an OpenGL object with coremotion functionality which will be rotating the object on device movement. And i am using the cmrotationmatrix of device motion to calculate rotation.
It works well on the device movement and also shows straight when the device is flat on the table.But if i change the angle of the device on start it shows bending.So is it possible to make the object to show straight at any angle of the device. Kindly response if anyone find solution.
CMDeviceMotion *deviceMotion = self.motionManager.deviceMotion;
float deviceOrientationRadians = 0.0f;
deviceOrientationRadians = M_PI_2;
GLKMatrix4 baseRotation =
GLKMatrix4MakeRotation(deviceOrientationRadians, 0.0f, 0.0f, 1.0f);
CMRotationMatrix a = deviceMotion.attitude.rotationMatrix;
deviceMotionAttitudeMatrix
= GLKMatrix4Make(a.m11, a.m21, a.m31, 0.0f,
a.m12, a.m22, a.m32, 0.0f,
a.m13, a.m23, a.m33, 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
deviceMotionAttitudeMatrix =
GLKMatrix4Multiply(baseRotation, deviceMotionAttitudeMatrix);
I'm trying to draw a 1 pixel width line on iOS, using OpenGL and I faced a problem.
That's how drawn line (zoomed) looks like in simulator:
iPhone 4S
iPhone 6 Plus
As you can see, line is more then 1 pixel width and also it's smoothed.
I think, that problem is not in OpenGL, but in screen scale factor.
I want that the line is a one-pixel on all types of screens.
That's how I draw the line
- (void)drawView {
[EAGLContext setCurrentContext:context];
glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
glViewport(0, 0, backingWidth, backingHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
glOrthof(-1.0f, 1.0f, -1.5f, 1.5f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
GLfloat vertices[4];
vertices[0] = -0.5;
vertices[1] = 0;
vertices[2] = 0.5;
vertices[3] = 0;
glVertexPointer(2, GL_FLOAT, 0, vertices);
glEnableClientState(GL_VERTEX_ARRAY);
glColor4f(1.0f, 1.0f, 0.0f, 1.0f);
glLineWidthx(1.0f);
glDrawArrays(GL_LINE_STRIP, 0, 2);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
[context presentRenderbuffer:GL_RENDERBUFFER_OES];
}
Have a look at http://oleb.net/blog/2014/11/iphone-6-plus-screen/
This shows that the iPhone 6 Plus uses a scaling factor and says that you can disable the scaling by "set the contentScaleFactor of your GLKView to the value of UIScreen.nativeScale"
Hopefully that will fix your problem
I am working on a 3D 1st person game, using the gyro in the phone, people can look up and down, side to side etc. I also want to add manual controls to add to this.
This code handles the gyro
GLKMatrix4 deviceMotionAttitudeMatrix;
if (_cmMotionmanager.deviceMotionActive) {
CMDeviceMotion *deviceMotion = _cmMotionmanager.deviceMotion;
GLKMatrix4 baseRotation = GLKMatrix4MakeRotation(M_PI_2, 0.0f , 0.0f , 1.0f );
// Note: in the simulator this comes back as the zero matrix.
// on device, this doesn't include the changes required to match screen rotation.
CMRotationMatrix a = deviceMotion.attitude.rotationMatrix;
deviceMotionAttitudeMatrix
= GLKMatrix4Make(a.m11, a.m21, a.m31, 0.0f,
a.m12 , a.m22, a.m32, 0.0f,
a.m13 , a.m23 , a.m33 , 0.0f,
0.0f, 0.0f, 0.0f, 1.0f);
deviceMotionAttitudeMatrix = GLKMatrix4Multiply(baseRotation, deviceMotionAttitudeMatrix);
// NSLog(#"%f %f %f %f %f %f %f %f", a.m11, a.m21, a.m31,
// a.m12 , a.m22, a.m32, a.m23, a.m33);
}
I then want to add the manual values for up/down left/up etc.
I can easily add left right
deviceMotionAttitudeMatrix = GLKMatrix4RotateZ(deviceMotionAttitudeMatrix, (self.rotateLeft / 20));
However when I add up down, it works in north/south direction but east/west direction then rotates on a different axis
deviceMotionAttitudeMatrix = GLKMatrix4RotateY(deviceMotionAttitudeMatrix, (self.rotateTop / 20));
I have tried to multiple the matrix but that also has the same issue. It feels like I need to merge them not multiple them
GLKMatrix4 leftRotation = GLKMatrix4MakeRotation((self.rotateLeft / 20), 0.0f, 0.0f, 1.0f);
GLKMatrix4 TopRotation = GLKMatrix4MakeRotation(-(self.rotateTop / 20), 0.0f, 1.0f, 0.0f);
GLKMatrix4 complete = GLKMatrix4Multiply(TopRotation, leftRotation);
deviceMotionAttitudeMatrix = GLKMatrix4Multiply(deviceMotionAttitudeMatrix,complete);
I am building an iOS game with OpenGL ES 2.0 that contains a scene with around 100 different 'objects' which I need to be able to transform independently of one another. I am new to OpenGL ES. As such, I initially thought I should start with OpenGL ES 1.1, then later migrate the app to 2.0 to take advantage of the enhanced visual effects.
However, just as I was getting comfortable with 1.1, I realized, partly based on Apple's very 2.0-centric Xcode template for OpenGL, that it was going to be more trouble than it's worth to fight moving straight into 2.0, so I bit the bullet.
Now, I'm finding it difficult to grasp the concepts enough to do simple transforms on my vertex array objects independently of one another. I read in the OpenGLES 2.0 docs that the best way to do this would be to use multiple VBOs, one for each vertex array. However, I can't seem to transform one of them without affecting the entire scene.
I started the project with the Apple OpenGL ES template and streamlined it, such that the setupGL method looks like this:
-(void)setupGL
{
// Setup
[EAGLContext setCurrentContext:self.context];
[self loadShaders];
self.effect = [[GLKBaseEffect alloc] init];
self.effect.light0.enabled = GL_TRUE;
self.effect.light0.diffuseColor = GLKVector4Make(1.0f, 0.4f, 0.4f, 1.0f);
glEnable(GL_DEPTH_TEST); // do depth comparisons and update the depth buffer
// Initialize first buffer
glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);
glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(gPyramidVertexData), gPyramidVertexData, GL_DYNAMIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBindVertexArrayOES(0);
// Initialize second buffer
glGenVertexArraysOES(2, &_vertexArray2);
glBindVertexArrayOES(_vertexArray2);
glGenBuffers(2, &_vertexBuffer2);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer2);
glBufferData(GL_ARRAY_BUFFER, sizeof(gCubeVertexData), gCubeVertexData, GL_STATIC_DRAW);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(0));
glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 24, BUFFER_OFFSET(12));
glBindVertexArrayOES(0);
}
I know that's incredibly sloppy code- I basically copy-and-pasted the buffer creation portion to set myself up for experimenting with two different vertextArrays in separate buffers. It appears to have worked, as I can render both buffers in the drawInRect method:
-(void)glkView:(GLKView *)view drawInRect:(CGRect)rect
{
glBindVertexArrayOES(_vertexArray);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, numberOfVerteces);
glBindVertexArrayOES(_vertexArray2);
glUseProgram(_program);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glDrawArrays(GL_TRIANGLES, 0, numberOfVerteces2);
}
My problem comes when I try to do transforms on one vertex array without affecting the other one. I tried adding transforms in the above method just before the glDrawArrays calls, without success- I think that may only work with 1.1. It appears my transforms must be done within the update method:
-(void)update
{
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 0.1f, 100.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
GLKMatrix4 baseModelViewMatrix = GLKMatrix4MakeTranslation( 0.0f, 0.0f, -4.0f);
baseModelViewMatrix = GLKMatrix4Rotate(baseModelViewMatrix, _sceneRotation, 1.0f, 1.0f, 1.0f);
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(0.0f, 0.0f, zoomFactor);
modelViewMatrix = GLKMatrix4Rotate(modelViewMatrix, _objectRotation, 0.0f, 1.0f, 0.0f);
modelViewMatrix = GLKMatrix4Multiply(baseModelViewMatrix, modelViewMatrix);
_normalMatrix = GLKMatrix3InvertAndTranspose(GLKMatrix4GetMatrix3(modelViewMatrix), NULL);
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
}
However, this is where I get really confused-- it's not at all clear how I could modify this method to do transforms to one VBO or the other. It's not even clear that th above code is making any reference to one particular buffer at all.
Eventually I would like to expand my game by moving the code for each game object into an instance of a custom class, which would handle the transforms, etc. But I would like to know if I'm completely misguided in my approach before doing so.
In case this is helpful to anyone having similar issues, I found the answers I was looking for on Ian Terrell's excellent blog, Games by Ian Terrell.
In particular, this tutorial and its accompanying sample code were exactly what I needed to get a grip on this very complicated subject. Hope this helps!
GLKMatrix4 _modelViewProjectionMatrix[5]; // Al inicio
En - (void)update utiliza
GLKMatrix4 projectionMatrix = GLKMatrix4MakeOrtho(-1.0f, 1.0f, -1.0f / aspect, 1.0f / aspect, -10.0f, 10.0f);
for (int i=0; i<5;i++) {
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeTranslation(i*0.2+ 0.3f, 0.0f, 0.0f);
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeZRotation(0.0 - _rotation));
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeXRotation(0.0 - _rotation));
modelViewMatrix = GLKMatrix4Multiply(modelViewMatrix, GLKMatrix4MakeYRotation(0.20 - _rotation));
_modelViewProjectionMatrix[i] = GLKMatrix4Multiply(projectionMatrix, modelViewMatrix);
}