I have a code below in C++ OpenGL. It has six triangles that form hexagonal.
However, I need to be able to rotate it in vertically.
Can someone help? TNX
Details: I have six independent triangles with vertices. In addition, there is two-dimensional array that is used for colors.
There is a loop starts at line [here] two keep windows rendering until it is exited. Another line at line [here-two] that is used to show all the triangles with their color.
//coordinates of triangle
float triangle[6][9] = {
{
0.0, 0.0, 0.0,
-0.5, 0.87, 0.0,
0.5, 0.87, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, -0.87, 0.0,
0.5, -0.87, 0.0
},
{
0.0, 0.0, 0.0,
0.5, 0.87, 0.0,
1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
0.5, -0.87, 0.0,
1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, 0.87, 0.0,
-1.0, 0.0, 0.0
},
{
0.0, 0.0, 0.0,
-0.5, -0.87, 0.0,
-1.0, 0.0, 0.0
}
};
float color[][9]{
{
255, 0, 0,
255, 0, 0,
255, 0, 0
},
{
0, 255, 0,
0, 255, 0,
0, 255, 0
},
{
0, 0, 255,
0, 0, 255,
0, 0, 255
}
};
int count = 0;
/* Loop until the user closes the window */ [here] while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
[here-two] for (int i = 0; i < 6; i++)
{
//Render OpenGL here
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, triangle[i]);
glColorPointer(3, GL_FLOAT, 0, color[count]);
glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
count++;
if (count > 2) count = 0;
}
//Swap front and back buffers
glfwSwapBuffers(window);
//Poll for and process events
glfwPollEvents();
// Poll for and process events
glfwPollEvents();
}
Read up on the use of matrices. What most games do in this case is they apply a matrix in the shader (as a uniform variable) that will rotate the object. In this case, you would create a rotation matrix of angle x, pass it to the shader, and then every new frame increment x and pass it to the shader again.
For more information on the specifics of the implementation read these:
https://www.opengl.org/wiki/Uniform_(GLSL) - Creating uniform
variables in a shader and updating them
http://inside.mines.edu/fs_home/gmurray/ArbitraryAxisRotation/ -
Creating a matrix that will rotate a vertex.
And a tip with matrix operations: remember to apply them in the right order. If you want to get the object to rotate around it's centre, make sure the rotation matrix is applied first and that the origin of your mesh is it's centre.
Related
As the title says I'm tyring to model a simple giraffe out of arraycubes in open GL wiht C++, now I got the concepts done, but ran into an issue, when I start on the neck for some reaosn I lose 5 out of the 6 faces of my cube, the example I'm following doesn't result in this. I linked a small video below to show the visual result and I'm wondering what might be causing this. If there's an easier way to go about this as well please do let me know.
Visual Result
Code Sample
#include <glut.h>
float angle[4];
GLfloat corners[8][3] = { {-0.5,0.5,-0.5},{0.5,0.5,-0.5},
{0.5,-0.5,-0.5},{-0.5,-0.5,-0.5},
{-0.5,0.5,0.5},{0.5,0.5,0.5},
{0.5,-0.5,0.5},{-0.5,-0.5,0.5} };
void drawFace(int a, int b, int c, int d) {
glBegin(GL_POLYGON);
glVertex3fv(corners[a]);
glVertex3fv(corners[b]);
glVertex3fv(corners[c]);
glVertex3fv(corners[d]);
glEnd();
}
void ArrayCube() {
glColor3f(1.0, 1.0, 1.0);
drawFace(0, 3, 2, 1);
glColor3f(1.0, 1.0, 1.0);
drawFace(3, 0, 4, 7);
glColor3f(1.0, 1.0, 1.0);
drawFace(2, 3, 7, 6);
glColor3f(1.0, 1.0, 1.0);
drawFace(1, 2, 6, 5);
glColor3f(1.0, 1.0, 1.0);
drawFace(4, 5, 6, 7);
glColor3f(1.0, 1.0, 1.0);
drawFace(5, 4, 0, 1);
}
void LowerNeck()
{
glPushMatrix();
glTranslatef(0.5, 0.25, -0.125);
glScalef(0.0, 0.5, 0.25);
ArrayCube();
glPopMatrix();
}
void MainBody()
{
glPushMatrix();
glScalef(1.25, 0.25, 0.5);
ArrayCube();
glPopMatrix();
}
void DrawGiraffe()
{
glRotatef(angle[0], 0.0, 1.0, 0.0);
MainBody();
LowerNeck();
}
void rotate() {
angle[0] += 1.0;
if (angle[0] > 360) angle[0] -= 360;
glutPostRedisplay();
}
void display() {
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.6, 0.6, 0.6, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
DrawGiraffe();
glutSwapBuffers();
}
void init() {
glClearColor(0.0, 0.0, 0.0, 0.0);
glColor3f(1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 2.5);
}
int main(int argc, char** argv) {
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(500, 500);
glutInitWindowPosition(0, 0);
glutCreateWindow("Basic 3D");
glutDisplayFunc(display);
init();
glutIdleFunc(rotate);
glutMainLoop();
}
For the second object (the neck) you apply a scale transformation on x that scales the x component of all the following drawn vertices to 0.0:
glScalef(0.0, 0.5, 0.25);
That 0.0 should've probably been a 1.0.
That's the reason you only see one quad in the render video: That's the quad/face (actually two faces) which still have a dimension in Y and Z. The faces that have a dimension on x are squished to degenerate quads and not displayed at all.
I have 3 rectangles and I need to place them in shape of podium. At this moment they look like this:
Code of display func:
glPushMatrix();
glRotated(rotate_x, 1.0, 0.0, 0.0);
glRotated(rotate_y, 0.0, 1.0, 0.0);
glScalef(1, 3, 1);
glColor3fv(gold);
glutSolidCube(2);
glPopMatrix();
glPushMatrix();
glTranslated(2, 0, -3);
glRotated(rotate_x, 1.0, 0.0, 0.0);
glRotated(rotate_y, 0.0, 1.0, 0.0);
glScalef(1, 2, 1);
glColor3fv(silver);
glutSolidCube(2);
glPopMatrix();
glPushMatrix();
glTranslatef(-2, 0, 0);
glScalef(1, 1, 1);
glRotated(rotate_x, 1.0, 0.0, 0.0);
glRotated(rotate_y, 0.0, 1.0, 0.0);
glColor3fv(bronze);
glutSolidCube(2);
glPopMatrix();
When I try to move silver rectangle a liitle bit down to make it on same level as yellow one by using glTranslatef(-2, 0, -2); it just becomes smaller:
The first two parameters of glTranslatef works just fine moving object left/right and closer/further, so why does third parameter changes object's size?
You moved it farther away. Objects which are farther away appear smaller; that's just how perspective works. And since you have no lighting, background objects, or any other depth cues, being farther away is visibly identical to scaling it to a smaller size.
I'm trying to draw a two patches of rectangle (for tessellation) and I want to draw them from 0,0 to 1,1 and other from 1,0 to 2,1
I'm using GL_PATCHES to send a quad to my graphics pipeline
My vertex data in homogeneous coordinates is
float vertices[32] = {
0.0, 0.0, 0.0, 1.0, //1st rec
1.0, 0.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0,
0.0, 1.0, 0.0, 1.0,
1.0, 0.0, 0.0, 1.0, //2nd rec
2.0, 0.0, 0.0, 1.0,
2.0, 1.0, 0.0, 1.0,
1.0, 1.0, 0.0, 1.0
};
And in C++ code
glPatchParameteri(GL_PATCH_VERTICES, 4);
glDrawArraysInstanced(GL_PATCHES, 0, 4, 2);
But I'm only getting one rectangle patch from 0,0 to 1,1 on my screen. I don't understand why it it doesn't draw the second rectangle
My tessellation evaluation shader is
vec4 vert= vec4(0.0, 0.0, 0.0, 1.0);
vert.x = gl_in[0].gl_Position.x + gl_TessCoord.x;
vert.y = gl_in[0].gl_Position.y + gl_TessCoord.y;
I convert this vert to vec4 and pass it to gl_Position
glDrawArraysInstanced draws several instances of the data specified. In your case, it draws two times the vertices 0 to 4, which gives you two quads lying on the same position.
I would suggest you simply use glDrawArrays(GL_PATCHES, 0, 8) instead, but you could also keep your draw call and translate in the vertex shader according to the gl_InstanceID.
I have the following code to try to draw a rectangle using vertex arrays:
glEnableClientState( GL_NORMAL_ARRAY );
glNormalPointer( GL_FLOAT, 0, &mNorms[ 0 ] );
glEnableClientState( GL_TEXTURE_COORD_ARRAY );
glTexCoordPointer( 2, GL_FLOAT, 0, &mTexCrds[ 0 ] );
glEnableClientState( GL_VERTEX_ARRAY );
glVertexPointer( 3, GL_FLOAT, 0, &mVtxs[ 0 ] );
glDrawArrays( GL_TRIANGLE_STRIP, 0, 4 );
The intent is to draw a simple rectangle via triangle strip using the corner pattern Far Left, Near Left, Far Right, Near Right. The variable values are as follows:
/* far left near left far right near right */
mNorms { 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0 }
mTexCrds { 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 }
mVtxs { -25.0, 0.0, -100.0, -25.0, 0.0, -50.0, 25.0, 0.0, -100.0, 25.0, 0.0, -50.0 }
My texture is a black tile with a thin blue border around all edges. When the rectangle is drawn using the above instructions, it is completely blue:
bad.jpg http://www.graemecentralstation.com/img/bad.jpg
Obviously, given the above texture coordinates I am expecting my 2D texture to be completely visible.
If I replace glDrawArrays() with a manually invocation using the same array data like this...
glBegin( GL_TRIANGLE_STRIP );
{
for( int i = 0; i < 4; ++i )
{
glNormal3fv( &mNorms[ i * 3 ] );
glTexCoord2fv( &mTexCrds[ i * 2 ] );
glVertex3fv( &mVtxs[ i * 3 ] );
}
}
glEnd();
... then the rectangle is drawn with the full texture map image visible as I expect:
good.jpg http://www.graemecentralstation.com/img/good.jpg
Any idea why glDrawArrays() would skew my texture so badly?
You can try to debug with using texture coordinates as colors in the fragment shader, so then you can see whether texture coordinates are correct.gl_FragColor = vec4( vec2( texCoord),0,1);
You perhaps need to add
glActiveTextureARB(GL_TEXTURE0_ARB);
glBindTexture(GL_TEXTURE_2D,texID);
just before glEnableClientState( GL_TEXTURE_COORD_ARRAY );
Why I am getting a full White colored window as an output of this program
Expected a box
code is here
#include<Gl/glut.h>
static GLfloat vertices[] = {0.0, 0.0, 0.0,
0.5, 0.0, 0.0,
0.5, 0.5, 0.0,
0.0, 0.5, 0.0,
};
void reshape(int w, int h)
{
glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 0.0);
}
void Draw()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0,1.0,1.0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, 0);
glBegin(GL_LINES);
glArrayElement(0);
glArrayElement(1);
glArrayElement(2);
glArrayElement(3);
glEnd();
glDisableClientState(GL_VERTEX_ARRAY);
glFlush();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(400,400);
glutInitWindowPosition(100,100);
glutCreateWindow("vectors");
glClearColor(0.0,0.0,0.0,0.0);
glutReshapeFunc(reshape);
glutDisplayFunc(Draw);
glutMainLoop();
}
Corrected GL_LINES to GL_QUADS
Multiple problems:
reshape() is broken; glOrtho() multiples by the current matrix and will give nonsensical results if you resize the window more than once.
You request a double-buffered (GLUT_DOUBLE) context but fail to swap the buffers. glFlush() is insufficient. Try glutSwapBuffers() instead.
You really ought to reset your projection/modelview matrices each frame. Helps prevent errors.
Give this a shot:
#include<Gl/glut.h>
static GLfloat vertices[] =
{
0.0, 0.0,
0.5, 0.0,
0.5, 0.5,
0.0, 0.5,
};
void Draw()
{
glClearColor(0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glMatrixMode( GL_PROJECTION );
glLoadIdentity();
glOrtho( -2, 2, -2, 2, -1, 1 );
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glColor3f(1.0,1.0,1.0);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer( 2, GL_FLOAT, 0, vertices );
glBegin(GL_QUADS);
glArrayElement(0);
glArrayElement(1);
glArrayElement(2);
glArrayElement(3);
glEnd();
glDisableClientState(GL_VERTEX_ARRAY);
glutSwapBuffers();
}
int main(int argc, char **argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGBA);
glutInitWindowSize(400,400);
glutInitWindowPosition(100,100);
glutCreateWindow("vectors");
glutDisplayFunc(Draw);
glutMainLoop();
}
I suspect the problem is your call to glVertexPointer(). The last parameter is supposed to be a pointer to the start of the array you're using, but at the moment you're just passing it a null pointer, so it's got nothing to work with.
Try this instead:
glVertexPointer(3, GL_FLOAT, 0, vertices);
EDIT: By the way, your code won't give you a box. If it works, I think it'll just give you two lines. Try using GL_QUADS instead of GL_LINES.
The main thing that pops out at me is the array:
//static GLfloat vertices[] = {0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.0, };
should be
static GLfloat vertices[] = {0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.5, 0.0 };
(note the removed comma)
Next thing is the enabling and disabling of the client state: that could be done in the main loop for example as it is expensive to enable and disable and your draw loop will suffer because of it.