int R3Mesh:: ReadImage(const char *filename) { // Create a mesh by reading an image file, // constructing vertices at (x,y,luminance), // and connecting adjacent pixels into faces. // That is, the image is interpretted as a height field, // where the luminance of each pixel provides its z-coordinate. // Read image R2Image *image = new R2Image(); if (!image->Read(filename)) return 0; // Create vertices and store in arrays R3MeshVertex ***vertices = new R3MeshVertex **[image->Width() ]; for (int i = 0; i < image->Width(); i++) { vertices[i] = new R3MeshVertex *[image->Height() ]; for (int j = 0; j < image->Height(); j++) { double luminance = image->Pixel(i, j).Luminance(); double z = luminance * image->Width(); R3Point position((double) i, (double) j, z); R2Point texcoords((double) i, (double) j); vertices[i][j] = CreateVertex(position, R3zero_vector, texcoords); } } // Create faces vector<R3MeshVertex *> face_vertices; for (int i = 1; i < image->Width(); i++) { for (int j = 1; j < image->Height(); j++) { face_vertices.clear(); face_vertices.push_back(vertices[i-1][j-1]); face_vertices.push_back(vertices[i][j-1]); face_vertices.push_back(vertices[i][j]); CreateFace(face_vertices); face_vertices.clear(); face_vertices.push_back(vertices[i-1][j-1]); face_vertices.push_back(vertices[i][j]); face_vertices.push_back(vertices[i-1][j]); CreateFace(face_vertices); } } // Delete vertex arrays for (int i = 0; i < image->Width(); i++) delete [] vertices[i]; delete [] vertices; // Delete image delete image; // Return success return 1; }
static R2Image * ReadImage(const char *filename) { // Allocate a image R2Image *image = new R2Image(); if (!image) { fprintf(stderr, "Unable to allocate image"); return NULL; } // Read image if (!image->Read(filename)) { fprintf(stderr, "Unable to read image file %s", filename); return NULL; } // Print message if (print_verbose) { printf("Read image from %s\n", filename); printf(" Resolution = %d %d\n", image->Width(), image->Height()); printf(" L1Norm = %g\n", image->L1Norm()); printf(" L2Norm = %g\n", image->L2Norm()); fflush(stdout); } // Return image return image; }
void R2Image:: Multiply(const R2Image& image) { // Multiply by image pixel-by-pixel assert(image.Width() == Width()); assert(image.Height() == Height()); assert(image.NChannels() == NChannels()); int nvalues = NValues(); for (int i = 0; i < nvalues; i++) { pixels[i] *= image.pixels[i]; } }
void R2Image:: Subtract(const R2Image& image) { // Subtract image pixel-by-pixel assert(image.Width() == Width()); assert(image.Height() == Height()); assert(image.NChannels() == NChannels()); int nvalues = NValues(); for (int i = 0; i < nvalues; i++) { pixels[i] -= image.pixels[i]; } }
void R2Image:: Filter(const R2Image& filter) { // Get useful variables int xr = filter.Width()/2; int yr = filter.Height()/2; R2Image copy(*this); // This is the straight-forward implementation (slow for large filters) for (int j = 0; j < Height(); j++) { for (int i = 0; i < Width(); i++) { for (int c = 0; c < NChannels(); c++) { int fc = (NChannels() == filter.NChannels()) ? c : 0; // Compute new value double sum = 0; for (int s = 0; s < filter.Width(); s++) { int x = i - xr + s; if (x < 0) x = 0; else if (x >= Width()) x = Width()-1; for (int t = 0; t < filter.Height(); t++) { int y = j - yr + t; if (y < 0) y = 0; else if (y >= Height()) y = Height()-1; double filter_value = filter.Value(s, t, fc); double image_value = copy.Value(x, y, c); sum += filter_value * image_value; } } // Assign new value for channel SetValue(i, j, c, sum); } } } }
void R2Image:: Divide(const R2Image& image) { // Add image pixel-by-pixel assert(image.Width() == Width()); assert(image.Height() == Height()); assert(image.NChannels() == NChannels()); int nvalues = NValues(); for (int i = 0; i < nvalues; i++) { if (image.pixels[i] == 0) { if (pixels[i] == 0.0) continue; else pixels[i] = FLT_MAX; } else { pixels[i] /= image.pixels[i]; } } }
void LoadMaterial(R3Material *material) { GLfloat c[4]; // Check if same as current static R3Material *current_material = NULL; if (material == current_material) return; current_material = material; // Compute "opacity" double opacity = 1 - material->kt.Luminance(); // Load ambient c[0] = material->ka[0]; c[1] = material->ka[1]; c[2] = material->ka[2]; c[3] = opacity; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, c); // Load diffuse c[0] = material->kd[0]; c[1] = material->kd[1]; c[2] = material->kd[2]; c[3] = opacity; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, c); // Load specular c[0] = material->ks[0]; c[1] = material->ks[1]; c[2] = material->ks[2]; c[3] = opacity; glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, c); // Load emission c[0] = material->emission.Red(); c[1] = material->emission.Green(); c[2] = material->emission.Blue(); c[3] = opacity; glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, c); // Load shininess c[0] = material->shininess; glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, c[0]); // Load texture if (material->texture) { if (material->texture_index <= 0) { // Create texture in OpenGL GLuint texture_index; glGenTextures(1, &texture_index); material->texture_index = (int) texture_index; glBindTexture(GL_TEXTURE_2D, material->texture_index); R2Image *image = material->texture; int npixels = image->NPixels(); R2Pixel *pixels = image->Pixels(); GLfloat *buffer = new GLfloat [ 4 * npixels ]; R2Pixel *pixelsp = pixels; GLfloat *bufferp = buffer; for (int j = 0; j < npixels; j++) { *(bufferp++) = pixelsp->Red(); *(bufferp++) = pixelsp->Green(); *(bufferp++) = pixelsp->Blue(); *(bufferp++) = pixelsp->Alpha(); pixelsp++; } glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexImage2D(GL_TEXTURE_2D, 0, 4, image->Width(), image->Height(), 0, GL_RGBA, GL_FLOAT, buffer); delete [] buffer; } // Select texture glBindTexture(GL_TEXTURE_2D, material->texture_index); glEnable(GL_TEXTURE_2D); } else { glDisable(GL_TEXTURE_2D); } // Enable blending for transparent surfaces if (opacity < 1) { glDepthMask(false); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_BLEND); } else { glDisable(GL_BLEND); glBlendFunc(GL_ONE, GL_ZERO); glDepthMask(true); } }