Opengl premultiplied alpha image render process - opengl

I'v been learning OpenGL2.0 rendering stuffs for a while and here are some personal understanding on alpha rendering I want to know if they are right:
Say I have a PNG (32 bit) file (none premultiplied alpha image) with only one pixel (src image)
PNG Shader - glFragColor GPU - SRC_ALPHA SRC_ONE
(255, 0, 0, 255) - red / none transparent (1.0, 0.0, 0.0, 1.0) (1.0, 0.0, 0.0, 1.0) (1.0, 0.0, 0.0, 1.0)
(255, 0, 0, 128) - red / half transparent (1.0, 0.0, 0.0, 0.5) (0.5, 0.0, 0.0, 0.75) (1.0, 0.0, 0.0, 1.0)
(128, 0, 0, 255) - drak red / none transparent (0.5, 0.0, 0.0, 1.0) (0.5, 0.0, 0.0, 1.0) (0.5, 0.0, 0.0, 1.0)
(128, 0, 0, 128) - drak red / half transparent (0.5, 0.0, 0.0, 0.5) (0.25, 0.0, 0.0, 0.75) (0.5, 0.0, 0.0, 1.0)
Here are four examples and 4 columns for each.
Take row NO.2 for example:
1. The PNG image is red but half transparent so the rgba should be (255, 0, 0, 128)
2. The texture info is passed to frag shader and the value for glFragColor shoud be (1.0, 0.0, 0.0, 0.5)
3. When rendering the src color to GPU OpenGL will try to bend it with the dst color
4. let's say the dst color is (0, 0, 0, 255) and blend func for dst is GL_ONE_MINUS_SRC_ALPHA
5. if the blend func for dst is GL_SRC_ALPHA, the final pixel rendered will be (0.5, 0.0, 0.0, 0.75)
6. if the blend func for dst is GL_ONE, the final pixel rendered will be (1.0, 0.0, 0.0, 1.0)
The result for (6) is definitely wrong since the transparency lost while the result for (5) should be good.
And that's why I should use GL_SRC_ALPHA for none premultiplied alpha image and GL_ONE for premultiplied alpha image.

Related

How do I correctly draw 3D axis in OpenGL?

I am trying to draw the 3D axis. I have also a cone which is rotating around its vertex and I would want the axis starting from there.
Here I have my function to draw the cone and I wrote the functions to draw the axis after gluLookAt:
GLfloat xRotated, yRotated, zRotated;
// Cone
GLdouble base=0.5;
GLdouble height=1.3;
GLint slices =20;
GLint stacks =20;
std::vector<std::array<GLfloat, 3>> data;
void displayCone(void)
{
// set matrix mode
glMatrixMode(GL_MODELVIEW);
// clear model view matrix
glLoadIdentity();
// multiply view matrix to current matrix
gluLookAt(0,2.,0.,0.,0.,-4.5,0,1,0); // <----------------------- add
// ******
glPushMatrix();
glLoadIdentity();
glTranslatef(0.0, 0.0, -4.5);
glBegin(GL_LINES);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(2.0, 0.0, 0.0);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 2.0, 0.0);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 2.0);
glEnd();
glPopMatrix();
// ******
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT);
// traslate the draw by z = -4.0
// Note this when you decrease z like -8.0 the drawing will looks far , or smaller.
glTranslatef(0.0,0.0,-4.5);
// Red color used to draw.
glColor3f(0.8, 0.2, 0.1);
// changing in transformation matrix.
// rotation about X axis
glRotatef(xRotated,1.0,0.0,0.0);
// rotation about Y axis
glRotatef(yRotated,0.0,1.0,0.0);
// rotation about Z axis
glRotatef(zRotated,0.0,0.0,1.0);
// scaling transfomation
glScalef(1.0,1.0,1.0);
// built-in (glut library) function , draw you a Cone.
// move the peak of the cone to the origin
glTranslatef(0.0, 0.0, -height);
glutSolidCone(base,height,slices,stacks);
// Flush buffers to screen
// gluLookAt(3,3,3,0,0,-4.5,0,1,0); <----------------------- delete
glFlush();
// sawp buffers called because we are using double buffering
// glutSwapBuffers();
}
I thought to draw the 3D axis in this way but I am making some mistakes.
What am I missing?
The lies are cleared immediately after they've been drawn by glClear. Do glClear(GL_COLOR_BUFFER_BIT); at the begin of displayCone:
If you want to draw the lines in view space, then the view matrix has to be set. Remove glLoadIdentity before drawing the lines.
e.g.
void displayCone(void)
{
// clear the drawing buffer.
glClear(GL_COLOR_BUFFER_BIT); // <---- add
// set matrix mode
glMatrixMode(GL_MODELVIEW);
// clear model view matrix
glLoadIdentity();
// multiply view matrix to current matrix
gluLookAt(3.0, 3.0, 3.0-4.5, 0.0, 0.0,-4.5,0,1,0);
// ******
glPushMatrix();
// glLoadIdentity(); <---- delete
glTranslatef(0.0, 0.0, -4.5);
glBegin(GL_LINES);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(2.0, 0.0, 0.0);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 2.0, 0.0);
glColor3f (1.0, 1.0, 0.0);
glVertex3f(0.0, 0.0, 0.0);
glVertex3f(0.0, 0.0, 2.0);
glEnd();
glPopMatrix();
// clear the drawing buffer.
// glClear(GL_COLOR_BUFFER_BIT); // <---- delete
// traslate the draw by z = -4.0
// Note this when you decrease z like -8.0 the drawing will looks far , or smaller.
glTranslatef(0.0,0.0,-4.5);
// Red color used to draw.
glColor3f(0.8, 0.2, 0.1);
// changing in transformation matrix.
// rotation about X axis
glRotatef(xRotated,1.0,0.0,0.0);
// rotation about Y axis
glRotatef(yRotated,0.0,1.0,0.0);
// rotation about Z axis
glRotatef(zRotated,0.0,0.0,1.0);
// scaling transfomation
glScalef(1.0,1.0,1.0);
// built-in (glut library) function , draw you a Cone.
// move the peak of the cone to the origin
glTranslatef(0.0, 0.0, -height);
glutSolidCone(base,height,slices,stacks);
// Flush buffers to screen
// gluLookAt(3,3,3,0,0,-4.5,0,1,0); <----------------------- delete
glFlush();
// sawp buffers called because we are using double buffering
// glutSwapBuffers();
}

Objects shake when rotating

I'm facing a problem in my opengl code
I'm trying to build a house, and rotate it 360°, for simplicity let's assume the house has the front wall with window and dor, and a back wall.
I'm using DEPTH_BUFFER not to see the back wall when viewing the front wall, and the other way around, but when I rotate the house the door and window start to shake and get distorced.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(0.0, 0.0, 0.0);
glLoadIdentity();
gluLookAt(0.0, 0.0, 40.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
glRotatef(angle, 0.0, 1.0, 0.0);
glEnable(GL_DEPTH_TEST);
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(8.0, 3.0, 0.0);
glVertex3f(8.0, -10.0, 0.0);
glVertex3f(1.0, -10.0, 0.0);
glVertex3f(1.0, 3.0, 0.0);
glEnd();
glColor3f(0.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(-9.0, -4.0, 0.0);
glVertex3f(-9.0, 3.0, 0.0);
glVertex3f(-2.0, 3.0, 0.0);
glVertex3f(-2.0, -4.0, 0.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, -10.0, -20.0);
glVertex3f(-10.0, -10.0, -20.0);
glVertex3f(-10.0, 10.0, -20.0);
glVertex3f(10.0, 10.0, -20.0);
glEnd();
glColor3f(1.0, 0.0, 0.0);
glBegin(GL_POLYGON);
glVertex3f(10.0, -10.0, 0.0);
glVertex3f(10.0, 10.0, 0.0);
glVertex3f(-10.0, 10.0, 0.0);
glVertex3f(-10.0, -10.0, 0.0);
glEnd();
glDisable(GL_DEPTH_TEST);
glutSwapBuffers();
The issue is called Z-fighting. This is caused, because depth of the "door", "window" and "wall" are equal. The vertiex coordinates are transformed by the model view matrix and projection matrix and interpolated for each fragment which is covered by the polygon. This results in inaccuracies of the final z coordinate (depth).
Enable the polygon fill offset (glPolygonOffset) by before drawing the walls, to solve the issue:
glEnable(GL_DEPTH_TEST);
glDisable( GL_POLYGON_OFFSET_FILL );
// draw door and window
// ...
glEnable( GL_POLYGON_OFFSET_FILL );
glPolygonOffset( 1, 1 );
// draw walls
// ...
Polygon fill offset manipulates the depth of a fragment by a minimum amount. This causes that the depth of the "walls" is different to the depth of the "window" and "door", even after the transformation by the model view and projection matrix.
Since an offset is added to the depth of the "wall", the "wall" is always behind the window and the door, independent of the point of view.

How to rotate an image in openGL?

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.

glDrawArraysInstanced is not doing multiple draw calls in OpenGL?

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.

3D texture coordinates for a cube

I want to use glTexImage3D with cube. what will be the texture coordinates for it? i am using GL_TEXTURE_3D as target.
I tried with u v coordinates same as 2d texture coordinates with z component 0-depth for each face. But that goes wrong.
These are the texture coordinates i was using which seems to be incorrect.
GLfloat texcoords[]={
0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,
0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,
0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,
0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,
0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0,
0.0, 0.0,0.0,
1.0, 0.0,1.0,
1.0, 1.0,1.0,
0.0, 1.0,0.0
};
You probably do not want to use a 3D texture just for texturing the faces of a cube. More likely you want to use a cube map – essentially a set of 6 2D textures one for each face of a cube – which by its very nature nicely matches the topology of a cube.