What is wrong with this text color? - c++

I'm using the openFrameworks ofxPango addon to render text with following code:
ofxPango* pango;
ofxPCContext* context;
ofxPCPangoLayout* layout;
ofImage text_image;
pango = new ofxPango();
context = pango->createContextWithSurface(width, height);
context->color4f(1,1,1, 0.0f);
context->paint();
layout = context->createPangoLayout();
layout->setText(text);
layout->setTextColor(186,34,29, 1.0f);
layout->setWidth(width);
layout->setJustify(true);
//context->paint();
ofxPCPangoFontDescription* fd = new ofxPCPangoFontDescription();
fd->createFromString(font);
layout->setFontDescription(*fd);
layout->show();
text_image.allocate(context->getSurface()->getWidth(), context->getSurface()->getHeight(), OF_IMAGE_COLOR_ALPHA);
text_image.setFromPixels(context->getSurface()->getPixels(), text_image.width, text_image.height, OF_IMAGE_COLOR_ALPHA, true);
I'm having trouble understanding how layout->setTextColor(r,g,b,a) works.
If I run:
0,0,0,1 - text is black as it should be
255,0,0 - text is red as it should be
186,34,29,1 - text appears very light gray (maybe white) when it should be red
186,34,0,1 - text is yellow, although it should be red
Why are these colors coming out wrong?

I think color values are supposed to be within the range 0.0f and 1.0f, where:
0.0f = no color
0.5f = half color
1.0f = full color
Here are some abridged examples from the Cairo library, which ofxPango calls out to:
color_white
1.0, 1.0, 1.0, 1.0
color_black
0.0, 0.0, 0.0, 1.0
color_transparent
0.0, 0.0, 0.0, 0.0
color_magenta
1.0, 0.0, 1.0, 1.0

Related

Translating a 3d model to 2d using assimp

I'm using c++ to translate a 3d model entered using command line arguments into a 2d picture in assimp. However I'm not sure of the best way to go about it. I have the basic hard coding for to create a set object but I need to redo it using vectors and loops. What's the best way to go about it?
void createSimpleQuad(Mesh &m) {
// Clear out vertices and elements
m.vertices.clear();
m.indices.clear();
// Create four corners
Vertex upperLeft, upperRight;
Vertex lowerLeft, lowerRight;
Vertex upperMiddle;
// Set positions of vertices
// Note: glm::vec3(x, y, z)
upperLeft.position = glm::vec3(-0.5, 0.5, 0.0);
upperRight.position = glm::vec3(0.5, 0.5, 0.0);
lowerLeft.position = glm::vec3(-0.5, -0.5, 0.0);
lowerRight.position = glm::vec3(0.5, -0.5, 0.0);
upperMiddle.position = glm::vec3(-0.9, 0.5, 0.0);
// Set vertex colors (red, green, blue, white)
// Note: glm::vec4(red, green, blue, alpha)
upperLeft.color = glm::vec4(1.0, 0.0, 0.0, 1.0);
upperRight.color = glm::vec4(0.0, 1.0, 0.0, 1.0);
lowerLeft.color = glm::vec4(0.0, 0.0, 1.0, 1.0);
lowerRight.color = glm::vec4(1.0, 1.0, 1.0, 1.0);
upperMiddle.color = glm::vec4(0.5, 0.15, 0.979797979, 1.0);
// Add to mesh's list of vertices
m.vertices.push_back(upperLeft);
m.vertices.push_back(upperRight);
m.vertices.push_back(lowerLeft);
m.vertices.push_back(lowerRight);
m.vertices.push_back(upperMiddle);
// Add indices for two triangles
m.indices.push_back(0);
m.indices.push_back(3);
m.indices.push_back(1);
m.indices.push_back(0);
m.indices.push_back(2);
m.indices.push_back(3);
m.indices.push_back(0);
m.indices.push_back(2);
m.indices.push_back(4);
}
If you want to generate a 2D-picture out of a 3D-Model you need to:
Import the model
Render it via a common render-lib into a texture or manually by using our viewer and take a snapshot
At this moment there is no post-process to generate a 2D-View automatically in Assimp.
But when you want to do this with your own render-code this is not so hard to do. After importing your model you have to:
Get the bounding box for your imported asset, just check the opengl-samples in the assimp-repo for some tips
Calculate the diameter for this bounding box.
Create a camera, for OpenGL you can use glm for calculating the View-Matrix
Place the asset at (0|0|0) world coordinate system
Move your camera by the diameter at let it view onto (0|0|0)
Render the view into a 2D-Texture or just take a screenshot

VTK volume rendering of mammography

I am working on vtk volume rendering of mammography. I have a 50 DICOM slices in folder to construct volume. Here I need to give vtkColorTransferFunction and vtkPiecewiseFunction to set RGB color and scalar opacity.
I am not getting exact values of color and opacity with respect to mammo images (breast images). I need values for color and opacity with respect to breast x-ray images.
Any suggestions will be helpful.
vtkGPUVolumeRayCastMapper *volumeGPUmapper =
vtkGPUVolumeRayCastMapper::New();
volumeGPUmapper->SetInputConnection(clip->GetOutputPort());
// RGB and alpha funcions
double skinOnBlueMap[28][5] =
{
{0, 0.987853825092316, 1.0, 1.0, 0.9},
{10000, 0.987853825092316, 1.0, 1.0, 0.9},
{20000, 0.987853825092316, 1.0, 1.0, 1.0},
{30000, 0.987853825092316, 1.0, 1.0, 1.0},
{40000, 0.0, 0.0, 0.0, 1.0},
{50000, 1.0, 0.0, 0.0, 1.0},
{60000, 1.0, 0.999206542968750, 0.0, 1.0},
{70000, 1.0, 1.0, 1.0, 1.0}
};
vtkSmartPointer<vtkPiecewiseFunction> alphaChannelFunc = vtkSmartPointer<vtkPiecewiseFunction>::New();
vtkSmartPointer<vtkColorTransferFunction> colorFunc = vtkSmartPointer<vtkColorTransferFunction>::New();
for(int i = 0; i < sizeof(skinOnBlueMap)/(5*sizeof(double)); i++)
{
colorFunc->AddRGBPoint(skinOnBlueMap[i][0], skinOnBlueMap[i][1], skinOnBlueMap[i][2], skinOnBlueMap[i][3]);
alphaChannelFunc->AddPoint(skinOnBlueMap[i][0], skinOnBlueMap[i][4]);
}
vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
volumeProperty->SetColor(colorFunc);
volumeProperty->SetInterpolationTypeToLinear();
volumeProperty->SetScalarOpacity(alphaChannelFunc);
vtkSmartPointer<vtkVolume> VTKvolume = vtkSmartPointer<vtkVolume>::New();
VTKvolume->SetMapper(volumeGPUmapper);
VTKvolume->SetProperty(volumeProperty);
Those scalar values seem strange to me. It could be the reason your results don't look correct. But to be sure we need the image stack and rendered result.
The scalar values are not even inside the range of the unsigned short type, that is generally used for the voxels.

perspective projection with aspect ratio != 1.0 for cubemap-like creation of overall image

I render 3 images (left-view, center-view, right-view) with 90° horizontal foV and map them on 3 grids that create an overall image (basically like left, front and right views of a cubemap texture). Therefore the 3 unique images have to fit together somehow.
Everything works fine if i define the projection matrix for each image like this:
gluPerspective(90, 1, 0.1, 500)
However, since i'm trying to create an image with 210° (horizontal) and 60° (vertical) field of View, i would like to define it like this:
gluPerspective(60, 1.5, 0.1, 500)
But using this, the 3 images don't fit together in terms of their image content, foV, frustum or whatever.
So my question is: Do i have to use an aspect ratio of 1 if i want the images to fit together. And if i have to, why?
Some additional information:
i render the images in an fbo with a resolution that has the same aspect ratio like my hor./ver. foV
viewport is defined like this: glViewport (0, 0, width, height);
The modelview definition for the 3 views:
left-view: gluLookAt(0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0);
center-view: gluLookAt(0.0, 0.0, 0.0, 0.0, -1.0, 0.0, 0.0, 0.0, 1.0);
right-view: gluLookAt(0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0);
This was a sufficient explanation for me:
http://ledin.cs.sonoma.edu/CS375_OpenGL_Slides/Perspective_gluFrustum.pdf

Inconsistency of shading in polygons on the same axis in OpenGL

I am building a house in OpenGL. On the outside and on the inside where there are doors or windows, I use a Quad to go below and above the windows all the way around the house, and then a quad to fill in the gaps between windows. These will have the same plane value, but for some reason GL_LIGHT passes shadows onto some. Any clue why?
Quad between windows
glBegin(GL_QUADS);
glTexCoord2d(0, 0);glVertex3d(0, 1.1, 0);
glTexCoord2d(2, 0);glVertex3d(0, 1.1, 2);
glTexCoord2d(2, 1.6);glVertex3d(0, 2.7, 2);
glTexCoord2d(0, 1.6);glVertex3d(0, 2.7, 0);
glEnd();
Below windows
glBegin(GL_QUADS);
glTexCoord2d(0, 0);glVertex3d(0, 0.1, 0);
glTexCoord2d(15, 0);glVertex3d(0, 0.1, 15);
glTexCoord2d(15, 1);glVertex3d(0, 1.1, 15);
glTexCoord2d(0.0, 1);glVertex3d(0, 1.1, 0);
glEnd();
Above windows
glBegin(GL_QUADS);
glTexCoord2d(0, 2.6);glVertex3d(0, 2.7, 0);
glTexCoord2d(15, 2.6);glVertex3d(0, 2.7, 15);
glTexCoord2d(15, 3.0);glVertex3d(0, 3.1, 15);
glTexCoord2d(0.0,3.0);glVertex3d(0, 3.1, 0);
glEnd();
here is the code for the light
GLfloat light_position[] = { 50, 50, -1.0};
GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat ambient[] = { 1.0, 1.0, 1.0, 1.0 };
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_NORMALIZE);
glLightfv(GL_LIGHT0, GL_POSITION , light_position );
glLightfv(GL_LIGHT0, GL_SPECULAR , specular);
glLightfv(GL_LIGHT0, GL_DIFFUSE , diffuse );
glLightfv(GL_LIGHT0, GL_AMBIENT , ambient );
Here is a screenshot of the result
http://imgur.com/WsgZWBF
Why is it doing this, and is there any way to fix it?
You need to supply (meaningful) vertex/face normals for OpenGL's lighting to work properly:
18.020 Why are my objects all one flat color and not shaded and illuminated?
This effect occurs when you fail to supply a normal at each vertex.
OpenGL needs normals to calculate lighting equations, and it won't calculate normals for you (with the exception of evaluators). If your application doesn't call glNormal*(), then it uses the default normal of (0.0, 0.0, 1.0) at every vertex. OpenGL will then compute the same, or nearly the same, lighting result at each vertex. This will cause your model to look flat and lack shading.
The solution is to simply calculate the normals that need to be specified at any given vertex. Then send them to OpenGL with a call to glNormal3f() just prior to specifying the vertex, which the normal is associated with.

Texture Displayed with Green Hue

I'm learning how to apply textures in OpenGL. I have a fairly simple cube on which I am trying to apply a texture to make it look like a wooden board. When I apply my texture, it displays with a green hue. I can apply some other textures that look just fine, so I can't figure out what is wrong with this one. I created the texture from a jpg that I downloaded. The bmp file looks fine when I view it in Preview (I'm on a Mac). I'll attach a screenshot of the original bitmap and also of how it looks when rendered by OpenGL.
The texture loading code that I am using can be found here:
unsigned int texture[2]; // Texture names
// define the board
float square_edge = 1;
float border = 0.5;
float board_thickness = 0.25;
float board_corner = 4 * square_edge + border;
float board_width = 2 * board_corner;
GLfloat board_vertices[8][3] = {
{-board_corner, board_corner, 0.0},
{-board_corner, -board_corner, 0.0},
{ board_corner, -board_corner, 0.0},
{ board_corner, board_corner, 0.0},
{-board_corner, board_corner, -board_thickness},
{-board_corner, -board_corner, -board_thickness},
{ board_corner, -board_corner, -board_thickness},
{ board_corner, board_corner, -board_thickness}
};
void polygon(int a, int b, int c, int d) {
glBindTexture(GL_TEXTURE_2D, texture[0]);
glBegin(GL_QUADS);
glTexCoord2f(0.0, 0.0); glVertex3fv(board_vertices[a]);
glTexCoord2f(1.0, 0.0); glVertex3fv(board_vertices[b]);
glTexCoord2f(1.0, 1.0); glVertex3fv(board_vertices[c]);
glTexCoord2f(0.0, 1.0); glVertex3fv(board_vertices[d]);
glEnd();
}
void draw_board() {
glPushMatrix();
glRotatef(rotx, 1.0, 0.0, 0.0);
glScalef(1/board_corner, 1/board_corner, 1/board_corner);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, board_vertices);
glBindTexture(GL_TEXTURE_2D, texture[1]);
glColor3f(1.0, 1.0, 1.0); //color of the border, sides, bottom of board
// draw the board
polygon(0,3,2,1);
polygon(2,3,7,6);
polygon(0,4,7,3);
polygon(1,2,6,5);
polygon(4,5,6,7);
polygon(0,1,5,4);
glPopMatrix();
}
void display()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glEnable(GL_TEXTURE_2D);
glLoadIdentity();
double Ex = -2*dim*Sin(th)*Cos(ph);
double Ey = +2*dim *Sin(ph);
double Ez = +2*dim*Cos(th)*Cos(ph);
gluLookAt(Ex,Ey,Ez , 0,0,0 , 0,Cos(ph),0);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
draw_board();
glFlush();
glutSwapBuffers();
}
The problem is in the bmp image itself. As I mentioned, I created this from a jpg file by converting it via Gimp. Somehow, this conversion went awry. When I run 'file wood.bmp' from the command line, my response is 'wood.bmp: data'. It should show 'wood.bmp: PC bitmap, Windows 3.x format, 128 x 128 x 24" or something similar. I did the conversion using good ol' MS Paint, and the problem went away.
I'm trying to find out how to do this in Gimp, but for now this all works. Thanks for all the suggestions!
When exporting a .bmp image with gimp, make sure you select the "Do not write color space information" option, underneath the Compatibility Options dropdown. .bmp images exported this way won't appear with a green hue when rendered with opengl.