5. Drawing a textureTime to get something on the screen. Two main drawing functions will be used -- BlitD3D() and BlitExD3D(). The only difference between the two is that BlitExD3D() supports colour modulation of all four corners of the quad, while BlitD3D() can only tint the whole quad. Please be aware that the rotation code provided here is horrible, and should be rewritten. Use it at your own risk. //Draw a textured quad on the back-buffer void BlitD3D (IDirect3DTexture9 *texture, RECT *rDest, D3DCOLOR vertexColour, float rotate) { TLVERTEX* vertices; //Lock the vertex buffer vertexBuffer->Lock(0, 0, (void**)&vertices, NULL); //Setup vertices //A -0.5f modifier is applied to vertex coordinates to match texture //and screen coords. Some drivers may compensate for this //automatically, but on others texture alignment errors are introduced //More information on this can be found in the Direct3D 9 documentation vertices[0].colour = vertexColour; vertices[0].x = (float) rDest->left - 0.5f; vertices[0].y = (float) rDest->top - 0.5f; vertices[0].z = 0.0f; vertices[0].rhw = 1.0f; vertices[0].u = 0.0f; vertices[0].v = 0.0f; vertices[1].colour = vertexColour; vertices[1].x = (float) rDest->right - 0.5f; vertices[1].y = (float) rDest->top - 0.5f; vertices[1].z = 0.0f; vertices[1].rhw = 1.0f; vertices[1].u = 1.0f; vertices[1].v = 0.0f; vertices[2].colour = vertexColour; vertices[2].x = (float) rDest->right - 0.5f; vertices[2].y = (float) rDest->bottom - 0.5f; vertices[2].z = 0.0f; vertices[2].rhw = 1.0f; vertices[2].u = 1.0f; vertices[2].v = 1.0f; vertices[3].colour = vertexColour; vertices[3].x = (float) rDest->left - 0.5f; vertices[3].y = (float) rDest->bottom - 0.5f; vertices[3].z = 0.0f; vertices[3].rhw = 1.0f; vertices[3].u = 0.0f; vertices[3].v = 1.0f; //Handle rotation if (rotate != 0) { RECT rOrigin; float centerX, centerY; //Find center of destination rectangle centerX = (float)(rDest->left + rDest->right) / 2; centerY = (float)(rDest->top + rDest->bottom) / 2; //Translate destination rect to be centered on the origin rOrigin.top = rDest->top - (int)(centerY); rOrigin.bottom = rDest->bottom - (int)(centerY); rOrigin.left = rDest->left - (int)(centerX); rOrigin.right = rDest->right - (int)(centerX); //Rotate vertices about the origin bufferVertices[index].x = rOrigin.left * cosf(rotate) - rOrigin.top * sinf(rotate); bufferVertices[index].y = rOrigin.left * sinf(rotate) + rOrigin.top * cosf(rotate); bufferVertices[index + 1].x = rOrigin.right * cosf(rotate) - rOrigin.top * sinf(rotate); bufferVertices[index + 1].y = rOrigin.right * sinf(rotate) + rOrigin.top * cosf(rotate); bufferVertices[index + 2].x = rOrigin.right * cosf(rotate) - rOrigin.bottom * sinf(rotate); bufferVertices[index + 2].y = rOrigin.right * sinf(rotate) + rOrigin.bottom * cosf(rotate); bufferVertices[index + 3].x = rOrigin.left * cosf(rotate) - rOrigin.bottom * sinf(rotate); bufferVertices[index + 3].y = rOrigin.left * sinf(rotate) + rOrigin.bottom * cosf(rotate); //Translate vertices to proper position bufferVertices[index].x += centerX; bufferVertices[index].y += centerY; bufferVertices[index + 1].x += centerX; bufferVertices[index + 1].y += centerY; bufferVertices[index + 2].x += centerX; bufferVertices[index + 2].y += centerY; bufferVertices[index + 3].x += centerX; bufferVertices[index + 3].y += centerY; } //Unlock the vertex buffer vertexBuffer->Unlock(); //Set texture DEVICE->SetTexture (0, texture); //Draw image DEVICE->DrawPrimitive (D3DPT_TRIANGLEFAN, 0, 2); } NOTE: Replace DEVICE with the name of your IDirect3DDevice9* object Here's a description of the arguments passed to the function: texture - A pointer to the texture to use on the quad. Whatever is passed here will show up on screen. rDest - A rectangle containing the screen coordinates of the quad. If the rectangle is of a different size than the texture, the image will be scaled. vertexColour - The colour used to tint the quad in 32-bit 0xAARRGGBB format. A value of 0xFFFFFFFF will not modify the appearance of the texture. fRotate - How much the quad should be rotated about its center. The value should be in radians. A value of 0 will, of course, not rotate the quad at all. The extended blitting function follows: //Draw a textured quad on the back-buffer void BlitExD3D (IDirect3DTexture9 *texture, RECT *rDest, D3DCOLOR *vertexColours /* -> D3DCOLOR[4] */, float rotate) { TLVERTEX* vertices; //Lock the vertex buffer vertexBuffer->Lock(0, 0, (void**)&vertices, NULL); //Setup vertices //A -0.5f modifier is applied to vertex coordinates to match texture //and screen coords. Some drivers may compensate for this //automatically, but on others texture alignment errors are introduced //More information on this can be found in the Direct3D 9 documentation vertices[0].colour = vertexColours[0]; vertices[0].x = (float) rDest->left - 0.5f; vertices[0].y = (float) rDest->top - 0.5f; vertices[0].z = 0.0f; vertices[0].rhw = 1.0f; vertices[0].u = 0.0f; vertices[0].v = 0.0f; vertices[1].colour = vertexColours[1]; vertices[1].x = (float) rDest->right - 0.5f; vertices[1].y = (float) rDest->top - 0.5f; vertices[1].z = 0.0f; vertices[1].rhw = 1.0f; vertices[1].u = 1.0f; vertices[1].v = 0.0f; vertices[2].colour = vertexColours[2]; vertices[2].x = (float) rDest->right - 0.5f; vertices[2].y = (float) rDest->bottom - 0.5f; vertices[2].z = 0.0f; vertices[2].rhw = 1.0f; vertices[2].u = 1.0f; vertices[2].v = 1.0f; vertices[3].colour = vertexColours[3]; vertices[3].x = (float) rDest->left - 0.5f; vertices[3].y = (float) rDest->bottom - 0.5f; vertices[3].z = 0.0f; vertices[3].rhw = 1.0f; vertices[3].u = 0.0f; vertices[3].v = 1.0f; //Handle rotation if (rotate != 0) { RECT rOrigin; float centerX, centerY; //Find center of destination rectangle centerX = (float)(rDest->left + rDest->right) / 2; centerY = (float)(rDest->top + rDest->bottom) / 2; //Translate destination rect to be centered on the origin rOrigin.top = rDest->top - (int)(centerY); rOrigin.bottom = rDest->bottom - (int)(centerY); rOrigin.left = rDest->left - (int)(centerX); rOrigin.right = rDest->right - (int)(centerX); //Rotate vertices about the origin bufferVertices[index].x = rOrigin.left * cosf(rotate) - rOrigin.top * sinf(rotate); bufferVertices[index].y = rOrigin.left * sinf(rotate) + rOrigin.top * cosf(rotate); bufferVertices[index + 1].x = rOrigin.right * cosf(rotate) - rOrigin.top * sinf(rotate); bufferVertices[index + 1].y = rOrigin.right * sinf(rotate) + rOrigin.top * cosf(rotate); bufferVertices[index + 2].x = rOrigin.right * cosf(rotate) - rOrigin.bottom * sinf(rotate); bufferVertices[index + 2].y = rOrigin.right * sinf(rotate) + rOrigin.bottom * cosf(rotate); bufferVertices[index + 3].x = rOrigin.left * cosf(rotate) - rOrigin.bottom * sinf(rotate); bufferVertices[index + 3].y = rOrigin.left * sinf(rotate) + rOrigin.bottom * cosf(rotate); //Translate vertices to proper position bufferVertices[index].x += centerX; bufferVertices[index].y += centerY; bufferVertices[index + 1].x += centerX; bufferVertices[index + 1].y += centerY; bufferVertices[index + 2].x += centerX; bufferVertices[index + 2].y += centerY; bufferVertices[index + 3].x += centerX; bufferVertices[index + 3].y += centerY; } //Unlock the vertex buffer vertexBuffer->Unlock(); //Set texture DEVICE->SetTexture (0, texture); //Draw image DEVICE->DrawPrimitive (D3DPT_TRIANGLEFAN, 0, 2); } NOTE: Replace DEVICE with the name of your IDirect3DDevice9* object The only argument here that is different from the BlitD3D() function is vertexColours. vertexColours must be a pointer to a D3DCOLOR array of size 4. The indices of the array correspond to the numbers of the vertices in the kick-ass diagram provided at the beginning of this article. Each vertex in the quad will have its colour and alpha modulated based on its corresponding value in vertexColours.
|
|