PageRenderTime 45ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/example_01.cpp

https://github.com/ksimons221/CS-184-Project1
C++ | 510 lines | 308 code | 143 blank | 59 comment | 50 complexity | 69395b05e552524407ab245782ec4519 MD5 | raw file
  1. #include <vector>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <cmath>
  5. #include <string>
  6. #include <sstream>
  7. #ifdef _WIN32
  8. #include <windows.h>
  9. #else
  10. #include <sys/time.h>
  11. #endif
  12. #ifdef OSX
  13. #include <GLUT/glut.h>
  14. #include <OpenGL/glu.h>
  15. #else
  16. #include <GL/glut.h>
  17. #include <GL/glu.h>
  18. #endif
  19. #include <time.h>
  20. #include <math.h>
  21. #include <stdio.h>
  22. //#include <stdlib.h>
  23. #include <GL/glut.h>
  24. #define PI 3.14159265 // Should be used from mathlib
  25. inline float sqr(float x) { return x*x; }
  26. using namespace std;
  27. struct lightSource
  28. {
  29. float xValue;
  30. float yValue;
  31. float zValue;
  32. float redValue;
  33. float greenValue;
  34. float blueValue;
  35. };
  36. float centerXSphere = 0;
  37. float centerYSphere = 0;
  38. float centerZSphere = 0;
  39. float kaR = 0;
  40. float kaG = 0;
  41. float kaB = 0;
  42. float kdR = 0;
  43. float kdG = 0;
  44. float kdB = 0;
  45. float ksR = 0;
  46. float ksG = 0;
  47. float ksB = 0;
  48. float powerCoefficient = 0;
  49. int numPointLights = 0;
  50. int numDirectionalLights = 0;
  51. lightSource pointLights[5];
  52. lightSource directionalLights[5];
  53. //****************************************************
  54. // Some Classes
  55. //****************************************************
  56. class Viewport;
  57. class Viewport {
  58. public:
  59. int w, h; // width and height
  60. };
  61. //****************************************************
  62. // Global Variables
  63. //****************************************************
  64. Viewport viewport;
  65. //****************************************************
  66. // Simple init function
  67. //****************************************************
  68. void initScene(){
  69. // Nothing to do here for this simple example.
  70. }
  71. //****************************************************
  72. // reshape viewport if the window is resized
  73. //****************************************************
  74. void myReshape(int w, int h) {
  75. viewport.w = w;
  76. viewport.h = h;
  77. glViewport (0,0,viewport.w,viewport.h);
  78. glMatrixMode(GL_PROJECTION);
  79. glLoadIdentity();
  80. gluOrtho2D(0, viewport.w, 0, viewport.h);
  81. }
  82. //****************************************************
  83. // A routine to set a pixel by drawing a GL point. This is not a
  84. // general purpose routine as it assumes a lot of stuff specific to
  85. // this example.
  86. //****************************************************
  87. void setPixel(int x, int y, GLfloat r, GLfloat g, GLfloat b) {
  88. glColor3f(r, g, b);
  89. glVertex2f(x + 0.5, y + 0.5); // The 0.5 is to target pixel
  90. // centers
  91. // Note: Need to check for gap
  92. // bug on inst machines.
  93. }
  94. //****************************************************
  95. // Draw a filled circle.
  96. //****************************************************
  97. void circle(float centerX, float centerY, float radius) {
  98. // Draw inner circle
  99. glBegin(GL_POINTS);
  100. // We could eliminate wasted work by only looping over the pixels
  101. // inside the sphere's radius. But the example is more clear this
  102. // way. In general drawing an object by loopig over the whole
  103. // screen is wasteful.
  104. int iStep,jStep; // Pixel indices
  105. int minI = max(0,(int)floor(centerX-radius));
  106. int maxI = min(viewport.w-1,(int)ceil(centerX+radius));
  107. int minJ = max(0,(int)floor(centerY-radius));
  108. int maxJ = min(viewport.h-1,(int)ceil(centerY+radius));
  109. for (iStep=0;iStep<viewport.w;iStep++) {
  110. for (jStep=0;jStep<viewport.h;jStep++) {
  111. // Location of the center of pixel relative to center of sphere
  112. float x = (iStep+0.5-centerX);
  113. float y = (jStep+0.5-centerY);
  114. float dist = sqrt(sqr(x) + sqr(y));
  115. if (dist<=radius) {
  116. // This is the front-facing Z coordinate
  117. float z = sqrt(radius*radius-dist*dist);
  118. //Normal
  119. float normalX = x / sqrt(sqr(x)+sqr(y)+sqr(z));
  120. float normalY = y / sqrt(sqr(x)+sqr(y)+sqr(z));
  121. float normalZ = z / sqrt(sqr(x)+sqr(y)+sqr(z));
  122. //Specular
  123. float specularRed = 0;
  124. float specularGreen = 0;
  125. float specularBlue = 0;
  126. for (int i = 0; i< numPointLights; i++) {
  127. float pointLightX = (pointLights[i].xValue * radius) -x;
  128. float pointLightY = (pointLights[i].yValue * radius)- y;
  129. float pointLightZ = (pointLights[i].zValue * radius)- z;
  130. float pointLightTotal = sqrt(sqr(pointLightX)+sqr(pointLightY)+sqr(pointLightZ));
  131. pointLightX = pointLightX / pointLightTotal;
  132. pointLightY = pointLightY / pointLightTotal;
  133. pointLightZ = pointLightZ / pointLightTotal;
  134. float dotProductResult = pointLightX * normalX + pointLightY * normalY + pointLightZ * normalZ;
  135. float scaledNormalX = dotProductResult*2*normalX;
  136. float scaledNormalY = dotProductResult*2*normalY;
  137. float scaledNormalZ = dotProductResult*2*normalZ;
  138. float reflectiveX = scaledNormalX + (pointLightX * -1);
  139. float reflectiveY = scaledNormalY + (pointLightY * -1);
  140. float reflectiveZ = scaledNormalZ + (pointLightZ * -1);
  141. // assume view = (0,0,1)
  142. float dotOfReflectiveViewer= pow(max(reflectiveZ, (float) 0), powerCoefficient);
  143. specularRed = specularRed + pointLights[i].redValue * ksR * dotOfReflectiveViewer;
  144. specularGreen = specularGreen+ pointLights[i].greenValue * ksG * dotOfReflectiveViewer;
  145. specularBlue = specularBlue+ pointLights[i].blueValue * ksB * dotOfReflectiveViewer;
  146. }
  147. // Directional
  148. for (int i = 0; i< numDirectionalLights; i++) {
  149. float directionLightX = centerXSphere - directionalLights[i].xValue;
  150. float directionLightY = centerYSphere - directionalLights[i].yValue;
  151. float directionLightZ = centerZSphere - directionalLights[i].zValue;
  152. float directionLightTotal = sqrt(sqr(directionLightX)+sqr(directionLightY)+sqr(directionLightZ));
  153. directionLightX = directionLightX / directionLightTotal;
  154. directionLightY = directionLightY / directionLightTotal;
  155. directionLightZ = directionLightZ / directionLightTotal;
  156. float dotProductResult = directionLightX * normalX + directionLightY * normalY + directionLightZ * normalZ;
  157. float scaledNormalX = dotProductResult*2*normalX;
  158. float scaledNormalY = dotProductResult*2*normalY;
  159. float scaledNormalZ = dotProductResult*2*normalZ;
  160. float reflectiveX = scaledNormalX + (directionLightX * -1);
  161. float reflectiveY = scaledNormalY + (directionLightY * -1);
  162. float reflectiveZ = scaledNormalZ + (directionLightZ * -1);
  163. // assume view = (0,0,1)
  164. float dotOfReflectiveViewer= pow(max(reflectiveZ , (float) 0), powerCoefficient);
  165. specularRed = specularRed + directionalLights[i].redValue * ksR * dotOfReflectiveViewer;
  166. specularGreen = specularGreen+ directionalLights[i].greenValue * ksG * dotOfReflectiveViewer;
  167. specularBlue = specularBlue+ directionalLights[i].blueValue * ksB * dotOfReflectiveViewer;
  168. }
  169. /// Diffuse
  170. float diffuseRed = 0;
  171. float diffuseGreen = 0;
  172. float diffuseBlue = 0;
  173. /// Point Source
  174. for (int i = 0; i< numPointLights; i++) {
  175. float pointLightX = (pointLights[i].xValue * radius) -x;
  176. float pointLightY = (pointLights[i].yValue * radius)- y;
  177. float pointLightZ = (pointLights[i].zValue * radius)- z;
  178. float pointLightTotal = sqrt(sqr(pointLightX)+sqr(pointLightY)+sqr(pointLightZ));
  179. pointLightX = pointLightX / pointLightTotal;
  180. pointLightY = pointLightY / pointLightTotal;
  181. pointLightZ = pointLightZ / pointLightTotal;
  182. float dotProductResult = max((float) 0, pointLightX * normalX + pointLightY * normalY + pointLightZ * normalZ);
  183. diffuseRed = diffuseRed + pointLights[i].redValue * kdR * dotProductResult;
  184. diffuseGreen = diffuseGreen+ pointLights[i].greenValue * kdG * dotProductResult;
  185. diffuseBlue = diffuseBlue+ pointLights[i].blueValue * kdB * dotProductResult;
  186. }
  187. //Directional
  188. for (int i = 0; i< numDirectionalLights; i++) {
  189. float directionLightX = centerXSphere - directionalLights[i].xValue;
  190. float directionLightY = centerYSphere - directionalLights[i].yValue;
  191. float directionLightZ = centerZSphere - directionalLights[i].zValue;
  192. float directionLightTotal = sqrt(sqr(directionLightX)+sqr(directionLightY)+sqr(directionLightZ));
  193. directionLightX = directionLightX / directionLightTotal;
  194. directionLightY = directionLightY / directionLightTotal;
  195. directionLightZ = directionLightZ / directionLightTotal;
  196. float dotProductResult = max((float) 0, directionLightX * normalX + directionLightY * normalY + directionLightZ * normalZ);
  197. diffuseRed = diffuseRed + directionalLights[i].redValue * kdR * dotProductResult;
  198. diffuseGreen = diffuseGreen+ directionalLights[i].greenValue * kdG * dotProductResult;
  199. diffuseBlue = diffuseBlue+ directionalLights[i].blueValue * kdB * dotProductResult;
  200. }
  201. //// Ambient Term
  202. float ambientRed = 0;
  203. float ambientGreen = 0;
  204. float ambientBlue = 0;
  205. for (int i = 0; i< numPointLights; i++) {
  206. ambientRed = ambientRed + ( kaR * pointLights[i].redValue);
  207. ambientGreen = ambientGreen+ (kaG * pointLights[i].greenValue);
  208. ambientBlue = ambientBlue +(kaB * pointLights[i].blueValue);
  209. }
  210. for (int i = 0; i< numDirectionalLights; i++) {
  211. ambientRed = ambientRed + ( kaR * directionalLights[i].redValue);
  212. ambientGreen = ambientGreen+ (kaG * directionalLights[i].greenValue);
  213. ambientBlue = ambientBlue +(kaB * directionalLights[i].blueValue);
  214. }
  215. setPixel(iStep,jStep, (specularRed+ambientRed+diffuseRed)/255,(specularGreen+ambientGreen+diffuseGreen)/255, (specularBlue+ambientBlue+diffuseBlue)/255);
  216. }
  217. }
  218. }
  219. glEnd();
  220. }
  221. //****************************************************
  222. // function that does the actual drawing of stuff
  223. //***************************************************
  224. void myDisplay() {
  225. glClear(GL_COLOR_BUFFER_BIT); // clear the color buffer
  226. glMatrixMode(GL_MODELVIEW); // indicate we are specifying camera transformations
  227. glLoadIdentity(); // make sure transformation is "zero'd"
  228. // Start drawing
  229. circle(viewport.w / 2.0 , viewport.h / 2.0 , min(viewport.w, viewport.h) / 3.0);
  230. glFlush();
  231. glutSwapBuffers(); // swap buffers (we earlier set double buffer)
  232. }
  233. void keyPressed (unsigned char key, int x, int y) {
  234. if (key == ' ') {
  235. exit(0);
  236. }
  237. }
  238. //****************************************************
  239. // the usual stuff, nothing exciting here
  240. //****************************************************
  241. int main(int argc, char *argv[]) { // first argument is the program running
  242. //This initializes glut
  243. glutInit(&argc, argv);
  244. int i = 1;
  245. while (i < argc) {
  246. string lineArg = argv [i];
  247. if (lineArg == "-ka" || lineArg == "-kd" || lineArg == "-ks") {
  248. if (i + 3 < argc == false) {
  249. cout << "Badly formatted command line arguments for ka, kd, or ks" << endl;
  250. break;
  251. }
  252. i++;
  253. string redString = argv [i];
  254. float redValue;
  255. istringstream(redString.c_str()) >> redValue;
  256. redValue = redValue * 255;
  257. i++;
  258. string greenString = argv [i];
  259. float greenValue;
  260. istringstream(greenString.c_str()) >> greenValue;
  261. greenValue = greenValue * 255;
  262. i++;
  263. string blueString = argv [i];
  264. float blueValue;
  265. istringstream(blueString.c_str()) >> blueValue;
  266. blueValue = blueValue * 255;
  267. if (redValue < 0 || redValue > 255 || greenValue < 0 || greenValue > 255 || blueValue < 0 || blueValue > 255) {
  268. cout << "Badly formatted command line arguments. ka, kd, ks value not within range" << endl;
  269. break;
  270. }
  271. if (lineArg == "-ka") {
  272. kaR = redValue;
  273. kaG = greenValue;
  274. kaB = blueValue;
  275. } else if ( lineArg == "-kd") {
  276. kdR = redValue;
  277. kdG = greenValue;
  278. kdB = blueValue;
  279. } else { //-ks
  280. ksR = redValue;
  281. ksG = greenValue;
  282. ksB = blueValue;
  283. }
  284. } else if (lineArg == "-sp") {
  285. if (i + 1 < argc == false) {
  286. cout << "Badly formatted command line arguments for sp" << endl;
  287. break;
  288. }
  289. i++;
  290. string powerString = argv [i];
  291. float powerValue;
  292. istringstream(powerString.c_str()) >> powerValue;
  293. powerCoefficient = powerValue;
  294. } else if (lineArg == "-pl" || lineArg == "-dl" ) {
  295. if (i + 6 < argc == false) {
  296. cout << "Badly formatted command line arguments for pl or dl" << endl;
  297. break;
  298. }
  299. i++;
  300. string xString = argv [i];
  301. //float xValue = (float)atof(xString.c_str());
  302. float xValue;
  303. istringstream(xString.c_str()) >> xValue;
  304. i++;
  305. string yString = argv [i];
  306. //float yValue = (float)atof(yString.c_str());
  307. float yValue;
  308. istringstream(yString.c_str()) >> yValue;
  309. i++;
  310. string zString = argv [i];
  311. //float zValue = (float)atof(zString.c_str());
  312. float zValue;
  313. istringstream(zString.c_str()) >> zValue;
  314. i++;
  315. string redString = argv [i];
  316. //float redValue = (float)atof(redString.c_str());
  317. float redValue;
  318. istringstream(redString.c_str()) >> redValue;
  319. i++;
  320. string greenString = argv [i];
  321. //float greenValue = (float)atof(greenString.c_str());
  322. float greenValue;
  323. istringstream(greenString.c_str()) >> greenValue;
  324. i++;
  325. string blueString = argv [i];
  326. // float blueValue = (float)atof(blueString.c_str());
  327. float blueValue;
  328. istringstream(blueString.c_str()) >> blueValue;
  329. lightSource s = {xValue, yValue, zValue, redValue, greenValue, blueValue};
  330. if (lineArg == "-pl") {
  331. if (numPointLights > 4) {
  332. cout << "Badly formatted command line arguments. " << endl;
  333. break;
  334. }
  335. pointLights[numPointLights] = s;
  336. numPointLights++;
  337. } else { //-dl
  338. if (numDirectionalLights > 4) {
  339. cout << "Badly formatted command line arguments. " << endl;
  340. break;
  341. }
  342. directionalLights[numDirectionalLights] = s;
  343. numDirectionalLights++;
  344. }
  345. } else {
  346. cout << "Badly formatted command line arguments. " << endl;
  347. break;
  348. }
  349. i++;
  350. }
  351. //This tells glut to use a double-buffered window with red, green, and blue channels
  352. glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
  353. // Initalize theviewport size
  354. viewport.w = 400;
  355. viewport.h = 400;
  356. //The size and position of the window
  357. glutInitWindowSize(viewport.w, viewport.h);
  358. glutInitWindowPosition(0,0);
  359. glutCreateWindow(argv[0]);
  360. glutKeyboardFunc(keyPressed);
  361. initScene(); // quick function to set up scene
  362. glutDisplayFunc(myDisplay); // function to run when its time to draw something
  363. glutReshapeFunc(myReshape); // function to run when the window gets resized
  364. glutMainLoop(); // infinite loop that will keep drawing and resizing
  365. // and whatever else
  366. return 0;
  367. }