OpenGL Vertex array not displaying properly - c

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).

Related

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: 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).

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.

OpenGL Lighting struggles

I'm in the middle of a project teaching the basics of OpenGL. I've got most of the requirements working fine in terms of camera rotation, translation etc. However I'm struggling a lot with the lighting.
This picture is a comparison of my current program (left) vs the sample solution (right).
In case you can't tell, I'm getting very monochrome colours on the truck. The shadows are very sharp and dark, the high points are singly coloured instead of specular.
The project calls for the use of textures; the one I've shown here is a basic texture of plain grey pixels but i could use any texture (including the beach sand one being used for the ground).
I'm drawing the object from a mesh:
GLfloat ambient[] = {0.1, 0.1, 0.1, 1};
GLfloat diffuse[] = {0.1, 0.1, 0.1, 1};
GLfloat specular[] = {1.0, 1.0, 1.0, 1.0};
GLfloat shine = 100.0;
glMaterialfv(GL_FRONT, GL_AMBIENT, ambient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, specular);
glMaterialf(GL_FRONT, GL_SHININESS, shine);
glEable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, textureNumber);
glBegin(GL_TRIANGLES);
for (int i = 0; i < meshes[n]->nTriangles; i++) {
for (int j = 0; j < 3; j++) {
glNormal3fv(mesh -> normals[mesh->triangles[i][j]]);
glTexCoord2fv(mesh->texCoords[mesh->triangles[i][j]]);
glVertex3fv(mesh -> vertices[mesh->triangles[i][j]]);
}
}
glEnd();
There is one light in the scene:
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST)
GLfloat diffuse0[]={1.0, 1.0, 1.0, 1.0};
GLfloat ambient0[]={1.0, 1.0, 1.0, 1.0};
GLfloat specular0[]={1.0, 1.0, 1.0, 1.0};
GLfloat light0_pos[]={1.0, 1.0, 1,0, 1.0};
glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
glLightfv(GL_LIGHT0, GL_AMBIENT, ambient0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0);
glLightfv(GL_LIGHT0, GL_SPECULAR, specular0);
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0);
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0);
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 2.0);
Is there something major that I'm missing that could be causing this severe difference? Particular values I should play with? Or a glEnable call I've missed?
Any help, advice or pointers to elsewhere much appreciated.
To eliminate the sharp drop-off, amp up the ambient light. There's no global illumination model in OpenGL so that parameter has absolutely no effect beyond being the colour the face will be if no other light falls upon it.
Since you're using glVertex-type calls, I'll go out on a limb and guess you're using the fixed functionality pipeline? If so then lighting is calculated at vertices, then interpolated across polygon surfaces. That means that specular highlights don't work very well on 'large' polygons — roughly speaking, the highlight can't appear in the middle of a polygon. GPUs with programmable pipelines (which includes the ones in mobile phones nowadays) can calculate lighting per pixel instead of per vertex but OpenGL doesn't do this for you, so you'd need to delve into shader programming yourself. Or just ensure that your model is made up of small enough polygons.
Your shininess exponent is also quite high - have you tried dialling that down a few notches?
when looking at the background, it looks like a spotlight on the right just bathing the Scene into warm light, and a Flakscheinwerfer on the left basking everything in extreme lightning, eliminating every shadow

OpenGL - drawing 2D polygons shapes with texture

I am trying to make a few effects in a C+GL game. So far I draw all my sprites as a quad, and it works.
However, I am trying to make a large ring appear at times, with a texture following that ring, as it takes less memory than a quad with the ring texture inside.
The type of ring I want to make is not a round-shaped GL mesh ring (the "tube" type) but a "paper" 2D ring. That way I can modify the "width" of the ring, getting more of the effect than a simple quad+ring texture.
So far all my attempts have been...kind of ridiculous, as I don't understand GL's coordinates too well (and I can't really understand the available documentation...I am just a designer with no coder help or background. A n00b, basically).
glBegin(GL_POLYGON);
for(i = 0;i < 360; i += 10){
glTexCoord2f(0, 0);
glVertex2f(Cos(i)*(H-10),Sin(i)*H);
glTexCoord2f(0, HP);
glVertex2f(Sin(i)*(H-10),Cos(i)*(H-10));
glTexCoord2f(WP, HP);
glVertex2f(Cos(i)*H,Sin(i)*(H-10));
glTexCoord2f(WP, 0);
glVertex2f(Sin(i)*H,Cos(i)*H);
}
glEnd();
This is my last attempt, and it seems to generate a "sunburst" from the right edge of the circle instead of a ring. It's an amusing effect but definitely not what I want. Other results included the circle looking exactly the same as the quad textured (aka drawing a sprite literally) or something that looked like a pop-art filter, by working on this train of thought.
Seems like my logic here is entirely flawed, so, what would be the easiest way to obtain such a ring? No need to reply in code, just some guidance for a non-math-skilled user...
Edit: A different way to word what I want, would be a sequence of rotated rectangles connected to each other, forming a low-resolution ring.
So you want an annulus? That is, the area between two circles with the same center but different radii? I'd try a quad strip like this:
glBegin(GL_QUAD_STRIP);
for(i = 0; i <= 360; i += 10){
glTexCoord2f(WP*i/360, 0);
glVertex2f(Cos(i)*(H-10),Sin(i)*(H-10));
glTexCoord2f(WP*i/360, HP);
glVertex2f(Cos(i)*H,Sin(i)*H);
}
glEnd();
Each quad is a 10-degree sector of the ring. Note that if you want to draw N quads in a strip, it takes 2*(N+1) points, so we draw a total of 2*(36+1) = 74 points.
The post here on the OpenGL forums seems to do what you want. An overview of the approach:
If you want a circle filed with a
texture, you can use triangle fan.
First, draw the vertex at the center
of the circle. Then draw the vertex on
the contour of the circle, use
cos(angle)*radius for x and
sin(angle)*radius for y. Since texture
coordinates s and t are in the range
[0 1] => s = (cos(angle)+1.0)*0.5 and
t = (sin(angle)+1.0)*0.5 . The texture
coordinate for the vertex at the
center of the circle is (0.5,0.5).
GLvoid draw_circle(const GLfloat radius,const GLuint num_vertex)
{
GLfloat vertex[4];
GLfloat texcoord[2];
const GLfloat delta_angle = 2.0*M_PI/num_vertex;
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texID);
glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
glBegin(GL_TRIANGLE_FAN);
//draw the vertex at the center of the circle
texcoord[0] = 0.5;
texcoord[1] = 0.5;
glTexCoord2fv(texcoord);
vertex[0] = vertex[1] = vertex[2] = 0.0;
vertex[3] = 1.0;
glVertex4fv(vertex);
for(int i = 0; i < num_vertex ; i++)
{
texcoord[0] = (std::cos(delta_angle*i) + 1.0)*0.5;
texcoord[1] = (std::sin(delta_angle*i) + 1.0)*0.5;
glTexCoord2fv(texcoord);
vertex[0] = std::cos(delta_angle*i) * radius;
vertex[1] = std::sin(delta_angle*i) * radius;
vertex[2] = 0.0;
vertex[3] = 1.0;
glVertex4fv(vertex);
}
texcoord[0] = (1.0 + 1.0)*0.5;
texcoord[1] = (0.0 + 1.0)*0.5;
glTexCoord2fv(texcoord);
vertex[0] = 1.0 * radius;
vertex[1] = 0.0 * radius;
vertex[2] = 0.0;
vertex[3] = 1.0;
glVertex4fv(vertex);
glEnd();
glDisable(GL_TEXTURE_2D);
}

Resources