PDA

View Full Version : Creating a numbered sphere



RChemuturi
11-12-2010, 03:32 AM
Hello All,
I am an absolute beginner with OpenGL. I could do some coding looking at some example programs and using the 'Red' book OpenGL Programming Guide.
I am creating a sphere using 'glutSolidSphere', that went on well, now if I need to display some number(single digit) within the sphere, is there a way to display numbers or should I have to go for pixel colouring within the sphere in the shape of required number?!
Thanks & Regards,

RChemuturi
11-12-2010, 03:32 AM
RChemuturi

carsten neumann
11-12-2010, 08:21 AM
take a look at glutBitmapCharacter, or search this forum for questions about rendering text with OpenGL.

RChemuturi
11-15-2010, 04:01 AM
Thank you.
glutBitmapCharacter works to render a character, but when I try to render it over a solid sphere, it doesn't work.
Still working out to solve this.
Any tips let me know.

Best Regards,

david_f_knight
11-15-2010, 09:02 AM
When you say "it doesn't work," what do you mean? Generally, the idea is that you apply the bitmap character as a texture to a quad (or triangles). The quad is 3D and must be positioned in space correctly. If it isn't correctly positioned, then it may be hidden (if you have depth testing enabled), or simply drawn over if it isn't the last thing drawn (if you don't have depth testing enabled). Or, you could apply the texture to the sphere's quads or triangles directly. (I don't use glut, so I'm not sure about how it generates triangles or quads, and in particular, I question whether there are any texture coordinates or how you'd know which ones go with which triangles or quads it generated. So, I'm assuming you'd need to define you own quads for text texture maps.)

carsten neumann
11-15-2010, 09:55 AM
glutBitmapCharacter uses glBitmap which underneath does something quite similar to glDrawPixels - my initial guess was depth test rejecting the pixels, but I'm not sure it even applies to glBitmap.

But I agree are more detailed description in which way it does not work would be helpful.

david_f_knight
11-15-2010, 10:21 AM
So, what order are things being rendered in? If the text is rendered first and doesn't modify the depth buffer, and then the sphere is rendered, won't the sphere overdraw the text pixels if they overlap?

RChemuturi
11-16-2010, 06:23 AM
Yes, now I understand that the number is 'overdrawn' by the 'sphere'.
I tried modifying the depth buffer bit. The commented code in the 'InitOpenGL()' and 'DrawNumberedSphere' is something I was trying to modify with various options of depth buffer bit and experimenting. Please can anyone suggest where I am going wrong. I am pasting the code below.

#include "stdafx.h"
#include <GL/glut.h>



// General OpenGL Material Parameters
GLfloat ObjectAmbient[] = {0.00, 0.66, 0.60, 1.00};
GLfloat ObjectDiffuse[] = {0.00, 0.80, 0.67, 1.00};

GLfloat Specular[] = {1.00, 1.00, 1.00, 1.00};
GLfloat Emissive[] = {0.00, 0.00, 0.00, 1.00};
GLfloat Shininess = {128.00};

GLfloat ObjectAmbient1[] = {1.0, 0.50, 0.00, 1.00};
GLfloat ObjectDiffuse1[] = {1.0, 0.50, 0.00, 1.00};

GLfloat Specular1[] = {1.00, 1.00, 1.00, 1.00};
GLfloat Emissive1[] = {0.00, 0.00, 0.00, 1.00};
GLfloat Shininess1 = {100.00};


void ObjectMaterial()
{
glMaterialfv(GL_FRONT, GL_AMBIENT, ObjectAmbient);
glMaterialfv(GL_FRONT, GL_DIFFUSE, ObjectDiffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, Specular);
glMaterialfv(GL_FRONT, GL_EMISSION, Emissive);
glMaterialf(GL_FRONT, GL_SHININESS, Shininess);
}


void ObjectMaterial1()
{
glMaterialfv(GL_FRONT, GL_AMBIENT, ObjectAmbient1);
glMaterialfv(GL_FRONT, GL_DIFFUSE, ObjectDiffuse1);
glMaterialfv(GL_FRONT, GL_SPECULAR, Specular1);
glMaterialfv(GL_FRONT, GL_EMISSION, Emissive1);
glMaterialf(GL_FRONT, GL_SHININESS, Shininess1);
}

void DrawNumberedSphere(void)
{
/*ObjectMaterial1();
glPushMatrix();
glTranslatef(0.1, 0.1, 0.1);
glutSolidSphere(0.03, 20, 20);
glPopMatrix();*/
ObjectMaterial();
glPushMatrix();
glTranslatef(0.1, 0.1, 0.1);
glRasterPos3f(0.0, 0.0, 0.0);
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1');
glPopMatrix();
}


void InitOpenGl (void)
{

glShadeModel(GL_SMOOTH);

glLoadIdentity();

GLfloat GrayLight[] = {0.75, 0.75, 0.75, 1.0};

GLfloat LightPosition[] = {1.0, 2.0, 1.0, 0.0};
GLfloat LightDirection[] = {0.0, 0.0, -1.0, 0.0};

glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
glLightfv(GL_LIGHT0, GL_AMBIENT, GrayLight);
glLightfv(GL_LIGHT0, GL_DIFFUSE, GrayLight);
glLightfv(GL_LIGHT0, GL_SPECULAR, GrayLight);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
//glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glClearColor(0.0, 0.3, 0.0, 0.0);
}

void Display (void)
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix ();

// define eyepoint in such a way that
// drawing can be done as in lab-frame rather than sgi-frame
// (so X towards user, Z is up)
gluLookAt (1.0, 0.5, 0.35, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0);
glutPostRedisplay();

DrawNumberedSphere();

glPopMatrix ();
glutSwapBuffers();
}

void Reshape(int iWidth, int iHeight)
{
glViewport (0, 0, (GLsizei)iWidth, (GLsizei)iHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();

float fAspect = (float)iWidth/iHeight;
gluPerspective (30.0, fAspect, 0.05, 20.0);

glMatrixMode (GL_MODELVIEW);
glLoadIdentity ();
}

int main(int argc, char* argv[])
{
glutInit(&amp;argc, argv);
glutInitDisplayMode (GLUT_DOUBLE| GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize (800, 600);

// Create The OpenGlWindow
glutCreateWindow ("Numbered Sphere");

InitOpenGl();

// More OpenGL Initialization Calls
glutReshapeFunc (Reshape);
glutDisplayFunc(Display);
glutMainLoop();
return 0;
}

Regards,

carsten neumann
11-16-2010, 08:11 AM
please use [ code][ /code] around source code snippets.



void DrawNumberedSphere(void)
{
/*ObjectMaterial1();
glPushMatrix();
glTranslatef(0.1, 0.1, 0.1);
glutSolidSphere(0.03, 20, 20); // [1]
glPopMatrix();*/

ObjectMaterial();
glPushMatrix();
glTranslatef(0.1, 0.1, 0.1);
glRasterPos3f(0.0, 0.0, 0.0);
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, '1'); // [2]
glPopMatrix();
}


At [1] you draw the solid sphere around (0.1, 0.1, 0.1) with radius 0.03, and then at [2] you draw your character at (0, 0, 0) (I think glRasterPos is not affected by glTranslate, but not sure). Anyway, that means you draw the number inside the sphere and then the depth test rejects those pixels. You need to put the character on top of the sphere by passing something like 0.14 as third argument to glRasterPos. Alternatively you could disable depth testing when drawing the character: glDisable(GL_DEPTH_TEST).

RChemuturi
11-18-2010, 06:21 AM
Thank you all,
I could solve this problem by doing a glPushMatrix() and then disabling the depth test before rendering the number and then re-enabling it. Now the number is displayed over the sphere. I continued with 'glRasterPos3f(0.0, 0.0, 0.0) '. Here is the modified code:

void DrawNumberedSphere(void)
{
int i = 5;
char num;
num = (char)(48+i);
glPushMatrix();
ObjectMaterial();
glTranslatef(0.1, 0.1, 0.1);
glutSolidSphere(0.03, 20, 20);
glPushMatrix();
ObjectMaterial1();
glDisable(GL_DEPTH_TEST);
glRasterPos3f(0.00, 0.0, 0.0);
glutBitmapCharacter(GLUT_BITMAP_HELVETICA_18, num);
glEnable(GL_DEPTH_TEST);
glPopMatrix();
glPopMatrix();
}

I am trying to render the number in a different colur, other than sphere, but as there is an overlap, the actual colour in which I want the number to be displayed is not being retained.
How can I retain the colour of a pixel to the last rendered object colour?!

Kind Regards,

RChemuturi
11-18-2010, 06:23 AM
Sorry for not using