Jump to content

Draw Bitmap Rotated


stevel

Recommended Posts

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

Link to comment
Share on other sites

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...