srg91

OGLHook [Плагин для использования OpenGL]

12 сообщений в этой теме

OGLHook v0.0.1

 

Добавляет возможность использовать функции библиотеки OPENG32.DLL и рисовать на экране игры (например как в этой теме).

Игра должна иметь подключенную библиотеку OPENG32.DLL.

 

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

 

Ссылка на скачивание: 

 

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

 

Небольшое описание:

Spoiler

Дабы копирайты были соблюдены (да и мне было не слишком париться), код прикрепления и вывод glOrtho был взят со stackoverflow.

Разрабатывался для Cheat Engine 6.6.

 

Плагин умеет:

  • Вызывать функции подключенной OPENGL32.DLL, такие как OPENGL32.glColor3f(1.0, 0, 0) и т. д.;
  • Использовать константы OpenGL по типу OPENGL32.GL_MODELVIEW;
  • Автоматически встраивает glOrtho поверх игры и позволяет быстро рисовать.

 

Не умеет:

  • Поддержка неопределенного количества функций (проверял на нескольких всего);
  • Содержит мало констант (возможно их можно выдирать из памяти, но если я правильно помню компилятором они заменяются на адреса памяти);
  • Не умеет получать размер окна, чтобы передавать в glOrtho;
  • Наверное много чего не умеет, напишите здесь свой вариант.

 

Будем развиваться (или найденные баги):

  • собственно весь код (не знаток Lua от слова совсем, будем развивать направление);
  • нужно больше констант;
  • думаю подключать GLU32.DLL;
  • вынести glOrtho в опционал, чтобы можно было инициализировать как хочешь;
  • вылетает на мелких программах, по типу KnowHowToDrawWithOpenGLLesson1.exe (но в играх или wglgears.exe)
    • собственно обсудив со SnedS91 думаем, что правильно ставить бряк и после инжектиться;
  • очень плохо взаимодействую с символами и памятью, нужно будет вкрячить правильные деструкторы и корректно перегружаться;
  • очень топорно затираю старые инструкции, нужно будет переиспользовать старый код (сейчас, например, счетчик FPS от Steam отваливается);
  • собственно тут тоже можете добавить свои варианты :).

 

Скриншоты:

  • TrainMe от Xipho  (спасибо посту и самому Xipho)
  • Spoiler

    DGftmUX.png

     

  • игра PapersPlease от Lucase Pope (спасибо Lucase Pope)
  • Spoiler

    bgMQJme.png

     

Пример вызова функции и использования констант:

OPENGL32.glColor3f(1.0, 0, 0)
OPENGL32.glMatrixMode(OPENGL32.GL_PROJECTION)

"Быстрый" пример использования в полевых условиях:

Spoiler

Вставляем код ниже в любой плагин (соответственно можно даже и в этот), загружаем CE, открываем игру.

Должны увидеть красный квадрат как на скриншотах :)


function TestDraw()
	OPENGL32.glColor3f(1.0, 0, 0)
	OPENGL32.glBegin(OPENGL32.GL_QUADS)
		OPENGL32.glVertex2f(0, 190)
		OPENGL32.glVertex2f(100, 190)
		OPENGL32.glVertex2f(100, 290)
		OPENGL32.glVertex2f(0, 290)
	OPENGL32.glEnd()
end

function onHotKey(pid)
	if process == nil or process == '' then
		openProcess(getForegroundProcess())
	end

	glHook = OGLHook_Create({0, 0, 640, 480})

	if type(glHook) == 'table' then
		glHook:registerUpdateFunc(TestDraw)
		glHook.update()
	end
end

 

 

Огромное спасибо SnedS91 за напоминание о том, что кодить на досуге можно и нужно, подсказки "не в бровь, а в глаз" по LUA и CE, main.lua, да и вообще хороший парень.

Собственно для его проекта я надеюсь и будет использована библиотека.

 

 

Изменено пользователем srg91
3

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Ребят, сколько  пост перечитывал, ошибок не заметил.

Но они конечно же есть.  Пост поправить не получается. поэтому напишу отдельным комментом.

 

В быстром примере не скопирался хоткей, полный код ниже.

Собственно и не указал как использовать: зайти в игру и нажать Ctrl+Insert.
Код аттачится к игре и рисует красный прямоугольник:

Spoiler

function TestDraw()
	OPENGL32.glColor3f(1.0, 0, 0)
	OPENGL32.glBegin(OPENGL32.GL_QUADS)
		OPENGL32.glVertex2f(0, 190)
		OPENGL32.glVertex2f(100, 190)
		OPENGL32.glVertex2f(100, 290)
		OPENGL32.glVertex2f(0, 290)
	OPENGL32.glEnd()
end

function onHotKey(pid)
	if process == nil or process == '' then
		openProcess(getForegroundProcess())
	end

	glHook = OGLHook_Create({0, 0, 640, 480})

	if type(glHook) == 'table' then
		glHook:registerUpdateFunc(TestDraw)
		glHook.update()
	end
end

createHotkey(onHotKey,VK_INSERT,VK_CONTROL)

 

 

И совсем забыл упомянуть про возвращаемые значения.

Если, например, нужно выполнить функцию и получить результат её работы, то можно указать просто передать регистр.

Функция запишет в него значение, после выполнения.

 

Указывается как аргумент вызываемой функции, после текстового аргумента ->.

Пример (записываем результат wglCreateContext в регистр oglh_context:

OPENGL32.wglCreateContext('[oglh_window_hdc]', '->', 'oglh_context')

Регистр соответственно должен быть аллоцирован и зарегистрирован как символ ранее.

Изменено пользователем srg91
1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

OGLHook v0.0.2

 

Ссылка на скачивание: 

Список изменений:

Spoiler
  • Добавлена возможность хука на лету или через breakpoint:
    • в OGLHook:init() добавлен параметр hot_attach (default = false);
    • при инициализации с hot_attach = true идет мгновенное встраивание в игру на лету, что не всегда стабильно, но не использует дебаггер;
    • при инициализации с hot_attach = false идет установка бряка на wglSwapBuffers и при его срабатывании выполняется инициализация. Это повышает стабильность, но требует подключение дебаггера.
  • Добавил небольшой деструктор - метод OGLHook:destory(), который очищает используемые регистры и символы:
    • вызывается в методе OGLHook:init() при пересоздании (если OGLHook уже создавался).
  • Сохраняются оригинальные опкоды:
    • теперь при запуске Steam игры, Cheat Engine и Fraps все три хука работают корректно
    Spoiler

    lbSVyDV.png

  • Размер области отрисовки растянут на всю игру

  • Добавлено больше констант OPENGL32 и константы GLU32

  • Небольшие фиксы

 

Пока изменения минимальны, поэтому почти без скриншотов.

 

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Небольшой анонс версии v0.0.3:

Spoiler

 

Вывел через Cheat Engine 3D куб из Lesson 06 Nehe поверх интерфейса в Counter-Strike 1.6.

Изменено пользователем srg91
3

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

OGL Hook v0.0.3

 

Ссылка на скачивание:

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

В целом код сейчас довольно разбит и не структурирован. Работаю над этим.

 

Список изменений:

Spoiler
  • Перенес все файлы в одну папку - OGLHook, наружу торчит только OGLHook.lua
  • Разделил главный файл на несколько и добавил простые неймспейсы (по типу OGLHook_Textures.LoadTexutre) (в процессе)
  • Добавил загрузку текстур через Windows Imaging Component (подробнее ниже), но в целом всё удалось свести к команде:
    • OGLHook_Textures.LoadTexutre([[D:\pictures\crosschair.png]], 'texture1')
  • Вынес инициализацию glOrtho в функции OGLHook_SimpleOrtho и OGLHook_SimplePerspective, которые можно вызвать при инициализации
  • Добавил функцию инициализации, которую может задать пользователь
  • Начал добавлять типы ошибок, но это слишком сильно увеличивает и запутывает код, поэтому пока приостановил данное действие

 

Фотоотчет:

Spoiler

Несколько типов загружаемых текстур:

Spoiler

Nltp8NS.jpg

 

Кастомный прицел:

Spoiler

576Ga7I.png

 

Spoiler

mpuYEMo.png

 

 

Подробнее о текстурах:

Spoiler

Пытался найти хороший универсальный способ загрузки изображений с поддержкой PNG и других. С наскоку не нашел решения, попробовал грузить через LoadImage (собственно видео из предыдущего поста - это его работа). Но LoadImage работает только с BMP и это удручило. Тащить за собой библиотеки по типу libpng и других еще больше удручило. GDI+ отмел по тем же причинам. Но потом наткнулся на Windows Imaging Component, который фактически подключается через InjectDLL('windowscodecs.dll'), которая лежит практически в каждой папке Windows\System32 (не уверен в этом).

 

Это был уникальный опыт... В общем и целом удалось превратить в набор ассемблерных команд код по ссылке. Огромное спасибо автору. Получившийся код приложу ниже, вдруг кому-то еще придется столкнуться :)

Прогонял на Windows 10 и Windows 7 грузит удачно основные типы изображений. По идее поддерживаются PNG, JPEG, BMP, ICO, GIF, TIFF, DDS. Но протестировал только на PNG, JPEG, BMP.  Причем само изображение загружается с помощью CE, поэтому не должно быть проблем связанных с поиском изображения на диске.

 

Огромное спасибо SnedS91 за поддержку :)

 

Пример использования с текстурами:

Spoiler

Выделяем игру, нажимаем Ctrl+Insert и код инжектится в игру.

Выводит на экран несколько изображений.


require([[autorun\OGLHook]])
require([[autorun\OGLHook\OGLHook_Commands]])
require([[autorun\OGLHook\OGLHook_Textures]])

function initOGLHook()
	OGLHook_SimpleOrtho()

	OGLHook_Textures.LoadTexutre([[D:\pictures\test_png.png]], 'texture1')
	OGLHook_Textures.LoadTexutre([[D:\pictures\test_jpg.jpg]], 'texture2')
	OGLHook_Textures.LoadTexutre([[D:\pictures\test_bmp.bmp]], 'texture3')
end


function TestDraw()
	OPENGL32.glEnable(OPENGL32.GL_BLEND);
	OPENGL32.glBlendFunc(OPENGL32.GL_SRC_ALPHA, OPENGL32.GL_ONE_MINUS_SRC_ALPHA);

	OPENGL32.glEnable(OPENGL32.GL_TEXTURE_2D)

	OPENGL32.glBindTexture(OPENGL32.GL_TEXTURE_2D, 'texture1')

	OPENGL32.glPushMatrix()

	OPENGL32.glTranslatef(700,100,0);

	OPENGL32.glBegin(OPENGL32.GL_QUADS)
	 	OPENGL32.glTexCoord2f(0, 0)
		OPENGL32.glVertex2f(0, 0)

	 	OPENGL32.glTexCoord2f(0, 1)
		OPENGL32.glVertex2f(0, 300)

	 	OPENGL32.glTexCoord2f(1, 1)
		OPENGL32.glVertex2f(300, 300)

	 	OPENGL32.glTexCoord2f(1, 0)
		OPENGL32.glVertex2f(300, 0)
	OPENGL32.glEnd()

	OPENGL32.glPopMatrix()

	OPENGL32.glBindTexture(OPENGL32.GL_TEXTURE_2D, 'texture2')

	OPENGL32.glPushMatrix()

	OPENGL32.glTranslatef(300,500,0);

	OPENGL32.glBegin(OPENGL32.GL_QUADS)
	 	OPENGL32.glTexCoord2f(0, 0)
		OPENGL32.glVertex2f(0, 0)

	 	OPENGL32.glTexCoord2f(0, 1)
		OPENGL32.glVertex2f(0, 180)

	 	OPENGL32.glTexCoord2f(1, 1)
		OPENGL32.glVertex2f(320, 180)

	 	OPENGL32.glTexCoord2f(1, 0)
		OPENGL32.glVertex2f(320, 0)
	OPENGL32.glEnd()

	OPENGL32.glPopMatrix()

	OPENGL32.glBindTexture(OPENGL32.GL_TEXTURE_2D, 'texture3')

	OPENGL32.glPushMatrix()

	OPENGL32.glTranslatef(200,200,0);

	OPENGL32.glBegin(OPENGL32.GL_QUADS)
	 	OPENGL32.glTexCoord2f(0, 0)
		OPENGL32.glVertex2f(0, 0)

	 	OPENGL32.glTexCoord2f(0, 1)
		OPENGL32.glVertex2f(0, 200)

	 	OPENGL32.glTexCoord2f(1, 1)
		OPENGL32.glVertex2f(267, 200)

	 	OPENGL32.glTexCoord2f(1, 0)
		OPENGL32.glVertex2f(267, 0)
	OPENGL32.glEnd()

	OPENGL32.glPopMatrix()

	OPENGL32.glDisable(OPENGL32.GL_TEXTURE_2D)
end

function onHotKey(pid)
	openProcess(getForegroundProcess())

	glHook = OGLHook_Create(true, initOGLHook)
	if type(glHook) ~= 'table' then
		ShowMessage('It is not OpenGL process')
		return
	end

	glHook:registerUpdateFunc(TestDraw)
	glHook:update()
end

createHotkey(onHotKey,VK_INSERT,VK_CONTROL)

 

 

Общий код загрузки изображения через Windows Image Component:

Spoiler

При инициализации спросит PNG изображение.

После требуется запустить через createthread(load_png_func)

 


{$lua}
function getAddressSilent(addr)
  local es = errorOnLookupFailure(false)
  local raddr = getAddress(addr) or 0
  errorOnLookupFailure(es)
  return raddr
end

if getAddressSilent('windowscodecs.dll') == 0 then
  if not injectDLL('windowscodecs.dll') then
    showMessage('Failed to load windowscodecs.dll')
  end
end

local m = createMemoryStream()
if not image_file_path then
   image_file_path = inputQuery('Open PNG', 'Enter the path to PNG file:', '')
end
m.loadFromFile(image_file_path)

local s = string.format([[
  globalalloc(%s, %d)
  globalalloc(source_png_size, 4)
]], 'source_png', m.size)
autoAssemble(s)

writeInteger(getAddress('source_png_size'), m.size)
writeBytes(getAddress('source_png'), m.read(m.size))

{$asm}

globalalloc(load_png_func, 16384)
globalalloc(png_pointer, 4)
globalalloc(png_data, 4)
globalalloc(stream_pointer, 4)
globalalloc(ip_decoder, 4)
globalalloc(ip_decoder_guid, 16)
//globalalloc(ip_decoder_sguid, 256)
globalalloc(CLSID_WICPngDecoder1, 16)
globalalloc(CLSID_WICPngDecoder2, 16)
globalalloc(OGLH_CLSID_WICBmpDecoder, 16)
globalalloc(GUID_WICPixelFormat32bppPBGRA, 16)
globalalloc(nFrameCount, 4)
globalalloc(ipFrame, 4)
globalalloc(ipBitmap, 4)
globalalloc(hbmp, 4)
globalalloc(bwidth, 4)
globalalloc(bheight, 4)
// 4+4+4+2+2+4+4+4+4+4+4= 40 = 0x28 + 4 = 0x2c
globalalloc(bitmapinfo, 44)
globalalloc(pvImageBits, 4)
// what is real size of hdc???
globalalloc(hdc_screen, 8)
globalalloc(cbStride, 4)
globalalloc(cbImage, 4)
globalalloc(img_ptr, 4)

label(fail_to_load)

CLSID_WICPngDecoder1:
dd 389ea17b
dw 5078
dw 4cde
db b6 ef 25 c1 51 75 c7 51

CLSID_WICPngDecoder2:
dd e018945b
dw aa86
dw 4008
db 9b d4 67 77 a1 e4 0c 11

OGLH_CLSID_WICBmpDecoder:
dd 6b462062
dw 7cbf
dw 400d
db 9f db 81 3d d1 0f 27 78

GUID_WICPixelFormat32bppPBGRA:
dd 6fddc324
dw 4e03
dw 4bfe
db b1 85 3d 77 76 8d c9 10

ip_decoder_guid:
//db F4 92 FC EF 89 71 3D 4E B1 C1 5A C9 10 20 27 D0
dd 9edde9e7
dw 8dee
dw 47ea
db 99 df e6 fa f2 ed 44 bf
//dd 0

// 4+4+4+2+2+4+4+4+4+4+4+4
bitmapinfo:
dd 0 0 0
dw 0 0
dd 0 0 0 0 0 0 0 0

//ip_decoder_sguid:
//db '9EDDE9E7-8DEE-47ea-99DF-E6FAF2ED44BF'

load_png_func:
push [source_png_size]
push 2
call GlobalAlloc
mov [png_pointer],eax

push [png_pointer]
call GlobalLock
mov [png_data],eax

push [source_png_size]
push source_png
push [png_data]
call memcpy
add esp,0C

push [png_pointer]
call GlobalUnlock
//push source_png
//pop [png_pointer]

// make stream from source_png
//mov eax,stream_pointer
//mov ebx,[source_png_size]

push [png_pointer]
call GlobalSize

push stream_pointer
push 1
push [png_pointer]
call combase.CreateStreamOnHGlobal

cmp eax,0
jne fail_to_load

//push ip_decoder_guid
//call combase.CoCreateGuid
//push ip_decoder_guid
//push ip_decoder_sguid
//call RtlGUIDFromString

//cmp eax,0
//jne fail_to_load


// как-то чекать, нужна ли инициализация?
// а то вызывать инициализацию по 100 раз подряд наверное не айс?
push 0
call ole32.CoInitialize

push ip_decoder
push ip_decoder_guid
push 1
push 0
//push CLSID_WICPngDecoder2
push CLSID_WICPngDecoder1
//push OGLH_CLSID_WICBmpDecoder
call combase.CoCreateInstance

cmp eax,0
jne fail_to_load

// Initialize
mov eax,[ip_decoder]
mov ecx,[eax]

push 1
push [stream_pointer]
push [ip_decoder]
call [ecx+10]

// GetFrameCount
mov eax,[ip_decoder]
mov ecx,[eax]

push nFrameCount
push [ip_decoder]
call [ecx+30]

cmp eax,0
jne fail_to_load

// Frames != 1 -> BAD!!
cmp [nFrameCount],1
jne fail_to_load

// GetFrame
mov eax,[ip_decoder]
mov ecx,[eax]

push ipFrame
push 0
push [ip_decoder]
call [ecx+34]

cmp eax,0
jne fail_to_load

// WICConvertBitmapSource
push ipBitmap
push [ipFrame]
push GUID_WICPixelFormat32bppPBGRA
call WICConvertBitmapSource

// ipFrame->Release
mov eax,[ipFrame]
mov ecx,[eax]

push [ipFrame]
call [ecx+08]

// ipFrame->Release
mov eax,[ip_decoder]
mov ecx,[eax]

push [ip_decoder]
call [ecx+08]

nop
nop
nop

// ipBitmap->GetSize
mov eax,[ipBitmap]
mov ecx,[eax]

push bheight
push bwidth
push [ipBitmap]
call [ecx+c]

// write bitmap header
// biSize
mov [bitmapinfo],28
// biWidth
push [bwidth]
pop [bitmapinfo+4]
// biHeight
mov eax,[bheight]
neg eax
mov [bitmapinfo+8],eax
// biPlanes
mov [bitmapinfo+c],#1
// biBitCount
mov [bitmapinfo+e],#32
// biCompression
mov [bitmapinfo+10],#0

push 0
call GetDC
mov [hdc_screen],eax

push 0
push 0
push pvImageBits
// DIB_RGB_COLORS
push 0
push bitmapinfo
push [hdc_screen]
call CreateDIBSection
mov [hbmp],eax


push [hdc_screen]
push 0
call ReleaseDC

// if hbmp == null -> end
nop

mov eax,[bwidth]
imul eax,#4
mov [cbStride],eax

imul eax,[bheight]
mov [cbImage],eax

// ipBitmap->CopyPixels
mov eax,[ipBitmap]
mov ecx,[eax]

push [pvImageBits]
push [cbImage]
push [cbStride]
push 0
push [ipBitmap]
call [ecx+1c]

nop
//

push img_ptr
push #24
push [hbmp]
call GetObjectA

fail_to_load:
ret

//unregistersymbol(source_png)
//dealloc(source_png)

 

 

В процессе впиливания текстур столкнулся с несколькими проблемами и прошу помощи/идей сообщества по нескольким вопросам:

  • встречались ли вы с загрузкой изображений в подобном кейсе (минимальные зависимости)? Как вы думаете вляется ли WIC достаточно функциональном и cross-windows решением?
  • Столкнулся с тем, что с версии Windows 8.1 должен использоваться другой PNG-декодер. Но не смог воспользоваться VerifyVersionInfo - всегда возвращает False. Кто-нибудь сталкивался с его использованием напрямую через ASM? Есть ли примеры? На самом деле вопрос не в стиле "Дайте код плз!!!111", я еще позже потом сам посмотрю, можно не отвечать, просто у меня не было времени детально посмотреть :)
  • Если инжектить DLL с помощью InjectDLL с включенным дебаггером (на конкретном брейкпоинте) - Cheat Engine просто напросто виснет. Кто-нибудь сталкивался с таким поведением?
    • Пока избегаю это просто вызовом InjectDLL перед включением дебаггера. Думал в сторону вызова pause(), но кажется нет возможности перехватить дебаггер с помощью debug_setBreakpoint, сделать pause() и выйдя из дебаггера запустить Inject. В целом надеюсь такой кейс и не пригодится.

 

4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

OGLHook v0.1

 

Ссылки на скачивание:

Получился довольно крупный релиз, поэтому было решено прыгнуть сразу на 0.1 версию.

 

Список изменений:

Spoiler
  • Добавлена команда запуска кода в отдельном потоке с ожиданием результата
  • Улучшена загрузка текстур, загрузка ведется через отдельный поток
  • Добавлены спрайты
    • теперь управлять процессом отрисовки проще, а плагин становится больше похож на D3D Hook
  • Добавлена генерация FontMap для символов ASCII 
  • Добавлены TextContainer для вывода текста на экран
  • Основные команды выведены в методы объекта OGLHook (создание спрайтов, загрузка текстур, формирование текста)
  • Упрощена и стабилизирована инициализация 
  • Потеряна возможность использовать инжект через брейкпоинт из-за несовместимости с работой в потоках
  • Сокращены названия модулей

 

Подробности:

Spoiler
  • Добавил возможность запуска ассемблерного кода с ожиданием результата

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

  • Загрузка текстур в потоке

В целом загрузка текстур уже была выделена в отдельные три функции, но выполнялась в потоке с игрой. Это накладывало ограничение и приходилось загружать текстуры в отдельной функции при инициализации OGLHook. Выделение кода в поток позволило грузить текстуры "на лету" дожидаясь окончания выполнения. Но, тут возник другой нюанс, а именно то, что OpenGL не дает использовать два контекста одновременно в одном окне. Эта проблема мешает помещать текстуры в память сразу же после их загрузки.

Решением оказалось создание фейкового невидимого окна размером 1x1 и инициализация в нем OpenGL нового контекста, который расшаривает информацию о текстурах / массивах данных / etc с основным контекстом через wglShareLists. Теперь можно грузить текстуры в любой момент времени, ю-ху!

  • Генерация FontMap

Генерацию карты символов для отрисовки надписей сделал по аналогии с D3D Hook - через Lua создается Picture, в ней подряд отрисовываются символы с 32 по 127 и загружается в память игры. Карта рисуется черно-белой, что позволяет после превратить черный цвет в прозрачность, а белый корректно изменять через метод glColor. 

 

Фотоотчет:

Spoiler

Hello, world или первая фраза OGLHook

Spoiler

-lsiXt3y17U.jpg

 

Вывод нескольких надписей (играемся со шрифтами)

Spoiler

2FecYOTdYcU.jpg

 

Тестирование прозрачности и скейлинга

Spoiler

6q78-fya4Vc.jpg

 

 

Видеоотчет:

Spoiler

Осторожно, звук

 

Код из видеоотчета:

Spoiler

require([[autorun\OGLHook\Main]])


textures = {}
sprites = {}
texts = {}
p = {
	anim_current = 1,
	anim_max = 8,
	bp_scale = 0.1,
	bp_scale_c = 0.01,
	grand_c = 2,
	that_ac = 0.05,
}

function loadTextures(glHook)
	-- test rotating
	textures.wat_grandma = glHook.loadTexture([[d:\pictures\wat_grandma.png]])
	-- test scaling (rotation)
	textures.that_feel = glHook.loadTexture([[d:\pictures\that_feel.png]])
	-- test resize
	textures.big_picture = glHook.loadTexture([[d:\pictures\big_picture.jpg]])
	-- random colors
	textures.jackie = glHook.loadTexture([[d:\pictures\jackie.jpg]])
	-- some animation
	textures.capguy = glHook.loadTexture([[d:\pictures\capguy-walk.png]])
end


function initSprites(glHook)
	sprites.big_picture = glHook.createSprite(38, 1000, textures.big_picture, true)
	sprites.big_picture:setScale(p.bp_scale, p.bp_scale)
	sprites.big_picture:setPivotPoint(0, sprites.big_picture.height)

	sprites.wat_grandma = glHook.createSprite(350, 350, textures.wat_grandma, true)
	sprites.wat_grandma.height = 350
	sprites.wat_grandma:setPivotPoint(sprites.wat_grandma.width / 2, sprites.wat_grandma.height)

	sprites.that_feel = glHook.createSprite(1200, 50, textures.that_feel, true)
	sprites.that_feel:setScale(0.7, 0.7)

	sprites.jackie = glHook.createSprite(1000, 800, textures.jackie, true)

	sprites.capguy = glHook.createSprite(800, 620, textures.capguy, true)
	sprites.capguy:setSize(sprites.capguy.width / p.anim_max, sprites.capguy.height)
	sprites.capguy:setPivotPoint(sprites.capguy.width / 2, sprites.capguy.height)
	sprites.capguy:setTextureCoordinates(0, 1 / p.anim_max, 0, 1)
end


function initTexts(glHook)
	font_1 = createFont()
	font_1.name = 'Helvetica Neue'
	font_1.color = 0x0000ff
	font_1.style = 'fsBold'
	font_1.size = 50

	font_2 = createFont()
	font_2.name = 'Comic Sans MS'
	font_2.color = 0x00cc00
	font_2.size = 32

	texts.font_map_1 = glHook.generateFontMap(font_1)
	texts.gamehacklab = glHook.createTextContainer(texts.font_map_1, 500, 20, "Gamehacklab[RU]", true)

	texts.font_map_2 = glHook.generateFontMap(font_2)
	texts.oglhook_text = glHook.createTextContainer(texts.font_map_2, 800, 630, "OGLHook v0.1", true)
	texts.oglhook_text:setPivotPoint(texts.oglhook_text.width / 2, texts.oglhook_text.height / 2)
end


function onTimer()
	-- update animation
	local anim_tw = p.anim_current * (1 / p.anim_max)
	sprites.capguy:setTextureCoordinates(anim_tw, anim_tw + 1 / p.anim_max, 0, 1)

	-- resize big picture
	sprites.big_picture:setScale(p.bp_scale, p.bp_scale)

	-- set color for jackie
	sprites.jackie:setColor(math.random(0xffffff))

	-- rotate grandma
	sprites.wat_grandma:setRotation(sprites.wat_grandma:getRotation() + p.grand_c)

	-- alpha
	sprites.that_feel:setAlpha(sprites.that_feel.alpha + p.that_ac)

	glHook:update()

	if sprites.big_picture.scale_x >= 0.7 or sprites.big_picture.scale_x < 0.1 then
		p.bp_scale_c = -p.bp_scale_c
	end
	p.bp_scale = p.bp_scale + p.bp_scale_c

	local grand_a = sprites.wat_grandma:getRotation()
	if grand_a < -45 or grand_a > 45 then
		p.grand_c = -p.grand_c
	end

	if sprites.that_feel.alpha >= 1 or sprites.that_feel.alpha <= 0 then
		p.that_ac = -p.that_ac
	end

	-- change animate frame
	p.anim_current = p.anim_current + 1
	if p.anim_current > p.anim_max then
		p.anim_current = 1
	end
end


function onHotKey(pid)
	-- TODO: dont forget about text
	openProcess(getForegroundProcess())

	glHook = OGLHook_Create()
	if type(glHook) ~= 'table' then
		ShowMessage('It is not OpenGL process')
		return
	end

	loadTextures(glHook)
	initSprites(glHook)
	initTexts(glHook)

	p.glHook = glHook

	update_timer = createTimer(nil, false)
	update_timer:setInterval(50)
	update_timer:setOnTimer(onTimer)
	update_timer:setEnabled(true)

end

createHotkey(onHotKey,VK_INSERT,VK_CONTROL)

 

 

4

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

OGLHook v0.1.1

 

Ссылки на скачивание:

 

В целом проект стал довольно стабилен и пригоден к использованию.

 

Список изменений:

Spoiler
  • Добавлен фоновый спрайт к текстовым контейнерам (теперь можно менять цвет фона, задавать фоном текстуру и т.д.);
  • Исправлен деструктор, теперь OGLHook корректно пересоздается, уничтожая предыдущий экземпляр;
  • Добавлена корректная проверка на версию Windows и в зависимости от этого используется правильная версия PNG декодера;
  • Подправлен механизм ошибок, теперь критичные функции вызывают error или отображают warning;

 

Фотоотчет:

Spoiler

LcexYTV.png

 

Код из фотоотчета:

Spoiler

f = createFont()
f.name = 'Helvetica Neue'
f.size = 32

local font_map = glHook.generateFontMap(f)

local tc = glHook.createTextContainer(font_map, 300, 300, 'Text Number One', true, true)
tc:setColor(0)
tc.background:assignTexture([[D:\pictures\220px-Brick_wall_close-up_view.jpg]])
tc.background:setTextureCoordinates(0, 1, 0.4, 0.6)

tc = glHook.createTextContainer(font_map, 300, 350, 'Second Text', true, true)
tc:setColor(0xffffff)
tc.background:setColor(0xed0000)

tc = glHook.createTextContainer(font_map, 360, 330, 'Transparent Text', true)
tc:setColor(0x0000ff)
tc:setPivotPoint(tc.width / 2, tc.height / 2)
tc:setRotation(-45)

 

 

Почему не работал VerifyVersionInfo:

Spoiler

К вопросу, поднятому выше - почему не работал VerifyVersionInfo и почти всегда возвращал False, даже на Windows 10.

Оказывается, чтобы версия Windows корректно проверялась - приложение, в котором выполняется VerifyVersionInfo должно содержать правильный GUID в манифесте для win 8.1 и win 10:


...
<!-- Windows 10 --> 
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
...

Если на этапе компиляции этого не было сделано, то VerifyVersionInfo при Windows >= 8.1 будет считать что работает под Windows 8.0.

 

Ура-ура, я пользователь :)

Изменено пользователем srg91
2

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
В 09.02.2017в01:14, srg91 сказал:

Ура-ура, я пользователь

Ура-ура, теперь ты Разработчик !

Спасибо за разработку. Теперь ты можешь публиковать свои работы в разделе "Файлы" и прикреплять файлы к сообщениям! 

Также ты видишь теперь скрытые для обычных пользователей разделы (правда, я не помню, есть у нас такие или нет) :) Поздравляю!

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Добро пожаловать в наш теплый круг разработчиков ;)

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
55 минут назад, Xipho сказал:

(правда, я не помню, есть у нас такие или нет)

:D Хорошая шутка!!!

srg91, поздравляю!!! (нашего полку прибыло.)

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

[offtop]

Ура-ура, спасибо! :) Будем изучать и делиться знаниями.

Happy GIF, 3.8 MB

[/offtop]

1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
8 минут назад, srg91 сказал:

и делиться знаниями.

Вот за это заранее - БОЛЬШОЙ СПАСЫБ!!!;)

0

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас