Changing OpenGL vertex attributes in a sample - c

I am using this tutorial / sample to do some basic object tracking on the iPhone. Everything works fine, I even tweaked the performance a whole lot, but I am still stuck with one problem.
The basic problem is that I do not understand OpenGL well enough and I should be punished for shamefully taking sample code and turning it into something that works for me. As a matter of fact I am being punished;
The sample shows how to render (with shaders) the iPhone's camera into an offscreen texture in order to be able to process it and show it on screen. Now I have figured out that it draws the texture/layer using an array of vertex attributes (a principle I barely understand, despite my Google searches).
The vertex array's are as follows:
static const GLfloat squareVertices[] = {
-1.0f, -1.0f,
1.0f, -1.0f,
-1.0f, 1.0f,
1.0f, 1.0f,
};
static const GLfloat textureVertices[] = {
1.0f, 1.0f,
1.0f, 0.0f,
0.0f, 1.0f,
0.0f, 0.0f,
};
I have also figured out that these vertex attributes can alter the orientation of the drawn texture. The texture is now drawn in portrait, which means that if I keep my iPhone in landscape (which I desire), and let the views rotate along, everything I see on the screen is a camera with a 90 degree angle.
I think I narrowed the problem down enough to blame these vertexes and I have been messing around with their values somewhat but without any acceptable result.
Is there anybody out there who can help me draw the texture in landscape?
P.S: if I inverse the values of 'squareVerticles' I am able to get a 180 degree rotated picture. But I want the texture to be rotated 90 degrees, not 180.

Imagine that your screen has normalized coordinates that go from -1.0,-1.0 (left, bottom) to 1.0, 1.0. The first array specifies the coordinates of the vertices of a square (presumably as a triangle strip, because they are given in a "Z" fashion).
The second array specifies the texture coordinates. Same thing, except that they are in the 0.0, 1.0 range.
So, to rotate 90 degrees clockwise:
1.0f, 0.0f
0.0f, 0.0f
1.0f, 1.0f
0.0f, 1.0f
anticlockwise:
0.0f, 1.0f
1.0f, 1.0f
0.0f, 0.0f
1.0f, 0.0f
I hope that works!

Related

OpenGL Try to draw square but its display a rectangle

I try to draw a simple square by OpenGL but the result its display a rectangle. I guess that the problem is in the reshape function but I have no idea why (I'm new to OpenGL).
I what to keep aspect when I resize the window, that is not to stretch or shrink my image.
image screenshot
my reshape function
#define WINDOW_W 640
#define WINDOW_H 480
void reshape(int width, int height) {
if (height == 0)
height = 1;
GLfloat aspect = (GLfloat)width / (GLfloat)height;
glViewport(0, 0, (GLsizei)width, (GLsizei)height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (width >= height)
gluOrtho2D(0.0f, (GLdouble)WINDOW_W * aspect, (GLdouble)WINDOW_H, 0.0f);
else
gluOrtho2D(0.0f, (GLdouble)WINDOW_W, (GLdouble)WINDOW_H / aspect, 0.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
my draw function
void display(void) {
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT);
glLoadIdentity();
// x=50 y=50 w=100 h=100 a square
glBegin(GL_QUADS);
glVertex2i(50, 50);
glVertex2i(50, 150);
glVertex2i(150, 150);
glVertex2i(150, 50);
glEnd();
glutSwapBuffers();
}
Right now, your "square" will always be exactly 1.3333 (640 / 480) times as tall as it is wide, because while you do take the actual window size into account and compute the actual aspect ratio given the actual window size, you multiply that with 640 for the width and 480 for the height, for whatever reason.
And that won't work since that will always stretch your actual aspect ratio by a factor of 1.3333 making your square always 1.3333 as tall as it is wide.
To solve this, just multiply the arguments to the gluOrtho2D() call with the same value, depending on what the extent in your world space or "view space" should be for a square view space with a square aspect ratio.

Reading in a list of csv floats with a prefix in C++

I am trying to read in a list of floats formatted like the example below from a file and into a vector, and print them back out again. Is there a way to modify the stream or the iterator to drop the 'f' that indicates float and correctly parse the data with minimal changes?
1.5f, 2.0f, 4.0f, 1.0f, 1.0f, 2.0f, 4.0f, 2.0f, 1.0f, 0.0f, 0.0f, 1.0f, 9.0f
Code here
std::ifstream infile("matrices.txt");
std::string s;
std::vector<float> A;
std::getline(infile,s,'\n');
std::stringstream mss(s);
std::copy(std::istream_iterator<float>( mss ), std::istream_iterator<float>(),std::back_inserter(A));
std::copy(A.begin(), A.end(), std::ostream_iterator<float>(std::cout, ", "));
You can request stringstream to ignore 2 characters every time a float is extracted.
float x{};
while (!mss.eof())
{
mss >> x;
mss.ignore(2);
vfloats.push_back(x);
}

Half cylinder/Closed cylinder in opengl

I currently have a cylinder
glPushMatrix();
glTranslatef(cylinder->pos[0], cylinder->pos[1], cylinder->pos[2]);
glRotatef(cylinder->angle, -1.0, 0, 0);
gluDisk(quad, 0.0, cylinder->radius, 300, 90);
gluCylinder(quad, cylinder->radius, cylinder->radius, cylinder->height, 30, 1);
gluDeleteQuadric(quad);
glPopMatrix();
but it only renders half of a cylinder instead of the whole thing (the half coming towards the view). Second issue is I don't know how to close the cylinder. The gludisk only closes the bottom of the cylinder and I'm not sure how to close the top side.
If I understand what you're describing, it sounds like you might have back face culling enabled. Do you have a glEnable(GL_CULL_FACE) call in your code? This will eliminate all polygons that face away from you. In any case, once you draw a cylinder that is closed at both sides, it will be fine to keep it enabled.
You can close the cylinder at the top with another gluDisk() call, after applying a translation that moves it to (0, 0, height). For correctness, I believe you need to rotate the disk that closes the cylinder at the bottom. Otherwise it will face to the inside of the cylinder instead of to the outside, which affects the normals, and would get it eliminated by back face culling when it should be visible.
For the full thing, it should look something like this (untested):
glPushMatrix();
glTranslatef(cylinder->pos[0], cylinder->pos[1], cylinder->pos[2]);
glRotatef(cylinder->angle, -1.0f, 0.0f, 0.0f);
gluCylinder(quad, cylinder->radius, cylinder->radius, cylinder->height, 30, 1);
glPushMatrix();
glTranslatef(0.0f, 0.0f, cylinder->height);
gluDisk(quad, 0.0f, cylinder->radius, 30, 1);
glPopMatrix();
glRotatef(180.0f, 1.0f, 0.0f, 0.0f);
gluDisk(quad, 0.0f, cylinder->radius, 30, 1);
gluDeleteQuadric(quad);
glPopMatrix();

Orthographic Camera Projection matrix

The goal
I'm trying to implement an orthographic camera for 2D rendering with OpenGL.
The issue
Nothing is drawn to the screen.
The setup
Each frame I am updating the camera using this call:
updateCamera(&gCamera, -10.0f, 10.0f, 0.0f, 10.0f, 1.0f, -1.0f);
The updateCamera method has the following declaration:
void updateCamera(Camera* cam, float top, float bottom, float left, float right, float zFar, float zNear);
The camera struct simply has a float opm[4][4] member which represents the matrix.
The updateCamera method has the following implementation:
cam->opm[0][0] = 2.0f / (right - left);
cam->opm[1][1] = 2.0f / (top - bottom);
cam->opm[2][2] = -2.0f / (zFar - zNear);
cam->opm[3][0] = -(right + left) / (right - left);
cam->opm[3][1] = -(top + bottom) / (top - bottom);
cam->opm[3][2] = -(zFar + zNear) / (zFar - zNear);
cam->opm[3][3] = 1.0f;
Everything is drawn correctly if I use an identity matrix instead of the one above. Perhaps there is an issue in my calculation of the matrix?
The problem lies in the definition of the vertices and the call to updateCamera.
The triangle is so small that it is not drawn with those parameters.
Using the following draw call:
updateCamera(&gCamera, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f);
everything works.
Use an identity matrix first to find out if drawing works - then add scaling and translation.

Rotate object around another object

I drew two rectangles in my scene, and now I'm trying to rotate one rectangle around the other.
When I press the "Left key" my first rectangle moves in direction to the other, but I don't have the effect of rotate because it is only moving in a straight line in direction of the other rectangle.
How do I change the Z direction of the first rectangle?
tl;dr: It's like a solar system, but I don't understand how can I have the depth effect.
I'm using GLUT and OpenGL.
EDIT: More Info:
This is my current code (function that shows the scene):
void RenderScene(void){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 0.0f, 0.0f);
glPushMatrix();
glTranslatef(-70.0f, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(xCor, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glFlush();
}
And a image to help:
Please enable depth test to hide objects beyond other objects.
Give a high value z vaue for the far object.
glEnable( GL_DEPTH_TEST );
glClear( GL_COLOR_BUFFER_BIT |GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(-70.0f, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -25.0f);
glPopMatrix();
glColor3f(1.0f, 1.0f, 0.0f);
glPushMatrix();
glTranslatef(xCor, 0.0f, 0.0f);
glRectf(-25.0f, 25.0f, 25.0f, -26.0f); // Z value of behind object is set far from eye
glPopMatrix();
What you want to do is moderately complicated.
The only way I know to locate rectangles in 3-space is to build them using glVertex3f() like this:
glBegin(GL_QUADS);
glVertex3f(x0, y0, z0);
glVertex3f(x1, y1, z1);
glVertex3f(x2, y2, z2);
glVertex3f(x3, y3, z3);
glEnd();
Your "solar system" will have to be located in screen coordinates: X->left/right, Y->up/down, Z->into/out of screen. To create the effect of orbiting, you'll have to recalculate all four X and Z for each movement increment.
I also suggest using gluLookAt() if you want to see a different view.
The man page for glPerspective() says that zNear is always positive but you've given it a negative number. I'd leave that line commented out until I saw some orbiting.
HTH.

Resources