zoukankan
html css js c++ java
一个简单的能处理MIPMAP的类
//
-------------------------------------------------------------------------
eiTexture::eiTexture(eiBool instance_type, eiBool mip_map_filter)
{
format
=
NONE;
type
=
SRC;
m_width
=
0
;
m_height
=
0
;
instance
=
instance_type;
use_mip_map
=
mip_map_filter;
bits
=
NULL;
}
//
-------------------------------------------------------------------------
eiTexture::
~
eiTexture()
{
}
//
-------------------------------------------------------------------------
eiBool eiTexture::load(eiChar
*
file_name)
{
CFile file;
if
(
!
file.Open( file_name, CFile::modeRead
|
CFile::shareDenyWrite ) )
{
msger.print(
"
Load texture failed.
"
);
return
false
;
}
BITMAPFILEHEADER bfhHeader;
file.Read(
&
bfhHeader,
sizeof
(BITMAPFILEHEADER) );
if
( bfhHeader.bfType
!=
0x4d42
)
{
msger.print(
"
Load texture failed.
"
);
return
false
;
}
eiUInt uBmpInfoLen
=
(eiUInt) bfhHeader.bfOffBits
-
sizeof
(BITMAPFILEHEADER);
LPBITMAPINFOHEADER m_lpBMPHdr
=
(LPBITMAPINFOHEADER)
new
eiByte [ uBmpInfoLen ];
eiUInt counts
=
file.Read(m_lpBMPHdr, uBmpInfoLen);
if
(m_lpBMPHdr
->
biSize
!=
sizeof
(BITMAPINFOHEADER))
{
msger.print(
"
Texture format error.
"
);
return
false
;
}
DWORD m_dwImageSize
=
m_lpBMPHdr
->
biSizeImage;
if
(m_dwImageSize
==
0
)
{
DWORD dwBytes
=
((DWORD) m_lpBMPHdr
->
biWidth
*
m_lpBMPHdr
->
biBitCount)
/
32
;
if
(((DWORD) m_lpBMPHdr
->
biWidth
*
m_lpBMPHdr
->
biBitCount)
%
32
)
{
dwBytes
++
;
}
dwBytes
*=
4
;
m_dwImageSize
=
dwBytes
*
m_lpBMPHdr
->
biHeight;
}
bits
=
(eiByte
*
)
new
eiByte [ m_dwImageSize ];
counts
=
file.Read(bits, m_dwImageSize);
file.Close();
m_width
=
m_lpBMPHdr
->
biWidth;
m_height
=
m_lpBMPHdr
->
biHeight;
delete []m_lpBMPHdr;
format
=
BMP;
normalize();
inv_width
=
1.0
/
m_width;
inv_height
=
1.0
/
m_height;
if
(use_mip_map)
{
make_mip_map();
}
return
true
;
}
//
-------------------------------------------------------------------------
eiVoid eiTexture::normalize()
{
eiByte
*
pbits;
eiInt n_width,n_height;
eiFloat dx,dy;
eiColor color;
pbits
=
bits;
n_width
=
(eiInt) powf(
2
, (eiInt) log2f( m_width )
+
1
);
n_height
=
(eiInt) powf(
2
, (eiInt) log2f( m_height )
+
1
);
dx
=
(eiFloat) m_width
/
(eiFloat) n_width;
dy
=
(eiFloat) m_height
/
(eiFloat) n_height;
src.resize( n_width
*
n_height
*
3
);
std::vector
<
eiByte
>
::iterator pbyPtr
=
src.begin();
for
(eiInt j
=
0
; j
<
n_height ; j
++
)
{
for
(eiInt i
=
0
; i
<
n_width ; i
++
)
{
color
=
get_bilinear_color( pbits, i
*
dx, j
*
dy );
pbyPtr[
0
]
=
(eiByte) ( color.b
*
255
);
pbyPtr[
1
]
=
(eiByte) ( color.g
*
255
);
pbyPtr[
2
]
=
(eiByte) ( color.r
*
255
);
pbyPtr
+=
3
;
}
}
delete []pbits;
bits
=
NULL;
m_width
=
n_width;
m_height
=
n_height;
}
//
-------------------------------------------------------------------------
eiInt eiTexture::get_width()
{
return
m_width;
}
//
-------------------------------------------------------------------------
eiInt eiTexture::get_height()
{
return
m_height;
}
//
-------------------------------------------------------------------------
eiColorB eiTexture::get_color(eiByte
*
dibbits, eiInt x, eiInt y)
{
eiColorB color;
color.r
=
color.g
=
color.b
=
0
;
if
(dibbits
==
NULL)
return
color;
if
(x
<
0
)
x
=
0
;
if
(x
>=
m_width)
x
=
m_width
-
1
;
if
(y
<
0
)
y
=
0
;
if
(y
>=
m_height)
y
=
m_height
-
1
;
eiByte
*
pbyPtr;
pbyPtr
=
dibbits
+
(y
*
m_width
+
x)
*
3
;
color.b
=
pbyPtr[
0
];
color.g
=
pbyPtr[
1
];
color.r
=
pbyPtr[
2
];
return
color;
}
//
-------------------------------------------------------------------------
eiColor eiTexture::get_bilinear_color(eiByte
*
dibbits, eiFloat x, eiFloat y)
{
eiInt u,v;
u
=
(eiInt) x;
v
=
(eiInt) y;
if
( (eiFloat) u
==
x
&&
(eiFloat) v
==
y )
{
eiColorB clr
=
get_color(dibbits,u,v);
return
newclr( clr.r
*
EI_BYTE_2_FLOAT,
clr.g
*
EI_BYTE_2_FLOAT,
clr.b
*
EI_BYTE_2_FLOAT );
}
eiFloat du,dv,r1,g1,b1,r2,g2,b2;
eiColorB c1,c2,c3,c4;
du
=
curve( x
-
u );
dv
=
curve( y
-
v );
c1
=
get_color(dibbits,u,v);
c2
=
get_color(dibbits,u
+
1
,v);
c3
=
get_color(dibbits,u
+
1
,v
+
1
);
c4
=
get_color(dibbits,u,v
+
1
);
r1
=
c1.r
+
(c2.r
-
c1.r)
*
du;
g1
=
c1.g
+
(c2.g
-
c1.g)
*
du;
b1
=
c1.b
+
(c2.b
-
c1.b)
*
du;
r2
=
c4.r
+
(c3.r
-
c4.r)
*
du;
g2
=
c4.g
+
(c3.g
-
c4.g)
*
du;
b2
=
c4.b
+
(c3.b
-
c4.b)
*
du;
r1
=
r1
+
(r2
-
r1)
*
dv;
g1
=
g1
+
(g2
-
g1)
*
dv;
b1
=
b1
+
(b2
-
b1)
*
dv;
r1
*=
EI_BYTE_2_FLOAT;
g1
*=
EI_BYTE_2_FLOAT;
b1
*=
EI_BYTE_2_FLOAT;
return
newclr(r1,g1,b1);
}
//
-------------------------------------------------------------------------
eiColorB eiTexture::get_src_color(eiInt x, eiInt y)
{
eiColorB color;
color.r
=
color.g
=
color.b
=
0
;
if
(src.empty())
return
color;
if
(x
<
0
)
x
=
0
;
if
(x
>=
m_width)
x
=
m_width
-
1
;
if
(y
<
0
)
y
=
0
;
if
(y
>=
m_height)
y
=
m_height
-
1
;
std::vector
<
eiByte
>
::iterator pbyPtr;
pbyPtr
=
src.begin()
+
(y
*
m_width
+
x)
*
3
;
color.b
=
pbyPtr[
0
];
color.g
=
pbyPtr[
1
];
color.r
=
pbyPtr[
2
];
return
color;
}
//
-------------------------------------------------------------------------
eiColor eiTexture::get_src_bilinear_color(eiFloat x, eiFloat y)
{
eiInt u,v;
u
=
(eiInt) x;
v
=
(eiInt) y;
if
( (eiFloat) u
==
x
&&
(eiFloat) v
==
y )
{
eiColorB clr
=
get_src_color(u,v);
return
newclr( clr.r
*
EI_BYTE_2_FLOAT,
clr.g
*
EI_BYTE_2_FLOAT,
clr.b
*
EI_BYTE_2_FLOAT );
}
eiFloat du,dv,r1,g1,b1,r2,g2,b2;
eiColorB c1,c2,c3,c4;
du
=
curve( x
-
u );
dv
=
curve( y
-
v );
c1
=
get_src_color(u,v);
c2
=
get_src_color(u
+
1
,v);
c3
=
get_src_color(u
+
1
,v
+
1
);
c4
=
get_src_color(u,v
+
1
);
r1
=
c1.r
+
(c2.r
-
c1.r)
*
du;
g1
=
c1.g
+
(c2.g
-
c1.g)
*
du;
b1
=
c1.b
+
(c2.b
-
c1.b)
*
du;
r2
=
c4.r
+
(c3.r
-
c4.r)
*
du;
g2
=
c4.g
+
(c3.g
-
c4.g)
*
du;
b2
=
c4.b
+
(c3.b
-
c4.b)
*
du;
r1
=
r1
+
(r2
-
r1)
*
dv;
g1
=
g1
+
(g2
-
g1)
*
dv;
b1
=
b1
+
(b2
-
b1)
*
dv;
r1
*=
EI_BYTE_2_FLOAT;
g1
*=
EI_BYTE_2_FLOAT;
b1
*=
EI_BYTE_2_FLOAT;
return
newclr(r1,g1,b1);
}
//
-------------------------------------------------------------------------
eiVoid eiTexture::blt(eiInt x1,eiInt y1,eiInt x2,eiInt y2,
eiInt width,eiInt height)
{
eiInt c1,c2,c3,c4;
std::vector
<
eiByte
>
::iterator pbyPtr;
for
( eiInt j
=
y1, mj
=
y2 ; j
<
(y1
+
height) ; j
+=
2
, mj
++
)
{
for
( eiInt i
=
x1, mi
=
x2 ; i
<
(x1
+
width) ; i
+=
2
, mi
++
)
{
pbyPtr
=
mip_map.begin()
+
j
*
m_width
+
i;
c1
=
pbyPtr[
0
];
c2
=
pbyPtr[
1
];
pbyPtr
+=
m_width;
c3
=
pbyPtr[
0
];
c4
=
pbyPtr[
1
];
pbyPtr
=
mip_map.begin()
+
mj
*
m_width
+
mi;
pbyPtr[
0
]
=
(eiByte) ( (eiFloat) ( c1
+
c2
+
c3
+
c4 )
*
0.25
);
}
}
}
//
-------------------------------------------------------------------------
eiVoid eiTexture::bltB(eiInt x1,eiInt y1,eiInt x2,eiInt y2,
eiInt width,eiInt height)
{
if
(width
==
0
||
height
==
0
)
return
;
eiInt width2,height2;
width2
=
width
/
2
;
height2
=
height
/
2
;
blt( x1, y1, x2, y2, width, height);
bltB( x2, y2, x2
/
2
, y2
/
2
, width2, height2 );
}
//
-------------------------------------------------------------------------
eiVoid eiTexture::bltG(eiInt x1,eiInt y1,eiInt x2,eiInt y2,
eiInt width,eiInt height)
{
if
(width
==
0
||
height
==
0
)
return
;
eiInt width2,height2;
width2
=
width
/
2
;
height2
=
height
/
2
;
blt( x1, y1, x2, y2, width, height);
bltG( x2, y2, x2
/
2
, y2, width2, height2 );
}
//
-------------------------------------------------------------------------
eiVoid eiTexture::bltR(eiInt x1,eiInt y1,eiInt x2,eiInt y2,
eiInt width,eiInt height)
{
if
(width
==
0
||
height
==
0
)
return
;
eiInt width2,height2;
width2
=
width
/
2
;
height2
=
height
/
2
;
blt( x1, y1, x2, y2, width, height);
bltR( x2, y2, x2, y2
/
2
, width2, height2 );
}
//
-------------------------------------------------------------------------
eiBool eiTexture::make_mip_map()
{
if
(format
==
NONE
||
type
==
MIP_MAP)
return
false
;
mip_map.resize( m_width
*
m_height );
eiColorB c1,c2,c3,c4;
eiFloat r,g,b;
std::vector
<
eiByte
>
::iterator pbyPtr;
eiInt width2,height2;
width2
=
m_width
/
2
;
height2
=
m_height
/
2
;
for
( eiInt j
=
0
, mj
=
0
; j
<
m_height ; j
+=
2
, mj
++
)
{
for
( eiInt i
=
0
, mi
=
0
; i
<
m_width ; i
+=
2
, mi
++
)
{
c1
=
get_src_color( i , j );
c2
=
get_src_color( i
+
1
, j );
c3
=
get_src_color( i
+
1
, j
+
1
);
c4
=
get_src_color( i , j
+
1
);
b
=
(eiFloat) ( (eiInt) c1.b
+
(eiInt) c2.b
+
(eiInt) c3.b
+
(eiInt) c4.b )
*
0.25
;
g
=
(eiFloat) ( (eiInt) c1.g
+
(eiInt) c2.g
+
(eiInt) c3.g
+
(eiInt) c4.g )
*
0.25
;
r
=
(eiFloat) ( (eiInt) c1.r
+
(eiInt) c2.r
+
(eiInt) c3.r
+
(eiInt) c4.r )
*
0.25
;
//
i have not considered efficiency problem in precomputing progress
/**/
/*
mip-map is built as follow :
NEXT GREEN
RED BLUE
*/
pbyPtr
=
mip_map.begin()
+
( mj
+
height2 )
*
m_width
+
mi
+
width2;
pbyPtr[
0
]
=
(eiByte) b;
pbyPtr
=
mip_map.begin()
+
mj
*
m_width
+
mi
+
width2;
pbyPtr[
0
]
=
(eiByte) g;
pbyPtr
=
mip_map.begin()
+
( mj
+
height2 )
*
m_width
+
mi;
pbyPtr[
0
]
=
(eiByte) r;
}
}
bltB( width2, height2, m_width
/
4
, m_height
/
4
, width2, height2 );
bltG( width2,
0
, m_width
/
4
,
0
, width2, height2 );
bltR(
0
, height2,
0
, m_height
/
4
, width2, height2 );
type
=
MIP_MAP;
return
true
;
}
//
-------------------------------------------------------------------------
eiFloat eiTexture::get_bilinear(eiFloat x, eiFloat y)
{
eiInt u,v;
std::vector
<
eiByte
>
::iterator pbyPtr;
u
=
(eiInt) x;
v
=
(eiInt) y;
if
( (eiFloat) u
==
x
&&
(eiFloat) v
==
y )
{
pbyPtr
=
mip_map.begin()
+
m_width
*
v
+
u;
return
pbyPtr[
0
]
*
EI_BYTE_2_FLOAT;
}
eiFloat du,dv,r1,r2;
eiByte f1,f2,f3,f4;
du
=
curve( x
-
u );
dv
=
curve( y
-
v );
pbyPtr
=
mip_map.begin()
+
m_width
*
v
+
u;
f1
=
pbyPtr[
0
];
f2
=
pbyPtr[
1
];
pbyPtr
+=
m_width;
f3
=
pbyPtr[
1
];
f4
=
pbyPtr[
0
];
r1
=
f1
+
(f2
-
f1)
*
du;
r2
=
f4
+
(f3
-
f4)
*
du;
r1
=
r1
+
(r2
-
r1)
*
dv;
return
r1
*
EI_BYTE_2_FLOAT;
}
//
-------------------------------------------------------------------------
eiColor eiTexture::get_pixel(eiFloat x, eiFloat y, eiInt d)
{
if
(src.empty()
||
( type
==
MIP_MAP
&&
mip_map.empty() ) )
return
newclr();
if
(d
==
0
)
{
return
get_src_bilinear_color( x, y );
}
eiFloat b,g,r,scale;
scale
=
1
/
powf(
2
, d );
eiFloat mx,my,width2,height2;
width2
=
m_width
*
scale;
height2
=
m_height
*
scale;
mx
=
x
*
scale;
my
=
y
*
scale;
b
=
get_bilinear( width2
+
mx , height2
+
my );
g
=
get_bilinear( width2
+
mx , my );
r
=
get_bilinear( mx , height2
+
my );
return
newclr(r,g,b);
}
//
-------------------------------------------------------------------------
eiColor eiTexture::lookup(
const
eiPlane
&
uv)
{
return
get_pixel(uv.x, uv.y, uv.z, uv.w);
}
//
-------------------------------------------------------------------------
eiColor eiTexture::get_pixel(eiFloat x, eiFloat y, eiFloat dx, eiFloat dy)
{
x
*=
m_width;
y
*=
m_height;
if
( type
==
SRC
||
( dx
==
0.0
&&
dy
==
0.0
) )
{
//
maybe shading for raytracing, do not use mip-map
return
get_src_bilinear_color( x, y );
}
dx
*=
m_width;
dy
*=
m_height;
eiFloat d;
eiInt di;
eiColor c1,c2;
d
=
max(dx,dy);
d
=
log2f(d);
di
=
(eiInt) d;
d
=
d
-
(eiFloat) di;
c1
=
get_pixel( x, y, di );
c2
=
get_pixel( x, y, di
+
1
);
return
mixclr( c1, c2, d );
}
//
-------------------------------------------------------------------------
查看全文
相关阅读:
西交应用统计学(四)
SPSS非参数检验
并查集实现
二叉树遍历非递归算法
算法导论——渐近符号、递归及解法
SPSS均值过程和T检验
二维数组的查找及向函数传递二维数组问题
printf()的格式
C++ string类型的读写
替换字符串中的空格
原文地址:https://www.cnblogs.com/len3d/p/188838.html
最新文章
大素数判断和素因子分解(millerrabin,Pollard_rho算法)
HDU 1151 Air Raid(最小路径覆盖)
KuhnMunkres算法(二分图最大权匹配)
HDU 1054 Strategic Game(二分图最小点覆盖)
转Primary Keys: IDs versus GUIDs (Mar 19, 2007)
unable to open an initial console解决
为Linux添加系统调用
linux中shell变量$#,$@,$0,$1,$2的含义解释
word2010公式编辑器(编辑office2003)
Linux内核中__init, __initdata, __initfunc(), asmlinkage, ENTRY(), FASTCALL()等作用
热门文章
diff和patch工具的使用
at91sam9g45 遇到的问题(不断更新)
国外的有名嵌入式网站收集
linux内核学习(好东西)
uboot make 错误总结
国内ARM开发网站列表
国外ARM开发网站列表
Ubuntu 12.04 root用户登录设置
SPSS报告
PS5选择选区操作
Copyright © 2011-2022 走看看