Jump to content

Draw Bitmap Rotated


Recommended Posts

Posted

I had a routine in a previous version of the engine, which would draw a rotated bitmap:

See old code.png attached.


Things changed, and the old code didn't work any more, so I tried to rewrite it, and got it mostly working, except for part of the bitmap, which isn't drawing correctly:

See New code.png attached


I'm not able to figure out what I need to do to get this new routine working like the old one, though I think the difference is just the fact that I had to use GFXTriangleStrip instead of GL_TRIANGLE_FAN


If someone who understands this stuff could look at these routines, and help me, it would be much appreciated.


old code:

 

// JSL - added for the HUD
//*********
void dglDrawBitmapRotated(TextureObject *texture,const RectI& dstRect,const RectI& srcRect,const U32 in_flip,F32 spinAngle)
{
  AssertFatal(texture != NULL, "GSurface::drawBitmapStretchSR: NULL Handle");
  if(!dstRect.isValidRect())
     return;
  AssertFatal(srcRect.isValidRect() == true,
              "GSurface::drawBitmapRotated: routines assume normal rects");
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, texture->texGLName);
  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  glEnable(GL_BLEND);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  glDisable(GL_LIGHTING);
  F32 texLeft   = F32(srcRect.point.x)                    / F32(texture->texWidth);
  F32 texRight  = F32(srcRect.point.x + srcRect.extent.x) / F32(texture->texWidth);
  F32 texTop    = F32(srcRect.point.y)                    / F32(texture->texHeight);
  F32 texBottom = F32(srcRect.point.y + srcRect.extent.y) / F32(texture->texHeight);
  F32 screenLeft   = dstRect.point.x;
  F32 screenRight  = dstRect.point.x + dstRect.extent.x;
  F32 screenTop    = dstRect.point.y;
  F32 screenBottom = dstRect.point.y + dstRect.extent.y;
  if(in_flip & GFlip_X)
  {
     F32 temp = texLeft;
     texLeft = texRight;
     texRight = temp;
  }
  if(in_flip & GFlip_Y)
  {
     F32 temp = texTop;
     texTop = texBottom;
     texBottom = temp;
  }

  glColor4ub(sg_bitmapModulation.red,
            sg_bitmapModulation.green,
            sg_bitmapModulation.blue,
            sg_bitmapModulation.alpha);

  F32 X = 0;
  // calculate the centroid of the rectangle (to use as rotation pivot)
  if (screenLeft < screenRight)
  {
       X = screenLeft + ((screenRight - screenLeft)*0.5f);
  }
  else
  {
       X = screenRight + ((screenLeft - screenRight)*0.5f);
  };
  F32 Y = 0;
  if (screenTop < screenBottom)
  {
       Y = screenTop + ((screenBottom - screenTop)*0.5f);
  }
  else
  {
       Y = screenBottom + ((screenTop - screenBottom)*0.5f);
  };

  // spin angle is in degree's so convert to radians..radians = degrees * pi /180
  spinAngle = spinAngle * 3.14 / 180.0f;
  Point2F screenPoint(X,Y); 
  F32 width = dstRect.extent.x;
  width *= 0.5;
  MatrixF rotMatrix( EulerF( 0.0, 0.0, spinAngle ) );
  Point3F offset( screenPoint.x, screenPoint.y, 0.0 );
  Point3F points[4];

  points[0] = Point3F(-width, -width, 0.0);
  points[1] = Point3F(-width,  width, 0.0);
  points[2] = Point3F( width,  width, 0.0);
  points[3] = Point3F( width, -width, 0.0);
  for( int i=0; i<4; i++ )
  {
     rotMatrix.mulP( points[i] );
     points[i] += offset;
  }
  glBegin(GL_TRIANGLE_FAN);
     glTexCoord2f(texLeft,texTop);
     glVertex2fv(points[0]);
     glTexCoord2f(texLeft, texBottom);
     glVertex2fv(points[1]);
     glTexCoord2f(texRight, texBottom);
     glVertex2fv(points[2]);
     glTexCoord2f(texRight, texTop);
     glVertex2fv(points[3]);
  glEnd();
  glDisable(GL_BLEND);
  glDisable(GL_TEXTURE_2D);
}

 


New code :

 

//
// JSL - added for the HUD
//*********
void GFXDrawUtil::drawBitmapRotated(GFXTextureObject *texture,const RectI& dstRect,const RectI& srcRect,F32 spinAngle)
{
  // Sanity if no texture is specified.
  if (!texture)
     return;

  GFXVertexBufferHandle<GFXVertexPCT> verts(mDevice, 4, GFXBufferTypeVolatile );
  verts.lock();

  F32 texLeft   = (srcRect.point.x)                    / (texture->mTextureSize.x);
  F32 texRight  = (srcRect.point.x + srcRect.extent.x) / (texture->mTextureSize.x);
  F32 texTop    = (srcRect.point.y)                    / (texture->mTextureSize.y);
  F32 texBottom = (srcRect.point.y + srcRect.extent.y) / (texture->mTextureSize.y);

  F32 screenLeft   = dstRect.point.x;
  F32 screenRight  = dstRect.point.x + dstRect.extent.x;
  F32 screenTop    = dstRect.point.y;
  F32 screenBottom = dstRect.point.y + dstRect.extent.y;

  // calculate the centroid of the rectangle (to use as rotation pivot)
  F32 X = 0;
  if (screenLeft < screenRight)
  {
       X = screenLeft + ((screenRight - screenLeft)*0.5f);
  }
  else
  {
       X = screenRight + ((screenLeft - screenRight)*0.5f);
  };
  F32 Y = 0;
  if (screenTop < screenBottom)
  {
       Y = screenTop + ((screenBottom - screenTop)*0.5f);
  }
  else
  {
       Y = screenBottom + ((screenTop - screenBottom)*0.5f);
  };

  // spin angle is in degree's so convert to radians..radians = degrees * pi /180
  spinAngle = spinAngle * 3.14 / 180.0f;
  Point2F screenPoint(X,Y); 
  F32 width = dstRect.extent.x;
  width *= 0.5;

  MatrixF rotMatrix( EulerF( 0.0, 0.0, spinAngle) );
  Point3F offset(screenPoint.x, screenPoint.y, 0.0 );
  Point3F points[4];

  points[0] = Point3F(-width, -width, 0.0);
  points[1] = Point3F(-width,  width, 0.0);
  points[2] = Point3F( width,  width, 0.0);
  points[3] = Point3F( width, -width, 0.0);
  for( int i=0; i<4; i++ )
  {
     rotMatrix.mulP( points[i] );
     points[i] += offset;
  }

  const F32 fillConv = mDevice->getFillConventionOffset();
  verts[0].point.set( points[0].x - fillConv, points[0].y - fillConv, 0.f );
  verts[1].point.set( points[1].x - fillConv, points[1].y - fillConv, 0.f );
  verts[2].point.set( points[2].x - fillConv, points[2].y - fillConv, 0.f );
  verts[3].point.set( points[3].x - fillConv, points[3].y - fillConv, 0.f );

  verts[0].color = verts[1].color = verts[2].color = verts[3].color = mBitmapModulation;

  verts[0].texCoord.set( texLeft,  texTop );
  verts[1].texCoord.set( texLeft,	texBottom );
  verts[2].texCoord.set( texRight,	texBottom );
  verts[3].texCoord.set( texRight,	texTop );

  verts.unlock();

  mDevice->setVertexBuffer( verts );

  mDevice->setStateBlock(mBitmapStretchWrapLinearSB);

  mDevice->setTexture( 0, texture );
  mDevice->setupGenericShaders( GFXDevice::GSModColorTexture );
  mDevice->drawPrimitive( GFXTriangleStrip, 0, 2 );
}

2048438751_oldcode.png.452a648ff1a561f12e4ac7f7322dab4e.png

665789804_newcode.png.72ce8273aea2a8d820bf6d3eba93a1a4.png

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...