[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] converting "object position" to "view position" in (py)opengl



The rows and columns don't matter since the part of the matrix you're
changing is symmetric. ;) I am pretty sure that the first index is the
the column and the second is the row.

Yes, just make sure you do the translate _before_ the billboarding
code is done. Otherwise, the translate would be relative to the camera
and not the world.

On Thu, Jul 2, 2009 at 11:45 PM, Astan Chee<astan.chee@xxxxxxxxx> wrote:
> Thanks for that.
> The thing is that I'm trying to do that in python and I'm stuck at
> modelview[16] in python because it is in [4][4] array in python and I'm not
> sure which one is rows and cols from c++ to python.
> Also, when I draw the quad at the object's center, do I need to do a
> glTranslatef? I'm guessing I do, right?
> Thanks again.
> Astan
>
> Forrest Voight wrote:
>
> I meant after the modelview matrix was tranformed to the camera position.
>
> This is the only code you need for billboarding - transforming the
> matrix to make the object always face the camera:
>
>
> float modelview[16];
> int i,j;
>
> // save the current modelview matrix
> glPushMatrix();
>
> // get the current modelview matrix
> glGetFloatv(GL_MODELVIEW_MATRIX , modelview);
>
> // undo all rotations
> // beware all scaling is lost as well
> for( i=0; i<3; i++ )
> 	for( j=0; j<3; j++ ) {
> 		if ( i==j )
> 			modelview[i*4+j] = 1.0;
> 		else
> 			modelview[i*4+j] = 0.0;
> 	}
>
> // set the modelview with no rotations and scaling
> glLoadMatrixf(modelview);
>
> drawObject();
>
> // restores the modelview matrix
> glPopMatrix();
>
>
> drawObject would be replaced by the code that draws a quad at the
> object's center. You would need to store the aspect ratio of the
> output of font.render (aspect = width/height) and use it to draw a
> correctly sized quad - for example, with a height of 1 and a width of
> aspect. The quad would need the appropriate texcoords - just 0,0 0,1
> 1,1 and 1,0 for the corners of the texture with the rendered text.
>
>
> On Thu, Jul 2, 2009 at 10:41 PM, Astan Chee<astan.chee@xxxxxxxxx> wrote:
>
>
> What do you mean "after the matrices are set"? is it when I'm doing an
> "initgl" like this:
>         glShadeModel(GL_SMOOTH)
>         glClearColor(0.0, 0.0, 0.0, 0.0)
>         glClearDepth(1.0)
>         glEnable(GL_DEPTH_TEST)
>         glDepthFunc(GL_LEQUAL)
>         glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST)
>         glEnable(GL_COLOR_MATERIAL)
>         glEnable(GL_TEXTURE_2D)
> or when the window resize is being called:
>     def resize(self,(width, height)):
>         if height==0:
>             height=1
>         glViewport(0, 0, width, height)
>         glMatrixMode(GL_PROJECTION)
>         glLoadIdentity()
>         gluPerspective(45, 1.0*width/height, 1.0, 10000.0)
>         glMatrixMode(GL_MODELVIEW)
>         glLoadIdentity()
> also, you lost me at your last sentence...I have no idea what that means but
> I'll google around.
> thanks again
>
> Forrest Voight wrote:
>
> When are you doing the gluProject? It should be after the matrices are
> set for the frame. Can you paste the code for that?
>
> To billboard text, you'd render it to a texture.
>
> Something like:
>
> surface = self.font.render(s, True, (255, 255, 255))
> gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, surface.get_width(),
> surface.get_height(), GL_RGBA, GL_UNSIGNED_BYTE,
> pygame.image.tostring(surface, "RGBA", True)
>
> Then, when rendering, transform the modelview matrix as in that link,
> and draw a quad with the correct aspect ratio.
>
> On Wed, Jul 1, 2009 at 10:58 PM, Astan Chee<astan.chee@xxxxxxxxx> wrote:
>
>
> Thanks for that, but it doesn't seem to work. Well, it gives coordinates of
> x,y(,z) but when the camera changes angle (but not position), the
> coordinates don't change. What else do I need to be doing in this?
> Anyway, I also forgot to mention this is how I make the text images:
> def __init__(self):
>         pygame.font.init()
>         self.font = pygame.font.Font(FONT,18)
>         self.char = []
>         for c in range(256):
>             self.char.append(self.CreateCharacter(chr(c)))
>         self.char = tuple(self.char)
>
>     def CreateCharacter(self,s):
>         try:
>             letter_render = self.font.render(s,1,(255,255,255), (0,0,0))
>             letter = pygame.image.tostring(letter_render,'RGBA',1)
>             letter_w,letter_h = letter_render.get_size()
>         except:
>             letter = None
>             letter_w = letter_h= 0
>         return (letter,letter_w,letter_h)
> Since I make the text this way, I'm thinking of just doing it billboard but
> I'm not sure how to implement half of this.
> Thanks again for any help.
> Cheers
> Astan
>
>
> Ian Mallett wrote:
>
> Er, the last three arguments return the data in C.  In Python, the syntax is
> different:
>
> C: gluProject(objx,objy,objz,model,proj,view,winx,winy,winz)
> Python: winx,winy,winz = gluProject(objx,objy,objz,model,proj)
>
> And yes, it returns a z-coord, which should take into account the near
> clipping plane.  As long as the plane is ~0, (x,y) should be fairly
> accurate.
>
> Keep in mind that the (x,y) coordinates are *real* coordinates, (i.e., the y
> is not flipped).  (0,0) is the bottom left.  If you rasterize the font as
> you were, it shouldn't be a problem.
>
> Ian
>
>
>
>
>
>
>