Compare commits

..

No commits in common. "5cb2875ba6fa77923224da0d9416a52b6558428d" and "1535d3ae35e8a62b1adf3331e36180e0fbfef158" have entirely different histories.

13 changed files with 85 additions and 225 deletions

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -23,6 +23,25 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME)
RESULT_VARIABLE _process_result
COMMAND_ERROR_IS_FATAL ANY
)
execute_process(
COMMAND
"${CMAKE_COMMAND}" -S ${CMAKE_CURRENT_SOURCE_DIR} -B ${CMAKE_SOURCE_DIR}/build_x86 -A
"Win32,version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" -G "${CMAKE_GENERATOR}"
-DCMAKE_SYSTEM_VERSION:STRING='${CMAKE_SYSTEM_VERSION}' -DVIRTUALCAM_GUID:STRING=${VIRTUALCAM_GUID}
-DCMAKE_MESSAGE_LOG_LEVEL:STRING=${CMAKE_MESSAGE_LOG_LEVEL} -DOBS_PARENT_ARCHITECTURE:STRING=ARM64
RESULT_VARIABLE _process_result
COMMAND_ERROR_IS_FATAL ANY
)
elseif(OBS_PARENT_ARCHITECTURE STREQUAL x64)
execute_process(
COMMAND
"${CMAKE_COMMAND}" -S ${CMAKE_CURRENT_SOURCE_DIR} -B ${CMAKE_SOURCE_DIR}/build_x86 -A
"Win32,version=${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}" -G "${CMAKE_GENERATOR}"
-DCMAKE_SYSTEM_VERSION:STRING='${CMAKE_SYSTEM_VERSION}' -DVIRTUALCAM_GUID:STRING=${VIRTUALCAM_GUID}
-DCMAKE_MESSAGE_LOG_LEVEL:STRING=${CMAKE_MESSAGE_LOG_LEVEL} -DOBS_PARENT_ARCHITECTURE:STRING=x64
RESULT_VARIABLE _process_result
COMMAND_ERROR_IS_FATAL ANY
)
endif()
else()
# target_disable_feature: Stub macro for child architecture builds

View File

@ -26,6 +26,8 @@ function(set_target_properties_obs target)
elseif(target STREQUAL inject-helper OR target STREQUAL get-graphics-offsets)
set(OBS_EXECUTABLE_DESTINATION "${OBS_DATA_DESTINATION}/obs-plugins/win-capture")
_target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION} x86)
if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64)
_target_install_obs(${target} DESTINATION ${OBS_EXECUTABLE_DESTINATION} x64)
endif()
@ -68,12 +70,16 @@ function(set_target_properties_obs target)
target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan64.json" "${target_destination}")
target_add_resource(graphics-hook "${CMAKE_CURRENT_SOURCE_DIR}/obs-vulkan32.json" "${target_destination}")
_target_install_obs(${target} DESTINATION ${target_destination} x86)
if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64)
_target_install_obs(${target} DESTINATION ${target_destination} x64)
endif()
elseif(target STREQUAL obs-virtualcam-module)
set(target_destination "${OBS_DATA_DESTINATION}/obs-plugins/win-dshow")
_target_install_obs(${target} DESTINATION ${target_destination} x86)
if(CMAKE_VS_PLATFORM_NAME STREQUAL ARM64)
_target_install_obs(${target} DESTINATION ${target_destination} x64)
endif()
@ -176,12 +182,33 @@ endfunction()
# _target_install_obs: Helper function to install build artifacts to rundir and install location
function(_target_install_obs target)
set(options "x64")
set(options "x86" "x64")
set(oneValueArgs "DESTINATION" "LIBRARY_DESTINATION" "HEADER_DESTINATION")
set(multiValueArgs "")
cmake_parse_arguments(PARSE_ARGV 0 _TIO "${options}" "${oneValueArgs}" "${multiValueArgs}")
if(_TIO_x64)
if(_TIO_x86)
get_target_property(target_type ${target} TYPE)
if(target_type STREQUAL EXECUTABLE)
set(suffix exe)
else()
set(suffix dll)
endif()
cmake_path(RELATIVE_PATH CMAKE_CURRENT_SOURCE_DIR BASE_DIRECTORY "${OBS_SOURCE_DIR}" OUTPUT_VARIABLE project_path)
set(32bit_project_path "${OBS_SOURCE_DIR}/build_x86/${project_path}")
set(target_file "${32bit_project_path}/$<CONFIG>/${target}32.${suffix}")
set(target_pdb_file "${32bit_project_path}/$<CONFIG>/${target}32.pdb")
set(comment "Copy ${target} (x86) to destination")
install(
FILES "${32bit_project_path}/$<CONFIG>/${target}32.${suffix}"
DESTINATION "${_TIO_DESTINATION}"
COMPONENT Runtime
OPTIONAL
)
elseif(_TIO_x64)
get_target_property(target_type ${target} TYPE)
if(target_type STREQUAL EXECUTABLE)
set(suffix exe)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 64 KiB

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>520</width>
<height>340</height>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
@ -73,22 +73,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="basedOn">
<property name="text">
<string notr="true">Based on &lt;a href="https://obsproject.com"&gt;OBS Studio&lt;/a&gt; (GPLv2)&lt;br/&gt;Secondary development by CAIIC</string>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
<property name="textInteractionFlags">
<set>Qt::TextBrowserInteraction</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 39 KiB

View File

@ -29,6 +29,15 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME)
)
endif()
if(CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)")
add_custom_command(
TARGET get-graphics-offsets
POST_BUILD
COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x86 --config $<CONFIG> -t get-graphics-offsets
COMMENT "Build x86 get-graphics-offsets"
)
endif()
add_dependencies(win-capture get-graphics-offsets)
endif()

View File

@ -64,6 +64,15 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME)
)
endif()
if(CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)")
add_custom_command(
TARGET graphics-hook
POST_BUILD
COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x86 --config $<CONFIG> -t graphics-hook
COMMENT "Build x86 graphics-hook"
)
endif()
add_dependencies(win-capture graphics-hook)
endif()

View File

@ -24,6 +24,15 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME)
)
endif()
if(CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)")
add_custom_command(
TARGET inject-helper
POST_BUILD
COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x86 --config $<CONFIG> -t inject-helper
COMMENT "Build x86 inject-helper"
)
endif()
add_dependencies(win-capture inject-helper)
endif()

View File

@ -114,6 +114,15 @@ if(OBS_PARENT_ARCHITECTURE STREQUAL CMAKE_VS_PLATFORM_NAME)
)
endif()
if(CMAKE_VS_PLATFORM_NAME MATCHES "(ARM64|x64)")
add_custom_command(
TARGET obs-virtualcam-module
POST_BUILD
COMMAND "${CMAKE_COMMAND}" --build ${CMAKE_SOURCE_DIR}/build_x86 --config $<CONFIG> -t obs-virtualcam-module
COMMENT "Build x86 obs-virtualcam-module"
)
endif()
add_dependencies(win-dshow obs-virtualcam-module)
endif()

View File

@ -1,206 +0,0 @@
// DOME-style icon generator for the CAIIC OBS fork.
// Renders a blue observatory/planetarium dome with a white three-blade
// aperture (nod to the OBS logo) wrapped by three CAIIC-colored arcs
// (orange top, green lower-left, yellow lower-right).
// Usage: node dome-icon-gen.js <out-dir>
const fs = require('fs');
const path = require('path');
const zlib = require('zlib');
const DEG = Math.PI / 180;
// ---------- CRC32 / PNG ----------
const crcTable = (() => {
const t = new Uint32Array(256);
for (let n = 0; n < 256; n++) {
let c = n;
for (let k = 0; k < 8; k++) c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
t[n] = c >>> 0;
}
return t;
})();
function crc32(buf) {
let c = 0xffffffff;
for (let i = 0; i < buf.length; i++) c = crcTable[(c ^ buf[i]) & 0xff] ^ (c >>> 8);
return (c ^ 0xffffffff) >>> 0;
}
function chunk(type, data) {
const out = Buffer.alloc(8 + data.length + 4);
out.writeUInt32BE(data.length, 0);
out.write(type, 4, 'ascii');
data.copy(out, 8);
out.writeUInt32BE(crc32(out.subarray(4, 8 + data.length)), 8 + data.length);
return out;
}
function pngEncode(width, height, rgba) {
const stride = width * 4;
const raw = Buffer.alloc((stride + 1) * height);
for (let y = 0; y < height; y++) {
raw[y * (stride + 1)] = 0;
rgba.copy(raw, y * (stride + 1) + 1, y * stride, (y + 1) * stride);
}
const ihdr = Buffer.alloc(13);
ihdr.writeUInt32BE(width, 0);
ihdr.writeUInt32BE(height, 4);
ihdr[8] = 8; // bit depth
ihdr[9] = 6; // RGBA
return Buffer.concat([
Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]),
chunk('IHDR', ihdr),
chunk('IDAT', zlib.deflateSync(raw, { level: 9 })),
chunk('IEND', Buffer.alloc(0)),
]);
}
function icoEncode(images) {
// images: [{size, png}]
const header = Buffer.alloc(6);
header.writeUInt16LE(1, 2);
header.writeUInt16LE(images.length, 4);
let offset = 6 + images.length * 16;
const entries = [];
for (const img of images) {
const e = Buffer.alloc(16);
e[0] = img.size >= 256 ? 0 : img.size;
e[1] = img.size >= 256 ? 0 : img.size;
e[4] = 1; // planes
e.writeUInt16LE(32, 6);
e.writeUInt32LE(img.png.length, 8);
e.writeUInt32LE(offset, 12);
offset += img.png.length;
entries.push(e);
}
return Buffer.concat([header, ...entries, ...images.map((i) => i.png)]);
}
// ---------- geometry ----------
function clamp(x, a, b) { return Math.min(Math.max(x, a), b); }
function mix(a, b, t) { return a + (b - a) * t; }
function mix3(c1, c2, t) { return [mix(c1[0], c2[0], t), mix(c1[1], c2[1], t), mix(c1[2], c2[2], t)]; }
// signed distance to a circular arc stroke (rounded caps), angles in radians
function arcSDF(px, py, cx, cy, r, a0, a1, w) {
const dx = px - cx, dy = py - cy;
const d = Math.hypot(dx, dy);
let ang = Math.atan2(dy, dx);
// normalize ang into [a0, a0 + 2PI)
const TWO_PI = Math.PI * 2;
while (ang < a0) ang += TWO_PI;
while (ang >= a0 + TWO_PI) ang -= TWO_PI;
let dist;
if (ang <= a1) {
dist = Math.abs(d - r);
} else {
const e0x = cx + r * Math.cos(a0), e0y = cy + r * Math.sin(a0);
const e1x = cx + r * Math.cos(a1), e1y = cy + r * Math.sin(a1);
dist = Math.min(Math.hypot(px - e0x, py - e0y), Math.hypot(px - e1x, py - e1y));
}
return dist - w / 2;
}
// rounded rect sdf
function rrSDF(px, py, cx, cy, hw, hh, r) {
const qx = Math.abs(px - cx) - (hw - r);
const qy = Math.abs(py - cy) - (hh - r);
const ax = Math.max(qx, 0), ay = Math.max(qy, 0);
return Math.hypot(ax, ay) + Math.min(Math.max(qx, qy), 0) - r;
}
// ---------- design ----------
const DOME_C = [0.5, 0.56]; // dome circle center
const DOME_R = 0.295; // dome radius
const BLADE_C = [0.5, 0.475]; // aperture center
const BLADE_R = 0.155;
const BLADE_W = 0.048;
const ARC_C = [0.5, 0.53];
const ARC_R = 0.4;
const ARC_W = 0.036;
const NAVY = [10, 52, 128];
const BLUE_HI = [110, 196, 250];
const BLUE_LO = [9, 68, 152];
const WHITE = [248, 252, 255];
const ORANGE = [240, 128, 60];
const GREEN = [110, 190, 74];
const YELLOW = [240, 204, 60];
function domeColor(px, py) {
const t = Math.pow(clamp(Math.hypot(px - 0.34, py - 0.36) / 0.5, 0, 1), 0.8);
let c = mix3(BLUE_HI, BLUE_LO, t);
// darken slightly toward the base for depth
const base = clamp((py - 0.42) / 0.16, 0, 1) * 0.18;
return [c[0] * (1 - base), c[1] * (1 - base), c[2] * (1 - base)];
}
function bladeSDF(px, py) {
let best = 1e9;
const span = 100 * DEG;
for (let i = 0; i < 3; i++) {
const a0 = (-90 + i * 120) * DEG;
best = Math.min(best, arcSDF(px, py, BLADE_C[0], BLADE_C[1], BLADE_R, a0, a0 + span, BLADE_W));
}
return best;
}
function arcsSDF(px, py) {
return [
{ sdf: arcSDF(px, py, ARC_C[0], ARC_C[1], ARC_R, -160 * DEG, -20 * DEG, ARC_W), color: ORANGE },
{ sdf: arcSDF(px, py, ARC_C[0], ARC_C[1], ARC_R, 105 * DEG, 170 * DEG, ARC_W), color: GREEN },
{ sdf: arcSDF(px, py, ARC_C[0], ARC_C[1], ARC_R, 10 * DEG, 75 * DEG, ARC_W), color: YELLOW },
];
}
function render(size) {
const SS = 4;
const R = size * SS;
const out = Buffer.alloc(size * size * 4);
const px = 1 / R;
for (let y = 0; y < size; y++) {
for (let x = 0; x < size; x++) {
let r = 0, g = 0, b = 0, a = 0;
for (let sy = 0; sy < SS; sy++) {
for (let sx = 0; sx < SS; sx++) {
const nx = (x * SS + sx + 0.5) / R;
const ny = (y * SS + sy + 0.5) / R;
const aa = (sdf) => clamp(0.5 - sdf / px, 0, 1);
let cr = 0, cg = 0, cb = 0, ca = 0;
const over = (sdf, col, opacity) => {
const cov = aa(sdf) * opacity;
cr = cr * (1 - cov) + col[0] * cov;
cg = cg * (1 - cov) + col[1] * cov;
cb = cb * (1 - cov) + col[2] * cov;
ca = ca * (1 - cov) + cov;
};
// base bar
over(rrSDF(nx, ny, 0.5, DOME_C[1] + 0.022, DOME_R + 0.045, 0.028, 0.026), NAVY, 1);
// dome (upper half of circle)
const dd = Math.max(Math.hypot(nx - DOME_C[0], ny - DOME_C[1]) - DOME_R, ny - DOME_C[1]);
over(dd, domeColor(nx, ny), 1);
// aperture blades
over(bladeSDF(nx, ny), WHITE, 0.95);
// colored arcs
for (const arc of arcsSDF(nx, ny)) over(arc.sdf, arc.color, 1);
r += cr; g += cg; b += cb; a += ca;
}
}
const n = SS * SS;
const o = (y * size + x) * 4;
out[o] = Math.round(clamp(r / n, 0, 255));
out[o + 1] = Math.round(clamp(g / n, 0, 255));
out[o + 2] = Math.round(clamp(b / n, 0, 255));
out[o + 3] = Math.round(clamp(a / n, 0, 1) * 255);
}
}
return out;
}
// ---------- main ----------
const outDir = process.argv[2] || '.';
const sizes = [16, 24, 32, 48, 64, 128, 256];
const images = sizes.map((s) => ({ size: s, png: pngEncode(s, s, render(s)) }));
fs.writeFileSync(path.join(outDir, 'obs.png'), images[images.length - 1].png);
fs.writeFileSync(path.join(outDir, 'obs-studio.ico'), icoEncode(images));
console.log('wrote obs.png (256x256) and obs-studio.ico (' + sizes.join(',') + ') to ' + outDir);