Draw Bitmap Rotated

Expanding and utilizing the engine via C++.
4 posts Page 1 of 1
stevel
Posts: 11
Joined: Thu Mar 19, 2015 12:15 am
by stevel » Fri Sep 16, 2016 8:46 pm
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:

Code: Select all

// 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 :

Code: Select all

//
// 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 );
}

Attachments

new code.png
new code.png (4.16 KiB) Viewed 551 times
old code.png
old code.png (18.49 KiB) Viewed 551 times
Azaezel
Posts: 379
Joined: Tue Feb 03, 2015 9:50 pm
 
by Azaezel » Sun Sep 18, 2016 8:28 pm
stevel
Posts: 11
Joined: Thu Mar 19, 2015 12:15 am
  by stevel » Mon Sep 19, 2016 7:21 pm
Brilliant! Thank you!
kent
Posts: 35
Joined: Sun Sep 04, 2016 11:54 pm
by kent » Sat Sep 24, 2016 6:50 pm

Hey! This precise thing is on my todo list. Thanks.
4 posts Page 1 of 1

Who is online

Users browsing this forum: No registered users and 3 guests