Advertisement
Guest User

Untitled

a guest
Mar 7th, 2012
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.54 KB | None | 0 0
  1.  
  2. #include "Shader.h"
  3. #include "OpenGLWin.h"
  4. #include "BitmapFile.h"
  5. #include "miscio.h"
  6. #include "shape.h"
  7. #include "scene.h"
  8. #include "time.h"
  9.  
  10. ///////////////////////////////////////////////////////////////////
  11. // The constant shader, shades each polygon with a constant color
  12. // The color is defined by the object's "diffuse color"
  13. ///////////////////////////////////////////////////////////////////
  14.  
  15. void constantShader::BeginShading(void)
  16. {
  17. glDisable(GL_LIGHTING);
  18. }
  19.  
  20. void constantShader::DrawPolygon(int n, point p[], vector vn[], vector pn, vector uv[])
  21. {
  22. // To Do
  23. //
  24. // Replace the following code with code that will draw a polygon that is shaded
  25. // a single constant color
  26. glBegin(GL_POLYGON);
  27. for (int i = 0; i < n; i++)
  28. glVertex3dv(p[i].AsArray());
  29. glEnd();
  30. }
  31.  
  32. void constantShader::EndShading(void)
  33. {
  34.  
  35. }
  36.  
  37. ///////////////////////////////////////////////////////////////////
  38. // The wireframe shader, each polygon is drawn as a wireframe
  39. // The color of each line is defined by the object's "diffuse color"
  40. ///////////////////////////////////////////////////////////////////
  41.  
  42. void wireframeShader::BeginShading(void)
  43. {
  44. glDisable(GL_LIGHTING);
  45. }
  46.  
  47. void wireframeShader::DrawPolygon(int n, point p[], vector vn[], vector pn, vector uv[])
  48. {
  49. glBegin(GL_LINE_LOOP);
  50. for (int i = 0; i < n; i++)
  51. glVertex3dv(p[i].AsArray());
  52. glEnd();
  53. }
  54.  
  55. void wireframeShader::EndShading(void)
  56. {
  57.  
  58. }
  59.  
  60. ///////////////////////////////////////////////////////////////////
  61. // The faceted shader, each polygon is drawn with a single normal
  62. // The color of each polygon is defined by the object's
  63. // Lighting properties, ambient, diffuse, specular and shininess
  64. // Attributes
  65. ///////////////////////////////////////////////////////////////////
  66.  
  67.  
  68. void facetedShader::BeginShading(void)
  69. {
  70. // To Do
  71. //
  72. // Enable lighting and set the shading mode to faceted shading
  73. glEnable(GL_LIGHTING);
  74. glEnable(GL_LIGHT0);
  75. glShadeModel(GL_FLAT);
  76. }
  77.  
  78. void facetedShader::DrawPolygon(int n, point p[], vector vn[], vector pn, vector uv[])
  79. {
  80. // To Do
  81. //
  82. // Replace the following code with code that will render the polygon with
  83. // faceted shading
  84. glBegin(GL_POLYGON);
  85. glNormal3d((GLdouble)pn[0], (GLdouble)pn[1], (GLdouble)pn[2]);
  86. for (int i = 0; i < n; i++)
  87. {
  88. glVertex3dv(p[i].AsArray());
  89. }
  90. glEnd();
  91. }
  92.  
  93. void facetedShader::EndShading(void)
  94. {
  95. // To Do
  96. //
  97. // Any cleanup neccessary
  98. }
  99.  
  100. ///////////////////////////////////////////////////////////////////
  101. // The gouraud shader, each vertex is given a normal and lighting
  102. // Calculations are performed per vertex to get a vertex color.
  103. // Colors are then bilinearly interpolated over the surface of the
  104. // polygon
  105. //
  106. // Lighting properties, ambient, diffuse, specular and shininess
  107. // Attributes determine the color at each vertex
  108. ///////////////////////////////////////////////////////////////////
  109.  
  110. void gouraudShader::BeginShading(void)
  111. {
  112. // To Do
  113. //
  114. // Enable lighting and set the shading model to smooth (gouraud) shading
  115. glEnable(GL_LIGHTING);
  116. glEnable(GL_LIGHT0);
  117. glShadeModel(GL_SMOOTH);
  118. }
  119.  
  120. void gouraudShader::DrawPolygon(int n, point p[], vector vn[], vector pn, vector uv[])
  121. {
  122. // To Do
  123. //
  124. // Replace the following code with the neccessary code for drawing a polygon
  125. // with smooth (gouraud shading)
  126. glBegin(GL_POLYGON);
  127. for (int i = 0; i < n; i++)
  128. {
  129. glNormal3d((GLdouble)vn[i][0], (GLdouble)vn[i][1], (GLdouble)vn[i][2]);
  130. glVertex3dv(p[i].AsArray());
  131. }
  132. glEnd();
  133. }
  134.  
  135. void gouraudShader::EndShading(void)
  136. {
  137. // To Do
  138. //
  139. // Any cleanup neccessary
  140. }
  141.  
  142. ///////////////////////////////////////////////////////////////////
  143. // The texture shader applies an image texture map to an object and
  144. // applies gouraud style lighting interpolation. It is much more
  145. // complex, requiring several parameters:
  146. //
  147. // map : The name of the texture map. This name should
  148. // refer to a file in one of the following formats
  149. //
  150. // bmp, tga
  151. //
  152. // shape : What shape is used to project the image onto the
  153. // Possible values are
  154. //
  155. // planar, cylindrical, spherical and box
  156. //
  157. // axis : What axis is used for the projection. The effect
  158. // of this parameter affects different shapes in
  159. // different ways. Possible values are:
  160. //
  161. // 0 = x-axis, 1 = y-axis, 2 = z-axis
  162. //
  163. // this should be replaced by a more general scheme
  164. //
  165. // entity : How are texture coordinates chosen for lookup
  166. // Possible values are
  167. //
  168. // position, centroid, normal, reflection
  169. //
  170. // and much much more ...
  171. //
  172. ///////////////////////////////////////////////////////////////////
  173.  
  174. textureShader::textureShader()
  175. {
  176. tObject = 0;
  177. tTextureUnit = 0;
  178. tEntity = Position;
  179. tCoordSys = Object;
  180. tShape = Planar;
  181. tAxis = XAxis;
  182. for (int i = 0; i < 10; i++)
  183. tName[i][0] = '\0';
  184. tMinFilter = GL_LINEAR_MIPMAP_LINEAR;
  185. tMagFilter = GL_LINEAR;
  186. tHorzWrap = GL_REPEAT;
  187. tVertWrap = GL_REPEAT;
  188. tBlend = GL_MODULATE;
  189. tBlendColor[0] = 1.0; tBlendColor[1] = 1.0; tBlendColor[2] = 1.0; tBlendColor[3] = 1.0;
  190. tConstColor[0] = 0.0; tConstColor[1] = 0.0; tConstColor[2] = 0.0; tConstColor[3] = 0.0;
  191. tFilterColor[0] = 1.0; tFilterColor[1] = 1.0; tFilterColor[2] = 1.0; tFilterColor[3] = 1.0;
  192. tViewTransform = false;
  193. tAnisotropy = 0;
  194. }
  195.  
  196. textureShader::~textureShader()
  197. {
  198. glDeleteTextures(1, &tObject);
  199. }
  200.  
  201. void textureShader::BeginShading(void)
  202. {
  203. // To Do
  204. //
  205. // Enable lighting and set smooth shading
  206. glEnable(GL_LIGHTING);
  207. glEnable(GL_LIGHT0);
  208. glShadeModel(GL_SMOOTH);
  209. glEnable(GL_BLEND);
  210.  
  211.  
  212. // To Do
  213. //
  214. // Enable the seperate specular color so that highlights can appear
  215. // on top
  216.  
  217. // To Do: Advanced
  218. //
  219. // Activate the proper texture unit for multi-texturing
  220.  
  221. // To Do
  222. //
  223. // Set up the texture by calling "SetupTextureMap" and enable the proper texture
  224. // target (e.g. GL_TEXTURE2D). Hint: the texture target is set at the top of
  225. // one of the methods below and is stored in a member of this object
  226. SetupTextureMap();
  227. glEnable(this->glTarget);
  228.  
  229. // Apply texture transforms
  230. glMatrixMode(GL_TEXTURE);
  231. glLoadIdentity();
  232.  
  233. // To Do: Advanced
  234. //
  235. // Apply texture transforms, and if we are using a viewing transform in the
  236. // texture (say for reflection mapping) then set up the proper viewing transform
  237.  
  238. if (tEntity == Eye) // Project to the screen.
  239. {
  240. // To Do: Advanced
  241. //
  242. // Apply the necessary transforms to project the 3D texture coordinates
  243. // (which, if this is active, will be the vertex object coordinates) to
  244. // the screen (normalized device coordinates)
  245. }
  246.  
  247. // Now we are done with the textrue transforms transforms
  248. glMatrixMode(GL_MODELVIEW);
  249.  
  250. // To Do: Advanced
  251. //
  252. // If appropriate, begin automatic coordinate generation for normal mapping or reflection mapping
  253. }
  254.  
  255. void textureShader::DrawPolygon(int n, point p[], vector vn[], vector pn, vector uv[])
  256. {
  257. BeginPolygon(n, p, vn, pn, uv); // Used to prevent texture tearing, and setup for advanced textures
  258.  
  259. // To Do
  260. //
  261. // Replace the following code with code that will draw the polygon
  262. // and apply the texture to it by calling the "ApplyTexture" method
  263. // on each vertex.
  264.  
  265. glBegin(GL_LINE_LOOP);
  266. for (int i = 0; i < n; i++)
  267. {
  268. glNormal3d((GLdouble)vn[i][0], (GLdouble)vn[i][1], (GLdouble)vn[i][2]);
  269. ApplyTexture(p[i], vn[i], uv[i]);
  270. glVertex3dv(p[i].AsArray());
  271. }
  272. glEnd();
  273. }
  274.  
  275. void textureShader::EndShading(void)
  276. {
  277. // To Do
  278. //
  279. // Any cleanup required (hint: whatever you've started up in BeginShading or
  280. // SetupTextureMap, you need to shut down here!)
  281. glDisable(GL_TEXTURE_2D);
  282. glDisable(GL_BLEND);
  283. }
  284.  
  285. void textureShader::SetupTextureMap(void)
  286. {
  287. if (tShape == Box)
  288. glTarget = GL_TEXTURE_CUBE_MAP;
  289. else
  290. glTarget = GL_TEXTURE_2D;
  291.  
  292. // Note that we only initialize the OpenGL texture objects if we
  293. // don't yet have an OpenGL texture object
  294. if (tObject <= 0)
  295. {
  296. // Find the number of textures that have been specified
  297. // Multiple images are used for manually specifiying mipmaps
  298. // and for box maps
  299. int nImages = 0;
  300. while (tName[nImages][0] != '\0' && nImages < MAX_IMAGES)
  301. nImages++;
  302.  
  303. // If there are none, then do nothing and return
  304. if (nImages < 1)
  305. return;
  306.  
  307. // Generate the texture object and bind it to the texture target defined above
  308. glGenTextures(1, &tObject);
  309. glBindTexture(glTarget, tObject);
  310.  
  311. // Now, loop through the images and send them to OpenGL
  312. for (int nImage = 0; nImage < nImages; nImage++)
  313. {
  314. BitmapFile texture;
  315. if (!texture.Read(tName[nImage]))
  316. complain("Couldn't read texture %s", tName);
  317.  
  318. // Now we will multiply the image by tFilterColor and add tConstColor.
  319. // We do these with methods in the BitmapFile class.
  320. if (tFilterColor[0] < .99999 || tFilterColor[1] < .99999 || tFilterColor[2] < .99999 || tFilterColor[3] < .99999)
  321. texture.Filter(tFilterColor[0], tFilterColor[1], tFilterColor[2], tFilterColor[3]);
  322. if (tConstColor[0] > .00001 || tConstColor[1] > .00001 || tConstColor[2] > .00001 || tConstColor[3] > .00001)
  323. texture.Add(tConstColor[0], tConstColor[1], tConstColor[2], tConstColor[3]);
  324.  
  325. // To Do
  326. //
  327. // Get the width and height from the texture file
  328. int w, h;
  329. w = texture.Width();
  330. h = texture.Height();
  331. // To Do
  332. //
  333. // Set the image data pointer to point do the data in the texture (Hint:
  334. // is there a method in the texture that
  335. GLubyte *imageData;
  336. imageData = texture.ImageData();
  337. // To Do
  338. //
  339. // Set the src and target formats for the texture data. The srcFormat should
  340. // match the format of the data in the texture file itself. Hint: what order
  341. // are the colors stored in bitmap and targa files? The targFormat is the
  342. // format that we want the data stored inside OpenGL. Note that these two
  343. // may not be the same.
  344. //
  345. // We also need to check here for the number of bytes per pixel in the image.
  346. // For our examples, it will be either 3 or 4. If it is 4, then there is an
  347. // alpha channel in the data, otherwise it is three. Set the srcFormat and
  348. // targFormat appropriately, or the data will not be read in correctly!
  349. GLuint srcFormat = GL_BGRA, targFormat = GL_RGBA;
  350. if(texture.BytesPerPixel() == 3)
  351. srcFormat = GL_BGR, targFormat = GL_RGB;
  352.  
  353. // Rows in our image are stored contiguously (not aligned on a specific number
  354. // of bytes, so set the unpack alignment to 1 --> single byte aligned
  355. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  356.  
  357. // To Do
  358. //
  359. // If it is a box map (which doesn't support manual mipmap specification in RGL)
  360. // or if only one image is supplied turn on automatic mipmap generation.
  361. //gluBuild2DMipmaps(glTarget, 3, w, h, srcFormat, GL_UNSIGNED_BYTE, imageData);
  362. if (nImages == 1 || tShape == Box)
  363. glTexParameteri(glTarget, GL_GENERATE_MIPMAP_SGIS, GL_TRUE);
  364.  
  365. // To Do
  366. //
  367. // Send the data to OpenGL. Be very careful when sending all the data. For a first
  368. // shot you may assume that the texture target is GL_TEXTURE2D, but you will need to
  369. // change this command when we enable box mapping!
  370. if (tShape != Box)
  371. glTexImage2D(GL_TEXTURE_2D, nImage, targFormat, (GLsizei)w, (GLsizei) h, (GLint)0, srcFormat, GL_UNSIGNED_BYTE, imageData);
  372. else
  373. glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + nImage, 0, targFormat, (GLsizei)w, (GLsizei)h, (GLint)0, srcFormat, GL_UNSIGNED_BYTE, imageData);
  374. }
  375. }
  376.  
  377. // To Do
  378. //
  379. // Now, bind the texture and set the texture parameters. You need to set several here.
  380. // Set the parameters for how the image wraps and what kind of magnification and minification
  381. // filter you want to use, and also, set the anisotropy level. Also set the blend mode and
  382. // blend color. Note, if you do not do this correctly, your textxure will not show up at all,
  383. // particularly for mipmapping. If you use a mipmapped filter without enabling mipmap generation
  384. // above, you will get nothing!
  385. //glBindTexture(glTarget, tObject);
  386. glTexParameteri(glTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//this->tMinFilter);
  387. glTexParameteri(glTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//this->tMagFilter);
  388. glTexParameteri(glTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);//this->tHorzWrap);
  389. glTexParameteri(glTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);//this->tVertWrap);
  390. glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, this->tAnisotropy);
  391. glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  392. glBlendFunc(this->tBlend, GL_ONE_MINUS_SRC_ALPHA);
  393. //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  394. glBlendColor(this->tBlendColor[0], this->tBlendColor[1], this->tBlendColor[2], this->tBlendColor[3]);
  395. // glEnable(GL_TEXTURE_2D);
  396. }
  397.  
  398. void textureShader::ApplyTexture(point &pObj, vector &nObj, vector &uvObj)
  399. {
  400. // For normal and reflection entities, we do nothing here. These texture coordinates
  401. // are generated on the graphics card. See the end of the BiginTexture method.
  402. if (tEntity == Normal || tEntity == Reflection)
  403. return;
  404. else if (tEntity == Eye)
  405. {
  406. // To Do: Advanced
  407. //
  408. // If the entity is "Eye" then send the object coordinates of the vertex.
  409. // They will be converted into screen coordinates by the texture transform.
  410. glTexCoord4d(pObj[0], pObj[1], pObj[2], pObj[3]);
  411. return;
  412. }
  413.  
  414. double u, v, w;
  415. CalculateTexCoords(pObj, nObj, uvObj, u, v, w);
  416.  
  417. // To Do
  418. //
  419. // Send the texture coordinates to OpenGL.
  420. //
  421. // Note that if the entity is UV then "CalculateTexCoords" will
  422. // Simply set u = uvObj[0] and v = uvObj[1], i.e. it passes the
  423. // uv coordinates into u and v in the previous call, so you don't
  424. // need to implement anything in CalculateTexCoords to render examples
  425. // that use a uv entity.
  426. //
  427. // When you implement box mapping, you will need to change this call
  428. // to send all three coordinates for the box map.
  429. //
  430. // (For multitexturing) Use the multitexturing version of the text coordinate
  431. // function from OpenGL.
  432. }
  433.  
  434. void textureShader::CalculateTexCoords(point &pObj, vector &nObj, vector &uvObj,
  435. double &u, double &v, double &w)
  436. {
  437. point coord;
  438. point tmp;
  439. point sMin, sMax, sCenter;
  440.  
  441. // This version of RenderGL can only work with texture coordinates based
  442. // on object coordinates, not world coordinates. This covers most common
  443. // texturing situations.
  444. point p = pObj;
  445.  
  446. curShape->MinMax(sMin, sMax);
  447. sCenter = curShape->Center();
  448. switch (tEntity)
  449. {
  450. case UV:
  451. // NOTE: for the uv entity, we set the values here and IMMEDIATELY RETURN
  452. //
  453. u = uvObj[0]; // Copy uv's from polygon data into output
  454. v = uvObj[1];
  455. w = 0.0; // This shape doesn't use "w"
  456. return; // Have filled the u and v so can return
  457. case Position:
  458. // To Do
  459. //
  460. // Calculate the position of the vertex relative to the min and max
  461. // of the object (retrieved above). Store the result in the array "tmp"
  462. break;
  463. case Centroid:
  464. // To Do
  465. //
  466. // Calculate the position of the vertex relative to the center of the object
  467. // and store the result in the point "tmp"
  468. break;
  469. }
  470.  
  471. // Here we apply the "map axis". We do this by rearranging the coordinates in
  472. // tmp and placing them in the point "coord". The mapaxis coordinate is always
  473. // placed in "z" and the other two are placed in x and y, while preserving
  474. // right-handedness.
  475. //
  476. // Note also that the default and only choice for Box shape is the z-axis.
  477. coord[0] = tmp[0]; coord[1] = tmp[1]; coord[2] = tmp[2];
  478. if (tShape != Box)
  479. {
  480. if (tAxis == XAxis)
  481. {
  482. coord[0] = tmp[1]; coord[1] = tmp[2]; coord[2] = tmp[0];
  483. }
  484. else if (tAxis == YAxis)
  485. {
  486. coord[0] = tmp[2]; coord[1] = tmp[0]; coord[2] = tmp[1];
  487. }
  488. }
  489.  
  490. // Here we apply the shape of the texture map (remember, for the uv entity,
  491. // we will never get here ... see above)
  492. u = v = w = 0;
  493. switch (tShape)
  494. {
  495. case Planar:
  496. PlanarMap(coord, u, v);
  497. break;
  498. case Cylindrical:
  499. CylindricalMap(coord, sMin[tAxis], sMax[tAxis], u, v);
  500. break;
  501. case Spherical:
  502. SphericalMap(coord, u, v);
  503. break;
  504. case Box:
  505. // Here we just copy the coordinates directly into u, v and w.
  506. u = coord[0];
  507. v = coord[1];
  508. w = coord[2];
  509. break;
  510. };
  511. }
  512.  
  513. void textureShader::PlanarMap(const point &p, double &u, double &v)
  514. {
  515. if (tEntity != Position)
  516. complain("The Planar map can only be used with the position entity");
  517.  
  518. // Note that the min-max calculation for planar is computed in the entity above
  519. // so there is nothing to do here. We just copy the coordinates from p directly
  520. // into u and v.
  521. u = p[0];
  522. v = p[1];
  523. }
  524.  
  525. void textureShader::CylindricalMap(const point &p, double minZ, double maxZ, double &u, double &v)
  526. {
  527. if (tEntity != Centroid)
  528. complain("The Cyindrical map can only be used with the centroid entity");
  529.  
  530. // To Do
  531. //
  532. // Calculate u and v for the texture map using the point p (which will be already
  533. // calcualted relative to the center of the object ... see above). Use the formula
  534. // for a cylindrical map. Note, you need to take care of ANY situations where the
  535. // could be zero!
  536.  
  537. // Note: The following piece of code makes sure that there is no seam
  538. // when the vertices of a polygon span the edge of the texture
  539. // When the polygon is begun, uBase is reset (see the DrawPolygon method)
  540. // So the first vertex process set's the uBase. Then all other
  541. // vertices are compared to this uBase value
  542. if (uBase == -1)
  543. uBase = u;
  544. else
  545. {
  546. if (uBase > .75 && u < .25)
  547. u += 1;
  548. else if (uBase < .25 && u > .75)
  549. u -= 1;
  550. }
  551. }
  552.  
  553. void textureShader::SphericalMap(const point &p, double &u, double &v)
  554. {
  555. if (tEntity != Centroid)
  556. complain("The Spherical map can only be used with the centroid entity");
  557.  
  558. // To Do
  559. //
  560. // Calculate u and v for the texture map using the point p (which will be already
  561. // calcualted relative to the center of the object ... see above). Use the formula
  562. // for a spherical map. Note, you need to take care of ANY situations where the
  563. // could be zero!
  564.  
  565. // As in the cylindrical map, The following piece of code makes sure
  566. // that there is no seam when the vertices of a polygon span the edge of the texture.
  567. //
  568. // To Do
  569. //
  570. // Replace the test around this piece of code to make sure that the point isn't
  571. // exactly at the center (i.e. p is zero)
  572. if (true)
  573. {
  574. if (uBase == -1)
  575. uBase = u;
  576. else
  577. {
  578. if (uBase > .75 && u < .25)
  579. u += 1;
  580. else if (uBase < .25 && u > .75)
  581. u -= 1;
  582. }
  583. }
  584. }
  585.  
  586. ///////////////////////////////////////////////////////////////////////////
  587. // The lightMap shader provides a texturing solution to per-pixel
  588. // specular lighting.
  589. ///////////////////////////////////////////////////////////////////////////
  590.  
  591. lightMap::lightMap()
  592. {
  593. for (int i = 0; i < 3; i++)
  594. specSurfColor[i] = 1.0;
  595. shininess = 1.0;
  596. }
  597.  
  598. lightMap::~lightMap()
  599. {
  600. glDeleteTextures(1, &tObject);
  601. }
  602.  
  603. void lightMap::BeginShading(void)
  604. {
  605. GLfloat fBlack[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
  606.  
  607. // To Do
  608. //
  609. // Disable specular lighting by setting the secular material to black.
  610. // You will need to reset the specula material once this is done, so
  611. // you will need to record the current specualr color to reset it in
  612. // the EndShading method.
  613.  
  614. // Next, set up multi-texturing as before
  615.  
  616. SetupTextureMap();
  617.  
  618. // Now, enable the cube map target for texturing
  619.  
  620. glMatrixMode(GL_TEXTURE);
  621. glLoadIdentity();
  622.  
  623. // Then apply texture transforms for light mapping. This is the inverse
  624. // of the camera transform.
  625.  
  626. glMatrixMode(GL_MODELVIEW);
  627.  
  628. // Last, set up texure coordinate generation for reflection coordinates.
  629. }
  630.  
  631. void lightMap::DrawPolygon(int n, point p[], vector vn[], vector pn, vector uv[])
  632. {
  633. // To Do
  634. //
  635. // Replace the following with a gouraud shaded polygon
  636. glBegin(GL_LINE_LOOP);
  637. for (int i = 0; i < n; i++)
  638. glVertex3dv(p[i].AsArray());
  639. glEnd();
  640. }
  641.  
  642. void lightMap::EndShading(void)
  643. {
  644. glActiveTextureARB(GL_TEXTURE0_ARB + tTextureUnit);
  645. glBindTexture(glTarget, 0);
  646.  
  647. // To Do
  648. //
  649. // Disable the cube texture target and the texture coordinates
  650. // generation
  651.  
  652. glEnable(GL_LIGHTING);
  653. }
  654.  
  655. void lightMap::SetupTextureMap(void)
  656. {
  657. int i;
  658.  
  659. if (tObject > 0)
  660. {
  661. glBindTexture(GL_TEXTURE_CUBE_MAP, tObject);
  662. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD);
  663. return;
  664. }
  665.  
  666. glGenTextures(1, &tObject);
  667. glBindTexture(GL_TEXTURE_CUBE_MAP, tObject);
  668.  
  669. int nLights = curScene->nLights;
  670. vector lightDir[8];
  671. point lightCol[8];
  672.  
  673. // To Do
  674. //
  675. // Loop through all the active lights and record their directions and colors
  676. // in the lightDir and lightCol arrays. Don't forget to normalize the direction
  677.  
  678. // The next loop creates the six faces
  679. for (i = 0; i < 6; i++)
  680. cubeMapFaces[i].Create(size, size);
  681.  
  682. // a "Pixel" is used to store color values for a bitmap. It is a structure
  683. // with integer members r, g, b and alpha. These have ranges between 0 and 255.
  684. Pixel p;
  685. p.r = 0; p.g = 0; p.b = 0; p.alpha = 255;
  686.  
  687. // Map for XPos
  688. for(i = 0; i < size; i++)
  689. {
  690. for (int j = 0; j < size; j++)
  691. {
  692. // To Do
  693. //
  694. // Calculate the vector to the corresponding point on the cube
  695. // then loop through the lights and calculate the specular color from
  696. // each of the lights. Store the total luminance in the pixel p
  697.  
  698. cubeMapFaces[0].PutPixel(i, j, p);
  699. }
  700. }
  701.  
  702. // Map for XNeg
  703. for(i = 0; i < size; i++)
  704. {
  705. for (int j = 0; j < size; j++)
  706. {
  707. // To Do
  708. //
  709. // Do the same for this map
  710. cubeMapFaces[1].PutPixel(i, j, p);
  711. }
  712. }
  713.  
  714. // Map for YPos
  715. for(i = 0; i < size; i++)
  716. {
  717. for (int j = 0; j < size; j++)
  718. {
  719. // To Do
  720. //
  721. // Do the same for this map
  722. cubeMapFaces[2].PutPixel(i, j, p);
  723. }
  724. }
  725.  
  726. // Map for YNeg
  727. for(i = 0; i < size; i++)
  728. {
  729. for (int j = 0; j < size; j++)
  730. {
  731. // To Do
  732. //
  733. // Do the same for this map
  734. cubeMapFaces[3].PutPixel(i, j, p);
  735. }
  736. }
  737.  
  738. // Map for ZPos
  739. for(i = 0; i < size; i++)
  740. {
  741. for (int j = 0; j < size; j++)
  742. {
  743. // To Do
  744. //
  745. // Do the same for this map
  746. cubeMapFaces[4].PutPixel(i, j, p);
  747. }
  748. }
  749.  
  750. // Map for ZNeg
  751. for(i = 0; i < size; i++)
  752. {
  753. for (int j = 0; j < size; j++)
  754. {
  755. // To Do
  756. //
  757. // Do the same for this map
  758. cubeMapFaces[5].PutPixel(i, j, p);
  759. }
  760. }
  761.  
  762. // Now, we loop through each of the maps and store the pixel values in the temporary
  763. // glIMage array
  764. GLbyte *glImage = new GLbyte[size * size * 4];
  765. for (int k = 0; k < 6; k++)
  766. {
  767. for (int i = 0; i < size; i++)
  768. {
  769. for (int j = 0; j < size; j++)
  770. {
  771. Pixel p = cubeMapFaces[k].GetPixel(i, j);
  772. glImage[4 * (size * j + i) + 0] = p.r;
  773. glImage[4 * (size * j + i) + 1] = p.g;
  774. glImage[4 * (size * j + i) + 2] = p.b;
  775. glImage[4 * (size * j + i) + 3] = char(255);
  776. }
  777. }
  778.  
  779. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  780. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  781.  
  782. // To Do
  783. //
  784. // Send this array to OpenGL using glTexImage2D. Remember, you need
  785. // to use the six "Cube map" texture targets.
  786. }
  787. delete [] glImage;
  788.  
  789. // To Do
  790. //
  791. // Set the texture filter and wrap paremeters. And set the blend mode to "add"
  792. // so that the specular highlight is added on top of any other textures.
  793. }
  794.  
  795. ///////////////////////////////////////////////////////////////////////////
  796. // The multiTexture shader builds on the texture shader by allowing multiple
  797. // textures to be active at once. This is very useful for situations like
  798. // light mapping and phong specular reflection through texturing (a
  799. // very fast alternative to the phong texturer above.
  800. ///////////////////////////////////////////////////////////////////////////
  801.  
  802. multiTexture::multiTexture()
  803. {
  804. glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextures);
  805.  
  806. textures = new textureShader *[maxTextures];
  807. for (int i = 0; i < maxTextures; i++)
  808. textures[i] = NULL;
  809.  
  810. disableLight = false;
  811. disableDiffuse = false;
  812. disableSpecular = false;
  813. disableAmbient = false;
  814. }
  815.  
  816. multiTexture::~multiTexture()
  817. {
  818. for (int i = 0; i < maxTextures; i++)
  819. if (textures[i])
  820. delete textures[i];
  821.  
  822. delete [] textures;
  823. }
  824.  
  825. void multiTexture::BeginShading(void)
  826. {
  827. // To Do
  828. //
  829. // Check to see if multi-texturing is supported!
  830. //
  831. // If it is, then loop through the active textures and call the BeginShading
  832. // method on each of them. An active texture is one whose pointer is not null.
  833. //
  834. // Push OpenGL's Lighting Attribute stack
  835. //
  836. // Now, if "disableLight" is true, you should disable lighting as the textures
  837. // contain a diffuse or specular map.
  838. //
  839. // If disable specular is true, then you should just disable the
  840. // specular reflectance of the object. Likewise for disablAmbient and
  841. // disableDiffuse
  842. }
  843.  
  844. void multiTexture::DrawPolygon(int n, point p[], vector vn[], vector pn, vector uv[])
  845. {
  846. // This code loops through and makes sure that each texture will not
  847. // tear.
  848. for (int i = 0; i < maxTextures; i++)
  849. if (textures[i])
  850. textures[i]->BeginPolygon(n, p, vn, pn, uv);
  851.  
  852. // To Do
  853. //
  854. // Replace the following code with code that will begin a polygon, and
  855. // for each vertex, loop through the textures and apply them with
  856. // their "ApplyTexture" method. Note that the ApplyTexture method will
  857. // need to have the multi-texturing version written.
  858. glBegin(GL_LINE_LOOP);
  859. for (int i = 0; i < n; i++)
  860. glVertex3dv(p[i].AsArray());
  861. glEnd();
  862. }
  863.  
  864. void multiTexture::EndShading(void)
  865. {
  866. // To Do
  867. //
  868. // Shut down each of the active textures, and pop the lighting stack
  869. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement