Orthographic Camera Projection matrix - c

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.

Related

OpenGL Vertex array not displaying properly

I have an OpenGL Graphics assignment and well for some reason I'm trying to create a flat square on the X,Z plane (Y is just 1.0 for every vertices). I've tried making the problem smaller by just trying to create 2 flat vertices instead of four, and for some reason 2 of the vertices always seem to go wayyy into the negative y direction.
glMaterialfv(GL_FRONT, GL_DIFFUSE, drone_mat_diffuseBUILDING);
glEnableClientState(GL_VERTEX_ARRAY);
float buildingsize = 8 * floors + 4;
GLfloat quadV[300];
quadV[0] = -6.5;
printf("%.5f", quadV[0]);
quadV[1] = 1.0;
printf("%.5f", quadV[1]);
quadV[2] = 8.5;
printf("%.5f", quadV[2]);
quadV[3] = -6.5;
printf("%.5f", quadV[3]);
quadV[4] = 1.0;
printf("%.5f", quadV[4]);
quadV[5] = -7.5;
printf("%.5f", quadV[5]);
glVertexPointer(3, GL_FLOAT, 0, quadV);
glDrawArrays(GL_POLYGON, 0, buildingsize);
glDisableClientState(GL_VERTEX_ARRAY);here
Here's what it looks like when ran:
The red line should be a flat line on the X Z plane.
For further simplicty, I'm trying to convert this code:
glBegin(GL_POLYGON);
glVertex3f(firstCubeXPOS - firstCubeXSCALE/2.0, 1.0, firstCubeZPOS + firstCubeZSCALE/2.0);
glVertex3f(firstCubeXPOS - firstCubeXSCALE / 2.0, 1.0, firstCubeZPOS - firstCubeZSCALE / 2.0);
glVertex3f(firstCubeXPOS + firstCubeXSCALE / 2.0, 1.0, firstCubeZPOS - firstCubeZSCALE / 2.0);
glVertex3f(firstCubeXPOS + firstCubeXSCALE / 2.0, 1.0, firstCubeZPOS + firstCubeZSCALE / 2.0);
glEnd();
glFlush();
Into a vertex array so I can add new elements / modify elements by each vertex. Because as of right now the code right above me shows what I need to see (2d square laying on the XZ plane).

2D Isometric Cube Draw

I want to draw an isometric cube such as below so I can get straight edge lines for 3d graphing. The third pic is an example of what I want - straight lines on the outer cube. From experiment this doesn't work with 3D using a perspective transform.
Off the infographic I tried drawing what would be the bottom square (shear 30, rotate -30) but its still a bit off.
void draw_outer()
{
int ii;
int w, h;
float equiv = 0.0f;
Matrix transform = IDENTITY_MATRIX;
w = glutGet(GLUT_WINDOW_WIDTH);
h = glutGet(GLUT_WINDOW_HEIGHT);
equiv = h/(float)w;
//vert scale
ScaleMatrix(&projection, 1.0f, .861f, 1.0f);
//shear x adjusted for aspect ratio
ConstructShearMatrixX(&projection, .5236f * equiv);
//rotation
//fix aspect ratio
RotateAboutZ(&projection, -.5236f);
ScaleMatrix(&projection, equiv, 1.0f, 1.0f);
glUniformMatrix4fv(uniform_ids[0], 1, GL_FALSE, model.m);
glUniformMatrix4fv(uniform_ids[1], 1, GL_FALSE, view.m);
glUniformMatrix4fv(uniform_ids[2], 1, GL_FALSE, projection.m);
}
My vertex shader is just glPosition = (Projection * View * Model * position.xyz).

openGL(c) draw square

i need to draw a square using c (openGL),
i only have 1 coordinate which is the center of the square (lets say 0.5,0.5) and i need to draw a square ABCD with each side 0.2 length (AB,BC,CD,DA),
I tried using the next function but it does not draw anything for some reson,
void drawSquare(double x1,double y1,double radius)
{
glColor3d(0,0,0);
glBegin(GL_POLYGON);
double locationX = x1;
double locationY = x2;
double r = radius;
for(double i=0; i <= 360 ; i+=0.1)
{
glVertex2d(locationX + radius*i, locationY + radius*i);
}
glEnd();
}
can someone please tell me why its not working\point me to the right direction (i do not want to draw polygon with 4 coordinated normally, but with only 1 coordinate with a givven radius,
thanks!
Your code will not even draw a circle. If anything, it will draw a diagonal line extending out of the view area very quickly. A circle plot would need to use sine and cosine, based on the radius and angle.
I have not tried this code, but it needs to be more like this to draw a square.
void drawSquare(double x1, double y1, double sidelength)
{
double halfside = sidelength / 2;
glColor3d(0,0,0);
glBegin(GL_POLYGON);
glVertex2d(x1 + halfside, y1 + halfside);
glVertex2d(x1 + halfside, y1 - halfside);
glVertex2d(x1 - halfside, y1 - halfside);
glVertex2d(x1 - halfside, y1 + halfside);
glEnd();
}
There are no normals defined: perhaps I should have travelled counter-clockwise.
Simple way to draw a square is to use GL_QUADS and the four vertices for the four corners of the square. Sample code is below-
glBegin(GL_QUADS);
glVertex2f(-1.0f, 1.0f); // top left
glVertex2f(1.0f, 1.0f); // top right
glVertex2f(1.0f, -1.0f); // bottom right
glVertex2f(-1.0f, -1.0f); // bottom left
glEnd();
Since in the case you have to draw square from the mid point which is interaction of two diagonals of square. You use the following facts and draw the same.
length of diagonal = x*square root of 2 (x=side of square)
diagonals of a square are perpendicular
diagonals of a square are the same length
If your point is at 0.5,0.5 which coordinate of interaction point, and side is 0.2. So you can easily determine the point coordinate of four corners as in the figure given below and code it accordingly.

OpenGL: Wrapping texture around cylinder

I am trying to add textures to a cylinder to draw a stone well. I'm starting with a cylinder and then mapping a stone texture I found here but am getting some weird results. Here is the function I am using:
void draw_well(double x, double y, double z,
double dx, double dy, double dz,
double th)
{
// Set specular color to white
float white[] = {1,1,1,1};
float black[] = {0,0,0,1};
glMaterialfv(GL_FRONT_AND_BACK,GL_SHININESS,shinyvec);
glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,white);
glMaterialfv(GL_FRONT_AND_BACK,GL_EMISSION,black);
glPushMatrix();
// Offset
glTranslated(x,y,z);
glRotated(th,0,1,0);
glScaled(dx,dy,dz);
// Enable textures
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
glBindTexture(GL_TEXTURE_2D,texture[0]); // Stone texture
glBegin(GL_QUAD_STRIP);
for (int i = 0; i <= 359; i++)
{
glNormal3d(Cos(i), 1, Sin(i));
glTexCoord2f(0,0); glVertex3f(Cos(i), -1, Sin(i));
glTexCoord2f(0,1); glVertex3f(Cos(i), 1, Sin(i));
glTexCoord2f(1,1); glVertex3f(Cos(i + 1), 1, Sin(i + 1));
glTexCoord2f(1,0); glVertex3f(Cos(i + 1), -1, Sin(i + 1));
}
glEnd();
glPopMatrix();
glDisable(GL_TEXTURE_2D);
}
// Later down in the display function
draw_well(0, 0, 0, 1, 1, 1, 0);
and the output I receive is
I'm still pretty new to OpenGL and more specifically textures so my understanding is pretty limited. My thought process here is that I would map the texture to each QUAD used to make the cylinder, but clearly I am doing something wrong. Any explanation on what is causing this weird output and how to fix it would be greatly appreciated.
There are possibly three main issues with your draw routine. quad-strip indexing, texture coordinates repeating too often and possible incorrect usage of the trig functions;
Trigonometric functions usually accept values which represent angles expressed in radians and not degrees. Double check what the parameters of the Sin and Cos functions you are using.
Quadstrip indexing is incorrect. Indexing should go like this...
Notice how the quad is defined in a clock-wise fashion, however the diagonal vertices are defined sequentially. You are defining the quad as v0, v1, v3, v2 instead of v0, v1, v2, v3 so swap the last two vertices of the four. This also leads to another error in not sharing the vertices correctly. You are duplicating them along each vertical edge since you draw the same set of vertices (i+1) in one loop, as you do in the next (i.e since i has now been incremented by 1).
Texture coordinates are in the range from 0, 1 for each quad which means you are defining a cylinder which is segmented 360 times and this texture is repeated 360 times around the cylinder. I'm assuming the texture should be mapped 1:1 to the Cylinder and not repeated?
Here is some example code using what you provided. I have reduced the number of segments down to 64, if you wish to still have 360 then ammend numberOfSegments accordingly.
float pi = 3.141592654f;
unsigned int numberOfSegments = 64;
float angleIncrement = (2.0f * pi) / static_cast<float>(numberOfSegments);
float textureCoordinateIncrement = 1.0f / static_cast<float>(numberOfSegments);
glBegin(GL_QUAD_STRIP);
for (unsigned int i = 0; i <= numberOfSegments; ++i)
{
float c = cos(angleIncrement * i);
float s = sin(angleIncrement * i);
glTexCoord2f( textureCoordinateIncrement * i, 0); glVertex3f( c, -1.0f, s);
glTexCoord2f( textureCoordinateIncrement * i, 1.0f); glVertex3f( c, 1.0f, s);
}
glEnd();
N.BYou are using an old version of OpenGL (the use of glBegin/glVertex etc).

Changing OpenGL vertex attributes in a sample

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!

Resources