Пятница, 26 Апреля 2024, 18:38

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Программирование » C/C++ » Проблема с блокированием поверхности
Проблема с блокированием поверхности
HagartingerДата: Понедельник, 03 Февраля 2014, 15:37 | Сообщение # 1
был не раз
Сейчас нет на сайте
Учусь работать с DitectDraw по книжке Андре Ламота. Не получается заблокировать плоскость, не пойму в чем проблема, подскажите пожалуйста в чем проблема.
Код

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <windowsx.h>  
#include <ddraw.h>
#include <math.h>
#include <mmsystem.h>
#include <iostream>  
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>  
#include <math.h>
#include <io.h>
#include <fcntl.h>

#pragma comment(lib,"ddraw.lib")
#pragma comment(lib,"DXGUID.lib")

// Параметры Экрана
#define SCREEN_WIDTH 1280
#define SCREEN_HEIGHT   1024
#define SCREEN_BPP      32     

#define BITMAP_ID            0x4D42 // universal id for a bitmap

#define MAX_COLORS_PALETTE   256

#define DDRAW_INIT_STRUCT(ddstruct) { memset(&ddstruct,0,sizeof(ddstruct)); ddstruct.dwSize=sizeof(ddstruct); }

// this builds a 16 bit color value in 5.5.5 format (1-bit alpha mode)
#define _RGB16BIT555(r,g,b) ((b & 31) + ((g & 31) << 5) + ((r & 31) << 10))

// this builds a 16 bit color value in 5.6.5 format (green dominate mode)
#define _RGB16BIT565(r,g,b) ((b & 31) + ((g & 63) << 5) + ((r & 31) << 11))

// this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
#define _RGB32BIT(a,r,g,b) ((b) + ((g) << 8) + ((r) << 16) + ((a) << 24))

//Глобальные переменные
WNDCLASSEX winclas;  
HWND hwnd;
MSG msg;
LPDIRECTDRAW7 lpdd= NULL;
LPDIRECTDRAWSURFACE7 lpddsprimary=NULL;
LPDIRECTDRAWSURFACE7 lpddsback=NULL;
DDSURFACEDESC2 ddsd;  

typedef struct BITMAP_FILE_TAG
         {
         BITMAPFILEHEADER bitmapfileheader;  // this contains the bitmapfile header
         BITMAPINFOHEADER bitmapinfoheader;  // this is all the info including the palette
         PALETTEENTRY     palette[256];      // we will store the palette here
         UCHAR            *buffer;           // this is a pointer to the data

         } BITMAP_FILE, *BITMAP_FILE_PTR;

int Flip_Bitmap(UCHAR *image, int bytes_per_line, int height)
{
// this function is used to flip bottom-up .BMP images

UCHAR *buffer; // used to perform the image processing
int index;     // looping index

// allocate the temporary buffer
if (!(buffer = (UCHAR *)malloc(bytes_per_line*height)))
    return(0);

// copy image to work area
memcpy(buffer,image,bytes_per_line*height);

// flip vertically
for (index=0; index < height; index++)
     memcpy(&image[((height-1) - index)*bytes_per_line],
            &buffer[index*bytes_per_line], bytes_per_line);

// release the memory
free(buffer);

// return success
return(1);

} // end Flip_Bitmap
int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
// this function opens a bitmap file and loads the data into bitmap

int file_handle,  // the file handle
     index;        // looping index

UCHAR   *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
OFSTRUCT file_data;          // the file data information

// open the file if it exists
if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
    return(0);

// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));

// test if this is a bitmap file
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
    {
    // close the file
    _lclose(file_handle);

    // return error
    return(0);
    } // end if

// now we know this is a bitmap, so read in all the sections

// first the bitmap infoheader

// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));

// now load the color palette if there is one
if (bitmap->bitmapinfoheader.biBitCount == 8)
    {
    _lread(file_handle, &bitmap->palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));

    // now set all the flags in the palette correctly and fix the reversed  
    // BGR RGBQUAD data format
    for (index=0; index < MAX_COLORS_PALETTE; index++)
        {
        // reverse the red and green fields
        int temp_color                = bitmap->palette[index].peRed;
        bitmap->palette[index].peRed  = bitmap->palette[index].peBlue;
        bitmap->palette[index].peBlue = temp_color;
         
        // always set the flags word to this
        bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
        } // end for index

     } // end if

// finally the image data itself
_llseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);

// now read in the image, if the image is 8 or 16 bit then simply read it
// but if its 24 bit then read it into a temporary area and then convert
// it to a 16 bit image

if (bitmap->bitmapinfoheader.biBitCount==8 || bitmap->bitmapinfoheader.biBitCount==16 ||  
     bitmap->bitmapinfoheader.biBitCount==24)
    {
    // delete the last image if there was one
    if (bitmap->buffer)
        free(bitmap->buffer);

    // allocate the memory for the image
    if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
       {
       // close the file
       _lclose(file_handle);

       // return error
       return(0);
       } // end if

    // now read it in
    _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biSizeImage);

    } // end if
else
    {
    // serious problem
    return(0);

    } // end else

#if 0
// write the file info out  
printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
         filename,
         bitmap->bitmapinfoheader.biSizeImage,
         bitmap->bitmapinfoheader.biWidth,
         bitmap->bitmapinfoheader.biHeight,
   bitmap->bitmapinfoheader.biBitCount,
         bitmap->bitmapinfoheader.biClrUsed,
         bitmap->bitmapinfoheader.biClrImportant);
#endif

// close the file
_lclose(file_handle);

// flip the bitmap
Flip_Bitmap(bitmap->buffer,  
             bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8),  
             bitmap->bitmapinfoheader.biHeight);

// return success
return(1);

} // end Load_Bitmap_File
int Unload_Bitmap_File(BITMAP_FILE_PTR bitmap)
{
// this function releases all memory associated with "bitmap"
if (bitmap->buffer)
    {
    // release memory
    free(bitmap->buffer);

    // reset pointer
    bitmap->buffer = NULL;

    } // end if

// return success
return(1);

} // end Unload_Bitmap_File

BITMAP_FILE bitmap;

LRESULT CALLBACK WinProc(HWND hwnd, UINT msg,WPARAM wparam,LPARAM Lparam)
{  
  PAINTSTRUCT ps;
  HDC hdc;
  switch (msg)
  {
  case WM_CREATE :
   {
    return(0);
   } break;
  case WM_PAINT:
   {
    hdc=BeginPaint(hwnd,&ps);
    EndPaint(hwnd,&ps);
    return(0);
   } break;
  case WM_DESTROY:  
   {
    PostQuitMessage(0);
    return(0);
   } break;
  }
  return (DefWindowProc(hwnd,msg,wparam,Lparam));
}
int Game_Main (void* parms = NULL, int num_parms = 0)
{
memset(&ddsd,0,sizeof(ddsd));  
ddsd.dwSize = sizeof(ddsd);
lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer to primary surfce
DWORD *primary_buffer = (DWORD *)ddsd.lpSurface;        

// process each line and copy it into the primary buffer
for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)
     {
     for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)
         {
         // get BGR values
         UCHAR blue  = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 0]),
               green = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 1]),
               red   = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 2]);

         // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
         DWORD pixel = _RGB32BIT(0,red,green,blue);

         // write the pixel
         primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;

         } // end for index_x

     } // end for index_y

// now unlock the primary surface
if (FAILED(lpddsprimary->Unlock(NULL)))
    return(0);

   

return(1);
}

int Game_Init(void* parms = NULL, int num_parms = 0)
{  
   

  if(FAILED(DirectDrawCreateEx(NULL,(VOID**)&lpdd,IID_IDirectDraw7,NULL)))
   return(0);

  if(FAILED(lpdd->SetCooperativeLevel(hwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX |  
                    DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
  return(0);
  if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,0,0))) return(0);

  memset(&ddsd,0,sizeof(ddsd));  
ddsd.dwSize = sizeof(ddsd);

// enable valid fields
ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
ddsd.dwBackBufferCount = 1;

// request primary surface
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_COMPLEX|DDSCAPS_FLIP;

// create the primary surface
if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL)))
    {
    
    return(0);
    }  

ddsd.ddsCaps.dwCaps=DDSCAPS_BACKBUFFER;
if(FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps,&lpddsback))) return(0);

if(!Load_Bitmap_File(&bitmap,"BMW.bmp"))
  return(0);

  return(1);
   

   

   
}

int Game_Shutdown (void* parms = NULL, int num_parms = 0)
{

  if(lpddsprimary)
  {
   lpddsprimary->Release();
   lpddsprimary=NULL;
  }
  if(lpdd)
  {
   lpdd->Release();
   lpdd=NULL;
  }

  return(1);
}
   
   
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)  
{
   

  winclas.cbSize = sizeof(WNDCLASSEX);
  winclas.style = CS_VREDRAW| CS_HREDRAW| CS_OWNDC| CS_DBLCLKS;
  winclas.lpfnWndProc= WinProc;
  winclas.cbClsExtra=0;
  winclas.cbWndExtra=0;
  winclas.hInstance=hInstance;
  winclas.hIcon= LoadIcon (NULL,IDI_APPLICATION);
  winclas.hCursor= LoadCursor(NULL, IDC_ARROW);
  winclas.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  winclas.lpszMenuName = NULL;
  winclas.lpszClassName = L"WINCLASS1";
  winclas.hIconSm= LoadIcon (NULL,IDI_APPLICATION);
  if(FAILED(RegisterClassEx(&winclas))) return(0);
  if(FAILED(CreateWindowEx(NULL,L"WINCLASS1",L"Мое Первое окно", WS_VISIBLE|WS_POPUP,0,0,SCREEN_WIDTH,SCREEN_HEIGHT,NULL,NULL,hInstance,NULL))) return(0);

  Game_Init();

  while (true)
  {  
   if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
   {
    if(msg.message==WM_QUIT) break;

   TranslateMessage(&msg);

   DispatchMessage(&msg);
   }
   Game_Main();
   // выполнение игры

  }
  Game_Shutdown();
  return(msg.wParam);
}

После запуска выдает ошибку "Необработанное исключение по адресу 0x00197BBB в Chapter6.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0x00000000."

и указывает мне на этот кусок кода :
Код
int Game_Main (void* parms = NULL, int num_parms = 0)
{
memset(&ddsd,0,sizeof(ddsd));  
ddsd.dwSize = sizeof(ddsd);
lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer to primary surfce
DWORD *primary_buffer = (DWORD *)ddsd.lpSurface;        

// process each line and copy it into the primary buffer
for (int index_y = 0; index_y < SCREEN_HEIGHT; index_y++)
     {
     for (int index_x = 0; index_x < SCREEN_WIDTH; index_x++)
         {
         // get BGR values
         UCHAR blue  = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 0]),
               green = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 1]),
               red   = (bitmap.buffer[index_y*SCREEN_WIDTH*3 + index_x*3 + 2]);

         // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode)
         DWORD pixel = _RGB32BIT(0,red,green,blue);

         // write the pixel
         primary_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel;

         } // end for index_x

     } // end for index_y

// now unlock the primary surface
if (FAILED(lpddsprimary->Unlock(NULL)))
    return(0);

   

return(1);
}

а именно на это строчку :
Код
lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);
ArchidoДата: Вторник, 04 Февраля 2014, 17:06 | Сообщение # 2
Сэнсэй
Сейчас нет на сайте
Советую быстро забить на DirectDraw и изучать как минимум Direct3D9 или OpenGL 2.0 \ 3.0

C++ - он особенный. С помощью него можно не только выстрелить себе в ногу, но и повеситься в пустой комнате:)
HagartingerДата: Среда, 05 Февраля 2014, 00:21 | Сообщение # 3
был не раз
Сейчас нет на сайте
Да я уже забил, изучаю сейчас SDL, потом потихонечку переберусь на OpenGL или Direct3D9
SanoraagДата: Среда, 05 Февраля 2014, 10:19 | Сообщение # 4
почетный гость
Сейчас нет на сайте
переходи на OpenGl biggrin . Он более гибкий

Форум игроделов » Программирование » C/C++ » Проблема с блокированием поверхности
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг