Clone of mesa.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571
  1. /* $Id: s_texture.c,v 1.3 2000/12/08 00:09:24 brianp Exp $ */
  2. /*
  3. * Mesa 3-D graphics library
  4. * Version: 3.5
  5. *
  6. * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a
  9. * copy of this software and associated documentation files (the "Software"),
  10. * to deal in the Software without restriction, including without limitation
  11. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  12. * and/or sell copies of the Software, and to permit persons to whom the
  13. * Software is furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included
  16. * in all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  19. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  21. * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  22. * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. #include "glheader.h"
  26. #include "context.h"
  27. #include "colormac.h"
  28. #include "macros.h"
  29. #include "mmath.h"
  30. #include "mem.h"
  31. #include "teximage.h"
  32. #include "s_context.h"
  33. #include "s_pb.h"
  34. #include "s_texture.h"
  35. /*
  36. * Paletted texture sampling.
  37. * Input: tObj - the texture object
  38. * index - the palette index (8-bit only)
  39. * Output: red, green, blue, alpha - the texel color
  40. */
  41. static void palette_sample(const struct gl_texture_object *tObj,
  42. GLint index, GLchan rgba[4] )
  43. {
  44. GLcontext *ctx = _mesa_get_current_context(); /* THIS IS A HACK */
  45. const GLchan *palette;
  46. GLenum format;
  47. if (ctx->Texture.SharedPalette) {
  48. ASSERT(!ctx->Texture.Palette.FloatTable);
  49. palette = (const GLchan *) ctx->Texture.Palette.Table;
  50. format = ctx->Texture.Palette.Format;
  51. }
  52. else {
  53. ASSERT(!tObj->Palette.FloatTable);
  54. palette = (const GLchan *) tObj->Palette.Table;
  55. format = tObj->Palette.Format;
  56. }
  57. switch (format) {
  58. case GL_ALPHA:
  59. rgba[ACOMP] = palette[index];
  60. return;
  61. case GL_LUMINANCE:
  62. case GL_INTENSITY:
  63. rgba[RCOMP] = palette[index];
  64. return;
  65. case GL_LUMINANCE_ALPHA:
  66. rgba[RCOMP] = palette[(index << 1) + 0];
  67. rgba[ACOMP] = palette[(index << 1) + 1];
  68. return;
  69. case GL_RGB:
  70. rgba[RCOMP] = palette[index * 3 + 0];
  71. rgba[GCOMP] = palette[index * 3 + 1];
  72. rgba[BCOMP] = palette[index * 3 + 2];
  73. return;
  74. case GL_RGBA:
  75. rgba[RCOMP] = palette[(index << 2) + 0];
  76. rgba[GCOMP] = palette[(index << 2) + 1];
  77. rgba[BCOMP] = palette[(index << 2) + 2];
  78. rgba[ACOMP] = palette[(index << 2) + 3];
  79. return;
  80. default:
  81. gl_problem(NULL, "Bad palette format in palette_sample");
  82. }
  83. }
  84. /*
  85. * These values are used in the fixed-point arithmetic used
  86. * for linear filtering.
  87. */
  88. #define WEIGHT_SCALE 65536.0F
  89. #define WEIGHT_SHIFT 16
  90. /*
  91. * Used to compute texel locations for linear sampling.
  92. */
  93. #define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \
  94. { \
  95. if (wrapMode == GL_REPEAT) { \
  96. U = S * SIZE - 0.5F; \
  97. I0 = ((GLint) myFloor(U)) & (SIZE - 1); \
  98. I1 = (I0 + 1) & (SIZE - 1); \
  99. } \
  100. else { \
  101. U = S * SIZE; \
  102. if (U < 0.0F) \
  103. U = 0.0F; \
  104. else if (U >= SIZE) \
  105. U = SIZE; \
  106. U -= 0.5F; \
  107. I0 = (GLint) myFloor(U); \
  108. I1 = I0 + 1; \
  109. if (wrapMode == GL_CLAMP_TO_EDGE) { \
  110. if (I0 < 0) \
  111. I0 = 0; \
  112. if (I1 >= SIZE) \
  113. I1 = SIZE - 1; \
  114. } \
  115. } \
  116. }
  117. /*
  118. * Used to compute texel location for nearest sampling.
  119. */
  120. #define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \
  121. { \
  122. if (wrapMode == GL_REPEAT) { \
  123. /* s limited to [0,1) */ \
  124. /* i limited to [0,width-1] */ \
  125. I = (GLint) (S * SIZE); \
  126. if (S < 0.0F) \
  127. I -= 1; \
  128. I &= (SIZE - 1); \
  129. } \
  130. else if (wrapMode == GL_CLAMP_TO_EDGE) { \
  131. const GLfloat min = 1.0F / (2.0F * SIZE); \
  132. const GLfloat max = 1.0F - min; \
  133. if (S < min) \
  134. I = 0; \
  135. else if (S > max) \
  136. I = SIZE - 1; \
  137. else \
  138. I = (GLint) (S * SIZE); \
  139. } \
  140. else { \
  141. ASSERT(wrapMode == GL_CLAMP); \
  142. /* s limited to [0,1] */ \
  143. /* i limited to [0,width-1] */ \
  144. if (S <= 0.0F) \
  145. I = 0; \
  146. else if (S >= 1.0F) \
  147. I = SIZE - 1; \
  148. else \
  149. I = (GLint) (S * SIZE); \
  150. } \
  151. }
  152. /*
  153. * Compute linear mipmap levels for given lambda.
  154. */
  155. #define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level) \
  156. { \
  157. if (lambda < 0.0F) \
  158. lambda = 0.0F; \
  159. else if (lambda > tObj->_M) \
  160. lambda = tObj->_M; \
  161. level = (GLint) (tObj->BaseLevel + lambda); \
  162. }
  163. /*
  164. * Compute nearest mipmap level for given lambda.
  165. */
  166. #define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level) \
  167. { \
  168. if (lambda <= 0.5F) \
  169. lambda = 0.0F; \
  170. else if (lambda > tObj->_M + 0.4999F) \
  171. lambda = tObj->_M + 0.4999F; \
  172. level = (GLint) (tObj->BaseLevel + lambda + 0.5F); \
  173. if (level > tObj->_P) \
  174. level = tObj->_P; \
  175. }
  176. /*
  177. * Bitflags for texture border color sampling.
  178. */
  179. #define I0BIT 1
  180. #define I1BIT 2
  181. #define J0BIT 4
  182. #define J1BIT 8
  183. #define K0BIT 16
  184. #define K1BIT 32
  185. /**********************************************************************/
  186. /* 1-D Texture Sampling Functions */
  187. /**********************************************************************/
  188. /*
  189. * Return floor of x, being careful of negative values.
  190. */
  191. static GLfloat myFloor(GLfloat x)
  192. {
  193. if (x < 0.0F)
  194. return (GLfloat) ((GLint) x - 1);
  195. else
  196. return (GLfloat) (GLint) x;
  197. }
  198. /*
  199. * Return the fractional part of x.
  200. */
  201. #define myFrac(x) ( (x) - myFloor(x) )
  202. /*
  203. * Given 1-D texture image and an (i) texel column coordinate, return the
  204. * texel color.
  205. */
  206. static void get_1d_texel( const struct gl_texture_object *tObj,
  207. const struct gl_texture_image *img, GLint i,
  208. GLchan rgba[4] )
  209. {
  210. const GLchan *texel;
  211. #ifdef DEBUG
  212. GLint width = img->Width;
  213. assert(i >= 0);
  214. assert(i < width);
  215. #endif
  216. switch (img->Format) {
  217. case GL_COLOR_INDEX:
  218. {
  219. GLint index = img->Data[i];
  220. palette_sample(tObj, index, rgba);
  221. return;
  222. }
  223. case GL_ALPHA:
  224. rgba[ACOMP] = img->Data[ i ];
  225. return;
  226. case GL_LUMINANCE:
  227. case GL_INTENSITY:
  228. rgba[RCOMP] = img->Data[ i ];
  229. return;
  230. case GL_LUMINANCE_ALPHA:
  231. texel = img->Data + i * 2;
  232. rgba[RCOMP] = texel[0];
  233. rgba[ACOMP] = texel[1];
  234. return;
  235. case GL_RGB:
  236. texel = img->Data + i * 3;
  237. rgba[RCOMP] = texel[0];
  238. rgba[GCOMP] = texel[1];
  239. rgba[BCOMP] = texel[2];
  240. return;
  241. case GL_RGBA:
  242. texel = img->Data + i * 4;
  243. rgba[RCOMP] = texel[0];
  244. rgba[GCOMP] = texel[1];
  245. rgba[BCOMP] = texel[2];
  246. rgba[ACOMP] = texel[3];
  247. return;
  248. default:
  249. gl_problem(NULL, "Bad format in get_1d_texel");
  250. return;
  251. }
  252. }
  253. /*
  254. * Return the texture sample for coordinate (s) using GL_NEAREST filter.
  255. */
  256. static void sample_1d_nearest( const struct gl_texture_object *tObj,
  257. const struct gl_texture_image *img,
  258. GLfloat s, GLchan rgba[4] )
  259. {
  260. const GLint width = img->Width2; /* without border, power of two */
  261. const GLchan *texel;
  262. GLint i;
  263. COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
  264. /* skip over the border, if any */
  265. i += img->Border;
  266. /* Get the texel */
  267. switch (img->Format) {
  268. case GL_COLOR_INDEX:
  269. {
  270. GLint index = img->Data[i];
  271. palette_sample(tObj, index, rgba );
  272. return;
  273. }
  274. case GL_ALPHA:
  275. rgba[ACOMP] = img->Data[i];
  276. return;
  277. case GL_LUMINANCE:
  278. case GL_INTENSITY:
  279. rgba[RCOMP] = img->Data[i];
  280. return;
  281. case GL_LUMINANCE_ALPHA:
  282. texel = img->Data + i * 2;
  283. rgba[RCOMP] = texel[0];
  284. rgba[ACOMP] = texel[1];
  285. return;
  286. case GL_RGB:
  287. texel = img->Data + i * 3;
  288. rgba[RCOMP] = texel[0];
  289. rgba[GCOMP] = texel[1];
  290. rgba[BCOMP] = texel[2];
  291. return;
  292. case GL_RGBA:
  293. texel = img->Data + i * 4;
  294. rgba[RCOMP] = texel[0];
  295. rgba[GCOMP] = texel[1];
  296. rgba[BCOMP] = texel[2];
  297. rgba[ACOMP] = texel[3];
  298. return;
  299. default:
  300. gl_problem(NULL, "Bad format in sample_1d_nearest");
  301. }
  302. }
  303. /*
  304. * Return the texture sample for coordinate (s) using GL_LINEAR filter.
  305. */
  306. static void sample_1d_linear( const struct gl_texture_object *tObj,
  307. const struct gl_texture_image *img,
  308. GLfloat s,
  309. GLchan rgba[4] )
  310. {
  311. const GLint width = img->Width2;
  312. GLint i0, i1;
  313. GLfloat u;
  314. GLuint useBorderColor;
  315. COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1);
  316. useBorderColor = 0;
  317. if (img->Border) {
  318. i0 += img->Border;
  319. i1 += img->Border;
  320. }
  321. else {
  322. if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
  323. if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
  324. }
  325. {
  326. const GLfloat a = myFrac(u);
  327. /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
  328. const GLint w0 = (GLint) ((1.0F-a) * WEIGHT_SCALE + 0.5F);
  329. const GLint w1 = (GLint) ( a * WEIGHT_SCALE + 0.5F);
  330. GLchan t0[4], t1[4]; /* texels */
  331. if (useBorderColor & I0BIT) {
  332. COPY_CHAN4(t0, tObj->BorderColor);
  333. }
  334. else {
  335. get_1d_texel( tObj, img, i0, t0 );
  336. }
  337. if (useBorderColor & I1BIT) {
  338. COPY_CHAN4(t1, tObj->BorderColor);
  339. }
  340. else {
  341. get_1d_texel( tObj, img, i1, t1 );
  342. }
  343. rgba[0] = (GLchan) ((w0 * t0[0] + w1 * t1[0]) >> WEIGHT_SHIFT);
  344. rgba[1] = (GLchan) ((w0 * t0[1] + w1 * t1[1]) >> WEIGHT_SHIFT);
  345. rgba[2] = (GLchan) ((w0 * t0[2] + w1 * t1[2]) >> WEIGHT_SHIFT);
  346. rgba[3] = (GLchan) ((w0 * t0[3] + w1 * t1[3]) >> WEIGHT_SHIFT);
  347. }
  348. }
  349. static void
  350. sample_1d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
  351. GLfloat s, GLfloat lambda,
  352. GLchan rgba[4] )
  353. {
  354. GLint level;
  355. COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
  356. sample_1d_nearest( tObj, tObj->Image[level], s, rgba );
  357. }
  358. static void
  359. sample_1d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
  360. GLfloat s, GLfloat lambda,
  361. GLchan rgba[4] )
  362. {
  363. GLint level;
  364. COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
  365. sample_1d_linear( tObj, tObj->Image[level], s, rgba );
  366. }
  367. static void
  368. sample_1d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
  369. GLfloat s, GLfloat lambda,
  370. GLchan rgba[4] )
  371. {
  372. GLint level;
  373. COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
  374. if (level >= tObj->_P) {
  375. sample_1d_nearest( tObj, tObj->Image[tObj->_P], s, rgba );
  376. }
  377. else {
  378. GLchan t0[4], t1[4];
  379. const GLfloat f = myFrac(lambda);
  380. sample_1d_nearest( tObj, tObj->Image[level ], s, t0 );
  381. sample_1d_nearest( tObj, tObj->Image[level+1], s, t1 );
  382. rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  383. rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  384. rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  385. rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  386. }
  387. }
  388. static void
  389. sample_1d_linear_mipmap_linear( const struct gl_texture_object *tObj,
  390. GLfloat s, GLfloat lambda,
  391. GLchan rgba[4] )
  392. {
  393. GLint level;
  394. COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
  395. if (level >= tObj->_P) {
  396. sample_1d_linear( tObj, tObj->Image[tObj->_P], s, rgba );
  397. }
  398. else {
  399. GLchan t0[4], t1[4];
  400. const GLfloat f = myFrac(lambda);
  401. sample_1d_linear( tObj, tObj->Image[level ], s, t0 );
  402. sample_1d_linear( tObj, tObj->Image[level+1], s, t1 );
  403. rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  404. rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  405. rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  406. rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  407. }
  408. }
  409. static void sample_nearest_1d( GLcontext *ctx, GLuint texUnit,
  410. const struct gl_texture_object *tObj, GLuint n,
  411. const GLfloat s[], const GLfloat t[],
  412. const GLfloat u[], const GLfloat lambda[],
  413. GLchan rgba[][4] )
  414. {
  415. GLuint i;
  416. struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  417. (void) t;
  418. (void) u;
  419. (void) lambda;
  420. for (i=0;i<n;i++) {
  421. sample_1d_nearest( tObj, image, s[i], rgba[i] );
  422. }
  423. }
  424. static void sample_linear_1d( GLcontext *ctx, GLuint texUnit,
  425. const struct gl_texture_object *tObj, GLuint n,
  426. const GLfloat s[], const GLfloat t[],
  427. const GLfloat u[], const GLfloat lambda[],
  428. GLchan rgba[][4] )
  429. {
  430. GLuint i;
  431. struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  432. (void) t;
  433. (void) u;
  434. (void) lambda;
  435. for (i=0;i<n;i++) {
  436. sample_1d_linear( tObj, image, s[i], rgba[i] );
  437. }
  438. }
  439. /*
  440. * Given an (s) texture coordinate and lambda (level of detail) value,
  441. * return a texture sample.
  442. *
  443. */
  444. static void sample_lambda_1d( GLcontext *ctx, GLuint texUnit,
  445. const struct gl_texture_object *tObj, GLuint n,
  446. const GLfloat s[], const GLfloat t[],
  447. const GLfloat u[], const GLfloat lambda[],
  448. GLchan rgba[][4] )
  449. {
  450. GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
  451. GLuint i;
  452. (void) t;
  453. (void) u;
  454. for (i=0;i<n;i++) {
  455. if (lambda[i] > MinMagThresh) {
  456. /* minification */
  457. switch (tObj->MinFilter) {
  458. case GL_NEAREST:
  459. sample_1d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
  460. break;
  461. case GL_LINEAR:
  462. sample_1d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
  463. break;
  464. case GL_NEAREST_MIPMAP_NEAREST:
  465. sample_1d_nearest_mipmap_nearest( tObj, lambda[i], s[i], rgba[i] );
  466. break;
  467. case GL_LINEAR_MIPMAP_NEAREST:
  468. sample_1d_linear_mipmap_nearest( tObj, s[i], lambda[i], rgba[i] );
  469. break;
  470. case GL_NEAREST_MIPMAP_LINEAR:
  471. sample_1d_nearest_mipmap_linear( tObj, s[i], lambda[i], rgba[i] );
  472. break;
  473. case GL_LINEAR_MIPMAP_LINEAR:
  474. sample_1d_linear_mipmap_linear( tObj, s[i], lambda[i], rgba[i] );
  475. break;
  476. default:
  477. gl_problem(NULL, "Bad min filter in sample_1d_texture");
  478. return;
  479. }
  480. }
  481. else {
  482. /* magnification */
  483. switch (tObj->MagFilter) {
  484. case GL_NEAREST:
  485. sample_1d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
  486. break;
  487. case GL_LINEAR:
  488. sample_1d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], rgba[i] );
  489. break;
  490. default:
  491. gl_problem(NULL, "Bad mag filter in sample_1d_texture");
  492. return;
  493. }
  494. }
  495. }
  496. }
  497. /**********************************************************************/
  498. /* 2-D Texture Sampling Functions */
  499. /**********************************************************************/
  500. /*
  501. * Given a texture image and an (i,j) integer texel coordinate, return the
  502. * texel color.
  503. */
  504. static void get_2d_texel( const struct gl_texture_object *tObj,
  505. const struct gl_texture_image *img, GLint i, GLint j,
  506. GLchan rgba[4] )
  507. {
  508. const GLint width = img->Width; /* includes border */
  509. const GLchan *texel;
  510. #ifdef DEBUG
  511. const GLint height = img->Height; /* includes border */
  512. assert(i >= 0);
  513. assert(i < width);
  514. assert(j >= 0);
  515. assert(j < height);
  516. #endif
  517. switch (img->Format) {
  518. case GL_COLOR_INDEX:
  519. {
  520. GLint index = img->Data[ width *j + i ];
  521. palette_sample(tObj, index, rgba );
  522. return;
  523. }
  524. case GL_ALPHA:
  525. rgba[ACOMP] = img->Data[ width * j + i ];
  526. return;
  527. case GL_LUMINANCE:
  528. case GL_INTENSITY:
  529. rgba[RCOMP] = img->Data[ width * j + i ];
  530. return;
  531. case GL_LUMINANCE_ALPHA:
  532. texel = img->Data + (width * j + i) * 2;
  533. rgba[RCOMP] = texel[0];
  534. rgba[ACOMP] = texel[1];
  535. return;
  536. case GL_RGB:
  537. texel = img->Data + (width * j + i) * 3;
  538. rgba[RCOMP] = texel[0];
  539. rgba[GCOMP] = texel[1];
  540. rgba[BCOMP] = texel[2];
  541. return;
  542. case GL_RGBA:
  543. texel = img->Data + (width * j + i) * 4;
  544. rgba[RCOMP] = texel[0];
  545. rgba[GCOMP] = texel[1];
  546. rgba[BCOMP] = texel[2];
  547. rgba[ACOMP] = texel[3];
  548. return;
  549. default:
  550. gl_problem(NULL, "Bad format in get_2d_texel");
  551. }
  552. }
  553. /*
  554. * Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
  555. */
  556. static void sample_2d_nearest( const struct gl_texture_object *tObj,
  557. const struct gl_texture_image *img,
  558. GLfloat s, GLfloat t,
  559. GLchan rgba[] )
  560. {
  561. const GLint imgWidth = img->Width; /* includes border */
  562. const GLint width = img->Width2; /* without border, power of two */
  563. const GLint height = img->Height2; /* without border, power of two */
  564. const GLchan *texel;
  565. GLint i, j;
  566. COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
  567. COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j);
  568. /* skip over the border, if any */
  569. i += img->Border;
  570. j += img->Border;
  571. switch (img->Format) {
  572. case GL_COLOR_INDEX:
  573. {
  574. GLint index = img->Data[ j * imgWidth + i ];
  575. palette_sample(tObj, index, rgba);
  576. return;
  577. }
  578. case GL_ALPHA:
  579. rgba[ACOMP] = img->Data[ j * imgWidth + i ];
  580. return;
  581. case GL_LUMINANCE:
  582. case GL_INTENSITY:
  583. rgba[RCOMP] = img->Data[ j * imgWidth + i ];
  584. return;
  585. case GL_LUMINANCE_ALPHA:
  586. texel = img->Data + ((j * imgWidth + i) << 1);
  587. rgba[RCOMP] = texel[0];
  588. rgba[ACOMP] = texel[1];
  589. return;
  590. case GL_RGB:
  591. texel = img->Data + (j * imgWidth + i) * 3;
  592. rgba[RCOMP] = texel[0];
  593. rgba[GCOMP] = texel[1];
  594. rgba[BCOMP] = texel[2];
  595. return;
  596. case GL_RGBA:
  597. texel = img->Data + ((j * imgWidth + i) << 2);
  598. rgba[RCOMP] = texel[0];
  599. rgba[GCOMP] = texel[1];
  600. rgba[BCOMP] = texel[2];
  601. rgba[ACOMP] = texel[3];
  602. return;
  603. default:
  604. gl_problem(NULL, "Bad format in sample_2d_nearest");
  605. }
  606. }
  607. /*
  608. * Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
  609. * New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
  610. */
  611. static void sample_2d_linear( const struct gl_texture_object *tObj,
  612. const struct gl_texture_image *img,
  613. GLfloat s, GLfloat t,
  614. GLchan rgba[] )
  615. {
  616. const GLint width = img->Width2;
  617. const GLint height = img->Height2;
  618. GLint i0, j0, i1, j1;
  619. GLuint useBorderColor;
  620. GLfloat u, v;
  621. COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1);
  622. COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, t, v, height, j0, j1);
  623. useBorderColor = 0;
  624. if (img->Border) {
  625. i0 += img->Border;
  626. i1 += img->Border;
  627. j0 += img->Border;
  628. j1 += img->Border;
  629. }
  630. else {
  631. if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
  632. if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
  633. if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
  634. if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
  635. }
  636. {
  637. const GLfloat a = myFrac(u);
  638. const GLfloat b = myFrac(v);
  639. /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
  640. const GLint w00 = (GLint) ((1.0F-a)*(1.0F-b) * WEIGHT_SCALE + 0.5F);
  641. const GLint w10 = (GLint) ( a *(1.0F-b) * WEIGHT_SCALE + 0.5F);
  642. const GLint w01 = (GLint) ((1.0F-a)* b * WEIGHT_SCALE + 0.5F);
  643. const GLint w11 = (GLint) ( a * b * WEIGHT_SCALE + 0.5F);
  644. GLchan t00[4];
  645. GLchan t10[4];
  646. GLchan t01[4];
  647. GLchan t11[4];
  648. if (useBorderColor & (I0BIT | J0BIT)) {
  649. COPY_CHAN4(t00, tObj->BorderColor);
  650. }
  651. else {
  652. get_2d_texel( tObj, img, i0, j0, t00 );
  653. }
  654. if (useBorderColor & (I1BIT | J0BIT)) {
  655. COPY_CHAN4(t10, tObj->BorderColor);
  656. }
  657. else {
  658. get_2d_texel( tObj, img, i1, j0, t10 );
  659. }
  660. if (useBorderColor & (I0BIT | J1BIT)) {
  661. COPY_CHAN4(t01, tObj->BorderColor);
  662. }
  663. else {
  664. get_2d_texel( tObj, img, i0, j1, t01 );
  665. }
  666. if (useBorderColor & (I1BIT | J1BIT)) {
  667. COPY_CHAN4(t11, tObj->BorderColor);
  668. }
  669. else {
  670. get_2d_texel( tObj, img, i1, j1, t11 );
  671. }
  672. rgba[0] = (GLchan) ((w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT);
  673. rgba[1] = (GLchan) ((w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1]) >> WEIGHT_SHIFT);
  674. rgba[2] = (GLchan) ((w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2]) >> WEIGHT_SHIFT);
  675. rgba[3] = (GLchan) ((w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3]) >> WEIGHT_SHIFT);
  676. }
  677. }
  678. static void
  679. sample_2d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
  680. GLfloat s, GLfloat t, GLfloat lambda,
  681. GLchan rgba[4] )
  682. {
  683. GLint level;
  684. COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
  685. sample_2d_nearest( tObj, tObj->Image[level], s, t, rgba );
  686. }
  687. static void
  688. sample_2d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
  689. GLfloat s, GLfloat t, GLfloat lambda,
  690. GLchan rgba[4] )
  691. {
  692. GLint level;
  693. COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
  694. sample_2d_linear( tObj, tObj->Image[level], s, t, rgba );
  695. }
  696. static void
  697. sample_2d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
  698. GLfloat s, GLfloat t, GLfloat lambda,
  699. GLchan rgba[4] )
  700. {
  701. GLint level;
  702. COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
  703. if (level >= tObj->_P) {
  704. sample_2d_nearest( tObj, tObj->Image[tObj->_P], s, t, rgba );
  705. }
  706. else {
  707. GLchan t0[4], t1[4]; /* texels */
  708. const GLfloat f = myFrac(lambda);
  709. sample_2d_nearest( tObj, tObj->Image[level ], s, t, t0 );
  710. sample_2d_nearest( tObj, tObj->Image[level+1], s, t, t1 );
  711. rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  712. rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  713. rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  714. rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  715. }
  716. }
  717. static void
  718. sample_2d_linear_mipmap_linear( const struct gl_texture_object *tObj,
  719. GLfloat s, GLfloat t, GLfloat lambda,
  720. GLchan rgba[4] )
  721. {
  722. GLint level;
  723. COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
  724. if (level >= tObj->_P) {
  725. sample_2d_linear( tObj, tObj->Image[tObj->_P], s, t, rgba );
  726. }
  727. else {
  728. GLchan t0[4], t1[4]; /* texels */
  729. const GLfloat f = myFrac(lambda);
  730. sample_2d_linear( tObj, tObj->Image[level ], s, t, t0 );
  731. sample_2d_linear( tObj, tObj->Image[level+1], s, t, t1 );
  732. rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  733. rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  734. rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  735. rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  736. }
  737. }
  738. static void sample_nearest_2d( GLcontext *ctx, GLuint texUnit,
  739. const struct gl_texture_object *tObj, GLuint n,
  740. const GLfloat s[], const GLfloat t[],
  741. const GLfloat u[], const GLfloat lambda[],
  742. GLchan rgba[][4] )
  743. {
  744. GLuint i;
  745. struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  746. (void) u;
  747. (void) lambda;
  748. for (i=0;i<n;i++) {
  749. sample_2d_nearest( tObj, image, s[i], t[i], rgba[i] );
  750. }
  751. }
  752. static void sample_linear_2d( GLcontext *ctx, GLuint texUnit,
  753. const struct gl_texture_object *tObj, GLuint n,
  754. const GLfloat s[], const GLfloat t[],
  755. const GLfloat u[], const GLfloat lambda[],
  756. GLchan rgba[][4] )
  757. {
  758. GLuint i;
  759. struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  760. (void) u;
  761. (void) lambda;
  762. for (i=0;i<n;i++) {
  763. sample_2d_linear( tObj, image, s[i], t[i], rgba[i] );
  764. }
  765. }
  766. /*
  767. * Given an (s,t) texture coordinate and lambda (level of detail) value,
  768. * return a texture sample.
  769. */
  770. static void sample_lambda_2d( GLcontext *ctx, GLuint texUnit,
  771. const struct gl_texture_object *tObj,
  772. GLuint n,
  773. const GLfloat s[], const GLfloat t[],
  774. const GLfloat u[], const GLfloat lambda[],
  775. GLchan rgba[][4] )
  776. {
  777. GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
  778. GLuint i;
  779. (void) u;
  780. for (i=0;i<n;i++) {
  781. if (lambda[i] > MinMagThresh) {
  782. /* minification */
  783. switch (tObj->MinFilter) {
  784. case GL_NEAREST:
  785. sample_2d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
  786. break;
  787. case GL_LINEAR:
  788. sample_2d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
  789. break;
  790. case GL_NEAREST_MIPMAP_NEAREST:
  791. sample_2d_nearest_mipmap_nearest( tObj, s[i], t[i], lambda[i], rgba[i] );
  792. break;
  793. case GL_LINEAR_MIPMAP_NEAREST:
  794. sample_2d_linear_mipmap_nearest( tObj, s[i], t[i], lambda[i], rgba[i] );
  795. break;
  796. case GL_NEAREST_MIPMAP_LINEAR:
  797. sample_2d_nearest_mipmap_linear( tObj, s[i], t[i], lambda[i], rgba[i] );
  798. break;
  799. case GL_LINEAR_MIPMAP_LINEAR:
  800. sample_2d_linear_mipmap_linear( tObj, s[i], t[i], lambda[i], rgba[i] );
  801. break;
  802. default:
  803. gl_problem(NULL, "Bad min filter in sample_2d_texture");
  804. return;
  805. }
  806. }
  807. else {
  808. /* magnification */
  809. switch (tObj->MagFilter) {
  810. case GL_NEAREST:
  811. sample_2d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
  812. break;
  813. case GL_LINEAR:
  814. sample_2d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], rgba[i] );
  815. break;
  816. default:
  817. gl_problem(NULL, "Bad mag filter in sample_2d_texture");
  818. }
  819. }
  820. }
  821. }
  822. /*
  823. * Optimized 2-D texture sampling:
  824. * S and T wrap mode == GL_REPEAT
  825. * GL_NEAREST min/mag filter
  826. * No border
  827. * Format = GL_RGB
  828. */
  829. static void opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
  830. const struct gl_texture_object *tObj,
  831. GLuint n, const GLfloat s[], const GLfloat t[],
  832. const GLfloat u[], const GLfloat lambda[],
  833. GLchan rgba[][4] )
  834. {
  835. const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
  836. const GLfloat width = (GLfloat) img->Width;
  837. const GLfloat height = (GLfloat) img->Height;
  838. const GLint colMask = img->Width - 1;
  839. const GLint rowMask = img->Height - 1;
  840. const GLint shift = img->WidthLog2;
  841. GLuint k;
  842. (void) u;
  843. (void) lambda;
  844. ASSERT(tObj->WrapS==GL_REPEAT);
  845. ASSERT(tObj->WrapT==GL_REPEAT);
  846. ASSERT(tObj->MinFilter==GL_NEAREST);
  847. ASSERT(tObj->MagFilter==GL_NEAREST);
  848. ASSERT(img->Border==0);
  849. ASSERT(img->Format==GL_RGB);
  850. /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */
  851. for (k=0;k<n;k++) {
  852. GLint i = (GLint) ((s[k] + 10000.0) * width) & colMask;
  853. GLint j = (GLint) ((t[k] + 10000.0) * height) & rowMask;
  854. GLint pos = (j << shift) | i;
  855. GLchan *texel = img->Data + pos + pos + pos; /* pos*3 */
  856. rgba[k][RCOMP] = texel[0];
  857. rgba[k][GCOMP] = texel[1];
  858. rgba[k][BCOMP] = texel[2];
  859. }
  860. }
  861. /*
  862. * Optimized 2-D texture sampling:
  863. * S and T wrap mode == GL_REPEAT
  864. * GL_NEAREST min/mag filter
  865. * No border
  866. * Format = GL_RGBA
  867. */
  868. static void opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
  869. const struct gl_texture_object *tObj,
  870. GLuint n, const GLfloat s[], const GLfloat t[],
  871. const GLfloat u[], const GLfloat lambda[],
  872. GLchan rgba[][4] )
  873. {
  874. const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
  875. const GLfloat width = (GLfloat) img->Width;
  876. const GLfloat height = (GLfloat) img->Height;
  877. const GLint colMask = img->Width - 1;
  878. const GLint rowMask = img->Height - 1;
  879. const GLint shift = img->WidthLog2;
  880. GLuint k;
  881. (void) u;
  882. (void) lambda;
  883. ASSERT(tObj->WrapS==GL_REPEAT);
  884. ASSERT(tObj->WrapT==GL_REPEAT);
  885. ASSERT(tObj->MinFilter==GL_NEAREST);
  886. ASSERT(tObj->MagFilter==GL_NEAREST);
  887. ASSERT(img->Border==0);
  888. ASSERT(img->Format==GL_RGBA);
  889. /* NOTE: negative float->int doesn't floor, add 10000 as to work-around */
  890. for (k=0;k<n;k++) {
  891. GLint i = (GLint) ((s[k] + 10000.0) * width) & colMask;
  892. GLint j = (GLint) ((t[k] + 10000.0) * height) & rowMask;
  893. GLint pos = (j << shift) | i;
  894. GLchan *texel = img->Data + (pos << 2); /* pos*4 */
  895. rgba[k][RCOMP] = texel[0];
  896. rgba[k][GCOMP] = texel[1];
  897. rgba[k][BCOMP] = texel[2];
  898. rgba[k][ACOMP] = texel[3];
  899. }
  900. }
  901. /**********************************************************************/
  902. /* 3-D Texture Sampling Functions */
  903. /**********************************************************************/
  904. /*
  905. * Given a texture image and an (i,j,k) integer texel coordinate, return the
  906. * texel color.
  907. */
  908. static void get_3d_texel( const struct gl_texture_object *tObj,
  909. const struct gl_texture_image *img,
  910. GLint i, GLint j, GLint k,
  911. GLchan rgba[4] )
  912. {
  913. const GLint width = img->Width; /* includes border */
  914. const GLint height = img->Height; /* includes border */
  915. const GLint rectarea = width * height;
  916. const GLchan *texel;
  917. #ifdef DEBUG
  918. const GLint depth = img->Depth; /* includes border */
  919. assert(i >= 0);
  920. assert(i < width);
  921. assert(j >= 0);
  922. assert(j < height);
  923. assert(k >= 0);
  924. assert(k < depth);
  925. #endif
  926. switch (img->Format) {
  927. case GL_COLOR_INDEX:
  928. {
  929. GLint index = img->Data[ rectarea * k + width * j + i ];
  930. palette_sample(tObj, index, rgba );
  931. return;
  932. }
  933. case GL_ALPHA:
  934. rgba[ACOMP] = img->Data[ rectarea * k + width * j + i ];
  935. return;
  936. case GL_LUMINANCE:
  937. case GL_INTENSITY:
  938. rgba[RCOMP] = img->Data[ rectarea * k + width * j + i ];
  939. return;
  940. case GL_LUMINANCE_ALPHA:
  941. texel = img->Data + ( rectarea * k + width * j + i) * 2;
  942. rgba[RCOMP] = texel[0];
  943. rgba[ACOMP] = texel[1];
  944. return;
  945. case GL_RGB:
  946. texel = img->Data + (rectarea * k + width * j + i) * 3;
  947. rgba[RCOMP] = texel[0];
  948. rgba[GCOMP] = texel[1];
  949. rgba[BCOMP] = texel[2];
  950. return;
  951. case GL_RGBA:
  952. texel = img->Data + (rectarea * k + width * j + i) * 4;
  953. rgba[RCOMP] = texel[0];
  954. rgba[GCOMP] = texel[1];
  955. rgba[BCOMP] = texel[2];
  956. rgba[ACOMP] = texel[3];
  957. return;
  958. default:
  959. gl_problem(NULL, "Bad format in get_3d_texel");
  960. }
  961. }
  962. /*
  963. * Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
  964. */
  965. static void sample_3d_nearest( const struct gl_texture_object *tObj,
  966. const struct gl_texture_image *img,
  967. GLfloat s, GLfloat t, GLfloat r,
  968. GLchan rgba[4] )
  969. {
  970. const GLint imgWidth = img->Width; /* includes border, if any */
  971. const GLint imgHeight = img->Height; /* includes border, if any */
  972. const GLint width = img->Width2; /* without border, power of two */
  973. const GLint height = img->Height2; /* without border, power of two */
  974. const GLint depth = img->Depth2; /* without border, power of two */
  975. const GLint rectarea = imgWidth * imgHeight;
  976. const GLchan *texel;
  977. GLint i, j, k;
  978. COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, s, width, i);
  979. COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, t, height, j);
  980. COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, r, depth, k);
  981. switch (tObj->Image[0]->Format) {
  982. case GL_COLOR_INDEX:
  983. {
  984. GLint index = img->Data[ rectarea * k + j * imgWidth + i ];
  985. palette_sample(tObj, index, rgba );
  986. return;
  987. }
  988. case GL_ALPHA:
  989. rgba[ACOMP] = img->Data[ rectarea * k + j * imgWidth + i ];
  990. return;
  991. case GL_LUMINANCE:
  992. case GL_INTENSITY:
  993. rgba[RCOMP] = img->Data[ rectarea * k + j * imgWidth + i ];
  994. return;
  995. case GL_LUMINANCE_ALPHA:
  996. texel = img->Data + ((rectarea * k + j * imgWidth + i) << 1);
  997. rgba[RCOMP] = texel[0];
  998. rgba[ACOMP] = texel[1];
  999. return;
  1000. case GL_RGB:
  1001. texel = img->Data + ( rectarea * k + j * imgWidth + i) * 3;
  1002. rgba[RCOMP] = texel[0];
  1003. rgba[GCOMP] = texel[1];
  1004. rgba[BCOMP] = texel[2];
  1005. return;
  1006. case GL_RGBA:
  1007. texel = img->Data + ((rectarea * k + j * imgWidth + i) << 2);
  1008. rgba[RCOMP] = texel[0];
  1009. rgba[GCOMP] = texel[1];
  1010. rgba[BCOMP] = texel[2];
  1011. rgba[ACOMP] = texel[3];
  1012. return;
  1013. default:
  1014. gl_problem(NULL, "Bad format in sample_3d_nearest");
  1015. }
  1016. }
  1017. /*
  1018. * Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
  1019. */
  1020. static void sample_3d_linear( const struct gl_texture_object *tObj,
  1021. const struct gl_texture_image *img,
  1022. GLfloat s, GLfloat t, GLfloat r,
  1023. GLchan rgba[4] )
  1024. {
  1025. const GLint width = img->Width2;
  1026. const GLint height = img->Height2;
  1027. const GLint depth = img->Depth2;
  1028. GLint i0, j0, k0, i1, j1, k1;
  1029. GLuint useBorderColor;
  1030. GLfloat u, v, w;
  1031. COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, s, u, width, i0, i1);
  1032. COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, t, v, height, j0, j1);
  1033. COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, r, w, depth, k0, k1);
  1034. useBorderColor = 0;
  1035. if (img->Border) {
  1036. i0 += img->Border;
  1037. i1 += img->Border;
  1038. j0 += img->Border;
  1039. j1 += img->Border;
  1040. k0 += img->Border;
  1041. k1 += img->Border;
  1042. }
  1043. else {
  1044. /* check if sampling texture border color */
  1045. if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
  1046. if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
  1047. if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
  1048. if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
  1049. if (k0 < 0 || k0 >= depth) useBorderColor |= K0BIT;
  1050. if (k1 < 0 || k1 >= depth) useBorderColor |= K1BIT;
  1051. }
  1052. {
  1053. const GLfloat a = myFrac(u);
  1054. const GLfloat b = myFrac(v);
  1055. const GLfloat c = myFrac(w);
  1056. /* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
  1057. GLint w000 = (GLint) ((1.0F-a)*(1.0F-b)*(1.0F-c) * WEIGHT_SCALE + 0.5F);
  1058. GLint w100 = (GLint) ( a *(1.0F-b)*(1.0F-c) * WEIGHT_SCALE + 0.5F);
  1059. GLint w010 = (GLint) ((1.0F-a)* b *(1.0F-c) * WEIGHT_SCALE + 0.5F);
  1060. GLint w110 = (GLint) ( a * b *(1.0F-c) * WEIGHT_SCALE + 0.5F);
  1061. GLint w001 = (GLint) ((1.0F-a)*(1.0F-b)* c * WEIGHT_SCALE + 0.5F);
  1062. GLint w101 = (GLint) ( a *(1.0F-b)* c * WEIGHT_SCALE + 0.5F);
  1063. GLint w011 = (GLint) ((1.0F-a)* b * c * WEIGHT_SCALE + 0.5F);
  1064. GLint w111 = (GLint) ( a * b * c * WEIGHT_SCALE + 0.5F);
  1065. GLchan t000[4], t010[4], t001[4], t011[4];
  1066. GLchan t100[4], t110[4], t101[4], t111[4];
  1067. if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {
  1068. COPY_CHAN4(t000, tObj->BorderColor);
  1069. }
  1070. else {
  1071. get_3d_texel( tObj, img, i0, j0, k0, t000 );
  1072. }
  1073. if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
  1074. COPY_CHAN4(t100, tObj->BorderColor);
  1075. }
  1076. else {
  1077. get_3d_texel( tObj, img, i1, j0, k0, t100 );
  1078. }
  1079. if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
  1080. COPY_CHAN4(t010, tObj->BorderColor);
  1081. }
  1082. else {
  1083. get_3d_texel( tObj, img, i0, j1, k0, t010 );
  1084. }
  1085. if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
  1086. COPY_CHAN4(t110, tObj->BorderColor);
  1087. }
  1088. else {
  1089. get_3d_texel( tObj, img, i1, j1, k0, t110 );
  1090. }
  1091. if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
  1092. COPY_CHAN4(t001, tObj->BorderColor);
  1093. }
  1094. else {
  1095. get_3d_texel( tObj, img, i0, j0, k1, t001 );
  1096. }
  1097. if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
  1098. COPY_CHAN4(t101, tObj->BorderColor);
  1099. }
  1100. else {
  1101. get_3d_texel( tObj, img, i1, j0, k1, t101 );
  1102. }
  1103. if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
  1104. COPY_CHAN4(t011, tObj->BorderColor);
  1105. }
  1106. else {
  1107. get_3d_texel( tObj, img, i0, j1, k1, t011 );
  1108. }
  1109. if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
  1110. COPY_CHAN4(t111, tObj->BorderColor);
  1111. }
  1112. else {
  1113. get_3d_texel( tObj, img, i1, j1, k1, t111 );
  1114. }
  1115. rgba[0] = (GLchan) (
  1116. (w000*t000[0] + w010*t010[0] + w001*t001[0] + w011*t011[0] +
  1117. w100*t100[0] + w110*t110[0] + w101*t101[0] + w111*t111[0] )
  1118. >> WEIGHT_SHIFT);
  1119. rgba[1] = (GLchan) (
  1120. (w000*t000[1] + w010*t010[1] + w001*t001[1] + w011*t011[1] +
  1121. w100*t100[1] + w110*t110[1] + w101*t101[1] + w111*t111[1] )
  1122. >> WEIGHT_SHIFT);
  1123. rgba[2] = (GLchan) (
  1124. (w000*t000[2] + w010*t010[2] + w001*t001[2] + w011*t011[2] +
  1125. w100*t100[2] + w110*t110[2] + w101*t101[2] + w111*t111[2] )
  1126. >> WEIGHT_SHIFT);
  1127. rgba[3] = (GLchan) (
  1128. (w000*t000[3] + w010*t010[3] + w001*t001[3] + w011*t011[3] +
  1129. w100*t100[3] + w110*t110[3] + w101*t101[3] + w111*t111[3] )
  1130. >> WEIGHT_SHIFT);
  1131. }
  1132. }
  1133. static void
  1134. sample_3d_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
  1135. GLfloat s, GLfloat t, GLfloat r,
  1136. GLfloat lambda, GLchan rgba[4] )
  1137. {
  1138. GLint level;
  1139. COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
  1140. sample_3d_nearest( tObj, tObj->Image[level], s, t, r, rgba );
  1141. }
  1142. static void
  1143. sample_3d_linear_mipmap_nearest( const struct gl_texture_object *tObj,
  1144. GLfloat s, GLfloat t, GLfloat r,
  1145. GLfloat lambda, GLchan rgba[4] )
  1146. {
  1147. GLint level;
  1148. COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
  1149. sample_3d_linear( tObj, tObj->Image[level], s, t, r, rgba );
  1150. }
  1151. static void
  1152. sample_3d_nearest_mipmap_linear( const struct gl_texture_object *tObj,
  1153. GLfloat s, GLfloat t, GLfloat r,
  1154. GLfloat lambda, GLchan rgba[4] )
  1155. {
  1156. GLint level;
  1157. COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
  1158. if (level >= tObj->_P) {
  1159. sample_3d_nearest( tObj, tObj->Image[tObj->_P], s, t, r, rgba );
  1160. }
  1161. else {
  1162. GLchan t0[4], t1[4]; /* texels */
  1163. const GLfloat f = myFrac(lambda);
  1164. sample_3d_nearest( tObj, tObj->Image[level ], s, t, r, t0 );
  1165. sample_3d_nearest( tObj, tObj->Image[level+1], s, t, r, t1 );
  1166. rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  1167. rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  1168. rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  1169. rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  1170. }
  1171. }
  1172. static void
  1173. sample_3d_linear_mipmap_linear( const struct gl_texture_object *tObj,
  1174. GLfloat s, GLfloat t, GLfloat r,
  1175. GLfloat lambda, GLchan rgba[4] )
  1176. {
  1177. GLint level;
  1178. COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
  1179. if (level >= tObj->_P) {
  1180. sample_3d_linear( tObj, tObj->Image[tObj->_P], s, t, r, rgba );
  1181. }
  1182. else {
  1183. GLchan t0[4], t1[4]; /* texels */
  1184. const GLfloat f = myFrac(lambda);
  1185. sample_3d_linear( tObj, tObj->Image[level ], s, t, r, t0 );
  1186. sample_3d_linear( tObj, tObj->Image[level+1], s, t, r, t1 );
  1187. rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  1188. rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  1189. rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  1190. rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  1191. }
  1192. }
  1193. static void sample_nearest_3d( GLcontext *ctx, GLuint texUnit,
  1194. const struct gl_texture_object *tObj, GLuint n,
  1195. const GLfloat s[], const GLfloat t[],
  1196. const GLfloat u[], const GLfloat lambda[],
  1197. GLchan rgba[][4] )
  1198. {
  1199. GLuint i;
  1200. struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  1201. (void) lambda;
  1202. for (i=0;i<n;i++) {
  1203. sample_3d_nearest( tObj, image, s[i], t[i], u[i], rgba[i] );
  1204. }
  1205. }
  1206. static void sample_linear_3d( GLcontext *ctx, GLuint texUnit,
  1207. const struct gl_texture_object *tObj, GLuint n,
  1208. const GLfloat s[], const GLfloat t[],
  1209. const GLfloat u[], const GLfloat lambda[],
  1210. GLchan rgba[][4] )
  1211. {
  1212. GLuint i;
  1213. struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
  1214. (void) lambda;
  1215. for (i=0;i<n;i++) {
  1216. sample_3d_linear( tObj, image, s[i], t[i], u[i], rgba[i] );
  1217. }
  1218. }
  1219. /*
  1220. * Given an (s,t,r) texture coordinate and lambda (level of detail) value,
  1221. * return a texture sample.
  1222. */
  1223. static void sample_lambda_3d( GLcontext *ctx, GLuint texUnit,
  1224. const struct gl_texture_object *tObj, GLuint n,
  1225. const GLfloat s[], const GLfloat t[],
  1226. const GLfloat u[], const GLfloat lambda[],
  1227. GLchan rgba[][4] )
  1228. {
  1229. GLuint i;
  1230. GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
  1231. for (i=0;i<n;i++) {
  1232. if (lambda[i] > MinMagThresh) {
  1233. /* minification */
  1234. switch (tObj->MinFilter) {
  1235. case GL_NEAREST:
  1236. sample_3d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
  1237. break;
  1238. case GL_LINEAR:
  1239. sample_3d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
  1240. break;
  1241. case GL_NEAREST_MIPMAP_NEAREST:
  1242. sample_3d_nearest_mipmap_nearest( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
  1243. break;
  1244. case GL_LINEAR_MIPMAP_NEAREST:
  1245. sample_3d_linear_mipmap_nearest( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
  1246. break;
  1247. case GL_NEAREST_MIPMAP_LINEAR:
  1248. sample_3d_nearest_mipmap_linear( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
  1249. break;
  1250. case GL_LINEAR_MIPMAP_LINEAR:
  1251. sample_3d_linear_mipmap_linear( tObj, s[i], t[i], u[i], lambda[i], rgba[i] );
  1252. break;
  1253. default:
  1254. gl_problem(NULL, "Bad min filterin sample_3d_texture");
  1255. }
  1256. }
  1257. else {
  1258. /* magnification */
  1259. switch (tObj->MagFilter) {
  1260. case GL_NEAREST:
  1261. sample_3d_nearest( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
  1262. break;
  1263. case GL_LINEAR:
  1264. sample_3d_linear( tObj, tObj->Image[tObj->BaseLevel], s[i], t[i], u[i], rgba[i] );
  1265. break;
  1266. default:
  1267. gl_problem(NULL, "Bad mag filter in sample_3d_texture");
  1268. }
  1269. }
  1270. }
  1271. }
  1272. /**********************************************************************/
  1273. /* Texture Cube Map Sampling Functions */
  1274. /**********************************************************************/
  1275. /*
  1276. * Choose one of six sides of a texture cube map given the texture
  1277. * coord (rx,ry,rz). Return pointer to corresponding array of texture
  1278. * images.
  1279. */
  1280. static const struct gl_texture_image **
  1281. choose_cube_face(const struct gl_texture_object *texObj,
  1282. GLfloat rx, GLfloat ry, GLfloat rz,
  1283. GLfloat *newS, GLfloat *newT)
  1284. {
  1285. /*
  1286. major axis
  1287. direction target sc tc ma
  1288. ---------- ------------------------------- --- --- ---
  1289. +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
  1290. -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
  1291. +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
  1292. -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
  1293. +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
  1294. -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
  1295. */
  1296. const struct gl_texture_image **imgArray;
  1297. const GLfloat arx = ABSF(rx), ary = ABSF(ry), arz = ABSF(rz);
  1298. GLfloat sc, tc, ma;
  1299. if (arx > ary && arx > arz) {
  1300. if (rx >= 0.0F) {
  1301. imgArray = (const struct gl_texture_image **) texObj->Image;
  1302. sc = -rz;
  1303. tc = -ry;
  1304. ma = arx;
  1305. }
  1306. else {
  1307. imgArray = (const struct gl_texture_image **) texObj->NegX;
  1308. sc = rz;
  1309. tc = -ry;
  1310. ma = arx;
  1311. }
  1312. }
  1313. else if (ary > arx && ary > arz) {
  1314. if (ry >= 0.0F) {
  1315. imgArray = (const struct gl_texture_image **) texObj->PosY;
  1316. sc = rx;
  1317. tc = rz;
  1318. ma = ary;
  1319. }
  1320. else {
  1321. imgArray = (const struct gl_texture_image **) texObj->NegY;
  1322. sc = rx;
  1323. tc = -rz;
  1324. ma = ary;
  1325. }
  1326. }
  1327. else {
  1328. if (rz > 0.0F) {
  1329. imgArray = (const struct gl_texture_image **) texObj->PosZ;
  1330. sc = rx;
  1331. tc = -ry;
  1332. ma = arz;
  1333. }
  1334. else {
  1335. imgArray = (const struct gl_texture_image **) texObj->NegZ;
  1336. sc = -rx;
  1337. tc = -ry;
  1338. ma = arz;
  1339. }
  1340. }
  1341. *newS = ( sc / ma + 1.0F ) * 0.5F;
  1342. *newT = ( tc / ma + 1.0F ) * 0.5F;
  1343. return imgArray;
  1344. }
  1345. static void
  1346. sample_nearest_cube(GLcontext *ctx, GLuint texUnit,
  1347. const struct gl_texture_object *tObj, GLuint n,
  1348. const GLfloat s[], const GLfloat t[],
  1349. const GLfloat u[], const GLfloat lambda[],
  1350. GLchan rgba[][4])
  1351. {
  1352. GLuint i;
  1353. (void) lambda;
  1354. for (i = 0; i < n; i++) {
  1355. const struct gl_texture_image **images;
  1356. GLfloat newS, newT;
  1357. images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT);
  1358. sample_2d_nearest( tObj, images[tObj->BaseLevel], newS, newT, rgba[i] );
  1359. }
  1360. }
  1361. static void
  1362. sample_linear_cube(GLcontext *ctx, GLuint texUnit,
  1363. const struct gl_texture_object *tObj, GLuint n,
  1364. const GLfloat s[], const GLfloat t[],
  1365. const GLfloat u[], const GLfloat lambda[],
  1366. GLchan rgba[][4])
  1367. {
  1368. GLuint i;
  1369. (void) lambda;
  1370. for (i = 0; i < n; i++) {
  1371. const struct gl_texture_image **images;
  1372. GLfloat newS, newT;
  1373. images = choose_cube_face(tObj, s[i], t[i], u[i], &newS, &newT);
  1374. sample_2d_linear( tObj, images[tObj->BaseLevel], newS, newT, rgba[i] );
  1375. }
  1376. }
  1377. static void
  1378. sample_cube_nearest_mipmap_nearest( const struct gl_texture_object *tObj,
  1379. GLfloat s, GLfloat t, GLfloat u,
  1380. GLfloat lambda, GLchan rgba[4] )
  1381. {
  1382. const struct gl_texture_image **images;
  1383. GLfloat newS, newT;
  1384. GLint level;
  1385. COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
  1386. images = choose_cube_face(tObj, s, t, u, &newS, &newT);
  1387. sample_2d_nearest( tObj, images[level], newS, newT, rgba );
  1388. }
  1389. static void
  1390. sample_cube_linear_mipmap_nearest( const struct gl_texture_object *tObj,
  1391. GLfloat s, GLfloat t, GLfloat u,
  1392. GLfloat lambda, GLchan rgba[4] )
  1393. {
  1394. const struct gl_texture_image **images;
  1395. GLfloat newS, newT;
  1396. GLint level;
  1397. COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level);
  1398. images = choose_cube_face(tObj, s, t, u, &newS, &newT);
  1399. sample_2d_linear( tObj, images[level], newS, newT, rgba );
  1400. }
  1401. static void
  1402. sample_cube_nearest_mipmap_linear( const struct gl_texture_object *tObj,
  1403. GLfloat s, GLfloat t, GLfloat u,
  1404. GLfloat lambda, GLchan rgba[4] )
  1405. {
  1406. const struct gl_texture_image **images;
  1407. GLfloat newS, newT;
  1408. GLint level;
  1409. COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
  1410. images = choose_cube_face(tObj, s, t, u, &newS, &newT);
  1411. if (level >= tObj->_P) {
  1412. sample_2d_nearest( tObj, images[tObj->_P], newS, newT, rgba );
  1413. }
  1414. else {
  1415. GLchan t0[4], t1[4]; /* texels */
  1416. const GLfloat f = myFrac(lambda);
  1417. sample_2d_nearest( tObj, images[level ], newS, newT, t0 );
  1418. sample_2d_nearest( tObj, images[level+1], newS, newT, t1 );
  1419. rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  1420. rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  1421. rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  1422. rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  1423. }
  1424. }
  1425. static void
  1426. sample_cube_linear_mipmap_linear( const struct gl_texture_object *tObj,
  1427. GLfloat s, GLfloat t, GLfloat u,
  1428. GLfloat lambda, GLchan rgba[4] )
  1429. {
  1430. const struct gl_texture_image **images;
  1431. GLfloat newS, newT;
  1432. GLint level;
  1433. COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level);
  1434. images = choose_cube_face(tObj, s, t, u, &newS, &newT);
  1435. if (level >= tObj->_P) {
  1436. sample_2d_linear( tObj, images[tObj->_P], newS, newT, rgba );
  1437. }
  1438. else {
  1439. GLchan t0[4], t1[4];
  1440. const GLfloat f = myFrac(lambda);
  1441. sample_2d_linear( tObj, images[level ], newS, newT, t0 );
  1442. sample_2d_linear( tObj, images[level+1], newS, newT, t1 );
  1443. rgba[RCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
  1444. rgba[GCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
  1445. rgba[BCOMP] = (GLchan) (GLint) ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
  1446. rgba[ACOMP] = (GLchan) (GLint) ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
  1447. }
  1448. }
  1449. static void
  1450. sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
  1451. const struct gl_texture_object *tObj, GLuint n,
  1452. const GLfloat s[], const GLfloat t[],
  1453. const GLfloat u[], const GLfloat lambda[],
  1454. GLchan rgba[][4])
  1455. {
  1456. GLfloat MinMagThresh = SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit];
  1457. GLuint i;
  1458. for (i = 0; i < n; i++) {
  1459. if (lambda[i] > MinMagThresh) {
  1460. /* minification */
  1461. switch (tObj->MinFilter) {
  1462. case GL_NEAREST:
  1463. {
  1464. const struct gl_texture_image **images;
  1465. GLfloat newS, newT;
  1466. images = choose_cube_face(tObj, s[i], t[i], u[i],
  1467. &newS, &newT);
  1468. sample_2d_nearest( tObj, images[tObj->BaseLevel],
  1469. newS, newT, rgba[i] );
  1470. }
  1471. break;
  1472. case GL_LINEAR:
  1473. {
  1474. const struct gl_texture_image **images;
  1475. GLfloat newS, newT;
  1476. images = choose_cube_face(tObj, s[i], t[i], u[i],
  1477. &newS, &newT);
  1478. sample_2d_linear( tObj, images[tObj->BaseLevel],
  1479. newS, newT, rgba[i] );
  1480. }
  1481. break;
  1482. case GL_NEAREST_MIPMAP_NEAREST:
  1483. sample_cube_nearest_mipmap_nearest( tObj, s[i], t[i], u[i],
  1484. lambda[i], rgba[i] );
  1485. break;
  1486. case GL_LINEAR_MIPMAP_NEAREST:
  1487. sample_cube_linear_mipmap_nearest( tObj, s[i], t[i], u[i],
  1488. lambda[i], rgba[i] );
  1489. break;
  1490. case GL_NEAREST_MIPMAP_LINEAR:
  1491. sample_cube_nearest_mipmap_linear( tObj, s[i], t[i], u[i],
  1492. lambda[i], rgba[i] );
  1493. break;
  1494. case GL_LINEAR_MIPMAP_LINEAR:
  1495. sample_cube_linear_mipmap_linear( tObj, s[i], t[i], u[i],
  1496. lambda[i], rgba[i] );
  1497. break;
  1498. default:
  1499. gl_problem(NULL, "Bad min filter in sample_lambda_cube");
  1500. }
  1501. }
  1502. else {
  1503. /* magnification */
  1504. const struct gl_texture_image **images;
  1505. GLfloat newS, newT;
  1506. images = choose_cube_face(tObj, s[i], t[i], u[i],
  1507. &newS, &newT);
  1508. switch (tObj->MagFilter) {
  1509. case GL_NEAREST:
  1510. sample_2d_nearest( tObj, images[tObj->BaseLevel],
  1511. newS, newT, rgba[i] );
  1512. break;
  1513. case GL_LINEAR:
  1514. sample_2d_linear( tObj, images[tObj->BaseLevel],
  1515. newS, newT, rgba[i] );
  1516. break;
  1517. default:
  1518. gl_problem(NULL, "Bad mag filter in sample_lambda_cube");
  1519. }
  1520. }
  1521. }
  1522. }
  1523. static void
  1524. null_sample_func( GLcontext *ctx, GLuint texUnit,
  1525. const struct gl_texture_object *tObj, GLuint n,
  1526. const GLfloat s[], const GLfloat t[],
  1527. const GLfloat u[], const GLfloat lambda[],
  1528. GLchan rgba[][4])
  1529. {
  1530. }
  1531. /**********************************************************************/
  1532. /* Texture Sampling Setup */
  1533. /**********************************************************************/
  1534. /*
  1535. * Setup the texture sampling function for this texture object.
  1536. */
  1537. void
  1538. _swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
  1539. const struct gl_texture_object *t )
  1540. {
  1541. SWcontext *swrast = SWRAST_CONTEXT(ctx);
  1542. if (!t->Complete) {
  1543. swrast->TextureSample[texUnit] = null_sample_func;
  1544. }
  1545. else {
  1546. GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter);
  1547. if (needLambda) {
  1548. /* Compute min/mag filter threshold */
  1549. if (t->MagFilter==GL_LINEAR
  1550. && (t->MinFilter==GL_NEAREST_MIPMAP_NEAREST ||
  1551. t->MinFilter==GL_LINEAR_MIPMAP_NEAREST)) {
  1552. swrast->_MinMagThresh[texUnit] = 0.5F;
  1553. }
  1554. else {
  1555. swrast->_MinMagThresh[texUnit] = 0.0F;
  1556. }
  1557. }
  1558. switch (t->Dimensions) {
  1559. case 1:
  1560. if (needLambda) {
  1561. swrast->TextureSample[texUnit] = sample_lambda_1d;
  1562. }
  1563. else if (t->MinFilter==GL_LINEAR) {
  1564. swrast->TextureSample[texUnit] = sample_linear_1d;
  1565. }
  1566. else {
  1567. ASSERT(t->MinFilter==GL_NEAREST);
  1568. swrast->TextureSample[texUnit] = sample_nearest_1d;
  1569. }
  1570. break;
  1571. case 2:
  1572. if (needLambda) {
  1573. swrast->TextureSample[texUnit] = sample_lambda_2d;
  1574. }
  1575. else if (t->MinFilter==GL_LINEAR) {
  1576. swrast->TextureSample[texUnit] = sample_linear_2d;
  1577. }
  1578. else {
  1579. ASSERT(t->MinFilter==GL_NEAREST);
  1580. if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
  1581. && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGB) {
  1582. swrast->TextureSample[texUnit] = opt_sample_rgb_2d;
  1583. }
  1584. else if (t->WrapS==GL_REPEAT && t->WrapT==GL_REPEAT
  1585. && t->Image[0]->Border==0 && t->Image[0]->Format==GL_RGBA) {
  1586. swrast->TextureSample[texUnit] = opt_sample_rgba_2d;
  1587. }
  1588. else
  1589. swrast->TextureSample[texUnit] = sample_nearest_2d;
  1590. }
  1591. break;
  1592. case 3:
  1593. if (needLambda) {
  1594. swrast->TextureSample[texUnit] = sample_lambda_3d;
  1595. }
  1596. else if (t->MinFilter==GL_LINEAR) {
  1597. swrast->TextureSample[texUnit] = sample_linear_3d;
  1598. }
  1599. else {
  1600. ASSERT(t->MinFilter==GL_NEAREST);
  1601. swrast->TextureSample[texUnit] = sample_nearest_3d;
  1602. }
  1603. break;
  1604. case 6: /* cube map */
  1605. if (needLambda) {
  1606. swrast->TextureSample[texUnit] = sample_lambda_cube;
  1607. }
  1608. else if (t->MinFilter==GL_LINEAR) {
  1609. swrast->TextureSample[texUnit] = sample_linear_cube;
  1610. }
  1611. else {
  1612. ASSERT(t->MinFilter==GL_NEAREST);
  1613. swrast->TextureSample[texUnit] = sample_nearest_cube;
  1614. }
  1615. break;
  1616. default:
  1617. gl_problem(NULL, "invalid dimensions in _mesa_set_texture_sampler");
  1618. }
  1619. }
  1620. }
  1621. #define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) )
  1622. static INLINE void
  1623. _mesa_texture_combine(const GLcontext *ctx,
  1624. const struct gl_texture_unit *textureUnit,
  1625. GLuint n,
  1626. GLchan (*primary_rgba)[4],
  1627. GLchan (*texel)[4],
  1628. GLchan (*rgba)[4])
  1629. {
  1630. GLchan ccolor [3][3*MAX_WIDTH][4];
  1631. GLchan (*argRGB [3])[4];
  1632. GLchan (*argA [3])[4];
  1633. GLuint i, j;
  1634. const GLuint RGBshift = textureUnit->CombineScaleShiftRGB;
  1635. const GLuint Ashift = textureUnit->CombineScaleShiftA;
  1636. ASSERT(ctx->Extensions.EXT_texture_env_combine);
  1637. for (j = 0; j < 3; j++) {
  1638. switch (textureUnit->CombineSourceA[j]) {
  1639. case GL_TEXTURE:
  1640. argA[j] = texel;
  1641. break;
  1642. case GL_PRIMARY_COLOR_EXT:
  1643. argA[j] = primary_rgba;
  1644. break;
  1645. case GL_PREVIOUS_EXT:
  1646. argA[j] = rgba;
  1647. break;
  1648. case GL_CONSTANT_EXT:
  1649. {
  1650. GLchan (*c)[4] = ccolor[j];
  1651. GLchan alpha = FLOAT_TO_CHAN(textureUnit->EnvColor[3]);
  1652. for (i = 0; i < n; i++)
  1653. c[i][ACOMP] = alpha;
  1654. argA[j] = ccolor[j];
  1655. }
  1656. break;
  1657. default:
  1658. gl_problem(NULL, "invalid combine source");
  1659. }
  1660. switch (textureUnit->CombineSourceRGB[j]) {
  1661. case GL_TEXTURE:
  1662. argRGB[j] = texel;
  1663. break;
  1664. case GL_PRIMARY_COLOR_EXT:
  1665. argRGB[j] = primary_rgba;
  1666. break;
  1667. case GL_PREVIOUS_EXT:
  1668. argRGB[j] = rgba;
  1669. break;
  1670. case GL_CONSTANT_EXT:
  1671. {
  1672. GLchan (*c)[4] = ccolor[j];
  1673. const GLchan red = FLOAT_TO_CHAN(textureUnit->EnvColor[0]);
  1674. const GLchan green = FLOAT_TO_CHAN(textureUnit->EnvColor[1]);
  1675. const GLchan blue = FLOAT_TO_CHAN(textureUnit->EnvColor[2]);
  1676. for (i = 0; i < n; i++) {
  1677. c[i][RCOMP] = red;
  1678. c[i][GCOMP] = green;
  1679. c[i][BCOMP] = blue;
  1680. }
  1681. argRGB[j] = ccolor[j];
  1682. }
  1683. break;
  1684. default:
  1685. gl_problem(NULL, "invalid combine source");
  1686. }
  1687. if (textureUnit->CombineOperandRGB[j] != GL_SRC_COLOR) {
  1688. GLchan (*src)[4] = argRGB[j];
  1689. GLchan (*dst)[4] = ccolor[j];
  1690. argRGB[j] = ccolor[j];
  1691. if (textureUnit->CombineOperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) {
  1692. for (i = 0; i < n; i++) {
  1693. dst[i][RCOMP] = CHAN_MAX - src[i][RCOMP];
  1694. dst[i][GCOMP] = CHAN_MAX - src[i][GCOMP];
  1695. dst[i][BCOMP] = CHAN_MAX - src[i][BCOMP];
  1696. }
  1697. }
  1698. else if (textureUnit->CombineOperandRGB[j] == GL_SRC_ALPHA) {
  1699. src = argA[j];
  1700. for (i = 0; i < n; i++) {
  1701. dst[i][RCOMP] = src[i][ACOMP];
  1702. dst[i][GCOMP] = src[i][ACOMP];
  1703. dst[i][BCOMP] = src[i][ACOMP];
  1704. }
  1705. }
  1706. else { /* GL_ONE_MINUS_SRC_ALPHA */
  1707. src = argA[j];
  1708. for (i = 0; i < n; i++) {
  1709. dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP];
  1710. dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP];
  1711. dst[i][BCOMP] = CHAN_MAX - src[i][ACOMP];
  1712. }
  1713. }
  1714. }
  1715. if (textureUnit->CombineOperandA[j] == GL_ONE_MINUS_SRC_ALPHA) {
  1716. GLchan (*src)[4] = argA[j];
  1717. GLchan (*dst)[4] = ccolor[j];
  1718. argA[j] = ccolor[j];
  1719. for (i = 0; i < n; i++) {
  1720. dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP];
  1721. }
  1722. }
  1723. if (textureUnit->CombineModeRGB == GL_REPLACE &&
  1724. textureUnit->CombineModeA == GL_REPLACE) {
  1725. break; /* done, we need only arg0 */
  1726. }
  1727. if (j == 1 &&
  1728. textureUnit->CombineModeRGB != GL_INTERPOLATE_EXT &&
  1729. textureUnit->CombineModeA != GL_INTERPOLATE_EXT) {
  1730. break; /* arg0 and arg1 are done. we don't need arg2. */
  1731. }
  1732. }
  1733. switch (textureUnit->CombineModeRGB) {
  1734. case GL_REPLACE:
  1735. {
  1736. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
  1737. if (RGBshift) {
  1738. for (i = 0; i < n; i++) {
  1739. GLuint r = (GLuint) arg0[i][RCOMP] << RGBshift;
  1740. GLuint g = (GLuint) arg0[i][GCOMP] << RGBshift;
  1741. GLuint b = (GLuint) arg0[i][BCOMP] << RGBshift;
  1742. rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
  1743. rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
  1744. rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
  1745. }
  1746. }
  1747. else {
  1748. for (i = 0; i < n; i++) {
  1749. rgba[i][RCOMP] = arg0[i][RCOMP];
  1750. rgba[i][GCOMP] = arg0[i][GCOMP];
  1751. rgba[i][BCOMP] = arg0[i][BCOMP];
  1752. }
  1753. }
  1754. }
  1755. break;
  1756. case GL_MODULATE:
  1757. {
  1758. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
  1759. const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
  1760. const GLint shift = 8 - RGBshift;
  1761. for (i = 0; i < n; i++) {
  1762. GLuint r = PROD(arg0[i][0], arg1[i][RCOMP]) >> shift;
  1763. GLuint g = PROD(arg0[i][1], arg1[i][GCOMP]) >> shift;
  1764. GLuint b = PROD(arg0[i][2], arg1[i][BCOMP]) >> shift;
  1765. rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
  1766. rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
  1767. rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
  1768. }
  1769. }
  1770. break;
  1771. case GL_ADD:
  1772. {
  1773. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
  1774. const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
  1775. for (i = 0; i < n; i++) {
  1776. GLint r = ((GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP]) << RGBshift;
  1777. GLint g = ((GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP]) << RGBshift;
  1778. GLint b = ((GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP]) << RGBshift;
  1779. rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
  1780. rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
  1781. rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
  1782. }
  1783. }
  1784. break;
  1785. case GL_ADD_SIGNED_EXT:
  1786. {
  1787. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
  1788. const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
  1789. for (i = 0; i < n; i++) {
  1790. GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] - 128;
  1791. GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] - 128;
  1792. GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] - 128;
  1793. r = (r < 0) ? 0 : r << RGBshift;
  1794. g = (g < 0) ? 0 : g << RGBshift;
  1795. b = (b < 0) ? 0 : b << RGBshift;
  1796. rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
  1797. rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
  1798. rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
  1799. }
  1800. }
  1801. break;
  1802. case GL_INTERPOLATE_EXT:
  1803. {
  1804. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
  1805. const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
  1806. const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
  1807. const GLint shift = 8 - RGBshift;
  1808. for (i = 0; i < n; i++) {
  1809. GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP])
  1810. + PROD(arg1[i][RCOMP], CHAN_MAX - arg2[i][RCOMP]))
  1811. >> shift;
  1812. GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP])
  1813. + PROD(arg1[i][GCOMP], CHAN_MAX - arg2[i][GCOMP]))
  1814. >> shift;
  1815. GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP])
  1816. + PROD(arg1[i][BCOMP], CHAN_MAX - arg2[i][BCOMP]))
  1817. >> shift;
  1818. rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
  1819. rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
  1820. rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
  1821. }
  1822. }
  1823. break;
  1824. default:
  1825. gl_problem(NULL, "invalid combine mode");
  1826. }
  1827. switch (textureUnit->CombineModeA) {
  1828. case GL_REPLACE:
  1829. {
  1830. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
  1831. if (Ashift) {
  1832. for (i = 0; i < n; i++) {
  1833. GLuint a = (GLuint) arg0[i][ACOMP] << Ashift;
  1834. rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
  1835. }
  1836. }
  1837. else {
  1838. for (i = 0; i < n; i++) {
  1839. rgba[i][ACOMP] = arg0[i][ACOMP];
  1840. }
  1841. }
  1842. }
  1843. break;
  1844. case GL_MODULATE:
  1845. {
  1846. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
  1847. const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
  1848. const GLint shift = 8 - Ashift;
  1849. for (i = 0; i < n; i++) {
  1850. GLuint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift);
  1851. rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
  1852. }
  1853. }
  1854. break;
  1855. case GL_ADD:
  1856. {
  1857. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
  1858. const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
  1859. for (i = 0; i < n; i++) {
  1860. GLint a = ((GLint) arg0[i][ACOMP] + arg1[i][ACOMP]) << Ashift;
  1861. rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
  1862. }
  1863. }
  1864. break;
  1865. case GL_ADD_SIGNED_EXT:
  1866. {
  1867. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
  1868. const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
  1869. for (i = 0; i < n; i++) {
  1870. GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] - 128;
  1871. a = (a < 0) ? 0 : a << Ashift;
  1872. rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
  1873. }
  1874. }
  1875. break;
  1876. case GL_INTERPOLATE_EXT:
  1877. {
  1878. const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
  1879. const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
  1880. const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
  1881. const GLint shift = 8 - Ashift;
  1882. for (i=0; i<n; i++) {
  1883. GLuint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP])
  1884. + PROD(arg1[i][ACOMP], CHAN_MAX - arg2[i][ACOMP]))
  1885. >> shift;
  1886. rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
  1887. }
  1888. }
  1889. break;
  1890. default:
  1891. gl_problem(NULL, "invalid combine mode");
  1892. }
  1893. }
  1894. #undef PROD
  1895. /**********************************************************************/
  1896. /* Texture Application */
  1897. /**********************************************************************/
  1898. /*
  1899. * Combine incoming fragment color with texel color to produce output color.
  1900. * Input: textureUnit - pointer to texture unit to apply
  1901. * format - base internal texture format
  1902. * n - number of fragments
  1903. * primary_rgba - primary colors (may be rgba for single texture)
  1904. * texels - array of texel colors
  1905. * InOut: rgba - incoming fragment colors modified by texel colors
  1906. * according to the texture environment mode.
  1907. */
  1908. static void
  1909. apply_texture( const GLcontext *ctx,
  1910. const struct gl_texture_unit *texUnit,
  1911. GLuint n,
  1912. GLchan primary_rgba[][4], GLchan texel[][4],
  1913. GLchan rgba[][4] )
  1914. {
  1915. GLint baseLevel;
  1916. GLuint i;
  1917. GLint Rc, Gc, Bc, Ac;
  1918. GLenum format;
  1919. ASSERT(texUnit);
  1920. ASSERT(texUnit->_Current);
  1921. baseLevel = texUnit->_Current->BaseLevel;
  1922. ASSERT(texUnit->_Current->Image[baseLevel]);
  1923. format = texUnit->_Current->Image[baseLevel]->Format;
  1924. if (format==GL_COLOR_INDEX) {
  1925. format = GL_RGBA; /* XXXX a hack! */
  1926. }
  1927. switch (texUnit->EnvMode) {
  1928. case GL_REPLACE:
  1929. switch (format) {
  1930. case GL_ALPHA:
  1931. for (i=0;i<n;i++) {
  1932. /* Cv = Cf */
  1933. /* Av = At */
  1934. rgba[i][ACOMP] = texel[i][ACOMP];
  1935. }
  1936. break;
  1937. case GL_LUMINANCE:
  1938. for (i=0;i<n;i++) {
  1939. /* Cv = Lt */
  1940. GLchan Lt = texel[i][RCOMP];
  1941. rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
  1942. /* Av = Af */
  1943. }
  1944. break;
  1945. case GL_LUMINANCE_ALPHA:
  1946. for (i=0;i<n;i++) {
  1947. GLchan Lt = texel[i][RCOMP];
  1948. /* Cv = Lt */
  1949. rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
  1950. /* Av = At */
  1951. rgba[i][ACOMP] = texel[i][ACOMP];
  1952. }
  1953. break;
  1954. case GL_INTENSITY:
  1955. for (i=0;i<n;i++) {
  1956. /* Cv = It */
  1957. GLchan It = texel[i][RCOMP];
  1958. rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It;
  1959. /* Av = It */
  1960. rgba[i][ACOMP] = It;
  1961. }
  1962. break;
  1963. case GL_RGB:
  1964. for (i=0;i<n;i++) {
  1965. /* Cv = Ct */
  1966. rgba[i][RCOMP] = texel[i][RCOMP];
  1967. rgba[i][GCOMP] = texel[i][GCOMP];
  1968. rgba[i][BCOMP] = texel[i][BCOMP];
  1969. /* Av = Af */
  1970. }
  1971. break;
  1972. case GL_RGBA:
  1973. for (i=0;i<n;i++) {
  1974. /* Cv = Ct */
  1975. rgba[i][RCOMP] = texel[i][RCOMP];
  1976. rgba[i][GCOMP] = texel[i][GCOMP];
  1977. rgba[i][BCOMP] = texel[i][BCOMP];
  1978. /* Av = At */
  1979. rgba[i][ACOMP] = texel[i][ACOMP];
  1980. }
  1981. break;
  1982. default:
  1983. gl_problem(ctx, "Bad format (GL_REPLACE) in apply_texture");
  1984. return;
  1985. }
  1986. break;
  1987. case GL_MODULATE:
  1988. switch (format) {
  1989. case GL_ALPHA:
  1990. for (i=0;i<n;i++) {
  1991. /* Cv = Cf */
  1992. /* Av = AfAt */
  1993. rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
  1994. }
  1995. break;
  1996. case GL_LUMINANCE:
  1997. for (i=0;i<n;i++) {
  1998. /* Cv = LtCf */
  1999. GLchan Lt = texel[i][RCOMP];
  2000. rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt );
  2001. rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt );
  2002. rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt );
  2003. /* Av = Af */
  2004. }
  2005. break;
  2006. case GL_LUMINANCE_ALPHA:
  2007. for (i=0;i<n;i++) {
  2008. /* Cv = CfLt */
  2009. GLchan Lt = texel[i][RCOMP];
  2010. rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt );
  2011. rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt );
  2012. rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt );
  2013. /* Av = AfAt */
  2014. rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
  2015. }
  2016. break;
  2017. case GL_INTENSITY:
  2018. for (i=0;i<n;i++) {
  2019. /* Cv = CfIt */
  2020. GLchan It = texel[i][RCOMP];
  2021. rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], It );
  2022. rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], It );
  2023. rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], It );
  2024. /* Av = AfIt */
  2025. rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], It );
  2026. }
  2027. break;
  2028. case GL_RGB:
  2029. for (i=0;i<n;i++) {
  2030. /* Cv = CfCt */
  2031. rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] );
  2032. rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] );
  2033. rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] );
  2034. /* Av = Af */
  2035. }
  2036. break;
  2037. case GL_RGBA:
  2038. for (i=0;i<n;i++) {
  2039. /* Cv = CfCt */
  2040. rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] );
  2041. rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] );
  2042. rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] );
  2043. /* Av = AfAt */
  2044. rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
  2045. }
  2046. break;
  2047. default:
  2048. gl_problem(ctx, "Bad format (GL_MODULATE) in apply_texture");
  2049. return;
  2050. }
  2051. break;
  2052. case GL_DECAL:
  2053. switch (format) {
  2054. case GL_ALPHA:
  2055. case GL_LUMINANCE:
  2056. case GL_LUMINANCE_ALPHA:
  2057. case GL_INTENSITY:
  2058. /* undefined */
  2059. break;
  2060. case GL_RGB:
  2061. for (i=0;i<n;i++) {
  2062. /* Cv = Ct */
  2063. rgba[i][RCOMP] = texel[i][RCOMP];
  2064. rgba[i][GCOMP] = texel[i][GCOMP];
  2065. rgba[i][BCOMP] = texel[i][BCOMP];
  2066. /* Av = Af */
  2067. }
  2068. break;
  2069. case GL_RGBA:
  2070. for (i=0;i<n;i++) {
  2071. /* Cv = Cf(1-At) + CtAt */
  2072. GLint t = texel[i][ACOMP], s = CHAN_MAX - t;
  2073. rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(texel[i][RCOMP],t);
  2074. rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(texel[i][GCOMP],t);
  2075. rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(texel[i][BCOMP],t);
  2076. /* Av = Af */
  2077. }
  2078. break;
  2079. default:
  2080. gl_problem(ctx, "Bad format (GL_DECAL) in apply_texture");
  2081. return;
  2082. }
  2083. break;
  2084. case GL_BLEND:
  2085. Rc = (GLint) (texUnit->EnvColor[0] * CHAN_MAXF);
  2086. Gc = (GLint) (texUnit->EnvColor[1] * CHAN_MAXF);
  2087. Bc = (GLint) (texUnit->EnvColor[2] * CHAN_MAXF);
  2088. Ac = (GLint) (texUnit->EnvColor[3] * CHAN_MAXF);
  2089. switch (format) {
  2090. case GL_ALPHA:
  2091. for (i=0;i<n;i++) {
  2092. /* Cv = Cf */
  2093. /* Av = AfAt */
  2094. rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
  2095. }
  2096. break;
  2097. case GL_LUMINANCE:
  2098. for (i=0;i<n;i++) {
  2099. /* Cv = Cf(1-Lt) + CcLt */
  2100. GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt;
  2101. rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt);
  2102. rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt);
  2103. rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt);
  2104. /* Av = Af */
  2105. }
  2106. break;
  2107. case GL_LUMINANCE_ALPHA:
  2108. for (i=0;i<n;i++) {
  2109. /* Cv = Cf(1-Lt) + CcLt */
  2110. GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt;
  2111. rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt);
  2112. rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt);
  2113. rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt);
  2114. /* Av = AfAt */
  2115. rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]);
  2116. }
  2117. break;
  2118. case GL_INTENSITY:
  2119. for (i=0;i<n;i++) {
  2120. /* Cv = Cf(1-It) + CcLt */
  2121. GLchan It = texel[i][RCOMP], s = CHAN_MAX - It;
  2122. rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, It);
  2123. rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, It);
  2124. rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, It);
  2125. /* Av = Af(1-It) + Ac*It */
  2126. rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], s) + CHAN_PRODUCT(Ac, It);
  2127. }
  2128. break;
  2129. case GL_RGB:
  2130. for (i=0;i<n;i++) {
  2131. /* Cv = Cf(1-Ct) + CcCt */
  2132. rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]);
  2133. rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]);
  2134. rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]);
  2135. /* Av = Af */
  2136. }
  2137. break;
  2138. case GL_RGBA:
  2139. for (i=0;i<n;i++) {
  2140. /* Cv = Cf(1-Ct) + CcCt */
  2141. rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]);
  2142. rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]);
  2143. rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]);
  2144. /* Av = AfAt */
  2145. rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]);
  2146. }
  2147. break;
  2148. default:
  2149. gl_problem(ctx, "Bad format (GL_BLEND) in apply_texture");
  2150. return;
  2151. }
  2152. break;
  2153. case GL_ADD: /* GL_EXT_texture_add_env */
  2154. switch (format) {
  2155. case GL_ALPHA:
  2156. for (i=0;i<n;i++) {
  2157. /* Rv = Rf */
  2158. /* Gv = Gf */
  2159. /* Bv = Bf */
  2160. rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
  2161. }
  2162. break;
  2163. case GL_LUMINANCE:
  2164. for (i=0;i<n;i++) {
  2165. GLuint Lt = texel[i][RCOMP];
  2166. GLuint r = rgba[i][RCOMP] + Lt;
  2167. GLuint g = rgba[i][GCOMP] + Lt;
  2168. GLuint b = rgba[i][BCOMP] + Lt;
  2169. rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
  2170. rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
  2171. rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
  2172. /* Av = Af */
  2173. }
  2174. break;
  2175. case GL_LUMINANCE_ALPHA:
  2176. for (i=0;i<n;i++) {
  2177. GLuint Lt = texel[i][RCOMP];
  2178. GLuint r = rgba[i][RCOMP] + Lt;
  2179. GLuint g = rgba[i][GCOMP] + Lt;
  2180. GLuint b = rgba[i][BCOMP] + Lt;
  2181. rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
  2182. rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
  2183. rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
  2184. rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
  2185. }
  2186. break;
  2187. case GL_INTENSITY:
  2188. for (i=0;i<n;i++) {
  2189. GLchan It = texel[i][RCOMP];
  2190. GLuint r = rgba[i][RCOMP] + It;
  2191. GLuint g = rgba[i][GCOMP] + It;
  2192. GLuint b = rgba[i][BCOMP] + It;
  2193. GLuint a = rgba[i][ACOMP] + It;
  2194. rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
  2195. rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
  2196. rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
  2197. rgba[i][ACOMP] = MIN2(a, CHAN_MAX);
  2198. }
  2199. break;
  2200. case GL_RGB:
  2201. for (i=0;i<n;i++) {
  2202. GLuint r = rgba[i][RCOMP] + texel[i][RCOMP];
  2203. GLuint g = rgba[i][GCOMP] + texel[i][GCOMP];
  2204. GLuint b = rgba[i][BCOMP] + texel[i][BCOMP];
  2205. rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
  2206. rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
  2207. rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
  2208. /* Av = Af */
  2209. }
  2210. break;
  2211. case GL_RGBA:
  2212. for (i=0;i<n;i++) {
  2213. GLuint r = rgba[i][RCOMP] + texel[i][RCOMP];
  2214. GLuint g = rgba[i][GCOMP] + texel[i][GCOMP];
  2215. GLuint b = rgba[i][BCOMP] + texel[i][BCOMP];
  2216. rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
  2217. rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
  2218. rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
  2219. rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
  2220. }
  2221. break;
  2222. default:
  2223. gl_problem(ctx, "Bad format (GL_ADD) in apply_texture");
  2224. return;
  2225. }
  2226. break;
  2227. case GL_COMBINE_EXT: /* GL_EXT_combine_ext; we modify texel array */
  2228. switch (format) {
  2229. case GL_ALPHA:
  2230. for (i=0;i<n;i++)
  2231. texel[i][RCOMP] = texel[i][GCOMP] = texel[i][BCOMP] = 0;
  2232. break;
  2233. case GL_LUMINANCE:
  2234. for (i=0;i<n;i++) {
  2235. /* Cv = Lt */
  2236. GLchan Lt = texel[i][RCOMP];
  2237. texel[i][GCOMP] = texel[i][BCOMP] = Lt;
  2238. /* Av = 1 */
  2239. texel[i][ACOMP] = CHAN_MAX;
  2240. }
  2241. break;
  2242. case GL_LUMINANCE_ALPHA:
  2243. for (i=0;i<n;i++) {
  2244. GLchan Lt = texel[i][RCOMP];
  2245. /* Cv = Lt */
  2246. texel[i][GCOMP] = texel[i][BCOMP] = Lt;
  2247. }
  2248. break;
  2249. case GL_INTENSITY:
  2250. for (i=0;i<n;i++) {
  2251. /* Cv = It */
  2252. GLchan It = texel[i][RCOMP];
  2253. texel[i][GCOMP] = texel[i][BCOMP] = It;
  2254. /* Av = It */
  2255. texel[i][ACOMP] = It;
  2256. }
  2257. break;
  2258. case GL_RGB:
  2259. for (i=0;i<n;i++) {
  2260. /* Av = 1 */
  2261. texel[i][ACOMP] = CHAN_MAX;
  2262. }
  2263. break;
  2264. case GL_RGBA: /* do nothing. */
  2265. break;
  2266. default:
  2267. gl_problem(ctx, "Bad format in apply_texture (GL_COMBINE_EXT)");
  2268. return;
  2269. }
  2270. _mesa_texture_combine(ctx, texUnit, n, primary_rgba, texel, rgba);
  2271. break;
  2272. default:
  2273. gl_problem(ctx, "Bad env mode in apply_texture");
  2274. return;
  2275. }
  2276. }
  2277. /*
  2278. * Apply a unit of texture mapping to the incoming fragments.
  2279. */
  2280. void gl_texture_pixels( GLcontext *ctx, GLuint texUnit, GLuint n,
  2281. const GLfloat s[], const GLfloat t[],
  2282. const GLfloat r[], GLfloat lambda[],
  2283. GLchan primary_rgba[][4], GLchan rgba[][4] )
  2284. {
  2285. const GLuint mask = TEXTURE0_ANY << (texUnit * 4);
  2286. if (ctx->Texture._ReallyEnabled & mask) {
  2287. const struct gl_texture_unit *textureUnit = &ctx->Texture.Unit[texUnit];
  2288. if (textureUnit->_Current) { /* XXX need this? */
  2289. GLchan texel[PB_SIZE][4];
  2290. if (textureUnit->LodBias != 0.0F) {
  2291. /* apply LOD bias, but don't clamp yet */
  2292. GLuint i;
  2293. for (i=0;i<n;i++) {
  2294. lambda[i] += textureUnit->LodBias;
  2295. }
  2296. }
  2297. if (textureUnit->_Current->MinLod != -1000.0
  2298. || textureUnit->_Current->MaxLod != 1000.0) {
  2299. /* apply LOD clamping to lambda */
  2300. GLfloat min = textureUnit->_Current->MinLod;
  2301. GLfloat max = textureUnit->_Current->MaxLod;
  2302. GLuint i;
  2303. for (i=0;i<n;i++) {
  2304. GLfloat l = lambda[i];
  2305. lambda[i] = CLAMP(l, min, max);
  2306. }
  2307. }
  2308. /* fetch texture images from device driver, if needed */
  2309. if (ctx->Driver.GetTexImage) {
  2310. if (!_mesa_get_teximages_from_driver(ctx, textureUnit->_Current)) {
  2311. return;
  2312. }
  2313. }
  2314. /* Sample the texture. */
  2315. SWRAST_CONTEXT(ctx)->TextureSample[texUnit]( ctx, texUnit,
  2316. textureUnit->_Current,
  2317. n, s, t, r,
  2318. lambda, texel );
  2319. apply_texture( ctx, textureUnit, n, primary_rgba, texel, rgba );
  2320. }
  2321. }
  2322. }