1
- ; Copyright (c) 2019-2022 David Vogel
1
+ ; Copyright (c) 2019-2023 David Vogel
2
2
;
3
3
; This software is released under the MIT License.
4
4
; https://opensource.org/licenses/MIT
@@ -15,44 +15,37 @@ Structure QueueElement
15
15
sy.i
16
16
EndStructure
17
17
18
- ; Source: https://www.purebasic.fr/english/viewtopic.php?f=13&t=29981&start=15
19
- Procedure EnumWindowsProc(hWnd.l, *lParam.Long)
20
- Protected lpProc.l
21
- GetWindowThreadProcessId_(hWnd, @lpProc)
22
- If *lParam\l = lpProc ; Check if current window's processID matches
23
- *lParam\l = hWnd ; Replace processID in the param With the hwnd As result
24
- ProcedureReturn #False ; Return false to stop iterating
25
- EndIf
26
- ProcedureReturn #True
27
- EndProcedure
18
+ Structure GLViewportDims
19
+ x.i
20
+ y.i
21
+ width.i
22
+ height.i
23
+ EndStructure
28
24
29
- ; Source: https://www.purebasic.fr/english/viewtopic.php?f=13&t=29981&start=15
30
- ; Returns the first window associated with the given process handle
31
- Procedure GetProcHwnd()
32
- Protected pID.l = GetCurrentProcessId_()
33
- Protected tempParam.l = pID
34
- EnumWindows_(@EnumWindowsProc(), @tempParam)
35
- If tempParam = pID ; Check if anything was found
36
- ProcedureReturn #Null
25
+ ; Returns the size of the main OpenGL rendering output.
26
+ ProcedureDLL GetGLViewportSize(*dims.GLViewportDims)
27
+ If Not *dims
28
+ ProcedureReturn #False
37
29
EndIf
38
- ProcedureReturn tempParam ; This is a valid hWnd at this point
30
+
31
+ glGetIntegerv_(#GL_VIEWPORT, *dims)
32
+
33
+ ProcedureReturn #True
39
34
EndProcedure
40
35
41
- ; Get the client rectangle of the "Main" window of this process in screen coordinates
36
+ ; Returns the size of the main OpenGL rendering output as a windows RECT.
42
37
ProcedureDLL GetRect(*rect.RECT)
43
- Protected hWnd.l = GetProcHwnd()
44
- If Not hWnd
45
- ProcedureReturn #False
46
- EndIf
47
38
If Not *rect
48
39
ProcedureReturn #False
49
40
EndIf
50
-
51
- GetClientRect_(hWnd, *rect)
52
-
53
- ; A RECT consists basically of two POINT structures
54
- ClientToScreen_(hWnd, @*rect\left)
55
- ClientToScreen_(hWnd, @*rect\Right)
41
+
42
+ Protected dims.GLViewportDims
43
+ glGetIntegerv_(#GL_VIEWPORT, dims)
44
+
45
+ *rect\left = dims\x
46
+ *rect\top = dims\y
47
+ *rect\right = dims\x + dims\width
48
+ *rect\bottom = dims\y + dims\height
56
49
57
50
ProcedureReturn #True
58
51
EndProcedure
@@ -84,7 +77,7 @@ Procedure Worker(*Dummy)
84
77
sy = Queue()\sy
85
78
DeleteElement(Queue())
86
79
UnlockMutex(Mutex)
87
-
80
+
88
81
If sx > 0 And sy > 0
89
82
ResizeImage(img, sx, sy)
90
83
EndIf
@@ -97,53 +90,56 @@ Procedure Worker(*Dummy)
97
90
EndProcedure
98
91
99
92
; Takes a screenshot of the client area of this process' active window.
100
- ; The portion of the client area that is captured is described by capRect, which is in window coordinates and relative to the client area .
93
+ ; The portion of the client area that is captured is described by capRect, which is in viewport coordinates.
101
94
; x and y defines the top left position of the captured rectangle in scaled world coordinates. The scale depends on the window to world pixel ratio.
102
95
; sx and sy defines the final dimensions that the screenshot will be resized to. No resize will happen if set to 0.
103
96
ProcedureDLL Capture(*capRect.RECT, x.l, y.l, sx.l, sy.l)
104
- Protected hWnd.l = GetProcHwnd()
105
- If Not hWnd
97
+ Protected viewportRect.RECT
98
+ If Not GetRect(@viewportRect)
106
99
ProcedureReturn #False
107
100
EndIf
108
101
109
- Protected rect.RECT
110
- If Not GetRect(@rect)
111
- ProcedureReturn #False
112
- EndIf
113
-
114
- ; Limit the desired capture area to the actual client area of the window.
102
+ ; Limit the desired capture area to the actual client area of the viewport.
115
103
If *capRect\left < 0 : *capRect\left = 0 : EndIf
116
- If *capRect\right > rect\right-rect\left : *capRect\right = rect\right-rect\left : EndIf
117
104
If *capRect\top < 0 : *capRect\top = 0 : EndIf
118
- If *capRect\bottom > rect\bottom-rect\top : *capRect\bottom = rect\bottom-rect\top : EndIf
119
-
120
- imageID = CreateImage(#PB_Any, *capRect\right-*capRect\left, *capRect\bottom-*capRect\top)
105
+ If *capRect\right < *capRect\left : *capRect\right = *capRect\left : EndIf
106
+ If *capRect\bottom < *capRect\top : *capRect\bottom = *capRect\top : EndIf
107
+ If *capRect\right > viewportRect\right : *capRect\right = viewportRect\right : EndIf
108
+ If *capRect\bottom > viewportRect\bottom : *capRect\bottom = viewportRect\bottom : EndIf
109
+
110
+ Protected capWidth = *capRect\right - *capRect\left
111
+ Protected capHeight = *capRect\bottom - *capRect\top
112
+
113
+ imageID = CreateImage(#PB_Any, capWidth, capHeight)
121
114
If Not imageID
122
115
ProcedureReturn #False
123
116
EndIf
124
-
125
- ; Get DC of window.
126
- windowDC = GetDC_(hWnd)
127
- If Not windowDC
128
- FreeImage(imageID)
129
- ProcedureReturn #False
130
- EndIf
117
+
118
+ ;Protected *pixelBuf = AllocateMemory(3 * width * height)
131
119
132
120
hDC = StartDrawing(ImageOutput(imageID))
133
121
If Not hDC
134
- ReleaseDC_(hWnd, windowDC)
135
122
FreeImage(imageID)
136
123
ProcedureReturn #False
137
124
EndIf
138
- If Not BitBlt_(hDC, 0, 0, *capRect\right-*capRect\left, *capRect\bottom-*capRect\top, windowDC, *capRect\left, *capRect\top, #SRCCOPY) ; After some time BitBlt will fail, no idea why. Also, that's moments before noita crashes.
139
- StopDrawing()
140
- ReleaseDC_(hWnd, windowDC)
141
- FreeImage(imageID)
142
- ProcedureReturn #False
143
- EndIf
144
- StopDrawing()
125
+
126
+ *pixelBuffer = DrawingBuffer()
127
+ glReadPixels_(*capRect\left, *capRect\top, capWidth, capHeight, #GL_BGR_EXT, #GL_UNSIGNED_BYTE, *pixelBuffer)
128
+
129
+ ;For y = 0 To *capRect\height - 1
130
+ ; *Line.Pixel = Buffer + Pitch * y
131
+ ;
132
+ ; For x = 0 To *capRect\width - 1
133
+ ;
134
+ ; *Line\Pixel = ColorTable(pos2) ; Write the pixel directly to the memory !
135
+ ; *Line+Offset
136
+ ;
137
+ ; ; You can try with regular plot to see the speed difference
138
+ ; ; Plot(x, y, ColorTable(pos2))
139
+ ; Next
140
+ ; Next
145
141
146
- ReleaseDC_(hWnd, windowDC )
142
+ StopDrawing( )
147
143
148
144
LockMutex(Mutex)
149
145
; Check if the queue has too many elements, if so, wait. (Emulate go's channels)
@@ -173,13 +169,13 @@ EndProcedure
173
169
;Capture(123, 123)
174
170
;Delay(1000)
175
171
176
- ; IDE Options = PureBasic 6.00 LTS (Windows - x64)
172
+ ; IDE Options = PureBasic 6.04 LTS (Windows - x64)
177
173
; ExecutableFormat = Shared dll
178
- ; CursorPosition = 94
179
- ; FirstLine = 39
180
- ; Folding = --
174
+ ; CursorPosition = 126
175
+ ; FirstLine = 98
176
+ ; Folding = -
181
177
; Optimizer
182
178
; EnableThread
183
179
; EnableXP
184
180
; Executable = capture.dll
185
- ; Compiler = PureBasic 6.00 LTS (Windows - x86)
181
+ ; Compiler = PureBasic 6.04 LTS (Windows - x86)
0 commit comments