Hi, i need draw a fog background, i search Internet find a source, but it run slow, how to optimize these code let it run fast( i nill malloc memory in twice, i want to unite DrawGradient function and ApplyTransformation function). or tell me other draw example.
Thanks.
<br />
#if !defined(AFX_GRADIENTRENDER_H__9B3090DB_F7D0_4D23_8BDA_9CFAC9A64ABE__INCLUDED_)<br />
#define AFX_GRADIENTRENDER_H__9B3090DB_F7D0_4D23_8BDA_9CFAC9A64ABE__INCLUDED_<br />
<br />
#if _MSC_VER > 1000<br />
#pragma once<br />
#endif // _MSC_VER > 1000<br />
<br />
class CGradientRender <br />
{<br />
private:<br />
unsigned char* m_Data;<br />
void ApplyTransformation(int width, int height);<br />
<br />
public:<br />
void DrawGradient( HDC hDC, RECT& rect, COLORREF startColor, COLORREF endColor);<br />
<br />
CGradientRender();<br />
virtual ~CGradientRender();<br />
<br />
};<br />
<br />
#endif // !defined(AFX_GRADIENTRENDER_H__9B3090DB_F7D0_4D23_8BDA_9CFAC9A64ABE__INCLUDED_)
<br />
#include "stdafx.h"<br />
#include "GradientRender.h"<br />
#include "math.h"<br />
<br />
#ifdef _DEBUG<br />
#undef THIS_FILE<br />
static char THIS_FILE[]=__FILE__;<br />
#define new DEBUG_NEW<br />
#endif<br />
<br />
<br />
CGradientRender::CGradientRender()<br />
{<br />
m_Data = NULL;<br />
}<br />
<br />
CGradientRender::~CGradientRender()<br />
{<br />
if ( m_Data != NULL )<br />
delete m_Data;<br />
}<br />
<br />
void CGradientRender::DrawGradient( HDC hDC, RECT& rect, COLORREF startColor, COLORREF endColor)<br />
{<br />
int i, j;<br />
double r;<br />
int X, Y;<br />
double fi;<br />
int width = rect.right - rect.left;<br />
int height = rect.bottom - rect.top;<br />
int size = height*width*4;<br />
double radius = sqrt( pow(height/2,2) + pow(width/2,2) );<br />
double R = sqrt( pow(width/4,2) + pow(height/4,2) );<br />
<br />
m_Data = new unsigned char[size];<br />
<br />
for ( i=0; i<height; i++ )<br />
{<br />
for ( j=0; j<width; j++ )<br />
{<br />
r = sqrt( pow(double(i-height/2)/radius,2) + pow(double(j-width/2)/radius,2) );<br />
if ( r <= 1.0 )<br />
{<br />
m_Data[i*width*4 + j*4] = (unsigned char)(r*GetBValue(endColor) + (1-r)*GetBValue(startColor));<br />
m_Data[i*width*4 + j*4+1] = (unsigned char)(r*GetGValue(endColor) + (1-r)*GetGValue(startColor));<br />
m_Data[i*width*4 + j*4+2] = (unsigned char)(r*GetRValue(endColor) + (1-r)*GetRValue(startColor));<br />
}<br />
else<br />
{<br />
m_Data[i*width*4 + j*4] = GetBValue(endColor);<br />
m_Data[i*width*4 + j*4+1] = GetGValue(endColor);<br />
m_Data[i*width*4 + j*4+2] = GetRValue(endColor);<br />
}<br />
<br />
}<br />
}<br />
<br />
<br />
ApplyTransformation( width, height );<br />
<br />
HBITMAP hBitmap = (HBITMAP)CreateBitmap( width, height, 1, 32, m_Data );<br />
<br />
HDC hMemDC = CreateCompatibleDC(hDC);<br />
HBITMAP hOldBitmap = (HBITMAP)SelectObject( hMemDC, hBitmap );<br />
<br />
BitBlt( hDC, rect.left, rect.top, width, height, hMemDC, 0, 0, SRCCOPY );<br />
<br />
SelectObject( hMemDC, hOldBitmap );<br />
DeleteDC(hMemDC);<br />
DeleteObject(hBitmap);<br />
delete m_Data;<br />
m_Data = NULL;<br />
}<br />
<br />
void CGradientRender::ApplyTransformation(int width, int height)<br />
{<br />
int X, Y;<br />
double r, fi;<br />
double R = sqrt( pow(width/4,2) + pow(height/4,2) );<br />
<br />
int size = height*width*4;<br />
unsigned char* newBuffer = new unsigned char[size];<br />
memcpy( newBuffer, m_Data, size );<br />
<br />
for ( int i=0; i<height; i++ )<br />
{<br />
for ( int j=0; j<width; j++ )<br />
{<br />
fi = atan(double(i-height/2)/double(j-width/2));<br />
r = sqrt( pow((i-height/2),2) + pow((j-width/2),2) );<br />
X = int((pow(r,2)/R)*cos(fi));<br />
Y = int(fabs((pow(r,2)/R)*sin(fi))) % height;<br />
newBuffer[i*width*4 + j*4] = m_Data[Y*width*4 + X*4];<br />
newBuffer[i*width*4 + j*4+1] = m_Data[Y*width*4 + X*4+1];<br />
newBuffer[i*width*4 + j*4+2] = m_Data[Y*width*4 + X*4+2];<br />
}<br />
}<br />
<br />
memcpy( m_Data, newBuffer, size );<br />
delete newBuffer;<br />
}
|