From e1b1056d314236a137539539285e6543368e8a3d Mon Sep 17 00:00:00 2001 From: Vadim Lopatin Date: Wed, 6 Apr 2016 14:39:52 +0300 Subject: [PATCH] fix mipmap levels support --- examples/d3d/src/d3d.d | 1 + examples/d3d/src/dminer/core/blocks.d | 40 ++++++++++++++++++------- examples/d3d/views/res/mdpi/blocks.png | Bin 22935 -> 31980 bytes src/dlangui/graphics/gldrawbuf.d | 10 +++---- src/dlangui/graphics/glsupport.d | 12 +++++--- src/dlangui/graphics/scene/material.d | 10 +++++-- 6 files changed, 51 insertions(+), 22 deletions(-) diff --git a/examples/d3d/src/d3d.d b/examples/d3d/src/d3d.d index d1158975..eb1d5ab9 100644 --- a/examples/d3d/src/d3d.d +++ b/examples/d3d/src/d3d.d @@ -198,6 +198,7 @@ class UiWidget : VerticalLayout, CellVisitor { updateMinerMesh(); Material minerMaterial = new Material(EffectId("textured.vert", "textured.frag", null), "blocks"); + minerMaterial.textureLinear = false; Model minerDrawable = new Model(minerMaterial, _minerMesh); Node3d minerNode = new Node3d("miner", minerDrawable); _scene.addChild(minerNode); diff --git a/examples/d3d/src/dminer/core/blocks.d b/examples/d3d/src/dminer/core/blocks.d index 4fe5e895..f1866525 100644 --- a/examples/d3d/src/dminer/core/blocks.d +++ b/examples/d3d/src/dminer/core/blocks.d @@ -8,9 +8,9 @@ immutable string BLOCK_TEXTURE_FILENAME = "blocks"; immutable int BLOCK_TEXTURE_DX = 1024; immutable int BLOCK_TEXTURE_DY = 1024; immutable int BLOCK_SPRITE_SIZE = 16; -immutable int BLOCK_SPRITE_STEP = 20; -immutable int BLOCK_SPRITE_OFFSET = 21; -immutable int BLOCK_TEXTURE_SPRITES_PER_LINE = 50; +immutable int BLOCK_SPRITE_STEP = 16; +immutable int BLOCK_SPRITE_OFFSET = 0; +immutable int BLOCK_TEXTURE_SPRITES_PER_LINE = 1024/16; immutable int VERTEX_COMPONENTS = 12; enum BlockVisibility { @@ -232,6 +232,24 @@ void registerBlockType(BlockDef def) { BLOCK_TERRAIN_SMOOTHING[def.id] = def.terrainSmoothing; } +enum BlockImage : int { + stone, + grass_top, + grass_side, + grass_top_footsteps, + dirt, + bedrock, + sand, + gravel, + sandstone, + clay, + cobblestone, + cobblestone_mossy, + brick, + stonebrick, + red_sand, +} + /// init block types array __gshared static this() { import std.string; @@ -248,14 +266,14 @@ __gshared static this() { // empty cell registerBlockType(new BlockDef(0, "empty", BlockVisibility.INVISIBLE, 0)); // standard block types - registerBlockType(new BlockDef(1, "gray_brick", BlockVisibility.OPAQUE, 0)); - registerBlockType(new BlockDef(2, "brick", BlockVisibility.OPAQUE, 1)); - registerBlockType(new BlockDef(3, "bedrock", BlockVisibility.OPAQUE, 2)); - registerBlockType(new BlockDef(4, "clay", BlockVisibility.OPAQUE, 3)); - registerBlockType(new BlockDef(5, "cobblestone", BlockVisibility.OPAQUE, 4)); - registerBlockType(new BlockDef(6, "gravel", BlockVisibility.OPAQUE, 5)); - registerBlockType(new BlockDef(7, "red_sand", BlockVisibility.OPAQUE, 6)); - registerBlockType(new BlockDef(8, "sand", BlockVisibility.OPAQUE, 7)); + registerBlockType(new BlockDef(1, "gray_brick", BlockVisibility.OPAQUE, BlockImage.stonebrick)); + registerBlockType(new BlockDef(2, "brick", BlockVisibility.OPAQUE, BlockImage.brick)); + registerBlockType(new BlockDef(3, "bedrock", BlockVisibility.OPAQUE, BlockImage.bedrock)); + registerBlockType(new BlockDef(4, "clay", BlockVisibility.OPAQUE, BlockImage.clay)); + registerBlockType(new BlockDef(5, "cobblestone", BlockVisibility.OPAQUE, BlockImage.cobblestone)); + registerBlockType(new BlockDef(6, "gravel", BlockVisibility.OPAQUE, BlockImage.gravel)); + registerBlockType(new BlockDef(7, "red_sand", BlockVisibility.OPAQUE, BlockImage.red_sand)); + registerBlockType(new BlockDef(8, "sand", BlockVisibility.OPAQUE, BlockImage.sand)); registerBlockType(new BlockDef(50, "box", BlockVisibility.HALF_OPAQUE, 50)); diff --git a/examples/d3d/views/res/mdpi/blocks.png b/examples/d3d/views/res/mdpi/blocks.png index 5a6c999b82b9a496cf1f6ff4105e6e0af4ea3a60..0440ab4bfce11772ed34fd0f01bb48077f628b10 100644 GIT binary patch literal 31980 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 literal 22935 zcmeHv4OEj?x^660W(tMQnmZz>q#aQ@qGEvp8X&E_ss3;X>Zr8WPN-I zn|%59e&2UL@AJHSlkdI?^n3q3yZ2x)*!!q$U+jXx-UTn;h5ca(cp|NI$^uVIzVY|_ z0`?y4uQ0@>Pada$mOmcZ7Mcu$S^RnaXA!KZWEp5QPeJYY(p>mQD~ol1qSBZZplM}n z@ZOZI*u#gT6X!33!L}wvA4rLg`VbeJa_B=p)Q+#BHbk4lU?0LzUwj^%HZVC9f3iYz zK&TNma4C{b!To*JA#Tq9SljjeB3_~0(yJwPe_HGj@?^=exH{CgH;FsVvcGj7diToW zmb~Sk932_|I#L;Z<;$|G&vbA*OG9mmM8#ZLLB<#Gg0`p`r$~LvAM;yBr_;RbpFcHer|oBF z3u_D`Q7)8#m#xqL$jQg-9C`IdFZ&u8_aAo_uJl4LD*ZD1^^bbTE4TfR>ZNc(%nTaY zL`3??1^rM<#*QZ9PdD?jmq!+AMr=;_vCn0n5Y@{_sz|E|eKQvuLq)h3!4`y+$&k(x;`%V6$myaJ5RKdpWYfMN>vhC+U3d zR~DSBByZyRRkmpMs0uVsPZ1w4x+Qrz#A1xxJZ#x~yC%b%*i?#u`PhTgOPe*pj~+N; zeydfeP|Z%`pWjEWv4qvYe=>JXuzahtrQUk8Vgn4G%v}jXqQMDnE&s8f5Ba?Ol+}c# zg_{UAFyYADG+xteEZq!^D&Fb__a83i!lS8vOY${F8y#FtTJ_3K0x!bSzr3{B{Egq6 zTDSI<^+Cg5hC_p2-fO-cffC$yIe+QJL(#M9?4qw4Q=T(MzTNEi;9QPrTB4Ctwu^Zla0?*D~3ikqONs`$4+w% z5$?^?T=*481{t|Cg9_)TeUMhaJ3iTUC{gpUCYBi%ThHeS1fBag-cR!iWQK9>=GxTO z*PmrFnN6y`a12Y-pgR=F8Pj$@UcY(Ut!^Ut7u98k@(awz0^FY`%?j>7yIx$93+2c9^& zdkjA=IX>TqJvCm-UyqJ7II_mL)35}zBMes4v`WaJmhx@$TY*;^lJ&m#3NH30L~ndn zfyPz}4#l|GR|pPO@=A=N+edz2P^olH<8JxnpV-3NID=49?qRo5tEKvQ8>|!p0h)Yq zC{Z-nklc{2h_TO9b^&{3==s9VYzv$2#QGj->TY`QwdUs1`2K3|VZ)YV(CUaEX=hS> zhXU6yqaKQ*Tvl8ZpdX}>Po8Kw>6;b2rtnc*UVv|T@X|2)*K6osPc-N}Dh1s2LFPq{ z_N2c$H_y&HZ0yP1+;nYFWT&`?mOOH2VzLp6kB@Ii5hv+biOrfB%{AcLFh=S#1%h-K z-+E`OsPpL~iXygdX_EHO7{!pBRWf~}EQIhkYwsj?p;m@-EeYO@byFy5W!o?qgap%B z(RGg4YMdZlg;Xrjr~AUf@Ho^Z4_AA2kJ$R!wQFQ5gK<4P&r&~hd4n_NvAl99?xG;V zQ>iuRXhM}$v%bthg?DW^fTVV&_61VQGW*#=NtE=FR!N`&hsM?o0S5!2 zmZC{bGU&p2j|T&fLHDwZ`|%$&u~?Mt%rhfL&Pf@Z!KP!b^;nkTczr{EvEjaF=wXj* zSNjQEcq8@m5PsfPsPlHdnY`jGy4~NI^#iyjj#(5)D**P7#$ug?v-dn^q*xL{h4(Hl zE^as`2@w$WQs6*GY_m27%ow{oU%R|}58~^JV(W@(`EzIc`dzC%cGG)z(LG!q^LMb& zLG0SIaTTRuRfPd$d@bePp&zFApNpx|R`*A2ONRccz3K<&jE~1G<>#i)eCG)Kv&uSR z4yUQiYAXoxqJSxP(zhHO6r8sEZbWm+CyWrM(P_`{Vq6aoD!EBO^dNUf|4=J}ceYql zxx35oE*>6rwXFV*z9B?Irh+=ytnD<56r$GF@(r!!2V87}u+vy~mx*KDiJx|h-;c4G zQyI!F;4vd$B$R+Pwc&Ht8`KD@l((2v+Z%XLSoiE@PDt|-m=ju4%|B}#>I`9@Rfsxi zdm5fO3Q(5{ zD|_J4UiOX!;?Iu69A4dD z6Ui0tu9|;OrJ&zRxM(9Kz{UQ3Fr_QaZW;Yn7w{HC?cO%e3Z@Tjo}ENG4NqY0o6YvS z*kU}FT@0(jxJ@FbRPl8KwYiXkZN48pB)%52c&~CHGsz7sYt`{@@3xjwyuFXe3z2v( zNwlX~ol{V?r<4PqbA~=f%}`0&Z^&X?vdutltb0+d#l659kH#YrX!MTyeolAy_7hn| z*&wUfL7OTO-tTqdjs3(ffsOH85#weTjl+2? zU%q@(+NmcPD63{{q7b97CP7swGMZK}erLq!K)=*E$e(@h4o24kbr_&k#j@{(&0?2nfu z3NjSW@$OExAK3wFWduE)zafG&iYz7)TTq>sYsMbv!m5Qg3S(+1M0VMpNRoFxy1B%+ z{4~gti5O=vtCD3GEX0%2O5VA|FNB*_7SG2#T4O8}FV-6)soU4k`zG3=O5#|Q18ju8 z8cJCvuIwqcxA43%8$>2uS5`g0pa2rHiNlicsvxM^t%w0|Y^#mYfX1Y*8y1)^Hd@yh z6ROea?uFaOR;3@hcUy>ANI=Clax*z>Z^k60jb&rdKpMTxiO7s7yuVKDDso+++)WSU zUc?~~vCILwM^WhBh`@5Re??fw{*BvenWysd_@SYp{_a#A$w`nteKgO*%9a!3+8d`jrLpLpo-9+T zQ+xLA-Ch;ac5xSq)o{wUkt!1e#sRM}Le`94?2e1_vRiFSLt`;sD_Dfq7USZ%D6j2| z5QH)cs-*>qx+^*wQl)uKb2MkTZm_Sf?;0^~y~=>|^PK7&q*$$ucakOyHc%?Y3f+o1 zlL^=g=EKg33HtRg#-q5NnlCX}4-vfi9Pkh>QP5eDYYm?r0)jWhd$1fN07ASgPBz#s4VPcsMUTQ@oEjUcld{wp0hKB{ zjda)O{7SXLK}j?LqQI)8IPPS97z6bCa&>j(F8b3+UhO=A%UkZTiyoXb@ra%=?poG1 zF%h@a#%6a_?|hce&dv_5>P^66F$98s2#GzWTN}8x&@C?Sq+g4&wFR6XX@py9&|o%| z8nsS^DBrBlm$1-wg}!SFcJ9j5sFqvlY^`)+)#mi+yV!9@dqdQQeK$)0IAIPP-GsW< z)KmiaqL+$Jo4LO#KkD$|^|bz==uuhB{B)aa)@%1=%w}xx$?yT$H{bBjgY=Lpkb_!l zZxT1txFwvsIb2%5^y1KE0BC4#`$U*J6_;eV$0+e;mH>DL%IQ|WMo_N=y_nA&@+r92 zlzg~fsmpp4Zeg3}D^@N6hc#Z)R1wMU=Kw9W@2OC4c|4V{dPs&YVx%s~LT{!@Q#SKE zl~b=!PGFt}*Sf;&iF!b(D=Gjo#U#hOGC~OIea5qq4X%2o#yH0kM9wNA@j@XEBo;`w zr+KCsnnPm&DxqfXEyqU1#{R8v`)X+_A~!cT6pfzeSJxUFi}#?@qf-T>g9lf&jBErs zony$=naQ0u1Vr9B$}SrK>=?D0B}j}bzo(>_b7Jm|9xdWzTjF~Z24;v;Zf=LIm7bzB zr?0QW1o5D33x9o?ki)|n;d>8X>P<*Y90$R^>DWZd2JfW5AsPv>?lwsVs-%aDg-#mE z=sS???GWKS5b{0=Od@nfO|X3e2QIZAu|&atj`g@ z+s<-Q4(X%9NtJml?dp7Dj^VY3$o+O=U-QhQv6g?};JefRn#iqo-T?*}iX1ceA6MToW1=$=we< zsSB$SS>KHGR9YVIkj#Hhnb!e#Nsff2~Y|?u>FlVLjW%f+E_TgxZiWCrpy;0p4An zcoFc7gUR@v#L;PymABc46d&{RT?s314zWXPDtpmInJk;LmALhT2ulY)q}h31931>< zCpPA&HkcemkaSKm-jO5U8McMJfkJ*n^IL3QX=!ndM-kKBEI3`a4BR{Z*rAY^v4sDPkpC(}Qi<(QzN0id{oeH)C zbFV4ixz>VVc_Qmkl`85&Y1n}6F$Coi`Ey!9+mTav!Y89`jb*~K&iew%0OtbM6f~)I zBccz$gwIgdA}J&1%K-Fn?;ZEoLxS6_g-{x_Z?S#mUr{sj5<L zh!C-_U;iPBj9N?YE4H=PiD+$#=>D!#pxwHVLm0*N9P*Wp1?PuS%JIK3`R*H`s@0F+?NmNP%fgUnJXNI*o&^?M{Px{(g zp8$e_-Y02GE2&VaPD(hzam?U}JWF-z?wWoK8i&QGZvyi#PgfS4#n|-t`}>DRA`2RE z@&{=Cy!Lx8R}^@__Uh_nG4T@F1A=5=c{=zJzwc;k=@*Jdc&|h+9RRb6H*lj6B-kEW zNb;yIJl4$)sB~9Axf{cmhaL*9efVRu{^Z|@nuoSfR*tc^*rK*RsR=shWw)l_s9M(o zgx&RUxlh3bp=8D8QPPpy!USf|4bjlMGQ+YLk^=J%5OHrqe46zsX_JqK`eAxDFwU3SyycwFuKB;=W=t1WmGC_ zZqC_Iu?i`ie>s^63KDZF;W>PNO%V5f4TCYS;|K(TR@X1|cA4r6$Bx~}wg8^hO*WD0 z`8&W-v8#=bWm6rrHqd^^7N!!fw6O5+X!8U)F0P^oMLHEn_@sd7JnGOwME1sg+S28j z>)#=kOQT$tMZ4M21QHIK-BFLGW^O1mDlsvbDGymr+R0ut%1b2YuB4xR=O`8;PHpr#%gKFI9jn|S(+DiANw>_%23{cZ4kYa>0-ab@4Kw}MI|R)?eb!y-1ha47w#|anS|Rn0-iFxGQ6*O23=J#t`9Rh= z)TpJG&CxSNkTinj!~`~c#m?DsLC^%11Sr8Ubz}26#0S!fT^DbNxN&M8{DFL}VH@!`hZ6BD!Q_SGRaI4h zEi@b*^^F5cfErlD8K2yCi>>Z}I3OjkpSS&4o)aWQRQb`oak% zYpj@&osclt+1{>f>?JfJHf4@yfN8$ASFC5f&;_-K#nm!WtFeG8GdBv%ZRX(P3cjGU z)E0@8MKl{#HJIy=*SCOu@=hNI3R{V1ty{moBBTmv+2_TnOns`(VEjlfv<+gnpsOBr zA7Z-LIu?ek8twYH%~OR(jE;N^L;{O7x???HAjcqEONh4~xU7BVetP)9*XF)QO4tl_cFCmM&PKu9oy-~`@nVL5&$T~4Nj4L*x z@yvX&s3F-26pISBSCFYx1~1%j`0xi=llK3yYEN2Y`-+Gy~_LU zr?~}?ydHpaCiJ8UjqPmuob5r_=Pnz3Fg`whp+6dj!T+z}0cMM}`5=$iu99HAr&OM} z7;jPMWl^znrn8N+S4rIJbSV?mFjD7>Dy&4us(4!WA-5#sAP*$n3NO5NS1C~^Ubk-D z(zpECD$!Vy8Ss@_9TEFRI3#+=t=yiP0OEUF1tU z1rs&BaTUCT%HFs!RevNGkjrpex9%La^D(1sdK~-BLjJd*k=%W-hW@x+S zop<^2nCu<{5dT0Vo9&?@R+5}hGi^a$_L1@GdZuY!tzA<^`!&ar;hd%JUeyP7KW;#yadhU=Zl7g~ z)Fi1|mbkQ7#rwk%m4`Lb>_ZeNl)lC889bcU`rdH|-au3Ov%p2KbA1+Db6U9Q)bq|=jkoG= zWgnQ?O5A(sm52i_*UzTGZ)}|V(d>BkiI=NI;Qmc;w&q)l7K4ov`HUO>#ubP)*y*d7 zH5y}DO&N5>q9uPbSfhIVBN1!ltPN9gsG-~!hJ!6gM*Do+mL_;K?1(vRp~63%=J-#< zgc<@XU1>J3g%|{5IFCDW0V)?P8s7J6p=y3a`eg**oOnY{d_*>KKE*gCh@ zhrO}@_lR%EJXgOc<;}Y)M47{PhOOSbV>1|Y7H-i3umk%)B>?-p-L>ZbetA)Vnz1^w zuo`9GVEL1?CgzlnzlVA5zWthu1#{`0!LM6s&+-5M)BjJ4m+!r9(Zy*$Zz0X;R_%|! zs}A7EOO{j{1VqWNtwdlmZLb*o@+n#+S!>iU=0eg5`3;qPvEzq*5|4)XoBU%jwj zuU34zbZ>kP`5{^9tW=Hirz0v7+@!l&r;M^-QQ0?fbXU#-dh``OyD4Y7Ag@C#cW zBjTUFw&Hvc@y_s@rc;PEy)n1{{io``ie(cN{xU2!LE(SdsPnUO-TxdEn&8g_f2}_^ zznS3A1b?q_)1MnYznDLm;O}Se1AQaCnAqPNTP}ZY{F>m;1b-&@ds)@`f7ylp2KxMe zFXWiu&jf!9rQP2=eof-nBz|A3O#bG@M-%*+;LikqKM}Yl@IP|DFLv^;=#feMn#AwI zLhElHzb5f(62B(#YZAZD8SHP4KEJqh{9m?Fd=PJ03xh2io&R2dpSfei1cm=TP-uXp z{0n(se)7S)w>yv%`IhgOrIc2$=Bzz_`b_KS;2#Mw-o&BWP$;UxN%FE^#p|IsvR+$1VV?)=v$ dS){;vMZwi8K5#4Q{P!cHz6|`LddvR5|8HR(a%TVl diff --git a/src/dlangui/graphics/gldrawbuf.d b/src/dlangui/graphics/gldrawbuf.d index abca55e6..69fc7c9d 100644 --- a/src/dlangui/graphics/gldrawbuf.d +++ b/src/dlangui/graphics/gldrawbuf.d @@ -833,14 +833,14 @@ static class GLTexture : RefCountedObject { return uv(_dx, _dy); } - this(string resourceId) { + this(string resourceId, int mipmapLevels = 0) { import dlangui.graphics.resources; _resourceId = resourceId; string path = drawableCache.findResource(resourceId); - this(cast(ColorDrawBuf)imageCache.get(path)); + this(cast(ColorDrawBuf)imageCache.get(path), mipmapLevels); } - this(ColorDrawBuf buf) { + this(ColorDrawBuf buf, int mipmapLevels = 0) { if (buf) { _dx = buf.width; _dy = buf.height; @@ -853,7 +853,7 @@ static class GLTexture : RefCountedObject { } uint * pixels = buf.scanLine(0); buf.invertAlpha(); - if (!glSupport.setTextureImage(_texture, buf.width, buf.height, cast(ubyte*)pixels, 10)) { + if (!glSupport.setTextureImage(_texture, buf.width, buf.height, cast(ubyte*)pixels, mipmapLevels)) { destroy(_texture); _texture = null; buf.invertAlpha(); @@ -896,7 +896,7 @@ class GLTextureCache { if (auto p = resourceId in _map) { return *p; } - GLTexture tx = new GLTexture(resourceId); + GLTexture tx = new GLTexture(resourceId, 6); _map[resourceId] = tx; return tx; } diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index 5f86d014..fcd3f5fa 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -973,7 +973,7 @@ final class GLSupport { } srcptr += srcstride; // skip srcline } - glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, newdx, newdy, 0, GL_RGBA, GL_UNSIGNED_BYTE, dst.ptr); + checkgl!glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, newdx, newdy, 0, GL_RGBA, GL_UNSIGNED_BYTE, dst.ptr); return true; } @@ -983,8 +983,10 @@ final class GLSupport { checkgl!glPixelStorei(GL_UNPACK_ALIGNMENT, 1); texture.setSamplerParams(true, true); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, mipmapLevels > 0 ? mipmapLevels - 1 : 0); // ORIGINAL: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dx, dy, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dx, dy, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + checkgl!glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, dx, dy, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); if (checkError("updateTexture - glTexImage2D")) { Log.e("Cannot set image for texture"); return false; @@ -1185,8 +1187,10 @@ class GLObject(GLObjectTypes type, GLuint target = 0) { static if(type == GLObjectTypes.Texture) { void setSamplerParams(bool linear, bool clamp = false, bool mipmap = false) { - glTexParameteri(target, GL_TEXTURE_MAG_FILTER, linear ? (!mipmap ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR) : (!mipmap ? GL_NEAREST : GL_NEAREST_MIPMAP_NEAREST)); - glTexParameteri(target, GL_TEXTURE_MIN_FILTER, linear ? (!mipmap ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR) : (!mipmap ? GL_NEAREST : GL_NEAREST_MIPMAP_NEAREST)); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, linear ? GL_LINEAR : GL_NEAREST); + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, linear ? + (!mipmap ? GL_LINEAR : GL_LINEAR_MIPMAP_LINEAR) : + (!mipmap ? GL_NEAREST : GL_LINEAR_MIPMAP_LINEAR)); //GL_NEAREST_MIPMAP_NEAREST checkError("filtering - glTexParameteri"); if(clamp) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); diff --git a/src/dlangui/graphics/scene/material.d b/src/dlangui/graphics/scene/material.d index 18326010..c0706e57 100644 --- a/src/dlangui/graphics/scene/material.d +++ b/src/dlangui/graphics/scene/material.d @@ -24,6 +24,7 @@ class Material : RefCountedObject { // textures protected TextureRef _texture; protected string _textureId; + protected bool _textureLinear = true; protected TextureRef _bumpTexture; protected string _bumpTextureId; @@ -109,6 +110,8 @@ class Material : RefCountedObject { _textureId = resourceId; return this; } + @property bool textureLinear() { return _textureLinear; } + @property Material textureLinear(bool v) { _textureLinear = v; return this; } @property TextureRef bumpTexture() { @@ -150,11 +153,11 @@ class Material : RefCountedObject { effect.bind(); if (!texture.isNull) { texture.texture.setup(); - texture.texture.setSamplerParams(true, true, true); + texture.texture.setSamplerParams(_textureLinear, true, true); } if (!bumpTexture.isNull) { bumpTexture.texture.setup(1); - bumpTexture.texture.setSamplerParams(true, true, true); + bumpTexture.texture.setSamplerParams(true, true, false); } // matrixes, positions uniforms if (_effect.hasUniform(DefaultUniform.u_worldViewProjectionMatrix)) @@ -221,6 +224,9 @@ class Material : RefCountedObject { if (!texture.isNull) { texture.texture.unbind(); } + if (!bumpTexture.isNull) { + bumpTexture.texture.unbind(); + } effect.unbind(); } }