IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   граффика в С++ (https://www.imho.ws/showthread.php?t=97445)

ЛеднеFF 17.12.2005 22:43

граффика в С++
 
есть microsoft visual C++

как в консольном приложении нарисовать точку(и) или линии?

ну по аналогии с бэйсиком (screen 2 : pset (x,y) цвет)

ну ни где не могу найти :idontnow:

Trotil 17.12.2005 22:49

Цитата:

ЛеднеFF:
COLORREF SetPixel (HDC,x,y, color )
Это функция из Win API, и для консольных приложений просто так применять нельзя. Нужно преварительно получить хендл и контекст устройства.
Код:

#include "stdafx.h"
#include "windows.h"
using namespace std;

BOOL CALLBACK EnumWndProc(HWND hwnd, LPARAM lParam)
{
  if(GetWindowThreadProcessId(hwnd, NULL) == GetCurrentThreadId())
  {
      *(HWND*)lParam = hwnd;
      return FALSE;
  }

  return TRUE;
}

int main(int argc, _TCHAR* argv[])
{
  HWND hWnd;
  HDC hDc;
  EnumWindows(EnumWndProc, (LPARAM)&hWnd);
  hDc = GetDC(hWnd);
  for (int i=20; i<100; i++)

  ::SetPixel(hDc,i,i,RGB(255,0,0));
  getchar();
        return 0;

}

Если у Вас MS VS 6.0, закомментируйте строку
Код:

using namespace std;
По идее должно работать и выводить наклонную красную черту.

Цитата:

ЛеднеFF:
особенно касающиеся какого там HDC
Это контекст устройства, получаемого через хендл, для выполнения опеpаций интеpфейса GDI, куда вы хотите вывести данный пиксель.
Хендл - говоря простым языком, описатетель или идентификатор объекта. Под объектом может подразумеваться все что угодно. (окно, кнопка, даже устройство). При этом гарантируется, что все хендлы (handle) в пределах одного процесса(?) будут уникальны.

ЛеднеFF 17.12.2005 23:01

не находит <stdafx.h>

Trotil 17.12.2005 23:05

Цитата:

ЛеднеFF:
не находит <stdafx.h>
Странно. Убери его тогда. ( + надо убрать getchar() )

Получилось?

ЛеднеFF 17.12.2005 23:08

error C2061: syntax error : identifier '_TCHAR'

Trotil 17.12.2005 23:11

int main(int argc, _TCHAR* argv[]) замени на int main(int argc, char* argv[]) или на int main(void)

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

Правда у меня MS VS 2003 .Net и MS VS 2005 .Net. 6-ую версию удалил год назад и возвращаться не собираюсь...
Но данный код по идее корректно должен работать и в 6-ой версии, с учетом небольшой корректировки.

ЛеднеFF 17.12.2005 23:20

откомпилировал, единственное что появилось это

press any key to continue на черном экране

PVitaliy 17.12.2005 23:53

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

Trotil 18.12.2005 00:01

Цитата:

PVitaliy:
И хоть теоретически это возможно, (найти окно, найти его девайсконтекст, и потом рисовать),
Да я так и сделал... :biggrin:
Цитата:

PVitaliy:
я всеже думаю что лучше не извращатся,
По-другому не получится, увы...

ЛеднеFF 18.12.2005 00:16

MSDN это куча каких то несвязанных данных (да еще на техническом английском) и найти там можно только то что знаешь и знаешь где искать, а я только начал врубаться что такое СИ++ и для обучения хочу написать прогу взаимодействия трех тел в пространстве- если как писать я знаю, то как выводить рисунок движения тел незнаю, в литературе (учебниках) даже простейшие вещи (возведение в степень, перехват символа с клавиатуры без ожидания ?, точность расчета - ну что б не округлял значения) неуказаны, а уж консоли не консоли это вообще :confused:

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

PVitaliy 18.12.2005 06:15

Я постоянно использую MSDN, там есть все, хотя периодически микрософт недоговаривает.
Игры пишутся с использованием библиотек ДиректХ, которые позволяют рисовать 3хмерную графику быстро на экране.
А програмирование имхо изучать надо начинать всеже с програмирования под виндовс: как кнопку вывести, как обработчик прикрутить, как меню создать, как с клавиатурой работать. Потом можно двинутся в сторону ДиректХ, и програмировать 3хмерную графику, или писать юзеринтерфейсы при помощи винконтролов, это уже кому чего больше нравится.

Trotil 18.12.2005 12:33

перехват символа с клавиатуры без ожидания
Это противоречит логике программирования ДОС-овских приложений, однако это как раз очень просто делается с помощью методов программирования под Windows (в этом и состоит одно из преимуществ Windows)
Но код приводить или что-либо объяснять - долго и наверняка ничего не поймешь. (надо прочитать про события, обработчики событий(в случае MFC) или про функцию окна)
ИМХО, ты сейчас бежишь впереди паравоза и достаточно далеко убежал. Не надо спешить. Ты сейчас хочешь сразу понять такие вещи, которые не так просты для понимания, как поначалу кажется.

Ты читал мой пост в ебуках относительно книг по VS? Какой книгой ты пользуешься? Какие цели ты преследуешь при изучении VS? Чего ты хочешь добиться в программировании? Какой уровень программирования на данный момент?

Надо ответить на эти вопросы, тогда здешние знающие люди могут подсказать оптимательное решение, путь к изучению...

А тем путем, которым пошел ты - естественно, преграды и непонимание будет встречаться на каждом пути...

ЛеднеFF 22.12.2005 14:53

Я тут немного разобрался как в Visual C++ писать проги и задавать события кнопкам, так вот вопрос:

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

И второй вопрос, при создании нового всплывающего диалогового окна код программы находится отдельно и эта часть программы не видит переменные предыдущего окна (ни глобальные ни другие), как их передать из предыдущего окна в текущее..... :confused:

SapeR 22.12.2005 16:51

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

не видит переменные предыдущего окна (ни глобальные ни другие), как их передать из предыдущего окна в текущее
допустим у меня есть родительское окно MyWnd и дочернее MyDlg и переменная родительского окна int MyWnd.m_Test . тогда я создаю в дочернем аналог данной переменной (вариант А) и копирую значение непосредственно перед показом окна. или поинтер на оригинальную переменную (вариант Б - уже немного наглость)

вариант А
определение
class MyDlg : CDialog { ...
int m_MyParentTest;
создание
MyDlg d1;
d1.m_MyParentTest = m_Test
использование
d1.DoModal()
... int x = m_MyParentTest
вариант Б
определение
class MyDlg : CDialog { ...
int* m_pMyParentTest;
создание
MyDlg d1;
d1.m_pMyParentTest = & m_Test;
использование
m_pMyParentTest = 10; // m_Test тоже меняется

ЛеднеFF 22.12.2005 17:38

Цитата:

Сообщение от SapeR
запускается моя прога - создавай новый поток, у тебя останется указатель на него, поток побежит параллельно основной программе, сможешь остановить когда угодно
[

Это в смысле ,создаем функцию отдельно, а в месте программы где идет реакция на нажатие кнопки вызываем эту функцию...да?

....что то не получается, нельзя ли то же пример :eek:

Drakosha 22.12.2005 21:38

про потоки:
http://ru.wikipedia.org/wiki/%D0%9C%...81%D1%82%D1%8C
http://en.wikipedia.org/wiki/Thread_...ter_science%29

PVitaliy 22.12.2005 23:26

Не, потоки тут по моему немного неправильно. Поток разве для того чтобы данные для прорисовки подготовить, и то это не та тема, которую нужно разбирать начинающему. А рисование должно быть типа как покадровым и конечным (не в вечном цикле), т.е. алгоритм перерисовывает весь экран, и заканчивается. И по таймеру вызывается вновь.

ЛеднеFF 24.12.2005 23:31

в Бэйсике есть обычная функция INKEY$ которая контролирует нажата ли какая нибудь клавиша, если нажата то сверяем не равна ли она нужной клавише, если не равна то повторяем цикл снова и так до тех пор пока не нажмем к примеру ESC. Так вот в С++ должно быть примерно также по моему?
а по поводу вечного цикла: представьте себе три тела в пространстве с начальными скоростями, моя программа ститает их взаимодействие с определенным заданным шагом по времени и отображает их положение на экране и все это отображается и считается пока мне не надоест и я не нажму кнопку Стоп. Так вот как это сделать....?

Trotil 25.12.2005 00:51

Еще раз хочу уточнить: какое приложение вы хотите создать? А то сначала речь шла о консольном приложении, теперь появились кнопка "Стоп"... :confused:

ЛеднеFF 25.12.2005 02:38

Про консольные я уже забыл :p , теперь речь идет о диалоговых окнах.
Создал окно для ввода параметров, потом после нажатия кнопки старт всплывает следующее окно на котором рисуется траектория движения тел, а так как летать они могут долго (несколько миллиардов лет :biggrin: ) то когда я хочу остановить это, то на окне есть кнопочка Стоп, но так как моя прога работает в бесконечном цикле, при нажатии на Стоп все зависает(в смысле программма), а если нарисовать только один цикл, то что бы тела летали и дальше нужно очень часто и ооочень быстро давить на кнопку Старт (шутка)..... так вот что бы этого не произошло я так понимаю в цикл нужно вставить функцию проверки нажатий на кноппочки и если они нажаты то все можно идти спать.... Только не знаю что это за функция :молись:

Или к примеру есть игра стреллялка (Квакер к примеру) там мужик ходит в разные стороны при нажатии соответствующих клавиш а коли не нажаты клавиши, то игра все равно не останавливается а просто живет своей жизнью и ждет нажатий на ктопки (она собственно тоже работает в "бесконечном" цикле)

AGoncharov 25.12.2005 07:19

Цитата:

ЛеднеFF:
Только не знаю что это за функция
Есть такая функция _kbhit() из conio.h:
Цитата:

_kbhit returns a nonzero value if a key has been pressed. Otherwise, it returns 0.
Так вот эта функция просто проверяет, было ли что-то нажато или нет. Если было, то она возвращает не 0. Если она вернула не 0, то можно пользоваться _getch() для получения нажатого символа, тогда ожидания ввода не будет.. НО, если нажата функцональная клавиша (F1-F12, стрелки, Home, End, ...), то надо вызывать _getch() два раза - первый раз получаем 0 или 0xE0, а второй раз символ..
Чтобы узнать цифровые значения функциональных клавиш - пишем простенькую программку - нажимаем и записываем в тетрадочку :) .
Чтобы программа не съедала 100% ресурсов процессора, сдобриваем код вызовами Sleep(0) .

P.S. Эх, как мало осталось людей, которые программировали под MS-DOS :rolleyes:

SapeR 25.12.2005 17:31

Цитата:

как моя прога работает в бесконечном цикле, при нажатии на Стоп все зависает
создай такую функцию
Код:

void WaitForEvents()
{
    MSG msg;
    while (::PeekMessage(&msg,NULL,0,0,PM_REMOVE))
    {   
        ::TranslateMessage(&msg);
        ::DispatchMessage(&msg);
    }
}

и вставь её выполнение в твой бесконечный цикл - обеспечит приостановку выполнения цыкла на время обработки нажатых клавиш. учти - потом побежит дальше ! я обычно сразу после неё проверяю а не пора ли вапче выходить из цыкла по причине отсутствия материнского окна :)

Цитата:

там мужик ходит в разные стороны при нажатии соответствующих клавиш а коли не нажаты клавиши, то игра все равно не останавливается
он ходит по таймеру, используя заранее заданный курс, а курс меняется согласно нажатым кнопкам, только никто не ждёт нажатия, у окна настроенна функция OnChar - срабатывает именно при нажатии кнопки, корректируем курс и побежали дальше. а если охота узнать между делом нажата ли конкретная кнопка - спрашиваем через GetAsyncKeyState

Цитата:

Эх, как мало осталось людей, которые программировали под MS-DOS
Нас не мало - мы просто хорошо маскируемся :)

ЛеднеFF 27.12.2005 16:12

При закрашивании окна точками в цикле по оси Х и по оси Y операторами

CClientDC dc(this);
for y....
for x.....
dc.SetPixel(X,Y,RGB(1,1,1));

все это дело проиходит достаточно медленно, а как можно все это ускорить, ведь при построении динамической трехмерной сцены каждый кадр рисуется путем вывода каждой точки на экран да еще плюс просчитывается вся сцена и происходит это куда быстрее. Приведенный выше алгоритм закрашивает область 800х600 точек около 1,5-2 сек это просто ни куда не годится.... :confused:

SapeR 27.12.2005 22:17

конечно ни в какие ворота не лезет - по точкам к экрану носить
учитывая что у тебя всё одним цветом - создай браш твоего цвета и используй dc.Rectangle(0,0,800,600)
даже если будут разные цвета - создай битмап в памяти и "натяни" его битблитом на dc - дешевле по времени выходит

AGoncharov 28.12.2005 00:11

Цитата:

Сообщение от ЛеднеFF
все это дело проиходит достаточно медленно, а как можно все это ускорить :confused:

Я бы даже советовал вообще сначала рисовать динамические картинки в памяти на Bitmap, а потом копировать ее в context окна без масштабирования - я так делал еще на i80386 проце и всё летало.

ЛеднеFF 28.12.2005 12:06

а как это делается?


Часовой пояс GMT +4, время: 07:20.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.