Can somebody tell me what is mistake here. It shows display window, but unfortunately doesn't draw a triangle.
#include<glut.h>
GLint vertices[] ={ /*vertex array */
0.25, 0.25,
-0.9, 0.8,
0.5, -0.5
-0.2, -0.8
};
GLfloat colors[]={ /*color array*/
1.0, 0.0, 0.0,
0.0, 1.0, 0.0,
0.0, 0.0, 1.0,
1.0, 1.0, 0.0
};
void display(){
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_COLOR_ARRAY); /* enabling color array*/
glEnableClientState(GL_VERTEX_ARRAY); /*enableing vertex array */
glColorPointer(3, GL_FLOAT, 0, colors);
glVertexPointer(2, GL_FLOAT, 0, vertices);
glBegin(GL_TRIANGLES); /* dereferencing */
glArrayElement(0);
glArrayElement(1);
glArrayElement(2);
glEnd();
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glFlush();
}
void main() {
glutInitDisplayMode(GLUT_RGBA);
glutInitWindowPosition(200, 200);
glutInitWindowSize(300,300);
glutCreateWindow("My application");
glutDisplayFunc(display);
glutMainLoop();
}
Your vertices array is of type GLint[], so all the float (or rather double) values in the initialization expression will just be truncated to 0 and it won't match the type given in glVertexPointer either, causing whatever weird results (though in exactly this case the binary representations of all those integer 0s are probably also the binary representations of a float 0.0f). Given the use of GL_FLOAT in glVertexPointer you probably meant it to be GLfloat vertices[].
(Side note: As noted in the comments the glArrayElement function is pretty useless and if you're already using vertex arrays, then you should actually draw them with a single array draw call instead of a million glArrayElement calls inside a glBegin/glEnd block, which is the whole purpose and advantage of arrays compared to glBegin/glEnd. So in fact your glBegin/glEnd block can be replaced by a simple glDrawArrays(GL_TRIANGLES, 0, 3);. But with the above mentioned correction of the array type it should at least work correctly.)
Related
I am trying to draw two quads using vertex buffer objects in OpenGL. They should be draw with different colors. Like you see, the first quad has a red, green, blue and yellow vertices. The second quad has different colors, but the problem is that they second quad gets drawn completely yellow. This is my code:
GLfloat vertices[24] = {10.0, 10.0, 0.0, 10.0, -10.0, 0.0, -10.0, -10.0, 0.0, -10.0, 10.0, 0.0,
20.0, 20.0, 0.0, 20.0, 10.0, 0.0, 10.0, 10.0, 0.0, 10.0, 20.0, 0.0 };
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 24, vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
GLfloat colors[24] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0,
0.5, 0.5, 0.5, 0.7, 0.2, 1.0, 0.2, 1.0, 0.7, 0.8, 0.0, 0.45 };
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, colorBuffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLfloat) * 24, colors, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glVertexPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, colorBuffer);
glColorPointer(3, GL_FLOAT, 0, 0);
glDrawArrays(GL_QUADS, 0, 8);
This is how the quads are drawn:
The second quad is the one on top right. It should be multicolored, but it's drawn using the 4th element of the color buffer. What should I do to fix it?
See OpenGL 2.1 Reference Pages; glColorPointer:
glColorPointer specifies the location and data format of an array of color components to use when rendering. ...
If a non-zero named buffer object is bound to the GL_ARRAY_BUFFER target while a color array is specified, pointer is treated as a byte offset into the buffer object's data store.
In your code buffer is bound to the target GL_ARRAY_BUFFER;
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
Then colorBuffer is bound to the target GL_ELEMENT_ARRAY_BUFFER and the color array is defined:
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, colorBuffer);
glColorPointer(3, GL_FLOAT, 0, 0);
Since buffer is still bound to the target GL_ARRAY_BUFFER at this point, glColorPointer uses buffer. This causes that the vertex coordinates are treated as colors and that`s what you can see in the rendering.
To solve the issue you have to bint colorBuffer to the target GL_ARRAY_BUFFER:
glBindBuffer(GL_ARRAY_BUFFER, colorBuffer);
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.
Like the picture showed in the link below. I want to color my robot hand with white color(RGB: 0.9 0.9 0.9). When I use glColor3f, the white color display correctly. But when I store RGB data in GLfloat array and call glColorPointer, the color becomes so weird.
Here is code of right arm
static const GLfloat playerBodyColor[] = {0.9, 0.9, 0.9};
glEnableClientState(GL_COLOR_ARRAY);
//glColor3f(0.9, 0.9, 0.9);
glColorPointer(3, GL_FLOAT, 0, playerBodyColor);
glTranslatef(0.0, player_body_height/6, player_body_width/2+LENGTH_UNIT/2);
glRotatef(340.0, 0.0, 0.0, 1.0);
glPushMatrix();
glTranslatef(2*LENGTH_UNIT, 0.0, 0.0);
glScalef (4.0, 1.0, 1.0);
copyCodeSolidCube (LENGTH_UNIT);
glDisableClientState(GL_COLOR_ARRAY);
glPopMatrix();
If I change code like this:
static const GLfloat playerBodyColor[] = {0.9, 0.9, 0.9};
//glEnableClientState(GL_COLOR_ARRAY);
glColor3f(0.9, 0.9, 0.9);
//glColorPointer(3, GL_FLOAT, 0, playerBodyColor);
glTranslatef(0.0, player_body_height/6, player_body_width/2+LENGTH_UNIT/2);
glRotatef(340.0, 0.0, 0.0, 1.0);
glPushMatrix();
glTranslatef(2*LENGTH_UNIT, 0.0, 0.0);
glScalef (4.0, 1.0, 1.0);
copyCodeSolidCube (LENGTH_UNIT);
//glDisableClientState(GL_COLOR_ARRAY);
glPopMatrix();
The color shows correct.
The picture of correct-color code:
http://imgur.com/S6zt5wf
The picture of wrong-color code:
http://imgur.com/8m5Ag1O
In the code, I also called a function copyCodeSolidCube.
Here is part of copyCodeSolidCube code:
glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_NORMAL_ARRAY);
glVertexPointer (3, GL_FLOAT, 0, vert);
glNormalPointer (GL_FLOAT, 0, norm);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, one);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, two);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, three);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, four);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, five);
glDrawElements(GL_TRIANGLE_FAN, 4, GL_UNSIGNED_BYTE, six);
glDisableClientState (GL_VERTEX_ARRAY);
glDisableClientState (GL_NORMAL_ARRAY);
Where is the problem?
With glColorPointer(), you specify an array of colors, one for each vertex. For example, if your cube has 8 vertices, you need an array of 8 colors. Since you have 3 components per color, the total size of the array you need is 24 floats.
Or, since you currently have 4 vertices per draw call, you need 4 colors in the color array, for 4 * 3 = 12 float values.
The big advantage of using this is of course that you can color each vertex individually. If you really want the same color for each vertex, glColor3f() was actually the right call to use. Or you can use a slight variation:
glColor3fv(playerBodyColor);
This is equivalent to the glColor3f() call you had, except that it's more convenient if you already have the color in an array of 3 values.
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.
I have programmed a little raytracer in c++,
and want to show the raytraced image in a window.
I tried using a pixel buffer object in opengl,
then map the buffer into memory and manipulate the pixels one by one,
but at fullscreen resolution 1920x1080, I only get 4 fps
without raytracing and without changing the pixels colors
just the mapping and unmapping!
so i'm basically looking for the fastest way to display a raytraced image in a window.
i'm currently doing this way:
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
glBufferDataARB(GL_PIXEL_UNPACK_BUFFER_ARB, width * height * 4, 0, GL_STREAM_DRAW_ARB);
if (pixels = (uint*)glMapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY_ARB))
{
//modify pixels
glUnmapBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB);
}
else
return;
//copy from pbo to texture
glBindTexture(GL_TEXTURE_2D, pbo_texture);
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, pbo);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_BGRA, GL_UNSIGNED_BYTE, 0);
glEnable(GL_TEXTURE_2D);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//draw image
glColor4f(1.0, 1.0, 1.0, 1.0);
glBindTexture(GL_TEXTURE_2D, pbo_texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 1.0); glVertex3f(-1.0, -1.0, 0.0);
glTexCoord2f(1.0, 1.0); glVertex3f( 1.0, -1.0, 0.0);
glTexCoord2f(1.0, 0.0); glVertex3f( 1.0, 1.0, 0.0);
glTexCoord2f(0.0, 0.0); glVertex3f(-1.0, 1.0, 0.0);
glEnd();
glutSwapBuffers();
glBindBufferARB(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
glBindTexture(GL_TEXTURE_2D, 0);
Check the memory traversal if you use loops. You should traverse your buffer in the right order, otherwise you may have cache miss at each iteration. If you use nested loops sometimes you only have to switch the x/y iteration order.
Also, don't read data from graphic memory. It tends to be slow. Only write to PBO.
It looks like a syncro issue. I'm not sure you need to map pbo at every frame. Check this link on OpenGL Pixel Buffer Object (PBO). There's also a workaround for stalls which could improve things