DirectDraw


DirectDraw

DirectDraw is an API to high performance of 2D graphics provided by the files ddraw.lib and ddraw.dll. DirectDraw can run on full screen or embedded in a window. However, high performance with two or more buffers is possible only on full screen mode. DirectDraw uses hardware acceleration, if it is available. Even though DirectDraw is a deprecated API, it provides direct access to the video card, and therefore, high performance.
DirectDraw es una API para alto desempeño para gráficos 2D proporcionada en los archivos ddraw.lib y ddraw.dll. DirectDraw puede ejecutarse en pantalla completa o en una ventana. Sin embargo, alto desempeño con dos o más bufferes es posible solamente en el modo de pantalla completa. DirectDraw usa aceleración por hardware, si éste esta disponible. Aún cuando DirectDraw es una API deprecada, esta proporciona acceso directo a la tarjeta de video, y por lo tanto, alto desempeño.

IDirectDrawSurface7

All drawing in DirectDraw is based on surfaces. A surface is a memory region that stores graphics that can be used in the program. That is, in order to display a graphic (i.e. a bitmap), the graphic needs to be stored in a surface.
Todo el dibujado en DirectDraw está basado en superficies. Una superficie una región de memoria que almacena gráficos que pueden ser usado en un programa. Esto es, a fin de mostrar un gráfico (por ejemplo un mapa de bits), el gráfico necesita estar almacenado en una superficie.

The primary surface and the back buffer surface.

To prevent flickering during drawing, it is necessary to have two surfaces: the primary surface (visible in the screen) and the back buffer surface. All drawing is performed on the back buffer surface; when we are down drawing, then the back buffer surface is "flip" and becomes the primary surface. In this moment, our drawing is visible and we have another off screen surface to draw the next frame. In other words, DirectDraw flips the two surfaces so that we can draw on a off-screen surface while the primary surface is visible.
Para prevenir el parpadeo durante el dibujado, es necesario tener dos superficies: la superficie primaria (visible en la pantalla) y la superficie del buffer de atrás. Todo el dibujado es realizado en la superficie del buffer de atrás; cuando nosotros terminamos de pintar, entonces la superficie del buffer de atrás se intercambia y está se convierte en la superficie primaria. En este momento, nuestro dibujo es visible y tenemos otra superficie fuera de la pantalla para dibujar la próxima escena o cuadro. En otras palabras, DirectDraw intercambia las dos superficies de tal forma que podamos dibujar en una superficie fuera de la pantalla mientras la superficie primaria es visible.

BitBlt (Bit Block Transfer)

A BitBlt copies a rectangular area from one surface to other surface. Using a color key, it is possible to copy everything from one surface to the other surface except those pixels with the color key.
A BitBlt copia una área rectangular desde una superficie a otra superficie. Usando un color key, es posible copiar todo desde una superficie a otra superficie excepto aquellos pixeles con el color de la color key.Definition Surface restoreSeveral DirectDraw functions return a DDERR_SURFACELOST value when a surface is lost. The surface may be lost because a display mode change or allocation (or release) of memory in the video card. The function Restore restores the surface but DOES NOT reload any graphics that were previously in the surface.
Varias funciones de DirectDraw regresar un valor de DDERR_SURFACELOST cuando una superficie se pierde. La superficie puede perderse por cambios en el modo de pantalla o alocación (o liberación) de memoria en la tarjeta de video. La función Restore reestablece la superficie pero NO recarga los gráficos que estaban en la superficie.

Problem 1
Create a Wintempla Window application call ColorWin to test DirectDraw. You will need an uncompress bitmap file for the eagle in the flag.
Cree una aplicación de Ventana con Wintempla llamada ColorWin para probar DirectDraw. Usted necesitará un archivo de bitmap sin comprimido para el águila de la bandera.

Step A
After creating the project, edit the stdafx.h file as shown to include DirectDraw libraries.
Después de crear el proyecto, edite el archivo stdafx.h cómo se muestra para incluir las librerías de DirectDraw.

stdafx.h
. . .
//_________________________________________ DirectDraw
#define WIN_DIRECTDRAW
. . .


ColorWinRun1

ColorWinRun2

Tip
When you define WIN_DIRECTDRAW, the file WintemplaWin.h includes and links the required files as shown below.
Cuando usted define WIN_DIRECTDRAW, el archivo de WintemplaWin.h incluye y enlaza los archivos requeridos cómo se muestra debajo.

WintemplaWin.h
...
#ifdef WIN_DIRECTDRAW
#include <ddraw.h>
#pragma comment(lib, "ddraw.lib")
#pragma comment(lib, "dxguid.lib")
#endif


Step B
Open Wintempla and double click anywhere in the editor to add the events shown below.
Abra Wintempla y haga clic doble en cualquier parte del editor para agregar los eventos mostrados debajo.

WindowEvents

Step C
Open the WinColor.h file to delete the Window_Paint event as shown.
Abra el archivo WinColor.h para borrar el evento de Window_Paint como se muestra.

WinColor.h
     . . .
     //_________________________________________________
     void Window_Idle(Win::Event& e);
     void Window_KeyDown(Win::Event& e);
     void Window_Open(Win::Event& e);
     //_________________________________________________
     bool EventHandler(Win::Event& e)
     {
          return false;
     }
};


Step D
Open the WinColor.cpp file to delete the function for the Window_Paint event. We do not need this function, because we are going to paint the window during the Window_Idle event. The Window_Paint event is called only when the window is moved, uncovered or resized. On the other hand, the Window_Idle event is called continuously.
Abra el archivo WinColor.cpp para borrar la función del evento de Window_Paint. Esta función no es necesaria, porque vamos a pintar la ventana duranta el evento de Window_Idle. El evento de Window_Paint es llamado solamente cuando la ventana se mueve, se descubre o cambia de tamaño. Por otro lado, el evento de Window_Idle se llama en forma continua.

WinColor.cpp
. . .
//void ColorWin::Window_Paint(Win::Event& e)
//{     
//     CG::Gdi gdi(hWnd, true, false);     
//}


Step D
Open the WinColor.cpp file and edit the top part of the file to:
  1. Use a NULL brush to paint the window background
  2. Extend the window to the full screen size
  3. Use the MessageLoopIdle instead of MessageLoop to be able to use the Window_Idle event
Do NOT run the program, it will run on full screen and you will not able to close the program.
Abra el archivo WinColor.cpp y edite la parte superior del archivo para
  1. Usar una brocha que no pinta para pintar el fondo de la ventana
  2. Extender la ventana a todo el tamaño de la ventana
  3. Usar el MessageLoopIdle en lugar de MessageLoop para poder usar el evento Window_Idle
NO ejecute el programa, esta correrá en pantalla completa y usted no podrá cerrar el programa.

WinColor.cpp
#include "stdafx.h" //________________________________________ ColorWin.cpp
#include "ColorWin.h"

int APIENTRY wWinMain(HINSTANCE hInstance, HINSTANCE , LPTSTR cmdLine, int cmdShow){
     ColorWin app;
     app.CreateMainWindow(0, WS_POPUP | WS_VISIBLE, 0, 0, ::GetSystemMetrics(SM_CXSCREEN), ::GetSystemMetrics(SM_CYSCREEN),
           L"ColorWin", cmdShow, IDI_ColorWin, NULL, (HBRUSH)::GetStockObject(NULL_BRUSH), hInstance);
     return app.MessageLoopIdle(IDC_ColorWin);
}
. . .


Step E
Edit the ColorWin.h file.
Edite el archivo ColorWin.h

ColorWin.h
#pragma once //______________________________________ ColorWin.h
#include "Resource.h"
class ColorWin: public Win::Window
{
public:
     ColorWin()
     {
          y = 0.0;
     }
     ~ColorWin()
     {     
     }
     DD7::Font font;
     DD7::DirectDRAW directDraw;
     DD7::Surface primary;
     DD7::Surface backBuffer;
     DD7::FileBitmap eagle;
     Sys::Stopwatch stopwatch;
     double y;
     const wchar_t * GetClassName(){return L"ColorWin";}
protected:
     . . .
};


Step F
Edit the ColorWin.cpp file. When done, run the program. You will be able to close the program by pressing the Escape key.
Edite el archivo ColorWin.cpp. Cuando termine, ejecute el programa. Usted podrá cerrar el programa presionando la tecla de Escape.

ColorWin.cpp
. . .
void ColorWin::Window_Open(Win::Event& e)
{
     //_______________________________________________________________ 1. Create DirectDraw
     if (directDraw.Create(hWnd, true, width, height) == false) return Destroy();
     //_______________________________________________________________ 2. Create primary surface
     if (primary.CreatePrimary(hWnd, directDraw, 1) == false) return Destroy();
     if (primary.SetClipper(hWnd, directDraw) == false) return Destroy();
     //_______________________________________________________________ 3. Create back buffer surface
     if (primary.GetBackBuffer(hWnd, backBuffer) == false) return Destroy();
     if (backBuffer.SetClipper(hWnd, directDraw) == false) return Destroy();
     //_______________________________________________________________ 4. Load the bitmap
     if (eagle.Load(hWnd, directDraw, L"eagle.bmp") == false) return Destroy();
     //_______________________________________________________________ 5. Create a font
     if (font.Create(hWnd, directDraw, L"Arial", 48, RGB(255, 255, 255), RGB(0, 0, 0)) == false)
     {
          this->MessageBox(L"Unable to create font", L"ColorWin", MB_OK | MB_ICONERROR);
     }
     const DWORD white = backBuffer.GetAdapterColor(255, 255, 255);
     font.SetSourceColorKey(white);
}

void ColorWin::Window_Idle(Win::Event& e)
{
     HRESULT hr = S_OK;
     const double second = stopwatch.GetSeconds();
     //______________________________________________________________ 1. Setup
     const int width = directDraw.GetWidth(hWnd);
     const int height = directDraw.GetHeight(hWnd);
     RECT rect = { 0, 0, width, height};
     const DWORD white = backBuffer.GetAdapterColor(255, 255, 255);
     const DWORD green = backBuffer.GetAdapterColor(0, 126, 72);
     const DWORD red = backBuffer.GetAdapterColor(237, 28, 36);
     backBuffer.Begin(hWnd);
     //______________________________________________________________ 2. Green, white, red
     backBuffer.Rectangle(0, 0, (int)(0.333*width + 0.5), height, green);
     backBuffer.Rectangle((int)(0.333*width + 0.5), 0, (int)(0.667*width + 0.5), height, white);
     backBuffer.Rectangle((int)(0.667*width + 0.5), 0, width, height, red);
     //______________________________________________________________ 3. Eagle
     const double scale = MINIMUM((0.25*width) / eagle.GetWidth(), (0.6*height) / eagle.GetHeight());
     const int eagleWidth = (int)(eagle.GetWidth()*scale+0.5);
     const int eagleHeight = (int)(eagle.GetHeight()*scale + 0.5);
     //
     y += (second*60.0); // 60 pixels/second
     if (y > height) y = -eagleWidth;
     backBuffer.BitBlt((width - eagleWidth) / 2, (int)(y + 0.5), eagleWidth, eagleHeight, eagle, 0);
     //______________________________________________________________ 4. Mexico
     const wchar_t* text = L"México";
     const int textWidth = font.GetTextWidth(text);
     backBuffer.Draw_Text(font, (width - textWidth) / 2, 0, text, DDBLT_KEYSRC);
     //backBuffer.Draw_Text(font, (width - textWidth) / 2, 0, text, 0);
     //__________________________________________________________________________________
     stopwatch.Start();
     primary.Flip();
}

void ColorWin::Window_KeyDown(Win::Event& e)
{
     switch (e.wParam)
     {
     case VK_ESCAPE:
          this->Destroy();
          break;
     }
}


Tip
You cannot switch to Windows when a DirectDraw application is running. You can use other events such as Window_Activate to decide what your application should do when the user de-activates the program by activating another program. The easy solution is to close the application when the user activates other application.
Usted no puede cambiar a Windows cuando una aplicación de DirectDraw esta corriendo. Usted puede usar otros eventos tales como Window_Activate para decidir que hace su aplicación cuando el usuario la desactiva al activar otro programa. La solución más fácil es cerrar el programa cuando el usuario activa otro programa.

© Copyright 2000-2019 Wintempla selo. All Rights Reserved. Sep 05 2019. Home