Выбрать главу

    else // Keep in 0-255 Range With>> 8

     *d = *s; // No Blending Just Do A Straight Copy

   }

  }

  d = d + (dst->width – (src_width + dst_xstart))*dst->format; // Add End Of Row

  s = s + (src->width – (src_width + src_xstart))*src->format; // Add End Of Row

 }

}

The InitGL() code has changed quite a bit. All of the code below is new. We start off by allocating enough memory to hold a 256x256x4 Bytes Per Pixel Image. t1 will point to the allocated ram if everything went well.

After allocating memory for our image, we attempt to load the image. We pass ReadTextureData() the name of the file we wish to open, along with a pointer to our Image Structure (t1).

If we were unable to load the .RAW image, a message box will pop up on the screen to let the user know there was a problem loading the texture.

We then do the same thing for t2. We allocate memory, and attempt to read in our second .RAW image. If anything goes wrong we pop up a message box.

int InitGL(GLvoid) // This Will Be Called Right After The GL Window Is Created

{

 t1 = AllocateTextureBuffer( 256, 256, 4 ); // Get An Image Structure

 if (ReadTextureData("Data/Monitor.raw",t1)==0) // Fill The Image Structure With Data

 { // Nothing Read?

  MessageBox(NULL, "Could Not Read 'Monitor.raw' Image Data", "TEXTURE ERROR", MB_OK | MB_ICONINFORMATION);

  return FALSE;

 }

 t2 = AllocateTextureBuffer( 256, 256, 4 ); // Second Image Structure

 if (ReadTextureData("Data/GL.raw", t2) == 0) // Fill The Image Structure With Data

 { // Nothing Read?

  MessageBox(NULL, "Could Not Read 'GL.raw' Image Data", "TEXTURE ERROR", MB_OK | MB_ICONINFORMATION);

  return FALSE;

 }

If we got this far, it's safe to assume the memory has been allocated and the images have been loaded. Now to use our Blit() command to merge the two images into one.

We start off by passing Blit() t2 and t1, both point to our TEXTURE_IMAGE structures (t2 is the second image, t1 is the first image.

Then we have to tell blit where to start grabbing data from on the source image. If you load the source image into Adobe Photoshop or any other program capable of loading .RAW images you will see that the entire image is blank except for the top right corner. The top right has a picture of the ball with GL written on it. The bottom left corner of the image is 0,0. The top right of the image is the width of the image-1 (255), the height of the image-1 (255). Knowing that we only want to copy 1/4 of the src image (top right), we tell Blit() to start grabbing from 127,127 (center of our source image).

Next we tell blit how many pixels we want to copy from our source point to the right, and from our source point up. We want to grab a 1/4 chunk of our image. Our image is 256×256 pixels, 1/4 of that is 128×128 pixels. All of the source information is done. Blit() now knows that it should copy from 127 on the x axis to 127+128 (255) on the x axis, and from 127 on the y axis to 127+128 (255) on the y axis.

So Blit() knows what to copy, and where to get the data from, but it doesn't know where to put the data once it's gotten it. We want to draw the ball with GL written on it in the middle our the monitor image. You find the center of the destination image (256×256) which is 128×128 and subtract half the width and height of the source image (128×128) which is 64×64. So (128-64) × (128-64) gives us a starting location of 64,64.

Last thing to do is tell our blitter routine we want to blend the two image (A one means blend, a zero means do not blend), and how much to blend the images. If the last value is 0, we blend the images 0%, meaning anything we copy will replace what was already there. If we use a value of 127, the two images blend together at 50%, and if you use 255, the image you are copying will be completely transparent and will not show up at all.

The pixels are copied from image2 (t2) to image1 (t1). The mixed image will be stored in t1.

 // Image To Blend In, Original Image, Src Start X & Y, Src Width & Height, Dst Location X & Y, Blend Flag, Alpha Value

 Blit(t2, t1, 127, 127, 128, 128, 64, 64, 1, 127); // Call The Blitter Routine

After we have mixed the two images (t1 and t2) together, we build a texture from the combined images (t1).

After the texture has been created, we can deallocate the memory holding our two TEXTURE_IMAGE structures.

The rest of the code is pretty standard. We enable texture mapping, depth testing, etc.

 BuildTexture (t1); // Load The Texture Map Into Texture Memory

 DeallocateTexture( t1 ); // Clean Up Image Memory Because Texture Is

 DeallocateTexture( t2 ); // In GL Texture Memory Now

 glEnable(GL_TEXTURE_2D); // Enable Texture Mapping

 glShadeModel(GL_SMOOTH); // Enables Smooth Color Shading

 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // This Will Clear The Background Color To Black

 glClearDepth(1.0); // Enables Clearing Of The Depth Buffer

 glEnable(GL_DEPTH_TEST); // Enables Depth Testing

 glDepthFunc(GL_LESS); // The Type Of Depth Test To Do

 return TRUE;

}

I shouldn't even have to explain the code below. We move 5 units into the screen, select our single texture, and draw a texture mapped cube. You should notice that both textures are now combined into one. We don't have to render everything twice to map both textures onto the cube. The blitter code combined the images for us.

GLvoid DrawGLScene(GLvoid) {

 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer

 glLoadIdentity(); // Reset The View

 glTranslatef(0.0f,0.0f,-5.0f);

 glRotatef(xrot,1.0f,0.0f,0.0f);

 glRotatef(yrot,0.0f,1.0f,0.0f);

 glRotatef(zrot,0.0f,0.0f,1.0f);

 glBindTexture(GL_TEXTURE_2D, texture[0]);

 glBegin(GL_QUADS);

  // Front Face

  glNormal3f( 0.0f, 0.0f, 1.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, –1.0f, 1.0f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, –1.0f, 1.0f);

  // Back Face

  glNormal3f( 0.0f, 0.0f,-1.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, –1.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, 1.0f, –1.0f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, –1.0f, –1.0f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, –1.0f, –1.0f);

  // Top Face

  glNormal3f( 0.0f, 1.0f, 0.0f);

  glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, –1.0f);

  glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, –1.0f);

  glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 1.0f);

  glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 1.0f);

  // Bottom Face

  glNormal3f( 0.0f,-1.0f, 0.0f);