OpenGL: Using glColorPointer make color weird - opengl

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.

Related

Unable to rotate 2D object properly with opengl

I'm using opengl, glfw and glew. I want to rotate the tip of the spaceship without moving the whole spaceship when users press on the left and right arrow respectively. I've tried using gltransform glrotate, it does rotate but it also move my spaceship along. The output of the movement of spaces
objects objects::rotateSpaceship(GLFWwindow * window, objects & sp)
{
GLfloat spaceship_angle = sp.getAngle();
GLfloat newAngle = sp.getAngle() + 0.5;
sp.setAngle(newAngle);
while (!glfwWindowShouldClose(window))
{
glClear(GL_COLOR_BUFFER_BIT);
GLfloat spaceShipRightLine[] =
{
x, y + 80, 0,
x - 50, y - 50, 0
};
GLfloat spaceShipLeftLine[] = {
x, y + 80, 0,
x + 50, y - 50, 0
};
GLfloat spaceShipMiddleLine[] = {
sp.x - 30 ,sp.y,0,
sp.x + 35,sp.y,0
};
glPushMatrix();
glTranslatef(0.0, 0.01, 0.0); // 3. Translate to the object's position.
glRotatef(sp.getAngle(), 0.0, 0.0, 1.0); // 2. Rotate the object.
glTranslatef(0.0, 0.01, 0.0); // 1. Translate to the origin.
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipRightLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipLeftLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipMiddleLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();
// Swap front and back buffers
glfwSwapBuffers(window);
// Poll for and process events
glfwPollEvents();
}
glfwTerminate();
return sp;
}
Note, that drawing by glBegin/glEnd sequences and the fixed function matrix stack is deprecated since decades.
Read about Fixed Function Pipeline and see Vertex Specification and Shader for a state of the art way of rendering.
I want to rotate the tip of the spaceship without moving the whole spaceship [...]
First you have to define the pivot, which is the "tip" of the spaceship:
float pivot_x = sp.x;
float pivot_y = sp.y + 80.0f;
To rotate around a pivot you have to define a model matrix, which displaces by the inverted pivot, then rotate (glRotatef) and final transforms back by to the pivot (glTranslate):
glTranslatef(pivot_x, pivot_y, 0);
glRotatef(angle, 0, 0, 1);
glTranslatef(-pivot_x, -pivot_y, 0);
The final code may look like that:
float pivot_x = x;
float pivot_y = y + 80.0f;
glPushMatrix();
glTranslatef(pivot_x, pivot_y, 0 ); // 3. Translate to the object's position.
glRotatef(sp.getAngle(), 0.0, 0.0, 1.0); // 2. Rotate the object.
glTranslatef(-pivot_x, -pivot_y, 0.0); // 1. Translate to the origin.
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipRightLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipLeftLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, spaceShipMiddleLine);
glDrawArrays(GL_LINES, 0, 2);
glDisableClientState(GL_VERTEX_ARRAY);
glPopMatrix();

VBO - Drawing multiple elements with different colors

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

fastest way to set every pixel

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

Using glArrayElement does not produce visible output

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

Can't draw with Buffer Object

So, I'm trying to study vbo and just do some examples, but opengl is killing me. I've been four hours trying to do this code work, but I dont have a clue why this dont work.
I was trying to draw 4 squares with different colors.
But if I try to draw using GL_POINTS i only see 4 points in the screen, and is supposed to be 9 points. If I try using GL_QUADS it simply don't draw nothing.
The interesting is that when I change this line:
glDrawElements(GL_POINTS, 16, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
to this:
glDrawElements(GL_POINTS, 64, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
Opengl draw the 9 dots, but only that, GL_QUADS dont work.
Please, someone give me a light on this problem, it's killing me!!
The complete code is here:
#define GL_GLEXT_PROTOTYPES
#include<GL/glut.h>
#include<iostream>
using namespace std;
#define BUFFER_OFFSET(offset) ((GLfloat*) NULL + offset)
#define VERTICES 0
#define INDICES 1
#define NUM_BUFFERS 2
void init_2(){
GLuint buffers[NUM_BUFFERS];
GLfloat vertices[][3]= {
{0.0, 0.0, 0.0},
{0.0, 40.0, 0.0},
{0.0, 80.0, 0.0},
{40.0, 0.0, 0.0},
{40.0, 40.0, 0.0},
{40.0, 80.0, 0.0},
{80.0, 0.0, 0.0},
{80.0, 40.0, 0.0},
{80.0, 80.0, 0.0}
};
GLuint indices[][4] = {
{0, 1, 4, 3},
{1, 2, 5, 4},
{3, 4, 7, 6},
{4, 5, 8, 7}
};
glGenBuffers(NUM_BUFFERS, buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[VERTICES]);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[INDICES]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
}
void display(void){
glPushMatrix();
glDrawElements(GL_POINTS, 16, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
glPopMatrix();
glutSwapBuffers();
}
void init()
{
glClearColor(0.0, 0.0, 0.0, 0.0);
gluOrtho2D((GLdouble) -1.0, (GLdouble) 90.0, (GLdouble) -1.0, (GLdouble) 90.0);
init2();
}
int main(int argv, char** argc) {
glutInit(&argv, argc);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
glutInitWindowSize(500,500);
glutInitWindowPosition(100,100);
glutCreateWindow("myCode.cpp");
init();
glutDisplayFunc(display);
glutMainLoop();
return 0;
}
Here's the problem:
GLuint indices[][4] = {
...
glDrawElements(GL_POINTS, 16, GL_UNSIGNED_BYTE, BUFFER_OFFSET(0));
You declare GLuint indices, but then tell glDrawElements that you're giving it bytes.
GLuint is a 32-bit type, so there are 4 bytes for each. As your index data is very small, each 32-bit value has only data in the bottom byte, leaving the rest as zero.
So in the first 16 bytes, which are the first 4 GLuints, there are only 4 discrete values, so you see 4 points. If you try 64 (which is 16 * 4), you will see all 9 points. However these points are mixed in with a lot of zeros, so when you try to render as GL_QUADS, nothing will be drawn.