Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2 3  Все   Вниз
  Печать  
Автор Тема: DirectInput в DirectX 9  (Прочитано 83829 раз)
0 Пользователей и 3 Гостей смотрят эту тему.
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« : 31-07-2009 08:44 » 

У меня:

1. Microsoft Visual C++ 6.0 Standard Edition
2. DirectX 9c SDK ноябрь 2008

А так начинается мой код

Код:
#define DIRECTINPUT_VERSION 0x0800

#include <windows.h>
// подключаем заголовочный файл DirectX 9 SDK
#include <d3d9.h>
#include <d3dx9.h>
// Для работы с mesh
#include <d3dx9mesh.h>

// Для работы с DirectInput
#include <dinput.h>
#include <math.h>
#include "camera.h"

#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
// Для работы с DirectInput
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")

// Для того, что бы работала функция timeGetTime()
#pragma comment(lib, "winmm.lib")

LPDIRECT3D9 pDirect3D = NULL;
LPDIRECT3DDEVICE9 pDirect3DDevice = NULL;

// Указатель на Mesh
LPD3DXMESH pMesh = NULL;
// Указател на буфер mesh-а
LPD3DXBUFFER pMeshBuffer = NULL;
// Указатель на буфер материалов
D3DMATERIAL9 *pMeshMaterial = NULL;
// Указатель на буфер текстур
LPDIRECT3DTEXTURE9 *pMeshTexture = NULL;
// Указатель на интерфейс DirectInput
LPDIRECTINPUT8 pInput = NULL;
//  Указатель на устройство ввода
LPDIRECTINPUTDEVICE8 pInputDevice = NULL;
// Количество материала и текстур
DWORD dwNumber = 0;

DWORD OneTick = 0;

HINSTANCE hInstance;
...
...
...

Ошибки:

--------------------Configuration: di - Win32 Debug--------------------
Compiling...
di.cpp
c:\di\di.cpp(38) : error C2146: syntax error : missing ';' before identifier 'pInput'
c:\di\di.cpp(38) : error C2501: 'LPDIRECTINPUT8' : missing storage-class or type specifiers
c:\di\di.cpp(38) : fatal error C1004: unexpected end of file found
Error executing cl.exe.

Подключить директории я не забыл, вот printscreen-ы





Я как-то не так задал библиотеки для работы DirectInput, а как правильно, не знаю, в Интернете по-разному пишут, но всё не работает.
Помогите, пожалуйста, избавиться от этих ошибок.
« Последнее редактирование: 13-09-2009 10:52 от Sel » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 31-07-2009 09:39 » 

прицепи проект

а кстати, не относится к теме, но
LPDIRECT3DTEXTURE9 *pMeshTexture = NULL;
надо ли тут * ? Улыбаюсь
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #2 : 31-07-2009 09:49 » 

Я тоже на счёт этого удивился, но без * вроде не работает.

Я прицепил не проект, а исходный код, проект прицепить не смог, так как он очень большой и не приципляется.

* di.rar (43.95 Кб - загружено 1095 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 31-07-2009 15:25 » 

как я выяснил путём ковыряния, происходит конфликт:
C:\Program Files\Microsoft DirectX SDK (August 2008)\Include\dinput.h
и
C:\Program Files\Visual Studio 6\VC98\Include\dinput.h


вставляется первый файл в списке - а это у нас обоих выходит студийный файл

победить ещё не смог
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #4 : 31-07-2009 17:28 » 

Алексей1153++

Какой хитрый DirectInput))). А я думал я что то туплю))). Ну уже есть от чего отталкиваться. Большое спасибо.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 31-07-2009 18:05 » 

поищи в интернете, наверняка кто то решал ) А я щас немного шарпом (бэ) занят, да и трафика маловато осталось. Потом расскажи, как это перебороть )
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #6 : 31-07-2009 20:10 » 

Вот код для правельной компиляции.

Код:
// Для работы с DirectInput
#define DIRECTINPUT_VERSION 0x0800
#define INITGUID

#include <dinput.h>

#pragma comment (lib, "dinput.lib")
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")

А так же настроить Microsoft Visual C++ 6.0 Standard Edition



И ещё несколько вопросов по DirectInput

1. В DirectInput делать лучше с буферизированным вводом с клавиатуры или без него?

2. В какой части кода я должен запускать функцию InitDirectInput в которой происходит инициализация и проверка нажатых клавиш может её надо разбить на две функции инициализация и проверка нажатых клавишь, тогда в каком месте кода писать эти две функции?

Сейчас у меня нажатия клавишь не ловятся, а должны ловится клавиши 1, 2, 3, 4.

Прикрепляю код.

* di_Edit.rar (43.99 Кб - загружено 1105 раз.)
« Последнее редактирование: 31-07-2009 21:16 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 01-08-2009 04:49 » 

я ещё не разбирался с инпутом ) А по интуиции:

1) клавиши навигации по 3D миру лучше не буферизировать - они актуальны только в момент нажатия. А вот клавиши вызова меню и прочик окошек - думаю стОит запомнить в буфер

2) инициализацию и настройку вынести в отдельную йункцию. А опрос делать где нибудь в конце функции Render

---------
насчёт кода:
компиляция у меня прошла, только линкер ругается
dxguid.lib(dxguid.obj) : fatal error LNK1103: debugging information corrupt; recompile module

пока не разбирался, почемур

------------
а ещё компилятор правильно подсказывает, что ползуешься неинициализированной переменной Ага
    return (int)msg.wParam;


Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #8 : 01-08-2009 05:21 » 

Цитата: Алексей1153++
а ещё компилятор правильно подсказывает, что ползуешься неинициализированной переменной
return (int)msg.wParam;

На счёт этого знаю. Пока руки не доходят поправить.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 01-08-2009 05:22 » 

это поправить невероятно легко

return 0;
Ага
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #10 : 01-08-2009 05:32 » new

Исправил что бы не было предупреждения связанного с return (int)msg.wParam; перенёс использование функции InitDirectInput(); в функцию рендерига, теперь клавиши стали определятся.

Осталось из функции  InitDirectInput(); вынуть код отвечающий за определения нажатой клавиши, и сделать из него отдельную функцию, а также сделать буферизированный ввод и нажатия мыши отловить, с джостиком вазится не буду если понадобится по ходу дела сделаю.
« Последнее редактирование: 01-08-2009 05:46 от zuze » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 01-08-2009 06:04 » 

Осталось из функции  InitDirectInput(); вынуть код отвечающий за определения нажатой клавиши, и сделать из него отдельную функцию,
воистину обязательно разднлить ) Ведь инитку надо вызвать один раз, а опрос - в конце каждого рендера

и вообще , напрашивается класс-обёртка
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #12 : 01-08-2009 06:08 » 

Класс я пуду делать когда буду первую игру создавать, а пока обойдусь этим.

К стати инициализацию DirectInput в какой части кода лучше проводить?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 01-08-2009 06:42 » 

где - ну, по смыслу. Когда игра началась, скажем )
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #14 : 01-08-2009 07:02 » 

То есть в конце функции int WINAPI WinMain(HINSTANCE hInst,   HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)?

И ещё такая странность, когда так всё прекрасно работает

То есть:
1. Нажимаю клавишу '1' выводится сообщение "Нажата клавиша 1"
3. Нажимаю клавишу '2' выводится сообщение "Нажата клавиша 2"
3. Нажимаю клавишу '3' выводится сообщение "Нажата клавиша 3"
4. Нажимаю клавишу '4' выводится сообщение "Нажата клавиша 4"

Код:
#define  KEYDOWN(name,key)(name[key] &0x80)

// Функция рендеринга Direct3D
void RenderingDirect3D(void)
{
            ...
            ...
            ...
InitDirectInput();
            ...
            ...
            ...
}


// Функция инициализация DirectInput
bool InitDirectInput(void)
{
    // Создание интерфейс устройства
    if FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL))
        return false;

    // Создание устройства клавиатуры
    if FAILED(pInput->CreateDevice(GUID_SysKeyboard, &pInputDevice, NULL))
    {
        DeleteDirectInput();
        return false;
    }

    // Установка формата данных клавиатуры
if FAILED(pInputDevice->SetDataFormat(&c_dfDIKeyboard))
    {
        DeleteDirectInput();
        return false;
    }
    // Установка уровня взаимодействия клавиатуры (совместный доступ)
    if FAILED(pInputDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))
    {
        DeleteDirectInput();
        return false;
    }

    // Захват доступа к клавиатуре (активизировать управление)
    if FAILED(pInputDevice->Acquire())
    {
        DeleteDirectInput();
        return false;
    }

char keyboard[256]; // Буфер для хранения полученных данных от клавиатуры

    // Полученние данных с клавиатуры
    if FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard))
    {
        DeleteDirectInput();
        return false;
    }

    // Обработка клавиши < 1 >
    // Изменяем окружающие освещенние на зеленный цвет
    if (KEYDOWN(keyboard, DIK_1))
       MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

    // Обработка клавиши < 2 >
    // Возвращаем в исходное состояние
    if (KEYDOWN(keyboard, DIK_2))
       MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

    // Обработка клавиши < 3 >
    // Изменяем окружающие освещенние на синий цвет
    if (KEYDOWN(keyboard, DIK_3))
       MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

    // Обработка клавиши < 4 >
    // Изменяем окружающие освещенние на красный цвет
    if (KEYDOWN(keyboard, DIK_4))
      MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);

    return true;
}

// Функция освобождает захваченные ресурсы DeleteInput
void DeleteDirectInput(void)
{
    if (pInput)
    {
        if (pInputDevice)
        {
           if (pInputDevice != NULL)
              pInputDevice->Unacquire();

           if (pInputDevice != NULL)
              pInputDevice->Release();
           pInputDevice = NULL;
        }
        if (pInput != NULL)
           pInput->Release();
        pInput = NULL;
    }
}

А так работает, не правильно

То есть
Вывод сообщений зацикливается сразу при запуске приложения.

Код:
int WINAPI WinMain(HINSTANCE hInst,	HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    ...
    ...
    ...
    InitDirectInput();
   
    return 0;
}

// Функция рендеринга Direct3D
void RenderingDirect3D(void)
{
            ...
            ...
            ...
// Обработка клавиши < 1 >
// Изменяем окружающие освещенние на зеленный цвет
            if (isKeyDown(DIK_1))
   MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

// Обработка клавиши < 2 >
// Возвращаем в исходное состояние
if (isKeyDown(DIK_2))
   MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

            // Обработка клавиши < 3 >
// Изменяем окружающие освещенние на синий цвет
            if (isKeyDown(DIK_3))
   MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

// Обработка клавиши < 4 >
// Изменяем окружающие освещенние на красный цвет
if (isKeyDown(DIK_4))
   MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);
            ...
            ...
            ...
}

// Функция инициализация DirectInput
bool InitDirectInput(void)
{
    // Создание интерфейс устройства
    if FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL))
        return false;

    // Создание устройства клавиатуры
    if FAILED(pInput->CreateDevice(GUID_SysKeyboard, &pInputDevice, NULL))
    {
        DeleteDirectInput();
        return false;
    }

    // Установка формата данных клавиатуры
if FAILED(pInputDevice->SetDataFormat(&c_dfDIKeyboard))
    {
        DeleteDirectInput();
        return false;
    }
    // Установка уровня взаимодействия клавиатуры (совместный доступ)
    if FAILED(pInputDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))
    {
        DeleteDirectInput();
        return false;
    }

    // Захват доступа к клавиатуре (активизировать управление)
    if FAILED(pInputDevice->Acquire())
    {
        DeleteDirectInput();
        return false;
    }

char keyboard[256]; // Буфер для хранения полученных данных от клавиатуры

    // Полученние данных с клавиатуры
    if FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard))
    {
        DeleteDirectInput();
        return false;
    }

    return true;
}

// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(int KeyCode)
{
char KeyState[256];
if (KeyState[KeyCode] & 0x80)
   return true;
else
   return false;
}

// Функция освобождает захваченные ресурсы DeleteInput
void DeleteDirectInput(void)
{
    if (pInput)
    {
        if (pInputDevice)
        {
           if (pInputDevice != NULL)
              pInputDevice->Unacquire();

           if (pInputDevice != NULL)
              pInputDevice->Release();
           pInputDevice = NULL;
        }
        if (pInput != NULL)
           pInput->Release();
        pInput = NULL;
    }
}

В чём же дело?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 01-08-2009 13:35 » 

считаю, что вопрос не ко мне, так как я  - говорил - ещё не разбирался со вводом. Улыбаюсь

но мысли такие
1)
должно быть две функции:
      InitDirectInput() //инитка - настройка, все дела
      CheckDirectInput() //опрос нажатых, буферизирование и тд

2) InitDirectInput() не должен быть в RenderingDirect3D(void)
3)  InitDirectInput()  должен топологически быть где то в начале Main()  (и никак не перед return 0 - ведь тогда функция не вызовется, по сути, во время работы программы)
4) CheckDirectInput() можно вызвать в конце Render()

а что зацикливается - не могу знать ( Не запускал, писал выше, с причиной не разбирался - занят друим проектом щас

Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #16 : 01-08-2009 13:37 » 

Алексей1153++

Спасибо и на этом, буду думать.
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #17 : 12-09-2009 10:10 » 

Алексей1153++

Прошу прощения что так долго не отвечал. Вот взялся дальше за изучение.

Цитата: zuze
А так работает, не правильно

То есть
Вывод сообщений зацикливается сразу при запуске приложения.

С этим я разобрался.

У меня было так

Код:
// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(int KeyCode)
{
char KeyState[256];
if (KeyState[KeyCode] & 0x80)
   return true;
else
   return false;
}

массив KeyState нужно не объявлять, а брать массив keyboard который уже объявлен.

Я решил вернутся к работающему коду, что его так расковырял что кнопкуи "1", "2", "3", "4" вообще не определяются.

Вот код который относится к DirectInput

Код:
// Для работы с DirectInput
#define DIRECTINPUT_VERSION 0x0800
#define INITGUID
#define KEYDOWN(name, key)(name[key] &0x80)
#include <dinput.h>

// Для работы с DirectInput
#pragma comment (lib, "dinput.lib")
#pragma comment (lib, "dinput8.lib")
#pragma comment (lib, "dxguid.lib")

// Указатель на интерфейс DirectInput
LPDIRECTINPUT8 pInput = NULL;
//  Указатель на устройство ввода
LPDIRECTINPUTDEVICE8 pInputDevice = NULL;
// Буфер для хранения полученных данных от клавиатуры
char keyboard[256];

// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
// Инициализация DirectInput
            InitDirectInput();
            ...
            ...
            ...
             if (SUCCEEDED(InitDirect3D(hwnd)))
            {
               if (SUCCEEDED(InitMesh()))
               {
      ShowWindow(hwnd, SW_SHOWDEFAULT);
                  UpdateWindow(hwnd);

      EnterMsgLoop(EnterKey);
               }
            }

            return 0;
}



// Я решил оставить в этой функцию полностью не убирать строки которые не относятся к DirectInput,
// что бы показать что я использую ещё метод определения клавишь WinAPI
// Функция обработки нажатия клавиш 
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
  TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
  TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
  TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
  TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
  TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
  TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
  TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
  TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
  TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
// Изменяем окружающие освещенние на зеленный цвет
if (KEYDOWN(keyboard, DIK_1))
  MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

// Обработка клавиши < 2 >
// Возвращаем в исходное состояние
if (KEYDOWN(keyboard, DIK_2))
   MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

// Обработка клавиши < 3 >
// Изменяем окружающие освещенние на синий цвет
if (KEYDOWN(keyboard, DIK_3))
   MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

    // Обработка клавиши < 4 >
// Изменяем окружающие освещенние на красный цвет
if (KEYDOWN(keyboard, DIK_4))
   MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);
}
return true;
}

// Функция синхронизации перемещения камеры по прошедшему с прошлого кадра времени (timeDelta)
void EnterMsgLoop (bool (*ptr_display)(float timeDelta))
{
MSG msg;
ZeroMemory(&msg, sizeof(msg));

static float lastTime = (float)timeGetTime();

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
        {
float currTime  = (float)timeGetTime();
float timeDelta = (currTime - lastTime)*0.001f;

ptr_display(timeDelta);
lastTime = currTime;

RenderingDirect3D();
}
    }
}

// Функция инициализация DirectInput
bool InitDirectInput(void)
{   
    // Создание интерфейс устройства
    if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL)))
        return false;

    // Создание устройства клавиатуры
    if (FAILED(pInput->CreateDevice(GUID_SysKeyboard, &pInputDevice, NULL)))
    {
        DeleteDirectInput();
        return false;
    }

    // Установка формата данных клавиатуры
if (FAILED(pInputDevice->SetDataFormat(&c_dfDIKeyboard)))
    {
        DeleteDirectInput();
        return false;
    }
    // Установка уровня взаимодействия клавиатуры (совместный доступ)
    if (FAILED(pInputDevice->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE)))
    {
        DeleteDirectInput();
        return false;
    }

    // Захват доступа к клавиатуре (активизировать управление)
    if (FAILED(pInputDevice->Acquire()))
    {
        DeleteDirectInput();
        return false;
    }

    // Полученние данных с клавиатуры
    if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
    {
        DeleteDirectInput();
        return false;
    }
    return true;
}

// Функция освобождает захваченные ресурсы DeleteInput
void DeleteDirectInput(void)
{
    if (pInput)
    {
        if (pInputDevice)
        {
           if (pInputDevice != NULL)
              pInputDevice->Unacquire();

           if (pInputDevice != NULL)
              pInputDevice->Release();
           pInputDevice = NULL;
        }
        if (pInput != NULL)
           pInput->Release();
        pInput = NULL;
    }
}     

Почему же перестали вообще кнопки определятся "1", "2", "3", "4"?

Для лучшего понимания привожу полный код.

* di2.rar (44.07 Кб - загружено 1096 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 12-09-2009 15:13 » 

в причине не разбирался, немного некогда...
но в глаза бросается следующее:

Код:
		if (KEYDOWN(keyboard, DIK_1))
  MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

после подстановки твоего макроса будет
Код:
		if (KEYDOWN(keyboard, DIK_1))
if ((keyboard[DIK_1] &0x80)))
  MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

наверное, выражение  keyboard[DIK_1] &0x80 у тебя всегда == 0

кстати, макрос советую переделать так (а лучше вообще не использовать тут макрос Улыбаюсь )

Код:
enum
{
   e_keys_count=256
};

char keyboard[e_keys_count];

#define KEYDOWN(name, key) (name[ (key<e_keys_count) ? key : 0 ] &0x80)
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #19 : 12-09-2009 16:57 » 

Алексей1153++

Учёл твои рекомендации и сделал так.

В место макроса сделал

Код:
// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(char KeyCode)
{
if (keyboard[KeyCode] & 0x80)
  return true;
else
  return false;
}

И изменил функцию bool EnterKey(float timeDelta)

Код:
// Функция обработки нажатия клавиш  
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
 TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
 TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
 TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
 TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
 TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
                      TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
 TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
 TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
 TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
 TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
 TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
 TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
// Изменяем окружающие освещенние на зеленный цвет
if (isKeyDown(DIK_1))
 MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

// Обработка клавиши < 2 >
// Возвращаем в исходное состояние
if (isKeyDown(DIK_2))
 MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

// Обработка клавиши < 3 >
// Изменяем окружающие освещенние на синий цвет
if (isKeyDown(DIK_3))
 MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

   // Обработка клавиши < 4 >
// Изменяем окружающие освещенние на красный цвет
if (isKeyDown(DIK_4))
 MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);
}
return true;
}

Результат пока тот же, кнопки определятся "1", "2", "3", "4".

* di2_1.rar (43.94 Кб - загружено 1100 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 12-09-2009 17:01 » 

я, как ни силился, не увидел нечто, подобное
Код:
GetAsyncKeyState('1')

.

А если твой массив - это буфер, в котором где то накапливаются флаги нажатых клавиш, то , значит, проверяй, как этот массив заполняется
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #21 : 12-09-2009 17:52 » 

Цитата: Алексей1153++
А если твой массив - это буфер, в котором где то накапливаются флаги нажатых клавиш, то , значит, проверяй, как этот массив заполняется.

Я воспользовался твоим советом, но решил начать проверять ещё глубже, а именно создаётся ли устройство DirectInput

У меня было так:

Код:
// Функция инициализация DirectInput
bool InitDirectInput(void)
{   
    // Создание интерфейс устройства
    if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL)))
       return false;
    ...
    ...
    ...
}

А стало так:

Код:
// Функция инициализация DirectInput
bool InitDirectInput(void)
{   
    // Создание интерфейс устройства
    if (FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&pInput, NULL)))
   {
      MessageBox(NULL, "Ошибка", "Сообщение", MB_OK);
      return false;
   }
   else
     MessageBox(NULL, "Успех", "Сообщение", MB_OK);
   ...
   ...
   ...
}

В результате было выясненно, что устройство DirectInput, не создаётся.

Интересно почему?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 12-09-2009 17:56 » 

откуда берёшь hInstance ?

В мсдн в примере делают так
GetModuleHandle(0)
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #23 : 12-09-2009 18:13 » 

Алексей1153++

Прошу прощения это я накосячил.

У меня было так

Код:

// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    // Инициализация DirectInput
    InitDirectInput();

    WNDCLASSEX windowsclass;
    hInstance = hInst;

    windowsclass.cbSize = sizeof(WNDCLASSEX);
    windowsclass.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
    windowsclass.lpfnWndProc = MainWinProc;
    windowsclass.cbClsExtra = 0;
    windowsclass.cbWndExtra = 0;
    windowsclass.hInstance = hInst;
    windowsclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    windowsclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowsclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    windowsclass.lpszMenuName = NULL;
    windowsclass.lpszClassName = "WINDOWSCLASS";
    windowsclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&windowsclass))
        return 0;

    hwnd = CreateWindowEx(NULL, "WINDOWSCLASS", "Загрузка Х-файла с вращением и камерой", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;
    ...
    ...
    ...
}

А нужно было так

Код:
// Функция которая является входной точкой приложения
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow)
{
    WNDCLASSEX windowsclass;
    hInstance = hInst;

    windowsclass.cbSize = sizeof(WNDCLASSEX);
    windowsclass.style = CS_DBLCLKS|CS_OWNDC|CS_HREDRAW|CS_VREDRAW;
    windowsclass.lpfnWndProc = MainWinProc;
    windowsclass.cbClsExtra = 0;
    windowsclass.cbWndExtra = 0;
    windowsclass.hInstance = hInst;
    windowsclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    windowsclass.hCursor = LoadCursor(NULL, IDC_ARROW);
    windowsclass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    windowsclass.lpszMenuName = NULL;
    windowsclass.lpszClassName = "WINDOWSCLASS";
    windowsclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

    if (!RegisterClassEx(&windowsclass))
        return 0;

    hwnd = CreateWindowEx(NULL, "WINDOWSCLASS", "Загрузка Х-файла с вращением и камерой", WS_OVERLAPPEDWINDOW|WS_VISIBLE,
        0, 0, 770, 500, NULL, NULL, hInst, NULL);
    if (!hwnd)
        return 0;

    // Инициализация DirectInput
    InitDirectInput();
    ...
    ...
    ...
}

Но  кнопки "1", "2", "3", "4" пока не определятся. Буду дальше думать.
Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #24 : 12-09-2009 19:28 » 

Выяснил что этот код

Код:
// Получения данных с клавиатуры
if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
{
   DeleteDirectInput();
   return false;
}

Работает только при запуске программы, а потом нет, а надо что бы этот код находился постоянно в работе.

Сейчас думаю куда его нужно перенести, может кто посоветует куда его правельно перенести?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #25 : 13-09-2009 02:40 » 

а как понять "этот код работает" ? Улыбаюсь То есть, он выполняется и просиходит вызов

   DeleteDirectInput();

а тогда, я так понимаю, снова надо вызывать

   InitDirectInput();

Точно ничего посоветвать не могу - нет опыта работы с Улыбаюсь

Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #26 : 13-09-2009 09:16 » 

Я разобрался надо код

Код:
// Получения данных с клавиатуры
if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
{
   DeleteDirectInput();
   return false;
}

Перенести в функцию bool isKeyDown(char KeyCode) и вот что получилось

Код:
// Функция определения нажатой клавиши на клавиатуре
bool isKeyDown(char KeyCode)
{
   // Полученние данных с клавиатуры
    if (FAILED(pInputDevice->GetDeviceState(sizeof(keyboard),(LPVOID)&keyboard)))
    {
        DeleteDirectInput();
        return false;
    }

    if (keyboard[KeyCode] & 0x80)
      return true;
    else
      return false;
}

Кнопки "1", "2", "3", "4" стали определятся!!!

Но почему-то после того как кнопка определилась выскакивает ошибка

---------------------------
Загрузка Х-файла с вращением и камерой: di2.exe - Ошибка приложения
---------------------------
Инструкция по адресу "0x00402349" обратилась к памяти по адресу "0x00000000". Память не может быть "read".


"ОК" -- завершение приложения
"Отмена" -- отладка приложения
---------------------------
ОК   Отмена   
---------------------------

Интересно почему и как избавится?

* di2_2.rar (43.96 Кб - загружено 1023 раз.)
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #27 : 13-09-2009 16:04 » 

волшебное средство - отладчик Улыбаюсь Особенно при таких вкусных ошибках, как обращение по нулевому указателю.
Где то не заполнен указатель
Записан

zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #28 : 13-09-2009 19:38 » 

Алексей1153++

Я попытался проанализировать код пока без отладчика.

Вот мои рассуждения маленькие:

1. Без DirectInput X-файл прекрасно загружается;
2. Код относящийся к загрузки X-файл не трогал;
3. Значит дело в коде который относится к DirectInput.

И что же получилось я в место кода (если оставить этот код, то получается ошибка которую я описал в прошлом своём посте)

Код:
// Функция обработки нажатия клавиш  
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
 TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
 TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
 TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
 TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
 TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
 TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
 TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
 TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
 TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
 TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
 TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
 TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
if (isKeyDown(DIK_1))
 MessageBox(NULL, "Нажата клавиша 1", "Сообщение", MB_OK);

// Обработка клавиши < 2 >
if (isKeyDown(DIK_2))
 MessageBox(NULL, "Нажата клавиша 2", "Сообщение", MB_OK);

// Обработка клавиши < 3 >
if (isKeyDown(DIK_3))
 MessageBox(NULL, "Нажата клавиша 3", "Сообщение", MB_OK);

   // Обработка клавиши < 4 >
if (isKeyDown(DIK_4))
 MessageBox(NULL, "Нажата клавиша 4", "Сообщение", MB_OK);*/
}
return true;
}

Написал код (тогда программа работает без ошибок)

Код:
// Функция обработки нажатия клавиш  
bool EnterKey(float timeDelta)
{
if(pDirect3DDevice)
{
if (GetAsyncKeyState('W') & 0x8000f)
 TheCamera.FirstBack(4.0f * timeDelta);

if (GetAsyncKeyState('S') & 0x8000f)
 TheCamera.FirstBack(-4.0f * timeDelta);

if (GetAsyncKeyState('A') & 0x8000f)
 TheCamera.LeftRight(-4.0f * timeDelta);

if (GetAsyncKeyState('D') & 0x8000f)
 TheCamera.LeftRight(4.0f * timeDelta);

if (GetAsyncKeyState('R') & 0x8000f)
 TheCamera.UpDown(4.0f * timeDelta);

if (GetAsyncKeyState('F') & 0x8000f)
 TheCamera.UpDown(-4.0f * timeDelta);

if (GetAsyncKeyState(VK_UP) & 0x8000f)
 TheCamera.RollRightVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_DOWN) & 0x8000f)
 TheCamera.RollRightVector(-1.0f * timeDelta);

if (GetAsyncKeyState(VK_LEFT) & 0x8000f)
 TheCamera.RollUpVector(1.0f * timeDelta);

if (GetAsyncKeyState(VK_RIGHT) & 0x8000f)
 TheCamera.RollUpVector(-1.0f * timeDelta);

if (GetAsyncKeyState('N') & 0x8000f)
 TheCamera.RollFirstVector(1.0f * timeDelta);

if (GetAsyncKeyState('M') & 0x8000f)
 TheCamera.RollFirstVector(-1.0f * timeDelta);

// Обработка клавиши < 1 >
if (isKeyDown(DIK_1))
 TheCamera.FirstBack(-4.0f * timeDelta);
}
return true;
}

В принципе я уже проверил, что у меня кнопки определяются при не буферизированном вводе с помощью DirectInput.

Но мне всё равно интересно почему при выводе окна сообщения программа слетает. Может кто знает поясните пожалуйста?
« Последнее редактирование: 14-09-2009 23:43 от zuze » Записан
zuze
Опытный

ru
Offline Offline
Пол: Мужской
Россия, Москва


« Ответ #29 : 15-09-2009 00:06 » 

На счёт ошибки "обращение по нулевому указателю" пока не получилось разобраться придётся воспользоваться отладчиком.
Эта функция, где я использую MessageBox, возвращает значение true и используется в моём коде в качестве параметра другой функции.

В связи с этим у меня появился маленький вопрос:
Если функция возвращает значение, а следовательно используется в качестве параметра другой функции, можно ли в ней делать MessageBox, если нельзя то и отлаживать не имеет смысла всё равно ничего не получится?

Ещё один маленький вопрос:
Как проверить правильно ли я сделал DirectInput с буферным вводом?

То есть при нажатии на "1" или на "s", но "s" отпадает так как сделана с помощью WinAPI.
Значит при нажатии на "1" определённое количество раз появляется mesh на экране. При буферизированном вводе он появится быстрее.

Если да, то я так проверю работает у меня буферизированный ввод или нет, если нет то как тогда проверить что буферизированный ввод работает?

« Последнее редактирование: 15-09-2009 01:02 от zuze » Записан
Страниц: [1] 2 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines