void display() { /* draw 1x1 cube about origin */ /* replace this code with your height field implementation */ /* you may also want to precede it with your rotation/translation/scaling */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(g_vLandTranslate[0],g_vLandTranslate[1],g_vLandTranslate[2]); glRotatef(g_vLandRotate[0],1,0,0); glRotatef(g_vLandRotate[1],0,1,0); glRotatef(g_vLandRotate[2],0,0,1); glScalef(g_vLandScale[0],-g_vLandScale[1],-g_vLandScale[2]); glPushMatrix(); glTranslatef(-(g_pHeightData->nx)/2, -(g_pHeightData->nx)/2, 0); // move object to centre //for loop goes through the pixel and draw the heightfield for(int i=0;i<g_pHeightData->ny-1;i++) { glBegin(GL_TRIANGLE_STRIP); for(int j=0;j<g_pHeightData->nx;j++) { float index0= PIC_PIXEL(g_pHeightData,j,i,0); float index1= PIC_PIXEL(g_pHeightData,j,i+1,0); float index2 = index0/255; float index3 = index1/255; //set the color based on the color depth of image glColor3f(index2, index2, index2); glVertex3f(j, i, index2*100); glColor3f(index3, index3, index3); glVertex3f(j, i+1, index3*100); }// next pixel in current row glEnd(); // finish drawing }// next row glPopMatrix(); if(a<300){ MakeFile(a); a++; } glutSwapBuffers(); // double buffer flush }
unsigned char Image::GetB(int iX, int iY) { //Returns the Blue for RGBA, or Returns Blue for luminance unsigned char cB; if(this->iType == 1) cB = PIC_PIXEL(this->pImageData,iX,iY,0); else cB = PIC_PIXEL(this->pImageData,iX,iY,2); return cB; }
unsigned char Image::GetG(int iX, int iY) { //Returns the Green for RGBA, or Returns Green for luminances unsigned char cG; if(this->iType == 1) cG = PIC_PIXEL(this->pImageData,iX,iY,0); else cG = PIC_PIXEL(this->pImageData,iX,iY,1); return cG; }
unsigned char Image::GetR(int iX, int iY) { //Returns the red for RGBA, or Returns red for luminances unsigned char cR; if(this->iType == 1) cR = PIC_PIXEL(this->pImageData,iX,iY,0); else cR = PIC_PIXEL(this->pImageData,iX,iY,0); return cR; }
unsigned char Image::GetBW(int iX, int iY) { //Returns the actual luminance of the pixel location unsigned char cBW,cR,cG,cB; if(this->iType == 1) cBW = PIC_PIXEL(this->pImageData,iX,iY,0); else { //Return the luminance of the color image cR = this->GetR(iX, iY); cG = this->GetR(iX, iY); cB = this->GetR(iX, iY); cBW = (unsigned char)((float)cR*0.3 + (float)cG*0.59 + (float)cB*0.11); } return cBW; }
/* Write a screenshot to the specified filename */ void saveScreenshot (char *filename){ int i, j; Pic *in = NULL; Pic *out = NULL; if (filename == NULL) return; in = pic_alloc(640, 480, 3, NULL); out = pic_alloc(640, 480, 3, NULL); printf("File to save to: %s\n", filename); glReadPixels(0, 0, 640, 480, GL_RGB, GL_UNSIGNED_BYTE, &in->pix[0]); for ( int j=0; j<480; j++ ) { for ( int i=0; i<640; i++ ) { PIC_PIXEL(out, i, j, 0) = PIC_PIXEL(in, i, 480-1-j, 0); PIC_PIXEL(out, i, j, 1) = PIC_PIXEL(in, i, 480-1-j, 1); PIC_PIXEL(out, i, j, 2) = PIC_PIXEL(in, i, 480-1-j, 2); } } if (jpeg_write(filename, out)) printf("File saved Successfully\n"); else printf("Error in Saving\n"); pic_free(in); pic_free(out); }
Vec3f scene::rayTrace(Vec3f eye, Vec3f dir, int recurseDepth) { //start with black, add color as we go Vec3f answer(0,0,0); //test for intersection against all our objects float dist = myObjGroup->testIntersections(eye, dir); //if we saw nothing, return the background color of our scene if (dist==9999999) return bgColor; Vec3f textureColor; //get the material index and normal vector(at the point we saw) of the object we saw int matIndex = myObjGroup->getClosest()->getMatIndex(); Vec3f normal = myObjGroup->getClosest()->getNormal(eye, dir * dist); //determine texture color if (myMaterials.at(matIndex).texture==NULL) //this is multiplicative, rather than additive //so if there is no texture, just use ones textureColor.Set(1,1,1); else { //if there is a texture image, ask the object for the image coordinates (between 0 and 1) Vec3f coords = myObjGroup->getClosest()->getTextureCoords(eye, dir * dist); //get the color from that image location textureColor.Set( PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),0), PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),1), PIC_PIXEL(myMaterials.at(matIndex).texture,(int)(myMaterials.at(matIndex).texture->nx*coords.x()),(int)(myMaterials.at(matIndex).texture->ny*coords.y()),2)); textureColor = textureColor*(1/255.0); } // add ambient light/color to our answer answer += multiplyColorVectors(ambLight, myMaterials.at(matIndex).diffuseCol); // set point slightly above the actual surface, prevents // issues with that point intersecting itself Vec3f point = eye + (dir * dist) + (normal * .0001); Vec3f real_point = eye + (dir * dist); // get the diffuse color of our material Vec3f diffuseColor = myMaterials.at(matIndex).diffuseCol; // iterate through lights for (int iter = 0; iter < myLights.size(); iter++) { Vec3f lightPos = myLights.at(iter).position; Vec3f direction= lightPos - point; direction.Normalize(); float distance = myObjGroup->testIntersections(point, direction); // if nothing between point and light if (distance == 9999999) { Vec3f color = multiplyColorVectors(diffuseColor, myLights.at(iter).color); float nl = abs(direction.Dot3(normal)); answer += (color * nl); // now do the specular // we need vector that goes from point to eye Vec3f backDir = dir * -1.0f; Vec3f h = (backDir + direction); h.Normalize(); Vec3f Cp = myMaterials.at(matIndex).specularCol; float p = myMaterials.at(matIndex).shininess; float nh = abs(normal.Dot3(h)); nh = pow(nh, p); answer += multiplyColorVectors(myLights.at(iter).color, Cp) * nh; } } //if the light can see the surface point, //add its diffuse color to a total diffuse for the point (using our illumination model) //use testIntersection to help decide this //add the diffuse light times the accumulated diffuse light to our answer if (recurseDepth < 3) { Vec3f e = dir * -1.0f; e.Normalize(); Vec3f r = dir + normal * 2.0f * e.Dot3(normal); r.Normalize(); Vec3f bounced = rayTrace(point, r, recurseDepth + 1); answer += (multiplyColorVectors(bounced, myMaterials.at(matIndex).reflectiveCol)); // refraction Vec3f transparentColor = myMaterials.at(matIndex).transparentCol; float transpar = transparentColor.Dot3(transparentColor); if (transpar > 0.0f) { float exitAngle, entryAngle; if (dir.Dot3(normal) < 0.0f) { entryAngle = acos(dir.Dot3(normal * -1.0f)); exitAngle = entryAngle * myMaterials.at(matIndex).refractionIndex; } else { entryAngle = acos(dir.Dot3(normal)); exitAngle = entryAngle / myMaterials.at(matIndex).refractionIndex; } Vec3f b = (dir + (normal * cos(entryAngle))) * (1.0f /sin(entryAngle)); b.Normalize(); Vec3f refracted = (b * sin(exitAngle)) - (normal * cos(exitAngle)); refracted.Normalize(); answer += multiplyColorVectors(rayTrace(real_point, refracted, recurseDepth + 1), myMaterials.at(matIndex).transparentCol); } } //put a limit on the depth of recursion //if (recurseDepth<3) //{ //reflect our view across the normal //recusively raytrace from the surface point along the reflected view //add the color seen times the reflective color //if going into material (dot prod of dir and normal is negative), bend toward normal //find entry angle using inverse cos of dot product of dir and -normal //multiply entry angle by index of refraction to get exit angle //else, bend away //find entry angle using inverse cos of dot product of dir and normal //divide entry angle by index of refraction to get exit angle //recursively raytrace from the other side of the object along the new direction //add the color seen times the transparent color //} //multiply whatever color we have found by the texture color answer=multiplyColorVectors(answer,textureColor); return answer; }
void makeFloor() { glBindTexture(GL_TEXTURE_2D, g_iFloorName); glEnable(GL_TEXTURE_2D); for (int y = 0; y < g_pFloorTexture->ny - 1; y++) { glBegin(GL_TRIANGLE_STRIP); for (int x = 0; x < g_pFloorTexture->nx; x++) { glTexCoord2f((float)x / g_pFloorTexture->nx, (y + 1) / (float)g_pFloorTexture->ny); glVertex3f(x - (float)g_pFloorTexture->nx / 2, (y + 1) - (float)g_pFloorTexture->ny / 2, PIC_PIXEL(g_pFloorHeight, x, y + 1, 0) / -4.0f + 5.0f); glTexCoord2f((float)x / g_pFloorTexture->nx, y / (float)g_pFloorTexture->ny); glVertex3f(x - (float)g_pFloorTexture->nx / 2, y - (float)g_pFloorTexture->ny / 2, PIC_PIXEL(g_pFloorHeight, x, y, 0) / -4.0f + 5.0f); } glEnd(); } glDisable(GL_TEXTURE_2D); }