OpenGL ES 2.0 Grid Lines With Triangle Strip - opengl-es-2.0

I need to draw a 10 x 10 grid in OpenGL ES 2.0. Are triangle strips the best way to do this? How do you draw this without drawing the diagonal lines? All of the searches that I come up with show grid lines with the diagonals drawn, but this defeats the purpose.
I've drawn the grid just using a bunch of lines, but I'm having trouble transforming it as a unit. Is this the right approach, but I'm not executing it correctly? Or is there a better way, like triangle strips? Thanks!
// draw the horizontal gridlines
for (i=0; i<12; i++) {
modelViewMatrixRight = GLKMatrix4MakeTranslation(0.0f, 1.0f/11.0f*(float)i - 0.5f, -2.0f);
// modelViewMatrixRight = GLKMatrix4Rotate(modelViewMatrixRight, GLKMathDegreesToRadians(-45.0f), 0.0f, 0.0f, 1.0f);
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrixRight, modelViewMatrixRight);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glUniform4fv(uniforms[UNIFORM_COLOR_VECTOR], 1, _color);
glBindVertexArrayOES( [my_line[i] getVertexArray] ); // make this line the current object
[my_line[i] render];
}
// draw the vertical gridlines
for (i=12; i<24; i++) {
modelViewMatrixRight = GLKMatrix4MakeTranslation(0.5f - 1.0f/11.0f * (float) (i-12), 0.0f, -2.0f);
modelViewMatrixRight = GLKMatrix4Rotate(modelViewMatrixRight, GLKMathDegreesToRadians(90.0f), 0.0f, 0.0f, 1.0f);
modelViewMatrixRight = GLKMatrix4Rotate(modelViewMatrixRight, GLKMathDegreesToRadians(60.0f), 1.0f, 0.0f, 1.0f);
_modelViewProjectionMatrix = GLKMatrix4Multiply(projectionMatrixRight, modelViewMatrixRight);
glUniformMatrix4fv(uniforms[UNIFORM_MODELVIEWPROJECTION_MATRIX], 1, 0, _modelViewProjectionMatrix.m);
glUniformMatrix3fv(uniforms[UNIFORM_NORMAL_MATRIX], 1, 0, _normalMatrix.m);
glUniform4fv(uniforms[UNIFORM_COLOR_VECTOR], 1, _color);
glBindVertexArrayOES( [my_line[i] getVertexArray] ); // make this line the current object
[my_line[i] render];
}

Related

Passing attributes to shader

I am using OPEN GL ES2.0 on Android.
I need pass two attributes to shader, one for position, one for texture coordinates,
//vertices for position
vertices = new float[12] { -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f, -1.0f, 1.0f };
//vertices for texture coordinates.
txtVertices = new float[12] { 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 1.0f, 0.0f, 1.0f };
//Passing to shader.
glVertexAttribPointer(texCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
txtVertices);
glVertexAttribPointer(vPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(vPositionHandle);
glEnableVertexAttribArray(texCoordHandle);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(vPositionHandle);
glDisableVertexAttribArray(texCoordHandle);
What's the problem of this piece of code? it's like the second one override the first one, and only one vertices are passed into my shader.
it seems that ther is no error in the code you posted. may have errors in shaders or in some other part
don't you pass 3 floats for vertexposition(x,y,z)

Draw multiple objects with textures

I want to draw cubes using textures.
void OperateWithMainMatrix(ESContext* esContext, GLfloat offsetX, GLfloat offsetY, GLfloat offsetZ) {
UserData *userData = (UserData*) esContext->userData;
ESMatrix modelview;
ESMatrix perspective;
//Manipulation with matrix
...
glVertexAttribPointer(userData->positionLoc, 3, GL_FLOAT, GL_FALSE, 0, cubeFaces);
//in cubeFaces coordinates verticles cube
glVertexAttribPointer(userData->normalLoc, 3, GL_FLOAT, GL_FALSE, 0, cubeFaces);
//for normals (use in fragment shaider for textures)
glEnableVertexAttribArray(userData->positionLoc);
glEnableVertexAttribArray(userData->normalLoc);
// Load the MVP matrix
glUniformMatrix4fv(userData->mvpLoc, 1, GL_FALSE,
(GLfloat*)&userData->mvpMatrix.m[0][0]);
//Bind base map
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, userData->baseMapTexId);
//Set the base map sampler to texture unit to 0
glUniform1i(userData->baseMapLoc, 0);
// Draw the cube
glDrawArrays(GL_TRIANGLES, 0, 36);
}
(coordinates transformation is in OperateWithMainMatrix() )
Then Draw() function is called:
void Draw(ESContext *esContext)
{
UserData *userData = esContext->userData;
// Set the viewport
glViewport(0, 0, esContext->width, esContext->height);
// Clear the color buffer
glClear(GL_COLOR_BUFFER_BIT);
// Use the program object
glUseProgram(userData->programObject);
OperateWithMainMatrix(esContext, 0.0f, 0.0f, 0.0f);
eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
}
This work fine, but if I try to draw multiple cubes (next code for example):
void Draw(ESContext *esContext)
{ ...
// Use the program object
glUseProgram(userData->programObject);
OperateWithMainMatrix(esContext, 2.0f, 0.0f, 0.0f);
OperateWithMainMatrix(esContext, 1.0f, 0.0f, 0.0f);
OperateWithMainMatrix(esContext, 0.0f, 0.0f, 0.0f);
OperateWithMainMatrix(esContext, -1.0f, 0.0f, 0.0f);
OperateWithMainMatrix(esContext, -2.0f, 0.0f, 0.0f);
eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
}
A side faces overlapes frontal face. This process is illustrated on image:
Alternate picture (with colours and clean image):
The side face of the right cube overlaps frontal face of the center cube.
How can i remove this effect and display miltiple cubes without it?
To fix this you need to utilize what's known as the depth buffer. This is what's responsible for making sure that surfaces don't get drawn overtop of surfaces that are nearer (like the side of a cube showing over the front of a cube).
Luckily it's not much work involved to do so:
Enable depth testing at initialization with glEnable(GL_DEPTH_TEST)
Clear depth buffer on each frame by adding it's bit to the glClear call:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
After this you should no longer see your surfaces popping on top of nearer surfaces.

CGContextAddEllipse - overlapping get's clipped - Quartz

I like to draw a glass with a few Elements
- Top Ellipse
- Bottom Ellipse
- and the Lines Inbetween
Next, it should be filled with a Gradient. The Elements work, but at the point, where the middle of the glass comes in touch with the top or bottom ellipse the area get's clipped.
- (void)drawRect:(CGRect)rect
{
CGPoint c = self.center;
// Drawing code
CGContextRef cx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(cx, 1.0);
[[UIColor whiteColor] setStroke];
// DrawTheShapeOfTheGlass
CGContextBeginPath(cx);
// Top and Bottom Ellipse
CGContextAddEllipseInRect(cx, CGRectMake(0, 0, 100, 20));
CGContextAddEllipseInRect(cx, CGRectMake(10, 90, 80, 20));
// Define the points for the Area inbetween
CGPoint points[] = { {0.0,10.0},{10.0,100.0},{90.0,100.0},{100.0,10.0} };
CGContextAddLines(cx, points, 4);
CGContextClosePath(cx);
// Clip, that's only the Clipped-Area wil be filled with the Gradient
CGContextClip(cx);
// CreateAndDraw the Gradient
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat colorSpace[] = {1.0f, 1.0f, 1.0f, 0.0f,
0.0f, 0.0f, 1.0f, 1.0f };
CGFloat locations[] = { 0.0, 1.0 };
CGGradientRef myGradient = CGGradientCreateWithColorComponents(rgbColorSpace, colorSpace, locations, 2);
CGPoint s = CGPointMake(0, 0);
CGPoint e = CGPointMake(100, 100);
CGContextDrawLinearGradient(cx, myGradient, s, e, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);
CGColorSpaceRelease(rgbColorSpace);
CGGradientRelease(myGradient);
}
Here how it looks like:
Is there any possibility to "fill" the whole ellipse? I played around with BlendModes but it didn't help.
Thanks
Try replacing the points[] initialization code with the following...
CGPoint points[] = {{0.0,10.0},{100.0,10.0},{90.0,100.0},{10.0,100.0}};
CoreGraphics uses the non-zero winding count rule to determine how to fill a path. Since ellipses are drawn clockwise and your trapezoid was drawn counter clockwise, the overlapping regions were not filled. Changing the drawing order of the trapezoid to clockwise will result in an object that is completely filled.

How to use GLKMatrixStack?

I'm writing an iOS game that draws many cubes on screen, but I have a problem with positioning the cubes.
I have a function draw_voxel that draws a cube:
void draw_voxel(Point location, Color color, GLKMatrixStackRef stack) {
GLKMatrixStackPush(stack);
GLKMatrixStackTranslate(stack, location.x, location.y, location.z);
std::array<Color, 36> triangle_colors;
triangle_colors.fill(color);
glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 0, static_cast<const GLvoid*>(triangle_vertices.data()));
glEnableVertexAttribArray(GLKVertexAttribColor);
glVertexAttribPointer(GLKVertexAttribColor, 4, GL_FLOAT, GL_FALSE, 0, static_cast<const GLvoid*>(triangle_colors.data()));
glDrawArrays(GL_TRIANGLES, 0, 36);
glDisableVertexAttribArray(GLKVertexAttribPosition);
glDisableVertexAttribArray(GLKVertexAttribColor);
GLKMatrixStackPop(stack);
}
I pass it a GLKMatrixStackRef, push the current matrix on top and use GLKMatrixStackTranslate to translate the top matrix. However, all cubes are still drawn at (0, 0, 0).
I call draw_voxel like this:
[self.effect prepareToDraw];
GLKMatrixStackRef stack = GLKMatrixStackCreate(nullptr);
draw_voxel(Point(-1.0f, 0.0f, 0.0f), Color(1.0f, 0.0f, 0.0f, 1.0f), stack);
draw_voxel(Point(+0.0f, 0.0f, 0.0f), Color(0.0f, 1.0f, 0.0f, 1.0f), stack);
draw_voxel(Point(+1.0f, 0.0f, 0.0f), Color(0.0f, 0.0f, 1.0f, 1.0f), stack);
CFRelease(stack);
I couldn't find any useful information on the internet about GLKit matrix stacks, and I'm really stuck. How do I "apply" the top matrix so that the cubes are translated?
While I still haven't fully grasp how to use GLKMatrixStack, looking at your code I think the problem is that you are not passing the top matrix of the stack to the shader, or, in GLKit words, you are not properly configuring the effect.
Probably, at some point you should be doing something like:
self.effect.transform.modelviewMatrix = GLKMatrixStackGetMatrix4(stack);
Hope this help, I'm stuck on that stack too :)

Unusual Lighting Effects - Random Polygons Coloured

I am working on creating an object loader for use with iOS, I have managed to load the vertices, normals and face data from and OBJ file, and then place this data into arrays for reconstructing the object. But I have come across an issue with the lighting, at the bottom is a video from the simulation of my program - this is with the lighting in the following position:
CGFloat position[] = { 0.0f, -1.0f, 0.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_POSITION, position);
This is specified in both the render method each frame and the setup view method which is called once at setup.
Various other lighting details are here, these are called once during setup:
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
CGFloat ambientLight[] = { 0.2f, 0.2f, 0.2f, 1.0f };
CGFloat diffuseLight[] = { 1.0f, 0.0f, 0.0, 1.0f };
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
CGFloat position[] = { 0.0f, -1.0f, 0.0f, 0.0f };
glLightfv(GL_LIGHT0, GL_POSITION, position);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_NORMALIZE);
The video of the issue can be found here:
http://youtu.be/dXm4wqzvO5c
Thanks,
Paul
[EDIT]
for further info normals are also supplied by the following code, they are currently in a large normals array or XYZ XYZ XYZ etc...
// FACE SHADING
glColorPointer(4, GL_FLOAT, 0, colors);
glEnableClientState(GL_COLOR_ARRAY);
glNormalPointer(GL_FLOAT, 3, normals);
glEnableClientState(GL_NORMAL_ARRAY);
glDrawArrays(GL_TRIANGLES, 0, 3*numOfFaces);
glDisableClientState(GL_COLOR_ARRAY);
I now feel incredibly stupid... All part of being a student programmer I guess. I will leave an answer to this so if anyone else gets this problem they can solve it too! The mistake was simply down to a typo:
glNormalPointer(GL_FLOAT, 3, normals);
Should have read
glNormalPointer(GL_FLOAT, 0, normals);
The second argument being the STRIDE which is only used if the array contains other values e.g. Vert Coords / Normals / Texture Coords. As mine are in single arrays the stride between the values should be 0.