Merge remote-tracking branch 'refs/remotes/origin/master' into vulkan

Former-commit-id: 7d8b0c7ab7d9dd9b2da8c6e0f6061d5314437686 [formerly 26c96fcff07aa0b1c0a3b95f18be3c29e03c9d88]
Former-commit-id: 04d8b83c2bb7719a83bcda40be25752fa4c7dd81
This commit is contained in:
Lynix 2016-06-12 23:00:33 +02:00
commit 8e9deee43e
185 changed files with 8172 additions and 850 deletions

2
.gitignore vendored
View File

@ -5,6 +5,8 @@ examples/bin/*.dll
examples/bin/*.so examples/bin/*.so
tests/*.exe tests/*.exe
tests/*.pdb tests/*.pdb
tests/*.dll
tests/*.so
lib/* lib/*
# Feature page # Feature page

View File

@ -33,6 +33,10 @@ namespace Ndk
bool Run(); bool Run();
#ifndef NDK_SERVER
inline void MakeExitOnLastWindowClosed(bool exitOnClosedWindows);
#endif
inline void Quit(); inline void Quit();
Application& operator=(const Application&) = delete; Application& operator=(const Application&) = delete;

View File

@ -61,6 +61,13 @@ namespace Ndk
return m_updateTime; return m_updateTime;
} }
#ifndef NDK_SERVER
inline void Application::MakeExitOnLastWindowClosed(bool exitOnClosedWindows)
{
m_exitOnClosedWindows = exitOnClosedWindows;
}
#endif
inline void Application::Quit() inline void Application::Quit()
{ {
m_shouldQuit = true; m_shouldQuit = true;

View File

@ -100,8 +100,8 @@ namespace Nz
params->animated = instance.CheckField<bool>("Animated", params->animated); params->animated = instance.CheckField<bool>("Animated", params->animated);
params->center = instance.CheckField<bool>("Center", params->center); params->center = instance.CheckField<bool>("Center", params->center);
params->flipUVs = instance.CheckField<bool>("FlipUVs", params->flipUVs); params->flipUVs = instance.CheckField<bool>("FlipUVs", params->flipUVs);
//params->matrix = instance.CheckField<Matrix4f>("Matrix", params->matrix);
params->optimizeIndexBuffers = instance.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers); params->optimizeIndexBuffers = instance.CheckField<bool>("OptimizeIndexBuffers", params->optimizeIndexBuffers);
params->scale = instance.CheckField<Vector3f>("Scale", params->scale);
return 1; return 1;
} }

View File

@ -1,5 +1,14 @@
NazaraBuild = {} -- L'équivalent d'un namespace en Lua est une table NazaraBuild = {} -- L'équivalent d'un namespace en Lua est une table
function NazaraBuild:AddExecutablePath(path)
self.ExecutableDir[path] = true
self.InstallDir[path] = true
end
function NazaraBuild:AddInstallPath(path)
self.InstallDir[path] = true
end
function NazaraBuild:Execute() function NazaraBuild:Execute()
if (_ACTION == nil) then -- Si aucune action n'est spécifiée if (_ACTION == nil) then -- Si aucune action n'est spécifiée
return -- Alors l'utilisateur voulait probablement savoir comment utiliser le programme, on ne fait rien return -- Alors l'utilisateur voulait probablement savoir comment utiliser le programme, on ne fait rien
@ -7,9 +16,9 @@ function NazaraBuild:Execute()
local platformData local platformData
if (os.is64bit()) then if (os.is64bit()) then
platformData = {"x64", "x86"} platformData = {"x64", "x32"}
else else
platformData = {"x86", "x64"} platformData = {"x32", "x64"}
end end
if (self.Actions[_ACTION] == nil) then if (self.Actions[_ACTION] == nil) then
@ -30,13 +39,13 @@ function NazaraBuild:Execute()
location(_ACTION) location(_ACTION)
kind("StaticLib") kind("StaticLib")
configuration("x86") configuration("x32")
libdirs("../extlibs/lib/common/x86") libdirs("../extlibs/lib/common/x86")
configuration("x64") configuration("x64")
libdirs("../extlibs/lib/common/x64") libdirs("../extlibs/lib/common/x64")
configuration({"codeblocks or codelite or gmake", "x86"}) configuration({"codeblocks or codelite or gmake", "x32"})
libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../extlibs/lib/" .. makeLibDir .. "/x86")
targetdir("../extlibs/lib/" .. makeLibDir .. "/x86") targetdir("../extlibs/lib/" .. makeLibDir .. "/x86")
@ -47,7 +56,7 @@ function NazaraBuild:Execute()
configuration("vs*") configuration("vs*")
buildoptions("/MP") buildoptions("/MP")
configuration({"vs*", "x86"}) configuration({"vs*", "x32"})
libdirs("../extlibs/lib/msvc/x86") libdirs("../extlibs/lib/msvc/x86")
targetdir("../extlibs/lib/msvc/x86") targetdir("../extlibs/lib/msvc/x86")
@ -55,7 +64,7 @@ function NazaraBuild:Execute()
libdirs("../extlibs/lib/msvc/x64") libdirs("../extlibs/lib/msvc/x64")
targetdir("../extlibs/lib/msvc/x64") targetdir("../extlibs/lib/msvc/x64")
configuration({"xcode3 or xcode4", "x86"}) configuration({"xcode3 or xcode4", "x32"})
libdirs("../extlibs/lib/xcode/x86") libdirs("../extlibs/lib/xcode/x86")
targetdir("../extlibs/lib/xcode/x86") targetdir("../extlibs/lib/xcode/x86")
@ -82,8 +91,11 @@ function NazaraBuild:Execute()
configuration("ReleaseStatic") configuration("ReleaseStatic")
targetsuffix("-s") targetsuffix("-s")
configuration({"not windows", "codeblocks or codelite or gmake or xcode3 or xcode4"})
buildoptions("-fPIC")
configuration("codeblocks or codelite or gmake or xcode3 or xcode4") configuration("codeblocks or codelite or gmake or xcode3 or xcode4")
buildoptions({"-fPIC", "-std=c++14"}) buildoptions({"-std=c++14", "-U__STRICT_ANSI__"})
for k, libTable in ipairs(self.OrderedExtLibs) do for k, libTable in ipairs(self.OrderedExtLibs) do
project(libTable.Name) project(libTable.Name)
@ -145,9 +157,6 @@ function NazaraBuild:Execute()
configuration({"linux or bsd or macosx", "gmake"}) configuration({"linux or bsd or macosx", "gmake"})
buildoptions("-fvisibility=hidden") buildoptions("-fvisibility=hidden")
configuration({"linux or bsd or macosx", "gmake"})
buildoptions("-fvisibility=hidden")
configuration("vs*") configuration("vs*")
buildoptions("/MP") -- Multiprocessus build buildoptions("/MP") -- Multiprocessus build
flags("NoMinimalRebuild") flags("NoMinimalRebuild")
@ -178,14 +187,14 @@ function NazaraBuild:Execute()
libdirs("../lib") libdirs("../lib")
libdirs("../extlibs/lib/common") libdirs("../extlibs/lib/common")
configuration("x86") configuration("x32")
libdirs("../extlibs/lib/common/x86") libdirs("../extlibs/lib/common/x86")
configuration("x64") configuration("x64")
defines("NAZARA_PLATFORM_x64") defines("NAZARA_PLATFORM_x64")
libdirs("../extlibs/lib/common/x64") libdirs("../extlibs/lib/common/x64")
configuration({"codeblocks or codelite or gmake", "x86"}) configuration({"codeblocks or codelite or gmake", "x32"})
libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../extlibs/lib/" .. makeLibDir .. "/x86")
libdirs("../lib/" .. makeLibDir .. "/x86") libdirs("../lib/" .. makeLibDir .. "/x86")
targetdir("../lib/" .. makeLibDir .. "/x86") targetdir("../lib/" .. makeLibDir .. "/x86")
@ -196,9 +205,9 @@ function NazaraBuild:Execute()
targetdir("../lib/" .. makeLibDir .. "/x64") targetdir("../lib/" .. makeLibDir .. "/x64")
-- Copy the module binaries to the example folder -- Copy the module binaries to the example folder
self:MakeCopyAfterBuild(moduleTable) self:MakeInstallCommands(moduleTable)
configuration({"vs*", "x86"}) configuration({"vs*", "x32"})
libdirs("../extlibs/lib/msvc/x86") libdirs("../extlibs/lib/msvc/x86")
libdirs("../lib/msvc/x86") libdirs("../lib/msvc/x86")
targetdir("../lib/msvc/x86") targetdir("../lib/msvc/x86")
@ -208,7 +217,7 @@ function NazaraBuild:Execute()
libdirs("../lib/msvc/x64") libdirs("../lib/msvc/x64")
targetdir("../lib/msvc/x64") targetdir("../lib/msvc/x64")
configuration({"xcode3 or xcode4", "x86"}) configuration({"xcode3 or xcode4", "x32"})
libdirs("../extlibs/lib/xcode/x86") libdirs("../extlibs/lib/xcode/x86")
libdirs("../lib/xcode/x86") libdirs("../lib/xcode/x86")
targetdir("../lib/xcode/x86") targetdir("../lib/xcode/x86")
@ -265,12 +274,16 @@ function NazaraBuild:Execute()
if (toolTable.Kind == "plugin" or toolTable.Kind == "library") then if (toolTable.Kind == "plugin" or toolTable.Kind == "library") then
kind("SharedLib") kind("SharedLib")
elseif (toolTable.Kind == "consoleapp") then
-- Copy the tool binaries to the example folder
self:MakeInstallCommands(toolTable)
elseif (toolTable.Kind == "application") then
debugdir(toolTable.Directory) debugdir(toolTable.Directory)
if (toolTable.EnableConsole) then
kind("ConsoleApp") kind("ConsoleApp")
elseif (toolTable.Kind == "windowapp") then else
debugdir(toolTable.Directory)
kind("WindowedApp") kind("WindowedApp")
end
else else
assert(false, "Invalid tool Kind") assert(false, "Invalid tool Kind")
end end
@ -283,14 +296,14 @@ function NazaraBuild:Execute()
libdirs("../lib") libdirs("../lib")
libdirs("../extlibs/lib/common") libdirs("../extlibs/lib/common")
configuration("x86") configuration("x32")
libdirs("../extlibs/lib/common/x86") libdirs("../extlibs/lib/common/x86")
configuration("x64") configuration("x64")
defines("NAZARA_PLATFORM_x64") defines("NAZARA_PLATFORM_x64")
libdirs("../extlibs/lib/common/x64") libdirs("../extlibs/lib/common/x64")
configuration({"codeblocks or codelite or gmake", "x86"}) configuration({"codeblocks or codelite or gmake", "x32"})
libdirs("../extlibs/lib/" .. makeLibDir .. "/x86") libdirs("../extlibs/lib/" .. makeLibDir .. "/x86")
libdirs("../lib/" .. makeLibDir .. "/x86") libdirs("../lib/" .. makeLibDir .. "/x86")
if (toolTable.Kind == "library") then if (toolTable.Kind == "library") then
@ -308,12 +321,7 @@ function NazaraBuild:Execute()
targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64") targetdir("../plugins/" .. toolTable.Name .. "/lib/" .. makeLibDir .. "/x64")
end end
-- Copy the tool binaries to the example folder configuration({"vs*", "x32"})
if (toolTable.CopyTargetToExampleDir) then
self:MakeCopyAfterBuild(toolTable)
end
configuration({"vs*", "x86"})
libdirs("../extlibs/lib/msvc/x86") libdirs("../extlibs/lib/msvc/x86")
libdirs("../lib/msvc/x86") libdirs("../lib/msvc/x86")
if (toolTable.Kind == "library") then if (toolTable.Kind == "library") then
@ -331,7 +339,7 @@ function NazaraBuild:Execute()
targetdir("../plugins/" .. toolTable.Name .. "/lib/msvc/x64") targetdir("../plugins/" .. toolTable.Name .. "/lib/msvc/x64")
end end
configuration({"xcode3 or xcode4", "x86"}) configuration({"xcode3 or xcode4", "x32"})
libdirs("../extlibs/lib/xcode/x86") libdirs("../extlibs/lib/xcode/x86")
libdirs("../lib/xcode/x86") libdirs("../lib/xcode/x86")
if (toolTable.Kind == "library") then if (toolTable.Kind == "library") then
@ -385,23 +393,34 @@ function NazaraBuild:Execute()
end end
for k, exampleTable in ipairs(self.OrderedExamples) do for k, exampleTable in ipairs(self.OrderedExamples) do
local destPath = "../examples/bin"
project("Demo" .. exampleTable.Name) project("Demo" .. exampleTable.Name)
location(_ACTION .. "/examples") location(_ACTION .. "/examples")
if (exampleTable.Console) then if (exampleTable.Kind == "plugin" or exampleTable.Kind == "library") then
kind("SharedLib")
self:MakeInstallCommands(toolTable)
elseif (exampleTable.Kind == "application") then
debugdir(exampleTable.Directory)
if (exampleTable.EnableConsole) then
kind("ConsoleApp") kind("ConsoleApp")
else else
kind("Window") kind("WindowedApp")
end
else
assert(false, "Invalid tool Kind")
end end
debugdir("../examples/bin") debugdir(destPath)
includedirs({ includedirs({
"../include", "../include",
"../extlibs/include" "../extlibs/include"
}) })
libdirs("../lib") libdirs("../lib")
targetdir("../examples/bin") targetdir(destPath)
files(exampleTable.Files) files(exampleTable.Files)
excludes(exampleTable.FilesExcluded) excludes(exampleTable.FilesExcluded)
@ -411,26 +430,26 @@ function NazaraBuild:Execute()
includedirs(exampleTable.Includes) includedirs(exampleTable.Includes)
links(exampleTable.Libraries) links(exampleTable.Libraries)
configuration("x86") configuration("x32")
libdirs("../extlibs/lib/common/x86") libdirs("../extlibs/lib/common/x86")
configuration("x64") configuration("x64")
defines("NAZARA_PLATFORM_x64") defines("NAZARA_PLATFORM_x64")
libdirs("../extlibs/lib/common/x64") libdirs("../extlibs/lib/common/x64")
configuration({"codeblocks or codelite or gmake", "x86"}) configuration({"codeblocks or codelite or gmake", "x32"})
libdirs("../lib/" .. makeLibDir .. "/x86") libdirs("../lib/" .. makeLibDir .. "/x86")
configuration({"codeblocks or codelite or gmake", "x64"}) configuration({"codeblocks or codelite or gmake", "x64"})
libdirs("../lib/" .. makeLibDir .. "/x64") libdirs("../lib/" .. makeLibDir .. "/x64")
configuration({"vs*", "x86"}) configuration({"vs*", "x32"})
libdirs("../lib/msvc/x86") libdirs("../lib/msvc/x86")
configuration({"vs*", "x64"}) configuration({"vs*", "x64"})
libdirs("../lib/msvc/x64") libdirs("../lib/msvc/x64")
configuration({"xcode3 or xcode4", "x86"}) configuration({"xcode3 or xcode4", "x32"})
libdirs("../lib/xcode/x86") libdirs("../lib/xcode/x86")
configuration({"xcode3 or xcode4", "x64"}) configuration({"xcode3 or xcode4", "x64"})
@ -448,6 +467,11 @@ end
function NazaraBuild:Initialize() function NazaraBuild:Initialize()
-- Commençons par les options -- Commençons par les options
newoption({
trigger = "install-path",
description = "Setup additionnals install directories (library binaries will be copied there)"
})
newoption({ newoption({
trigger = "server", trigger = "server",
description = "Excludes client-only modules/tools/examples" description = "Excludes client-only modules/tools/examples"
@ -470,10 +494,19 @@ function NazaraBuild:Initialize()
self.Actions = {} self.Actions = {}
self.Examples = {} self.Examples = {}
self.ExecutableDir = {}
self.ExtLibs = {} self.ExtLibs = {}
self.InstallDir = {}
self.Modules = {} self.Modules = {}
self.Tools = {} self.Tools = {}
if (_OPTIONS["install-path"]) then
local paths = string.explode(_OPTIONS["install-path"], ";")
for k,v in pairs(paths) do
self:AddInstallPath(v)
end
end
-- Actions -- Actions
modules = os.matchfiles("scripts/actions/*.lua") modules = os.matchfiles("scripts/actions/*.lua")
for k,v in pairs(modules) do for k,v in pairs(modules) do
@ -499,7 +532,7 @@ function NazaraBuild:Initialize()
local f, err = loadfile(v) local f, err = loadfile(v)
if (f) then if (f) then
LIBRARY = {} LIBRARY = {}
self:SetupInfoTable(LIBRARY) self:SetupExtlibTable(LIBRARY)
f() f()
@ -519,18 +552,10 @@ function NazaraBuild:Initialize()
local moduleName = v:match(".*/(.*).lua") local moduleName = v:match(".*/(.*).lua")
local moduleNameLower = moduleName:lower() local moduleNameLower = moduleName:lower()
if (moduleNameLower ~= "core") then -- exclure le noyau n'aurait aucun sens
newoption({
trigger = "exclude-" .. moduleNameLower,
description = "Exclude the " .. moduleName .. " module from the build system"
})
end
if (not _OPTIONS["exclude-" .. moduleNameLower]) then
local f, err = loadfile(v) local f, err = loadfile(v)
if (f) then if (f) then
MODULE = {} MODULE = {}
self:SetupInfoTable(MODULE) self:SetupModuleTable(MODULE)
f() f()
@ -542,7 +567,6 @@ function NazaraBuild:Initialize()
print("Unable to load module file: " .. err) print("Unable to load module file: " .. err)
end end
end end
end
MODULE = nil MODULE = nil
-- Continue with the tools (ex: SDK) -- Continue with the tools (ex: SDK)
@ -551,16 +575,10 @@ function NazaraBuild:Initialize()
local toolName = v:match(".*/(.*).lua") local toolName = v:match(".*/(.*).lua")
local toolNameLower = toolName:lower() local toolNameLower = toolName:lower()
newoption({
trigger = "exclude-" .. toolNameLower,
description = "Exclude the " .. toolName .. " tool from the build system"
})
if (not _OPTIONS["exclude-" .. toolNameLower]) then
local f, err = loadfile(v) local f, err = loadfile(v)
if (f) then if (f) then
TOOL = {} TOOL = {}
self:SetupInfoTable(TOOL) self:SetupToolTable(TOOL)
f() f()
@ -572,7 +590,6 @@ function NazaraBuild:Initialize()
print("Unable to load tool file: " .. err) print("Unable to load tool file: " .. err)
end end
end end
end
TOOL = nil TOOL = nil
-- Examples -- Examples
@ -585,7 +602,7 @@ function NazaraBuild:Initialize()
if (f) then if (f) then
EXAMPLE = {} EXAMPLE = {}
EXAMPLE.Directory = dirName EXAMPLE.Directory = dirName
self:SetupInfoTable(EXAMPLE) self:SetupExampleTable(EXAMPLE)
f() f()
@ -618,7 +635,7 @@ function NazaraBuild:Initialize()
if (self:Process(projectTable)) then if (self:Process(projectTable)) then
table.insert(orderedTables[k], projectTable) table.insert(orderedTables[k], projectTable)
else else
print("Rejected client-only " .. projectTable.Name .. " " .. projectTable.Type) print("Rejected " .. projectTable.Name .. " " .. string.lower(projectTable.Type) .. ": " .. projectTable.ExcludeReason)
end end
end end
@ -761,7 +778,7 @@ function NazaraBuild:RegisterTool(toolTable)
end end
local lowerCaseKind = toolTable.Kind:lower() local lowerCaseKind = toolTable.Kind:lower()
if (lowerCaseKind == "library" or lowerCaseKind == "plugin" or lowerCaseKind == "consoleapp" or lowerCaseKind == "windowapp") then if (lowerCaseKind == "library" or lowerCaseKind == "plugin" or lowerCaseKind == "application") then
toolTable.Kind = lowerCaseKind toolTable.Kind = lowerCaseKind
else else
return false, "Invalid tool type" return false, "Invalid tool type"
@ -780,20 +797,17 @@ local PosixOSes = {
} }
function NazaraBuild:Process(infoTable) function NazaraBuild:Process(infoTable)
if (infoTable.ClientOnly and _OPTIONS["server"]) then
return false
end
local libraries = {} local libraries = {}
for k, library in pairs(infoTable.Libraries) do for k, library in pairs(infoTable.Libraries) do
local moduleName = library:match("Nazara(%w+)") local projectName = library:match("Nazara(%w+)")
local moduleTable = moduleName and self.Modules[moduleName:lower()] local moduleTable = projectName and self.Modules[projectName:lower()]
local toolTable = moduleName and self.Tools[moduleName:lower()] local toolTable = projectName and self.Tools[projectName:lower()]
if (moduleTable) then if (moduleTable) then
if (moduleTable.ClientOnly and _OPTIONS["server"]) then if (moduleTable.Excluded) then
infoTable.ClientOnly = true infoTable.Excluded = true
return false -- We depend on a client-only library infoTable.ExcludeReason = "depends on excluded " .. projectName .. " module"
return false
end end
if (_OPTIONS["united"]) then if (_OPTIONS["united"]) then
@ -811,9 +825,10 @@ function NazaraBuild:Process(infoTable)
else else
local extLibTable = self.ExtLibs[library:lower()] local extLibTable = self.ExtLibs[library:lower()]
if (extLibTable) then if (extLibTable) then
if (extLibTable.ClientOnly and _OPTIONS["server"]) then if (extLibTable.Excluded) then
infoTable.ClientOnly = true infoTable.Excluded = true
return false -- We depend on a client-only library infoTable.ExcludeReason = "depends on excluded " .. extLibTable.Name .. " external library"
return false
end end
library = extLibTable.Name library = extLibTable.Name
@ -824,9 +839,10 @@ function NazaraBuild:Process(infoTable)
table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s") table.insert(infoTable.ConfigurationLibraries.ReleaseDynamic, library .. "-s")
else else
if (toolTable and toolTable.Kind == "library") then if (toolTable and toolTable.Kind == "library") then
if (toolTable.ClientOnly and _OPTIONS["server"]) then if (toolTable.Excluded) then
infoTable.ClientOnly = true infoTable.Excluded = true
return false -- We depend on a client-only library infoTable.ExcludeReason = "depends on excluded " .. toolTable.Name .. " tool"
return false
end end
library = "Nazara" .. toolTable.Name library = "Nazara" .. toolTable.Name
@ -890,37 +906,71 @@ function NazaraBuild:Process(infoTable)
end end
end end
if (infoTable.Kind == "application") then
self:AddExecutablePath(infoTable.Directory)
end
return true return true
end end
function NazaraBuild:Resolve(infoTable) function NazaraBuild:Resolve(infoTable)
if (infoTable.ClientOnly and _OPTIONS["server"]) then
infoTable.Excluded = true
infoTable.ExcludeReason = "excluded by command-line options (client-only)"
end
if (infoTable.Excludable) then
local optionName = "excludes-" .. string.lower(infoTable.Type .. "-" .. infoTable.Name)
newoption({
trigger = optionName,
description = "Excludes the " .. infoTable.Name .. " " .. string.lower(infoTable.Type) .. " and projects relying on it"
})
if (_OPTIONS[optionName]) then
infoTable.Excluded = true
infoTable.ExcludeReason = "excluded by command-line options"
end
end
if (type(infoTable.Libraries) == "function") then if (type(infoTable.Libraries) == "function") then
infoTable.Libraries = infoTable.Libraries() infoTable.Libraries = infoTable.Libraries()
end end
end end
function NazaraBuild:MakeCopyAfterBuild(infoTable) function NazaraBuild:MakeInstallCommands(infoTable)
if (PremakeVersion < 50) then
return
end
if (os.is("windows")) then if (os.is("windows")) then
configuration({}) configuration({})
postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "..\..\..\examples\bin\" /E /Y]]})
for k,v in pairs(self.InstallDir) do
local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k)
postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath):sub(1, -5) .. ".dll"}" "]] .. destPath .. [[\" /E /Y]]})
end
for k,v in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do for k,v in pairs(table.join(infoTable.Libraries, infoTable.DynLib)) do
local paths = {} local paths = {}
table.insert(paths, {"x86", "../extlibs/lib/common/x86/" .. v .. ".dll"}) table.insert(paths, {"x32", "../extlibs/lib/common/x86/" .. v .. ".dll"})
table.insert(paths, {"x86", "../extlibs/lib/common/x86/lib" .. v .. ".dll"}) table.insert(paths, {"x32", "../extlibs/lib/common/x86/lib" .. v .. ".dll"})
table.insert(paths, {"x64", "../extlibs/lib/common/x64/" .. v .. ".dll"}) table.insert(paths, {"x64", "../extlibs/lib/common/x64/" .. v .. ".dll"})
table.insert(paths, {"x64", "../extlibs/lib/common/x64/lib" .. v .. ".dll"}) table.insert(paths, {"x64", "../extlibs/lib/common/x64/lib" .. v .. ".dll"})
for k,v in pairs(paths) do for k,v in pairs(paths) do
local config = v[1] local config = v[1]
local path = v[2] local srcPath = v[2]
if (os.isfile(path)) then if (os.isfile(srcPath)) then
if (infoTable.Kind == "plugin") then if (infoTable.Kind == "plugin") then
path = "../../" .. path srcPath = "../../" .. srcPath
end end
configuration(config) configuration(config)
postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. path .. [[")}" "..\..\..\examples\bin\" /E /Y]]})
for k,v in pairs(self.ExecutableDir) do
local destPath = path.translate(path.isabsolute(k) and k or "../../" .. k)
postbuildcommands({[[xcopy "%{path.translate(cfg.linktarget.relpath:sub(1, -#cfg.linktarget.name - 1) .. "../../]] .. srcPath .. [[")}" "]] .. destPath .. [[\" /E /Y]]})
end
end end
end end
end end
@ -928,6 +978,7 @@ function NazaraBuild:MakeCopyAfterBuild(infoTable)
end end
function NazaraBuild:SetupInfoTable(infoTable) function NazaraBuild:SetupInfoTable(infoTable)
infoTable.Excludable = true
infoTable.ConfigurationLibraries = {} infoTable.ConfigurationLibraries = {}
infoTable.ConfigurationLibraries.DebugStatic = {} infoTable.ConfigurationLibraries.DebugStatic = {}
infoTable.ConfigurationLibraries.ReleaseStatic = {} infoTable.ConfigurationLibraries.ReleaseStatic = {}
@ -940,3 +991,24 @@ function NazaraBuild:SetupInfoTable(infoTable)
infoTable["Os" .. v] = {} infoTable["Os" .. v] = {}
end end
end end
function NazaraBuild:SetupExampleTable(infoTable)
self:SetupInfoTable(infoTable)
infoTable.Directory = "../examples/bin"
infoTable.Kind = "application"
end
function NazaraBuild:SetupExtlibTable(infoTable)
self:SetupInfoTable(infoTable)
infoTable.Kind = "library"
end
function NazaraBuild:SetupModuleTable(infoTable)
self:SetupInfoTable(infoTable)
infoTable.Kind = "library"
end
NazaraBuild.SetupToolTable = NazaraBuild.SetupInfoTable

View File

@ -1,6 +1,7 @@
MODULE.Name = "Core" MODULE.Name = "Core"
MODULE.Excludable = false -- Excluding the core makes no sense as everything relies on it
MODULE.Files = { -- Les autres fichiers seront ajoutés automatiquement MODULE.Files = { -- Other files will be automatically added
"../include/Nazara/Prerequesites.hpp", "../include/Nazara/Prerequesites.hpp",
"../include/Nazara/Math/**.hpp", "../include/Nazara/Math/**.hpp",
"../include/Nazara/Math/**.inl", "../include/Nazara/Math/**.inl",

View File

@ -3,8 +3,6 @@ TOOL.Name = "Assimp"
TOOL.Directory = "../SDK/lib" TOOL.Directory = "../SDK/lib"
TOOL.Kind = "Plugin" TOOL.Kind = "Plugin"
TOOL.CopyTargetToExampleDir = true
TOOL.Includes = { TOOL.Includes = {
"../include", "../include",
"../plugins/Assimp" "../plugins/Assimp"

View File

@ -1,7 +1,5 @@
TOOL.Name = "SDK" TOOL.Name = "SDK"
TOOL.CopyTargetToExampleDir = true
TOOL.Directory = "../SDK/lib" TOOL.Directory = "../SDK/lib"
TOOL.Kind = "Library" TOOL.Kind = "Library"

View File

@ -1,7 +1,5 @@
TOOL.Name = "SDKServer" TOOL.Name = "SDKServer"
TOOL.CopyTargetToExampleDir = true
TOOL.Directory = "../SDK/lib" TOOL.Directory = "../SDK/lib"
TOOL.Kind = "Library" TOOL.Kind = "Library"
@ -23,7 +21,7 @@ TOOL.Files = {
"../SDK/src/NDK/**.cpp" "../SDK/src/NDK/**.cpp"
} }
-- Exlude client-only files -- Excludes client-only files
TOOL.FilesExcluded = { TOOL.FilesExcluded = {
"../SDK/**/CameraComponent.*", "../SDK/**/CameraComponent.*",
"../SDK/**/Console.*", "../SDK/**/Console.*",

View File

@ -1,7 +1,8 @@
TOOL.Name = "UnitTests" TOOL.Name = "UnitTests"
TOOL.Directory = "../tests" TOOL.Directory = "../tests"
TOOL.Kind = "ConsoleApp" TOOL.EnableConsole = true
TOOL.Kind = "Application"
TOOL.Defines = { TOOL.Defines = {
} }

View File

@ -1,6 +1,6 @@
EXAMPLE.Name = "DopplerEffect" EXAMPLE.Name = "DopplerEffect"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"

View File

@ -1,6 +1,6 @@
EXAMPLE.Name = "FirstScene" EXAMPLE.Name = "FirstScene"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"

View File

@ -1,6 +1,6 @@
EXAMPLE.Name = "MeshInfos" EXAMPLE.Name = "MeshInfos"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"

View File

@ -1,6 +1,6 @@
EXAMPLE.Name = "Tut00_EmptyProject" EXAMPLE.Name = "Tut00_EmptyProject"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"

View File

@ -1,6 +1,6 @@
EXAMPLE.Name = "Tut01_HelloWorld" EXAMPLE.Name = "Tut01_HelloWorld"
EXAMPLE.Console = true EXAMPLE.EnableConsole = true
EXAMPLE.Files = { EXAMPLE.Files = {
"main.cpp" "main.cpp"

View File

@ -7,11 +7,21 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup audio
* \brief Mixes channels in mono
*
* \param input Input buffer with multiples channels
* \param output Output butter for mono
* \param channelCount Number of channels
* \param frameCount Number of frames
*
* \remark The input buffer may be the same as the output one
*/
template<typename T> template<typename T>
void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount) void MixToMono(T* input, T* output, unsigned int channelCount, unsigned int frameCount)
{ {
///DOC: Le buffer d'entrée peut être le même que le buffer de sortie // To avoid overflow, we use, as an accumulator, a type which is large enough: (u)int 64 bits for integers, double for floatings
// Pour éviter l'overflow, on utilise comme accumulateur un type assez grand, (u)int 64 bits pour les entiers, double pour les flottants
typedef typename std::conditional<std::is_unsigned<T>::value, UInt64, Int64>::type BiggestInt; typedef typename std::conditional<std::is_unsigned<T>::value, UInt64, Int64>::type BiggestInt;
typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest; typedef typename std::conditional<std::is_integral<T>::value, BiggestInt, double>::type Biggest;

View File

@ -27,18 +27,23 @@
#ifndef NAZARA_CONFIG_AUDIO_HPP #ifndef NAZARA_CONFIG_AUDIO_HPP
#define NAZARA_CONFIG_AUDIO_HPP #define NAZARA_CONFIG_AUDIO_HPP
/// Modifier la configuration d'un module nécessite une recompilation quasi-intégrale de celui-ci et de ceux en héritant /*!
* \defgroup audio (NazaraAudio) Audio module
* Audio/System module including classes to handle music, sound, etc...
*/
// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) /// Each modification of a parameter needs a recompilation of the module
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
#define NAZARA_AUDIO_MANAGE_MEMORY 0 #define NAZARA_AUDIO_MANAGE_MEMORY 0
// Active les tests de sécurité supplémentaires (Teste notamment les arguments des fonctions, conseillé pour le développement) // Activate the security tests based on the code (Advised for development)
#define NAZARA_AUDIO_SAFE 1 #define NAZARA_AUDIO_SAFE 1
// Le nombre de buffers utilisés lors du streaming d'objets audio (Au moins deux) // The number of buffers used for audio streaming (At least two)
#define NAZARA_AUDIO_STREAMED_BUFFER_COUNT 2 #define NAZARA_AUDIO_STREAMED_BUFFER_COUNT 2
/// Vérification des valeurs et types de certaines constantes /// Checking the values and types of certain constants
#include <Nazara/Audio/ConfigCheck.hpp> #include <Nazara/Audio/ConfigCheck.hpp>
#if !defined(NAZARA_STATIC) #if !defined(NAZARA_STATIC)

View File

@ -7,12 +7,12 @@
#ifndef NAZARA_CONFIG_CHECK_AUDIO_HPP #ifndef NAZARA_CONFIG_CHECK_AUDIO_HPP
#define NAZARA_CONFIG_CHECK_AUDIO_HPP #define NAZARA_CONFIG_CHECK_AUDIO_HPP
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp /// This file is used to check the constant values defined in Config.hpp
#include <type_traits> #include <type_traits>
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err) #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug // We force the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY #if defined(NAZARA_DEBUG) && !NAZARA_AUDIO_MANAGE_MEMORY
#undef NAZARA_AUDIO_MANAGE_MEMORY #undef NAZARA_AUDIO_MANAGE_MEMORY
#define NAZARA_AUDIO_MANAGE_MEMORY 0 #define NAZARA_AUDIO_MANAGE_MEMORY 0

View File

@ -2,7 +2,7 @@
// This file is part of the "Nazara Engine - Audio module" // This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp // We assume that Debug.hpp has already been included, same thing for Config.hpp
#if NAZARA_AUDIO_MANAGE_MEMORY #if NAZARA_AUDIO_MANAGE_MEMORY
#undef delete #undef delete
#undef new #undef new

View File

@ -13,7 +13,7 @@ namespace Nz
{ {
AudioFormat_Unknown = -1, AudioFormat_Unknown = -1,
// La valeur entière est le nombre de canaux possédés par ce format // The integer value is the number of channels used by the format
AudioFormat_Mono = 1, AudioFormat_Mono = 1,
AudioFormat_Stereo = 2, AudioFormat_Stereo = 2,
AudioFormat_Quad = 4, AudioFormat_Quad = 4,

View File

@ -15,18 +15,18 @@
#include <Nazara/Core/String.hpp> #include <Nazara/Core/String.hpp>
#include <vector> #include <vector>
// Inclusion des headers OpenAL // Inclusion of OpenAL headers
// Étant donné que les headers OpenAL ne nous permettent pas de n'avoir que les signatures sans les pointeurs de fonctions // OpenAL headers does not allow us to only get the signatures without the pointers to the functions
// Et que je ne souhaite pas les modifier, je suis contraint de les placer dans un espace de nom différent pour ensuite // And I do no want to modify them, I'm obliged to put them in a different namespace
// remettre dans l'espace global les choses intéressantes (les typedef notamment) // to put only interesting things back in the global namespace (specially typedef)
namespace OpenALDetail namespace OpenALDetail
{ {
#include <AL/al.h> #include <AL/al.h>
#include <AL/alc.h> #include <AL/alc.h>
} }
// Si quelqu'un a une meilleure idée ... // If someone has a better idea ...
using OpenALDetail::ALboolean; using OpenALDetail::ALboolean;
using OpenALDetail::ALbyte; using OpenALDetail::ALbyte;
using OpenALDetail::ALchar; using OpenALDetail::ALchar;

View File

@ -7,6 +7,13 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Creates a new sound buffer from the arguments
* \return A reference to the newly created sound buffer
*
* \param args Arguments for the sound buffer
*/
template<typename... Args> template<typename... Args>
SoundBufferRef SoundBuffer::New(Args&&... args) SoundBufferRef SoundBuffer::New(Args&&... args)
{ {

View File

@ -12,7 +12,7 @@
#include <Nazara/Audio/Enums.hpp> #include <Nazara/Audio/Enums.hpp>
#include <Nazara/Math/Vector3.hpp> #include <Nazara/Math/Vector3.hpp>
///TODO: Faire hériter SoundEmitter de Node ///TODO: Inherit SoundEmitter from Node
namespace Nz namespace Nz
{ {

View File

@ -12,7 +12,7 @@
#include <type_traits> #include <type_traits>
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err) #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
// We fore the value of MANAGE_MEMORY in debug // We force the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY #if defined(NAZARA_DEBUG) && !NAZARA_CORE_MANAGE_MEMORY
#undef NAZARA_CORE_MANAGE_MEMORY #undef NAZARA_CORE_MANAGE_MEMORY
#define NAZARA_CORE_MANAGE_MEMORY 0 #define NAZARA_CORE_MANAGE_MEMORY 0

View File

@ -10,6 +10,17 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup core
* \class Nz::HandledObject<T>
* \brief Core class that represents a handled object
*/
/*!
* \brief Constructs a HandledObject object by assignation
*
* \param object HandledObject to assign into this
*/
template<typename T> template<typename T>
HandledObject<T>::HandledObject(const HandledObject& object) HandledObject<T>::HandledObject(const HandledObject& object)
{ {
@ -17,6 +28,11 @@ namespace Nz
// Don't copy anything, we're a copy of the object, we have no handle right now // Don't copy anything, we're a copy of the object, we have no handle right now
} }
/*!
* \brief Constructs a HandledObject object by move semantic
*
* \param object HandledObject to move into this
*/
template<typename T> template<typename T>
HandledObject<T>::HandledObject(HandledObject&& object) : HandledObject<T>::HandledObject(HandledObject&& object) :
m_handles(std::move(object.m_handles)) m_handles(std::move(object.m_handles))
@ -25,18 +41,33 @@ namespace Nz
handle->OnObjectMoved(static_cast<T*>(this)); handle->OnObjectMoved(static_cast<T*>(this));
} }
/*!
* \brief Destructs the object and calls UnregisterAllHandles
*
* \see UnregisterAllHandles
*/
template<typename T> template<typename T>
HandledObject<T>::~HandledObject() HandledObject<T>::~HandledObject()
{ {
UnregisterAllHandles(); UnregisterAllHandles();
} }
/*!
* \brief Creates a ObjectHandle for this
* \return ObjectHandle to this
*/
template<typename T> template<typename T>
ObjectHandle<T> HandledObject<T>::CreateHandle() ObjectHandle<T> HandledObject<T>::CreateHandle()
{ {
return ObjectHandle<T>(static_cast<T*>(this)); return ObjectHandle<T>(static_cast<T*>(this));
} }
/*!
* \brief Sets the reference of the HandledObject with the handle from another
* \return A reference to this
*
* \param object The other HandledObject
*/
template<typename T> template<typename T>
HandledObject<T>& HandledObject<T>::operator=(const HandledObject& object) HandledObject<T>& HandledObject<T>::operator=(const HandledObject& object)
{ {
@ -44,6 +75,12 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Moves the HandledObject into this
* \return A reference to this
*
* \param object HandledObject to move in this
*/
template<typename T> template<typename T>
HandledObject<T>& HandledObject<T>::operator=(HandledObject&& object) HandledObject<T>& HandledObject<T>::operator=(HandledObject&& object)
{ {
@ -54,13 +91,22 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Registers a handle
*
* \param handle Handle to register
*
* \remark One handle can only be registered once, errors can occur if it's more than once
*/
template<typename T> template<typename T>
void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle) void HandledObject<T>::RegisterHandle(ObjectHandle<T>* handle)
{ {
///DOC: Un handle ne doit être enregistré qu'une fois, des erreurs se produisent s'il l'est plus d'une fois
m_handles.push_back(handle); m_handles.push_back(handle);
} }
/*!
* \brief Unregisters all handles
*/
template<typename T> template<typename T>
void HandledObject<T>::UnregisterAllHandles() void HandledObject<T>::UnregisterAllHandles()
{ {
@ -71,10 +117,17 @@ namespace Nz
m_handles.clear(); m_handles.clear();
} }
/*!
* \brief Unregisters a handle
*
* \param handle Handle to unregister
*
* \remark One handle can only be unregistered once, crash can occur if it's more than once
* \remark Produces a NazaraAssert if handle not registered
*/
template<typename T> template<typename T>
void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) noexcept void HandledObject<T>::UnregisterHandle(ObjectHandle<T>* handle) noexcept
{ {
///DOC: Un handle ne doit être libéré qu'une fois, et doit faire partie de la liste, sous peine de crash
auto it = std::find(m_handles.begin(), m_handles.end(), handle); auto it = std::find(m_handles.begin(), m_handles.end(), handle);
NazaraAssert(it != m_handles.end(), "Handle not registered"); NazaraAssert(it != m_handles.end(), "Handle not registered");
@ -83,6 +136,14 @@ namespace Nz
m_handles.pop_back(); m_handles.pop_back();
} }
/*!
* \brief Updates one handle with another
*
* \param oldHandle Old handle to replace
* \param newHandle New handle to take place
*
* \remark Produces a NazaraAssert if handle not registered
*/
template<typename T> template<typename T>
void HandledObject<T>::UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept void HandledObject<T>::UpdateHandle(ObjectHandle<T>* oldHandle, ObjectHandle<T>* newHandle) noexcept
{ {

View File

@ -9,12 +9,26 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup core
* \class Nz::ObjectHandle
* \brief Core class that represents a object handle
*/
/*!
* \brief Constructs a ObjectHandle object by default
*/
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle() : ObjectHandle<T>::ObjectHandle() :
m_object(nullptr) m_object(nullptr)
{ {
} }
/*!
* \brief Constructs a ObjectHandle object with a pointer to an object
*
* \param object Pointer to handle like an object (can be nullptr)
*/
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle(T* object) : ObjectHandle<T>::ObjectHandle(T* object) :
ObjectHandle() ObjectHandle()
@ -22,59 +36,97 @@ namespace Nz
Reset(object); Reset(object);
} }
/*!
* \brief Constructs a ObjectHandle object by assignation
*
* \param handle ObjectHandle to assign into this
*/
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle(const ObjectHandle<T>& handle) : ObjectHandle<T>::ObjectHandle(const ObjectHandle& handle) :
ObjectHandle() ObjectHandle()
{ {
Reset(handle); Reset(handle);
} }
/*!
* \brief Constructs a ObjectHandle object by move semantic
*
* \param handle ObjectHandle to move into this
*/
template<typename T> template<typename T>
ObjectHandle<T>::ObjectHandle(ObjectHandle<T>&& handle) noexcept : ObjectHandle<T>::ObjectHandle(ObjectHandle&& handle) noexcept :
ObjectHandle() ObjectHandle()
{ {
Reset(std::move(handle)); Reset(std::move(handle));
} }
/*!
* \brief Destructs the object and calls reset with nullptr
*
* \see Reset
*/
template<typename T> template<typename T>
ObjectHandle<T>::~ObjectHandle() ObjectHandle<T>::~ObjectHandle()
{ {
Reset(nullptr); Reset(nullptr);
} }
/*!
* \brief Gets the underlying object
* \return Underlying object
*/
template<typename T> template<typename T>
T* ObjectHandle<T>::GetObject() const T* ObjectHandle<T>::GetObject() const
{ {
return m_object; return m_object;
} }
/*!
* \brief Checks whether the object is valid
* \return true if object is not nullptr
*/
template<typename T> template<typename T>
bool ObjectHandle<T>::IsValid() const bool ObjectHandle<T>::IsValid() const
{ {
return m_object != nullptr; return m_object != nullptr;
} }
/*!
* \brief Resets the content of the ObjectHandle with another object
*
* \param object Object to handle
*/
template<typename T> template<typename T>
void ObjectHandle<T>::Reset(T* object) void ObjectHandle<T>::Reset(T* object)
{ {
// Si nous avions déjà une entité, nous devons l'informer que nous ne pointons plus sur elle // If we already have an entity, we must alert it that we are not pointing to it anymore
if (m_object) if (m_object)
m_object->UnregisterHandle(this); m_object->UnregisterHandle(this);
m_object = object; m_object = object;
if (m_object) if (m_object)
// On informe la nouvelle entité que nous pointons sur elle // We alert the new entity that we are pointing to it
m_object->RegisterHandle(this); m_object->RegisterHandle(this);
} }
/*!
* \brief Resets the content of this with another object
*
* \param handle New object to handle
*/
template<typename T> template<typename T>
void ObjectHandle<T>::Reset(const ObjectHandle<T>& handle) void ObjectHandle<T>::Reset(const ObjectHandle& handle)
{ {
Reset(handle.GetObject()); Reset(handle.GetObject());
} }
/*!
* \brief Resets the content of this with another object by move semantic
*
* \param handle New object to handle to move into this
*/
template<typename T> template<typename T>
void ObjectHandle<T>::Reset(ObjectHandle<T>&& handle) noexcept void ObjectHandle<T>::Reset(ObjectHandle&& handle) noexcept
{ {
if (m_object) if (m_object)
m_object->UnregisterHandle(this); m_object->UnregisterHandle(this);
@ -87,12 +139,18 @@ namespace Nz
} }
} }
/*!
* \brief Swaps the content of the two ObjectHandle
* \return A reference to this
*
* \param handle ObjectHandle to swap
*/
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle<T>& handle) ObjectHandle<T>& ObjectHandle<T>::Swap(ObjectHandle& handle)
{ {
// Comme nous inversons les handles, nous devons prévenir les entités // As we swap the two handles, we must alert the entities
// La version par défaut de swap (à base de move) aurait fonctionné, // The default version with swap (move) would be working,
// mais en enregistrant les handles une fois de plus que nécessaire (à cause de la copie temporaire). // but will register handles one more time (due to temporary copy).
if (m_object) if (m_object)
{ {
m_object->UnregisterHandle(this); m_object->UnregisterHandle(this);
@ -105,11 +163,15 @@ namespace Nz
handle.m_object->RegisterHandle(this); handle.m_object->RegisterHandle(this);
} }
// On effectue l'échange // We do the swap
std::swap(m_object, handle.m_object); std::swap(m_object, handle.m_object);
return *this; return *this;
} }
/*!
* \brief Gives a string representation
* \return A string representation of the object "ObjectHandle(object representation) or Null"
*/
template<typename T> template<typename T>
Nz::String ObjectHandle<T>::ToString() const Nz::String ObjectHandle<T>::ToString() const
{ {
@ -125,24 +187,44 @@ namespace Nz
return ss; return ss;
} }
/*!
* \brief Converts the ObjectHandle to bool
* \return true if reference is not nullptr
*
* \see IsValid
*/
template<typename T> template<typename T>
ObjectHandle<T>::operator bool() const ObjectHandle<T>::operator bool() const
{ {
return IsValid(); return IsValid();
} }
/*!
* \brief Dereferences the ObjectHandle
* \return Underlying pointer
*/
template<typename T> template<typename T>
ObjectHandle<T>::operator T*() const ObjectHandle<T>::operator T*() const
{ {
return m_object; return m_object;
} }
/*!
* \brief Dereferences the ObjectHandle
* \return Underlying pointer
*/
template<typename T> template<typename T>
T* ObjectHandle<T>::operator->() const T* ObjectHandle<T>::operator->() const
{ {
return m_object; return m_object;
} }
/*!
* \brief Assigns the entity into this
* \return A reference to this
*
* \param entity Pointer to handle like an object (can be nullptr)
*/
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity) ObjectHandle<T>& ObjectHandle<T>::operator=(T* entity)
{ {
@ -151,22 +233,37 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Sets the handle of the ObjectHandle with the handle from another
* \return A reference to this
*
* \param handle The other ObjectHandle
*/
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle<T>& handle) ObjectHandle<T>& ObjectHandle<T>::operator=(const ObjectHandle& handle)
{ {
Reset(handle); Reset(handle);
return *this; return *this;
} }
/*!
* \brief Moves the ObjectHandle into this
* \return A reference to this
*
* \param handle ObjectHandle to move in this
*/
template<typename T> template<typename T>
ObjectHandle<T>& ObjectHandle<T>::operator=(ObjectHandle<T>&& handle) noexcept ObjectHandle<T>& ObjectHandle<T>::operator=(ObjectHandle&& handle) noexcept
{ {
Reset(std::move(handle)); Reset(std::move(handle));
return *this; return *this;
} }
/*!
* \brief Action to do on object destruction
*/
template<typename T> template<typename T>
void ObjectHandle<T>::OnObjectDestroyed() void ObjectHandle<T>::OnObjectDestroyed()
{ {
@ -174,6 +271,9 @@ namespace Nz
m_object = nullptr; m_object = nullptr;
} }
/*!
* \brief Action to do on object move
*/
template<typename T> template<typename T>
void ObjectHandle<T>::OnObjectMoved(T* newObject) void ObjectHandle<T>::OnObjectMoved(T* newObject)
{ {
@ -181,114 +281,247 @@ namespace Nz
m_object = newObject; m_object = newObject;
} }
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param handle The ObjectHandle to output
*/
template<typename T> template<typename T>
std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle) std::ostream& operator<<(std::ostream& out, const ObjectHandle<T>& handle)
{ {
return handle.ToString(); return handle.ToString();
} }
/*!
* \brief Checks whether the first object handle is equal to the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator==(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return lhs.GetObject() == rhs.GetObject(); return lhs.GetObject() == rhs.GetObject();
} }
/*!
* \brief Checks whether the object is equal to the second object handle
* \return true if it is the case
*
* \param first Object to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator==(const T& lhs, const ObjectHandle<T>& rhs) bool operator==(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return &lhs == rhs.GetObject(); return &lhs == rhs.GetObject();
} }
/*!
* \brief Checks whether the object handle is equal to the second object
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second Object to compare in right hand side
*/
template<typename T> template<typename T>
bool operator==(const ObjectHandle<T>& lhs, const T& rhs) bool operator==(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return lhs.GetObject() == &rhs; return lhs.GetObject() == &rhs;
} }
/*!
* \brief Checks whether the first object handle is equal to the second object handle
* \return false if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator!=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
/*!
* \brief Checks whether the object is equal to the second object handle
* \return false if it is the case
*
* \param first Object to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator!=(const T& lhs, const ObjectHandle<T>& rhs) bool operator!=(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
/*!
* \brief Checks whether the object handle is equal to the second object
* \return false if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second Object to compare in right hand side
*/
template<typename T> template<typename T>
bool operator!=(const ObjectHandle<T>& lhs, const T& rhs) bool operator!=(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return !(lhs == rhs); return !(lhs == rhs);
} }
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator<(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return lhs.m_object < rhs.m_object; return lhs.m_object < rhs.m_object;
} }
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<(const T& lhs, const ObjectHandle<T>& rhs) bool operator<(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return &lhs < rhs.m_object; return &lhs < rhs.m_object;
} }
/*!
* \brief Checks whether the first object handle is less than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<(const ObjectHandle<T>& lhs, const T& rhs) bool operator<(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return lhs.m_object < &rhs; return lhs.m_object < &rhs;
} }
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator<=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs > rhs); return !(lhs > rhs);
} }
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<=(const T& lhs, const ObjectHandle<T>& rhs) bool operator<=(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs > rhs); return !(lhs > rhs);
} }
/*!
* \brief Checks whether the first object handle is less or equal than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator<=(const ObjectHandle<T>& lhs, const T& rhs) bool operator<=(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return !(lhs > rhs); return !(lhs > rhs);
} }
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator>(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return rhs < lhs; return rhs < lhs;
} }
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>(const T& lhs, const ObjectHandle<T>& rhs) bool operator>(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return rhs < lhs; return rhs < lhs;
} }
/*!
* \brief Checks whether the first object handle is greather than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>(const ObjectHandle<T>& lhs, const T& rhs) bool operator>(const ObjectHandle<T>& lhs, const T& rhs)
{ {
return rhs < lhs; return rhs < lhs;
} }
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs) bool operator>=(const ObjectHandle<T>& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs < rhs); return !(lhs < rhs);
} }
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>=(const T& lhs, const ObjectHandle<T>& rhs) bool operator>=(const T& lhs, const ObjectHandle<T>& rhs)
{ {
return !(lhs < rhs); return !(lhs < rhs);
} }
/*!
* \brief Checks whether the first object handle is greather or equal than the second object handle
* \return true if it is the case
*
* \param first ObjectHandle to compare in left hand side
* \param second ObjectHandle to compare in right hand side
*/
template<typename T> template<typename T>
bool operator>=(const ObjectHandle<T>& lhs, const T& rhs) bool operator>=(const ObjectHandle<T>& lhs, const T& rhs)
{ {
@ -301,6 +534,12 @@ namespace Nz
namespace std namespace std
{ {
/*!
* \brief Swaps two ObjectHandle, specialisation of std
*
* \param lhs First object handle
* \param rhs Second object handle
*/
template<typename T> template<typename T>
void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs) void swap(Nz::ObjectHandle<T>& lhs, Nz::ObjectHandle<T>& rhs)
{ {

View File

@ -50,6 +50,8 @@ namespace Nz
void SetParameter(const String& name, void* value); void SetParameter(const String& name, void* value);
void SetParameter(const String& name, void* value, Destructor destructor); void SetParameter(const String& name, void* value, Destructor destructor);
String ToString() const;
ParameterList& operator=(const ParameterList& list); ParameterList& operator=(const ParameterList& list);
ParameterList& operator=(ParameterList&&) = default; ParameterList& operator=(ParameterList&&) = default;
@ -73,7 +75,7 @@ namespace Nz
ParameterType type; ParameterType type;
union Value union Value
{ {
// On définit un constructeur/destructeur vide, permettant de mettre des classes dans l'union // We define an empty constructor/destructor, to be able to put classes in the union
Value() {} Value() {}
Value(const Value&) {} // Placeholder Value(const Value&) {} // Placeholder
~Value() {} ~Value() {}
@ -98,4 +100,6 @@ namespace Nz
}; };
} }
std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList);
#endif // NAZARA_PARAMETERLIST_HPP #endif // NAZARA_PARAMETERLIST_HPP

View File

@ -66,7 +66,7 @@ namespace Nz
return false; return false;
} }
File file(path); // Ouvert seulement en cas de besoin File file(path); // Open only if needed
bool found = false; bool found = false;
for (Loader& loader : Type::s_loaders) for (Loader& loader : Type::s_loaders)

View File

@ -7,6 +7,10 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a Billboard object by default
*/
inline Billboard::Billboard() inline Billboard::Billboard()
{ {
SetColor(Color::White); SetColor(Color::White);
@ -15,6 +19,12 @@ namespace Nz
SetSize(64.f, 64.f); SetSize(64.f, 64.f);
} }
/*!
* \brief Constructs a Billboard object with a reference to a material
*
* \param material Reference to a material
*/
inline Billboard::Billboard(MaterialRef material) inline Billboard::Billboard(MaterialRef material)
{ {
SetColor(Color::White); SetColor(Color::White);
@ -23,6 +33,12 @@ namespace Nz
SetSize(64.f, 64.f); SetSize(64.f, 64.f);
} }
/*!
* \brief Constructs a Billboard object with a pointer to a texture
*
* \param texture Pointer to a texture
*/
inline Billboard::Billboard(Texture* texture) inline Billboard::Billboard(Texture* texture)
{ {
SetColor(Color::White); SetColor(Color::White);
@ -31,6 +47,12 @@ namespace Nz
SetTexture(texture, true); SetTexture(texture, true);
} }
/*!
* \brief Constructs a Billboard object by assignation
*
* \param billboard Billboard to copy into this
*/
inline Billboard::Billboard(const Billboard& billboard) : inline Billboard::Billboard(const Billboard& billboard) :
InstancedRenderable(billboard), InstancedRenderable(billboard),
m_color(billboard.m_color), m_color(billboard.m_color),
@ -41,31 +63,61 @@ namespace Nz
{ {
} }
/*!
* \brief Gets the color of the billboard
* \return Current color
*/
inline const Color& Billboard::GetColor() const inline const Color& Billboard::GetColor() const
{ {
return m_color; return m_color;
} }
/*!
* \brief Gets the material of the billboard
* \return Current material
*/
inline const MaterialRef& Billboard::GetMaterial() const inline const MaterialRef& Billboard::GetMaterial() const
{ {
return m_material; return m_material;
} }
/*!
* \brief Gets the rotation of the billboard
* \return Current rotation
*/
inline float Billboard::GetRotation() const inline float Billboard::GetRotation() const
{ {
return m_rotation; return m_rotation;
} }
/*!
* \brief Gets the size of the billboard
* \return Current size
*/
inline const Vector2f& Billboard::GetSize() const inline const Vector2f& Billboard::GetSize() const
{ {
return m_size; return m_size;
} }
/*!
* \brief Sets the color of the billboard
*
* \param color Color for the billboard
*/
inline void Billboard::SetColor(const Color& color) inline void Billboard::SetColor(const Color& color)
{ {
m_color = color; m_color = color;
} }
/*!
* \brief Sets the default material of the billboard (just default material)
*/
inline void Billboard::SetDefaultMaterial() inline void Billboard::SetDefaultMaterial()
{ {
MaterialRef material = Material::New(); MaterialRef material = Material::New();
@ -75,6 +127,13 @@ namespace Nz
SetMaterial(std::move(material)); SetMaterial(std::move(material));
} }
/*!
* \brief Sets the material of the billboard
*
* \param material Material for the billboard
* \param resizeBillboard Should billboard be resized to the material size (diffuse map)
*/
inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard) inline void Billboard::SetMaterial(MaterialRef material, bool resizeBillboard)
{ {
m_material = std::move(material); m_material = std::move(material);
@ -86,25 +145,51 @@ namespace Nz
} }
} }
/*!
* \brief Sets the rotation of the billboard
*
* \param rotation Rotation for the billboard
*/
inline void Billboard::SetRotation(float rotation) inline void Billboard::SetRotation(float rotation)
{ {
m_rotation = rotation; m_rotation = rotation;
m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation)); m_sinCos.Set(std::sin(m_rotation), std::cos(m_rotation));
} }
/*!
* \brief Sets the size of the billboard
*
* \param size Size for the billboard
*/
inline void Billboard::SetSize(const Vector2f& size) inline void Billboard::SetSize(const Vector2f& size)
{ {
m_size = size; m_size = size;
// On invalide la bounding box // We invalidate the bounding volume
InvalidateBoundingVolume(); InvalidateBoundingVolume();
} }
/*!
* \brief Sets the size of the billboard
*
* \param sizeX Size in X for the billboard
* \param sizeY Size in Y for the billboard
*/
inline void Billboard::SetSize(float sizeX, float sizeY) inline void Billboard::SetSize(float sizeX, float sizeY)
{ {
SetSize(Vector2f(sizeX, sizeY)); SetSize(Vector2f(sizeX, sizeY));
} }
/*!
* \brief Sets the texture of the billboard
*
* \param texture Texture for the billboard
* \param resizeBillboard Should billboard be resized to the texture size
*/
inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard) inline void Billboard::SetTexture(TextureRef texture, bool resizeBillboard)
{ {
if (!m_material) if (!m_material)
@ -118,6 +203,13 @@ namespace Nz
m_material->SetDiffuseMap(std::move(texture)); m_material->SetDiffuseMap(std::move(texture));
} }
/*!
* \brief Sets the current billboard with the content of the other one
* \return A reference to this
*
* \param billboard The other Billboard
*/
inline Billboard& Billboard::operator=(const Billboard& billboard) inline Billboard& Billboard::operator=(const Billboard& billboard)
{ {
InstancedRenderable::operator=(billboard); InstancedRenderable::operator=(billboard);
@ -131,6 +223,13 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Creates a new billboard from the arguments
* \return A reference to the newly created billboard
*
* \param args Arguments for the billboard
*/
template<typename... Args> template<typename... Args>
BillboardRef Billboard::New(Args&&... args) BillboardRef Billboard::New(Args&&... args)
{ {

View File

@ -7,6 +7,13 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Creates a new color background from the arguments
* \return A reference to the newly created color background
*
* \param args Arguments for the color background
*/
template<typename... Args> template<typename... Args>
ColorBackgroundRef ColorBackground::New(Args&&... args) ColorBackgroundRef ColorBackground::New(Args&&... args)
{ {

View File

@ -27,23 +27,28 @@
#ifndef NAZARA_CONFIG_GRAPHICS_HPP #ifndef NAZARA_CONFIG_GRAPHICS_HPP
#define NAZARA_CONFIG_GRAPHICS_HPP #define NAZARA_CONFIG_GRAPHICS_HPP
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci /*!
* \defgroup graphics (NazaraGraphics) Graphics module
* Graphics/System module including classes to handle graphical elements...
*/
// À partir de combien d'instances d'un même mesh/matériau l'instancing doit-il être utilisé ? /// Each modification of a paramater of the module needs a recompilation of the unit
// How much instances are need of a same mesh/material to enable instancing ?
#define NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT 10 #define NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT 10
// Utilise un manager de mémoire pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) // Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
#define NAZARA_GRAPHICS_MANAGE_MEMORY 0 #define NAZARA_GRAPHICS_MANAGE_MEMORY 0
// Active les tests de sécurité basés sur le code (Conseillé pour le développement) // Activate the security tests based on the code (Advised for development)
#define NAZARA_GRAPHICS_SAFE 1 #define NAZARA_GRAPHICS_SAFE 1
/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code /// Each modification of a parameter following implies a modification (often minor) of the code
// Le nombre maximum de lumières qu'un shader standard supportera // The maximum number of lights in a standard shader
#define NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS 3 #define NAZARA_GRAPHICS_MAX_LIGHT_PER_PASS 3
/// Vérification des valeurs et types de certaines constantes /// Checking the values and types of certain constants
#include <Nazara/Graphics/ConfigCheck.hpp> #include <Nazara/Graphics/ConfigCheck.hpp>
#if defined(NAZARA_STATIC) #if defined(NAZARA_STATIC)

View File

@ -7,12 +7,12 @@
#ifndef NAZARA_CONFIG_CHECK_GRAPHICS_HPP #ifndef NAZARA_CONFIG_CHECK_GRAPHICS_HPP
#define NAZARA_CONFIG_CHECK_GRAPHICS_HPP #define NAZARA_CONFIG_CHECK_GRAPHICS_HPP
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp /// This file is used to check the constant values defined in Config.hpp
#include <type_traits> #include <type_traits>
#define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err) #define NazaraCheckTypeAndVal(name, type, op, val, err) static_assert(std::is_ ##type <decltype(name)>::value && name op val, #type err)
// On force la valeur de MANAGE_MEMORY en mode debug // We fore the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_GRAPHICS_MANAGE_MEMORY #if defined(NAZARA_DEBUG) && !NAZARA_GRAPHICS_MANAGE_MEMORY
#undef NAZARA_GRAPHICS_MANAGE_MEMORY #undef NAZARA_GRAPHICS_MANAGE_MEMORY
#define NAZARA_GRAPHICS_MANAGE_MEMORY 0 #define NAZARA_GRAPHICS_MANAGE_MEMORY 0

View File

@ -2,7 +2,7 @@
// This file is part of the "Nazara Engine - Graphics module" // This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp // We suppose that Debug.hpp is already included, same goes for Config.hpp
#if NAZARA_GRAPHICS_MANAGE_MEMORY #if NAZARA_GRAPHICS_MANAGE_MEMORY
#undef delete #undef delete
#undef new #undef new

View File

@ -29,7 +29,7 @@ namespace Nz
float GetBrightThreshold() const; float GetBrightThreshold() const;
Texture* GetTexture(unsigned int i) const; Texture* GetTexture(unsigned int i) const;
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
bool Resize(const Vector2ui& dimensions); bool Resize(const Vector2ui& dimensions);
void SetBlurPassCount(unsigned int passCount); void SetBlurPassCount(unsigned int passCount);

View File

@ -23,7 +23,7 @@ namespace Nz
DeferredDOFPass(); DeferredDOFPass();
virtual ~DeferredDOFPass(); virtual ~DeferredDOFPass();
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
bool Resize(const Vector2ui& dimensions); bool Resize(const Vector2ui& dimensions);
protected: protected:

View File

@ -21,7 +21,7 @@ namespace Nz
DeferredFXAAPass(); DeferredFXAAPass();
virtual ~DeferredFXAAPass(); virtual ~DeferredFXAAPass();
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
protected: protected:
RenderStates m_states; RenderStates m_states;

View File

@ -21,7 +21,7 @@ namespace Nz
DeferredFinalPass(); DeferredFinalPass();
virtual ~DeferredFinalPass(); virtual ~DeferredFinalPass();
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
protected: protected:
RenderStates m_states; RenderStates m_states;

View File

@ -21,7 +21,7 @@ namespace Nz
DeferredFogPass(); DeferredFogPass();
virtual ~DeferredFogPass(); virtual ~DeferredFogPass();
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
protected: protected:
RenderStates m_states; RenderStates m_states;

View File

@ -21,7 +21,7 @@ namespace Nz
virtual ~DeferredForwardPass(); virtual ~DeferredForwardPass();
void Initialize(DeferredRenderTechnique* technique); void Initialize(DeferredRenderTechnique* technique);
bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const; bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const;
protected: protected:
const ForwardRenderTechnique* m_forwardTechnique; const ForwardRenderTechnique* m_forwardTechnique;

View File

@ -21,7 +21,7 @@ namespace Nz
DeferredGeometryPass(); DeferredGeometryPass();
virtual ~DeferredGeometryPass(); virtual ~DeferredGeometryPass();
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
bool Resize(const Vector2ui& dimensions); bool Resize(const Vector2ui& dimensions);
protected: protected:

View File

@ -28,7 +28,7 @@ namespace Nz
bool IsLightMeshesDrawingEnabled() const; bool IsLightMeshesDrawingEnabled() const;
bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const; bool Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const;
protected: protected:
LightUniforms m_directionalLightUniforms; LightUniforms m_directionalLightUniforms;

View File

@ -38,7 +38,7 @@ namespace Nz
bool IsEnabled() const; bool IsEnabled() const;
virtual bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned sceneTexture) const = 0; virtual bool Process(const SceneData& sceneData, unsigned int workTexture, unsigned int sceneTexture) const = 0;
virtual bool Resize(const Vector2ui& GBufferSize); virtual bool Resize(const Vector2ui& GBufferSize);
DeferredRenderPass& operator=(const DeferredRenderPass&) = delete; DeferredRenderPass& operator=(const DeferredRenderPass&) = delete;

View File

@ -67,7 +67,7 @@ namespace Nz
}; };
std::map<RenderPassType, std::map<int, std::unique_ptr<DeferredRenderPass>>, RenderPassComparator> m_passes; std::map<RenderPassType, std::map<int, std::unique_ptr<DeferredRenderPass>>, RenderPassComparator> m_passes;
ForwardRenderTechnique m_forwardTechnique; // Doit être initialisé avant la RenderQueue ForwardRenderTechnique m_forwardTechnique; // Must be initialized before the RenderQueue
DeferredRenderQueue m_renderQueue; DeferredRenderQueue m_renderQueue;
mutable RenderBufferRef m_depthStencilBuffer; mutable RenderBufferRef m_depthStencilBuffer;
mutable RenderTexture m_GBufferRTT; mutable RenderTexture m_GBufferRTT;

View File

@ -6,6 +6,14 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Checks whether the material is suitable to fit in the render queue
* \return true If it is the case
*
* \param material Material to verify
*/
bool DepthRenderQueue::IsMaterialSuitable(const Material* material) const bool DepthRenderQueue::IsMaterialSuitable(const Material* material) const
{ {
NazaraAssert(material, "Invalid material"); NazaraAssert(material, "Invalid material");

View File

@ -128,7 +128,7 @@ namespace Nz
SceneNodeType_Max = SceneNodeType_User SceneNodeType_Max = SceneNodeType_User
}; };
// Ces paramètres sont indépendants du matériau: ils peuvent être demandés à tout moment // These parameters are independant of the material: they can not be asked for the moment
enum ShaderFlags enum ShaderFlags
{ {
ShaderFlags_None = 0, ShaderFlags_None = 0,

View File

@ -159,6 +159,7 @@ namespace Nz
std::map<int, Layer> layers; std::map<int, Layer> layers;
private: private:
BillboardData* GetBillboardData(int renderOrder, const Material* material, unsigned int count);
Layer& GetLayer(int i); ///TODO: Inline Layer& GetLayer(int i); ///TODO: Inline
void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer); void OnIndexBufferInvalidation(const IndexBuffer* indexBuffer);

View File

@ -31,7 +31,7 @@ namespace Nz
AbstractRenderQueue* GetRenderQueue() override; AbstractRenderQueue* GetRenderQueue() override;
RenderTechniqueType GetType() const override; RenderTechniqueType GetType() const override;
void SetMaxLightPassPerObject(unsigned int passCount); void SetMaxLightPassPerObject(unsigned int maxLightPassPerObject);
static bool Initialize(); static bool Initialize();
static void Uninitialize(); static void Uninitialize();
@ -70,11 +70,11 @@ namespace Nz
LightUniforms lightUniforms; LightUniforms lightUniforms;
bool hasLightUniforms; bool hasLightUniforms;
/// Moins coûteux en mémoire que de stocker un LightUniforms par index de lumière, /// Less costly in memory than storing a LightUniforms by index of light,
/// à voir si ça fonctionne chez tout le monde /// this may not work everywhere
int lightOffset; // "Distance" entre Lights[0].type et Lights[1].type int lightOffset; // "Distance" between Lights[0].type and Lights[1].type
// Autre uniformes // Other uniforms
int eyePosition; int eyePosition;
int sceneAmbient; int sceneAmbient;
int textureOverlay; int textureOverlay;

View File

@ -6,6 +6,16 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Sens the uniforms for light
*
* \param shader Shader to send uniforms to
* \param uniforms Uniforms to send
* \param index Index of the light
* \param uniformOffset Offset for the uniform
* \param availableTextureUnit Unit texture available
*/
inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const inline void ForwardRenderTechnique::SendLightUniforms(const Shader* shader, const LightUniforms& uniforms, unsigned int index, unsigned int uniformOffset, UInt8 availableTextureUnit) const
{ {
// If anyone got a better idea.. // If anyone got a better idea..
@ -104,6 +114,14 @@ namespace Nz
} }
} }
/*!
* \brief Computes the score for directional light
* \return 0.f
*
* \param object Sphere symbolising the object
* \param light Light to compute
*/
inline float ForwardRenderTechnique::ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light) inline float ForwardRenderTechnique::ComputeDirectionalLightScore(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light)
{ {
NazaraUnused(object); NazaraUnused(object);
@ -113,18 +131,42 @@ namespace Nz
return 0.f; return 0.f;
} }
/*!
* \brief Computes the score for point light
* \return Distance to the light
*
* \param object Sphere symbolising the object
* \param light Light to compute
*/
inline float ForwardRenderTechnique::ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light) inline float ForwardRenderTechnique::ComputePointLightScore(const Spheref& object, const AbstractRenderQueue::PointLight& light)
{ {
///TODO: Compute a score depending on the light luminosity ///TODO: Compute a score depending on the light luminosity
return object.SquaredDistance(light.position); return object.SquaredDistance(light.position);
} }
/*!
* \brief Computes the score for spot light
* \return Distance to the light
*
* \param object Sphere symbolising the object
* \param light Light to compute
*/
inline float ForwardRenderTechnique::ComputeSpotLightScore(const Spheref& object, const AbstractRenderQueue::SpotLight& light) inline float ForwardRenderTechnique::ComputeSpotLightScore(const Spheref& object, const AbstractRenderQueue::SpotLight& light)
{ {
///TODO: Compute a score depending on the light luminosity and spot direction ///TODO: Compute a score depending on the light luminosity and spot direction
return object.SquaredDistance(light.position); return object.SquaredDistance(light.position);
} }
/*!
* \brief Checks whether the directional light is suitable for the computations
* \return true if light is enoughly close
*
* \param object Sphere symbolising the object
* \param light Light to compute
*/
inline bool ForwardRenderTechnique::IsDirectionalLightSuitable(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light) inline bool ForwardRenderTechnique::IsDirectionalLightSuitable(const Spheref& object, const AbstractRenderQueue::DirectionalLight& light)
{ {
NazaraUnused(object); NazaraUnused(object);
@ -134,12 +176,28 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Checks whether the point light is suitable for the computations
* \return true if light is enoughly close
*
* \param object Sphere symbolising the object
* \param light Light to compute
*/
inline bool ForwardRenderTechnique::IsPointLightSuitable(const Spheref& object, const AbstractRenderQueue::PointLight& light) inline bool ForwardRenderTechnique::IsPointLightSuitable(const Spheref& object, const AbstractRenderQueue::PointLight& light)
{ {
// If the object is too far away from this point light, there is not way it could light it // If the object is too far away from this point light, there is not way it could light it
return object.SquaredDistance(light.position) <= light.radius * light.radius; return object.SquaredDistance(light.position) <= light.radius * light.radius;
} }
/*!
* \brief Checks whether the spot light is suitable for the computations
* \return true if light is enoughly close
*
* \param object Sphere symbolising the object
* \param light Light to compute
*/
inline bool ForwardRenderTechnique::IsSpotLightSuitable(const Spheref& object, const AbstractRenderQueue::SpotLight& light) inline bool ForwardRenderTechnique::IsSpotLightSuitable(const Spheref& object, const AbstractRenderQueue::SpotLight& light)
{ {
///TODO: Exclude spot lights based on their direction and outer angle? ///TODO: Exclude spot lights based on their direction and outer angle?

View File

@ -4,6 +4,12 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a InstancedRenderable object by assignation
*
* \param renderable InstancedRenderable to copy into this
*/
inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) : inline InstancedRenderable::InstancedRenderable(const InstancedRenderable& renderable) :
RefCounted(), RefCounted(),
m_boundingVolume(renderable.m_boundingVolume), m_boundingVolume(renderable.m_boundingVolume),
@ -11,22 +17,43 @@ namespace Nz
{ {
} }
/*!
* \brief Ensures that the bounding volume is up to date
*/
inline void InstancedRenderable::EnsureBoundingVolumeUpdated() const inline void InstancedRenderable::EnsureBoundingVolumeUpdated() const
{ {
if (!m_boundingVolumeUpdated) if (!m_boundingVolumeUpdated)
UpdateBoundingVolume(); UpdateBoundingVolume();
} }
/*!
* \brief Invalidates the bounding volume
*/
inline void InstancedRenderable::InvalidateBoundingVolume() inline void InstancedRenderable::InvalidateBoundingVolume()
{ {
m_boundingVolumeUpdated = false; m_boundingVolumeUpdated = false;
} }
/*!
* \brief Invalidates the instance data based on flags
*
* \param flags Flags to invalidate
*/
inline void InstancedRenderable::InvalidateInstanceData(UInt32 flags) inline void InstancedRenderable::InvalidateInstanceData(UInt32 flags)
{ {
OnInstancedRenderableInvalidateData(this, flags); OnInstancedRenderableInvalidateData(this, flags);
} }
/*!
* \brief Sets the current instanced renderable with the content of the other one
* \return A reference to this
*
* \param renderable The other InstancedRenderable
*/
inline InstancedRenderable& InstancedRenderable::operator=(const InstancedRenderable& renderable) inline InstancedRenderable& InstancedRenderable::operator=(const InstancedRenderable& renderable)
{ {
m_boundingVolume = renderable.m_boundingVolume; m_boundingVolume = renderable.m_boundingVolume;
@ -35,6 +62,10 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Updates the bounding volume
*/
inline void InstancedRenderable::UpdateBoundingVolume() const inline void InstancedRenderable::UpdateBoundingVolume() const
{ {
MakeBoundingVolume(); MakeBoundingVolume();

View File

@ -7,6 +7,10 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a Light object by default
*/
inline Light::Light(const Light& light) : inline Light::Light(const Light& light) :
Renderable(light), Renderable(light),
m_color(light.m_color), m_color(light.m_color),
@ -28,6 +32,12 @@ namespace Nz
{ {
} }
/*!
* \brief Enables shadow casting
*
* \param castShadows Should shadows be cast
*/
inline void Light::EnableShadowCasting(bool castShadows) inline void Light::EnableShadowCasting(bool castShadows)
{ {
if (m_shadowCastingEnabled != castShadows) if (m_shadowCastingEnabled != castShadows)
@ -37,72 +47,141 @@ namespace Nz
} }
} }
/*!
* \brief Ensures that the shadow map is up to date
*/
inline void Light::EnsureShadowMapUpdate() const inline void Light::EnsureShadowMapUpdate() const
{ {
if (!m_shadowMapUpdated) if (!m_shadowMapUpdated)
UpdateShadowMap(); UpdateShadowMap();
} }
/*!
* \brief Gets the ambient factor
* \return Current ambient factor
*/
inline float Light::GetAmbientFactor() const inline float Light::GetAmbientFactor() const
{ {
return m_ambientFactor; return m_ambientFactor;
} }
/*!
* \brief Gets the light attenuation (in 1 / R^2)
* \return Attenuation
*/
inline float Light::GetAttenuation() const inline float Light::GetAttenuation() const
{ {
return m_attenuation; return m_attenuation;
} }
/*!
* \brief Gets the color of the light
* \return Light color
*/
inline Color Light::GetColor() const inline Color Light::GetColor() const
{ {
return m_color; return m_color;
} }
/*!
* \brief Gets the diffuse factor
* \return Current diffuse factor
*/
inline float Light::GetDiffuseFactor() const inline float Light::GetDiffuseFactor() const
{ {
return m_diffuseFactor; return m_diffuseFactor;
} }
/*!
* \brief Gets the inner angle in spot light
* \return Inner angle
*/
inline float Light::GetInnerAngle() const inline float Light::GetInnerAngle() const
{ {
return m_innerAngle; return m_innerAngle;
} }
/*!
* \brief Gets the cosine inner angle in spot light
* \return Cosine inner angle
*/
inline float Light::GetInnerAngleCosine() const inline float Light::GetInnerAngleCosine() const
{ {
return m_innerAngleCosine; return m_innerAngleCosine;
} }
/*!
* \brief Gets the inverse of the radius
* \return Inverse of the radius
*/
inline float Light::GetInvRadius() const inline float Light::GetInvRadius() const
{ {
return m_invRadius; return m_invRadius;
} }
/*!
* \brief Gets the type of the light
* \return Light type
*/
inline LightType Light::GetLightType() const inline LightType Light::GetLightType() const
{ {
return m_type; return m_type;
} }
/*!
* \brief Gets the outer angle in spot light
* \return Outer angle
*/
inline float Light::GetOuterAngle() const inline float Light::GetOuterAngle() const
{ {
return m_outerAngle; return m_outerAngle;
} }
/*!
* \brief Gets the cosine outer angle in spot light
* \return Cosine outer angle
*/
inline float Light::GetOuterAngleCosine() const inline float Light::GetOuterAngleCosine() const
{ {
return m_outerAngleCosine; return m_outerAngleCosine;
} }
/*!
* \brief Gets the tangent outer angle in spot light
* \return Tangent outer angle
*/
inline float Light::GetOuterAngleTangent() const inline float Light::GetOuterAngleTangent() const
{ {
return m_outerAngleTangent; return m_outerAngleTangent;
} }
/*!
* \brief Gets the radius of the light
* \return Light radius
*/
inline float Light::GetRadius() const inline float Light::GetRadius() const
{ {
return m_radius; return m_radius;
} }
/*!
* \brief Gets the shadow map
* \return Reference to the shadow map texture
*/
inline TextureRef Light::GetShadowMap() const inline TextureRef Light::GetShadowMap() const
{ {
EnsureShadowMapUpdate(); EnsureShadowMapUpdate();
@ -110,47 +189,97 @@ namespace Nz
return m_shadowMap; return m_shadowMap;
} }
/*!
* \brief Gets the format of the shadow map
* \return Shadow map format
*/
inline PixelFormatType Light::GetShadowMapFormat() const inline PixelFormatType Light::GetShadowMapFormat() const
{ {
return m_shadowMapFormat; return m_shadowMapFormat;
} }
/*!
* \brief Gets the size of the shadow map
* \return Shadow map size
*/
inline const Vector2ui& Light::GetShadowMapSize() const inline const Vector2ui& Light::GetShadowMapSize() const
{ {
return m_shadowMapSize; return m_shadowMapSize;
} }
/*!
* \brief Checks whether the shadow casting is enabled
* \return true If it is the case
*/
inline bool Light::IsShadowCastingEnabled() const inline bool Light::IsShadowCastingEnabled() const
{ {
return m_shadowCastingEnabled; return m_shadowCastingEnabled;
} }
/*!
* \brief Sets the ambient factor
*
* \param factor Ambient factor
*/
inline void Light::SetAmbientFactor(float factor) inline void Light::SetAmbientFactor(float factor)
{ {
m_ambientFactor = factor; m_ambientFactor = factor;
} }
/*!
* \brief Sets the light attenuation (in 1 / R^2)
*
* \param attenuation Light attenuation
*/
inline void Light::SetAttenuation(float attenuation) inline void Light::SetAttenuation(float attenuation)
{ {
m_attenuation = attenuation; m_attenuation = attenuation;
} }
/*!
* \brief Sets the color of the light
*
* \param color Light color
*/
inline void Light::SetColor(const Color& color) inline void Light::SetColor(const Color& color)
{ {
m_color = color; m_color = color;
} }
/*!
* \brief Sets the diffuse factor
*
* \param factor Diffuse factor
*/
inline void Light::SetDiffuseFactor(float factor) inline void Light::SetDiffuseFactor(float factor)
{ {
m_diffuseFactor = factor; m_diffuseFactor = factor;
} }
/*!
* \brief Sets the inner angle in spot light
* \return innerAngle Inner angle
*/
inline void Light::SetInnerAngle(float innerAngle) inline void Light::SetInnerAngle(float innerAngle)
{ {
m_innerAngle = innerAngle; m_innerAngle = innerAngle;
m_innerAngleCosine = std::cos(DegreeToRadian(m_innerAngle)); m_innerAngleCosine = std::cos(DegreeToRadian(m_innerAngle));
} }
/*!
* \brief Sets the type of light
*
* \param type Light type
*/
inline void Light::SetLightType(LightType type) inline void Light::SetLightType(LightType type)
{ {
m_type = type; m_type = type;
@ -158,6 +287,13 @@ namespace Nz
InvalidateShadowMap(); InvalidateShadowMap();
} }
/*!
* \brief Sets the outer angle in spot light
* \return outerAngle Outer angle
*
* \remark Invalidates the bounding volume
*/
inline void Light::SetOuterAngle(float outerAngle) inline void Light::SetOuterAngle(float outerAngle)
{ {
m_outerAngle = outerAngle; m_outerAngle = outerAngle;
@ -167,6 +303,13 @@ namespace Nz
InvalidateBoundingVolume(); InvalidateBoundingVolume();
} }
/*!
* \brief Sets the radius of the light
* \return radius Light radius
*
* \remark Invalidates the bounding volume
*/
inline void Light::SetRadius(float radius) inline void Light::SetRadius(float radius)
{ {
m_radius = radius; m_radius = radius;
@ -176,6 +319,15 @@ namespace Nz
InvalidateBoundingVolume(); InvalidateBoundingVolume();
} }
/*!
* \brief Sets the shadow map format
*
* \param shadowFormat Shadow map format
*
* \remark Invalidates the shadow map
* \remark Produces a NazaraAssert if format is not a depth type
*/
inline void Light::SetShadowMapFormat(PixelFormatType shadowFormat) inline void Light::SetShadowMapFormat(PixelFormatType shadowFormat)
{ {
NazaraAssert(PixelFormat::GetContent(shadowFormat) == PixelFormatContent_DepthStencil, "Shadow format type is not a depth format"); NazaraAssert(PixelFormat::GetContent(shadowFormat) == PixelFormatContent_DepthStencil, "Shadow format type is not a depth format");
@ -185,6 +337,15 @@ namespace Nz
InvalidateShadowMap(); InvalidateShadowMap();
} }
/*!
* \brief Sets the size of the shadow map
*
* \param size Shadow map size
*
* \remark Invalidates the shadow map
* \remark Produces a NazaraAssert if size is zero
*/
inline void Light::SetShadowMapSize(const Vector2ui& size) inline void Light::SetShadowMapSize(const Vector2ui& size)
{ {
NazaraAssert(size.x > 0 && size.y > 0, "Shadow map size must have a positive size"); NazaraAssert(size.x > 0 && size.y > 0, "Shadow map size must have a positive size");
@ -194,6 +355,15 @@ namespace Nz
InvalidateShadowMap(); InvalidateShadowMap();
} }
/*!
* \brief Sets the current light with the content of the other one
* \return A reference to this
*
* \param light The other Light
*
* \remark Invalidates the shadow map
*/
inline Light& Light::operator=(const Light& light) inline Light& Light::operator=(const Light& light)
{ {
Renderable::operator=(light); Renderable::operator=(light);
@ -218,6 +388,10 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Invalidates the shadow map
*/
inline void Light::InvalidateShadowMap() inline void Light::InvalidateShadowMap()
{ {
m_shadowMapUpdated = false; m_shadowMapUpdated = false;

View File

@ -151,7 +151,7 @@ namespace Nz
inline Material& operator=(const Material& material); inline Material& operator=(const Material& material);
static MaterialRef GetDefault(); inline static MaterialRef GetDefault();
template<typename... Args> static MaterialRef New(Args&&... args); template<typename... Args> static MaterialRef New(Args&&... args);
// Signals: // Signals:

File diff suppressed because it is too large Load Diff

View File

@ -68,8 +68,6 @@ namespace Nz
bool SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material); bool SetMaterial(unsigned int skinIndex, const String& subMeshName, Material* material);
void SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material); void SetMaterial(unsigned int skinIndex, unsigned int matIndex, Material* material);
virtual void SetMesh(Mesh* mesh); virtual void SetMesh(Mesh* mesh);
bool SetSequence(const String& sequenceName);
void SetSequence(unsigned int sequenceIndex);
void SetSkin(unsigned int skin); void SetSkin(unsigned int skin);
void SetSkinCount(unsigned int skinCount); void SetSkinCount(unsigned int skinCount);

View File

@ -7,6 +7,13 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Creates a new Model from the arguments
* \return A reference to the newly created model
*
* \param args Arguments for the model
*/
template<typename... Args> template<typename... Args>
ModelRef Model::New(Args&&... args) ModelRef Model::New(Args&&... args)
{ {

View File

@ -62,9 +62,9 @@ namespace Nz
/* /*
** -Lynix: ** -Lynix:
** Il serait aussi possible de préciser le stride de façon indépendante, ce que je ne permets pas ** It would be also possible to precise the stride by an independant way, what I don't allow
** pour décomplexifier l'interface en enlevant quelque chose que je juge inutile. ** to decomplexify the interface of something I consider useless.
** Si vous pensez que ça peut être utile, n'hésitez pas à me le faire savoir ! ** If you think that could be useful, don't hesitate to make me aware !
*/ */
}; };

View File

@ -7,10 +7,20 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Gets a pointer to iterate through same components
* \return SparsePtr pointing to same components
*
* \param component Component to get in the declaration
*
* \remark The same components are not continguous but separated by sizeof(ParticleSize)
* \remark Produces a NazaraError if component is disabled
*/
template <typename T> template <typename T>
SparsePtr<T> ParticleMapper::GetComponentPtr(ParticleComponent component) SparsePtr<T> ParticleMapper::GetComponentPtr(ParticleComponent component)
{ {
// Ensuite le composant qui nous intéresse // Then the component that are interesting
bool enabled; bool enabled;
ComponentType type; ComponentType type;
unsigned int offset; unsigned int offset;
@ -18,7 +28,7 @@ namespace Nz
if (enabled) if (enabled)
{ {
///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? ///TODO: Check the ratio between the type of the attribute and the template type ?
return SparsePtr<T>(m_ptr + offset, m_declaration->GetStride()); return SparsePtr<T>(m_ptr + offset, m_declaration->GetStride());
} }
else else
@ -28,10 +38,20 @@ namespace Nz
} }
} }
/*!
* \brief Gets a pointer to iterate through same components
* \return SparsePtr pointing to same components
*
* \param component Component to get in the declaration
*
* \remark The same components are not continguous but separated by sizeof(ParticleSize)
* \remark Produces a NazaraError if component is disabled
*/
template <typename T> template <typename T>
SparsePtr<const T> ParticleMapper::GetComponentPtr(ParticleComponent component) const SparsePtr<const T> ParticleMapper::GetComponentPtr(ParticleComponent component) const
{ {
// Ensuite le composant qui nous intéresse // Then the component that are interesting
bool enabled; bool enabled;
ComponentType type; ComponentType type;
unsigned int offset; unsigned int offset;
@ -39,7 +59,7 @@ namespace Nz
if (enabled) if (enabled)
{ {
///TODO: Vérifier le rapport entre le type de l'attribut et le type template ? ///TODO: Check the ratio between the type of the attribute and the template type ?
return SparsePtr<const T>(m_ptr + offset, m_declaration->GetStride()); return SparsePtr<const T>(m_ptr + offset, m_declaration->GetStride());
} }
else else

View File

@ -4,17 +4,31 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Ensures that the bounding volume is up to date
*/
inline void Renderable::EnsureBoundingVolumeUpdated() const inline void Renderable::EnsureBoundingVolumeUpdated() const
{ {
if (!m_boundingVolumeUpdated) if (!m_boundingVolumeUpdated)
UpdateBoundingVolume(); UpdateBoundingVolume();
} }
/*!
* \brief Invalidates the bounding volume
*/
inline void Renderable::InvalidateBoundingVolume() inline void Renderable::InvalidateBoundingVolume()
{ {
m_boundingVolumeUpdated = false; m_boundingVolumeUpdated = false;
} }
/*!
* \brief Updates the bounding volume by a matrix
*
* \param transformMatrix Matrix transformation for our bounding volume
*/
inline void Renderable::UpdateBoundingVolume() const inline void Renderable::UpdateBoundingVolume() const
{ {
MakeBoundingVolume(); MakeBoundingVolume();

View File

@ -7,31 +7,62 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Gets the movement offset
* \return Offset of the movement
*/
inline const Vector3f& Nz::SkyboxBackground::GetMovementOffset() const inline const Vector3f& Nz::SkyboxBackground::GetMovementOffset() const
{ {
return m_movementOffset; return m_movementOffset;
} }
/*!
* \brief Gets the movement scale
* \return Scale of the movement
*/
inline float SkyboxBackground::GetMovementScale() const inline float SkyboxBackground::GetMovementScale() const
{ {
return m_movementScale; return m_movementScale;
} }
/*!
* \brief Gets the texture of the background
* \return Texture of the background
*/
inline const TextureRef& SkyboxBackground::GetTexture() const inline const TextureRef& SkyboxBackground::GetTexture() const
{ {
return m_texture; return m_texture;
} }
/*!
* \brief Gets the texture sampler of the background
* \return A reference to the texture sampler of the background
*/
inline TextureSampler& SkyboxBackground::GetTextureSampler() inline TextureSampler& SkyboxBackground::GetTextureSampler()
{ {
return m_sampler; return m_sampler;
} }
/*!
* \brief Gets the texture sampler of the background
* \return A constant reference to the texture sampler of the background
*/
inline const TextureSampler& SkyboxBackground::GetTextureSampler() const inline const TextureSampler& SkyboxBackground::GetTextureSampler() const
{ {
return m_sampler; return m_sampler;
} }
/*!
* \brief Sets the movement offset
*
* \param offset Offset of the movement
*/
inline void SkyboxBackground::SetMovementOffset(const Vector3f& offset) inline void SkyboxBackground::SetMovementOffset(const Vector3f& offset)
{ {
NazaraAssert(std::isfinite(offset.x) && std::isfinite(offset.y) && std::isfinite(offset.z), "Offset must be a finite vector"); NazaraAssert(std::isfinite(offset.x) && std::isfinite(offset.y) && std::isfinite(offset.z), "Offset must be a finite vector");
@ -39,6 +70,12 @@ namespace Nz
m_movementOffset = offset; m_movementOffset = offset;
} }
/*!
* \brief Sets the movement scale
*
* \param scale Scale of the movement
*/
inline void SkyboxBackground::SetMovementScale(float scale) inline void SkyboxBackground::SetMovementScale(float scale)
{ {
NazaraAssert(std::isfinite(scale), "Scale must be a finite value"); NazaraAssert(std::isfinite(scale), "Scale must be a finite value");
@ -46,6 +83,12 @@ namespace Nz
m_movementScale = scale; m_movementScale = scale;
} }
/*!
* \brief Sets the texture of the background
*
* \param cubemapTexture Texture of the background
*/
inline void SkyboxBackground::SetTexture(TextureRef cubemapTexture) inline void SkyboxBackground::SetTexture(TextureRef cubemapTexture)
{ {
NazaraAssert(!cubemapTexture || cubemapTexture->IsValid(), "Invalid texture"); NazaraAssert(!cubemapTexture || cubemapTexture->IsValid(), "Invalid texture");
@ -54,11 +97,24 @@ namespace Nz
m_texture = std::move(cubemapTexture); m_texture = std::move(cubemapTexture);
} }
/*!
* \brief Sets the texture sampler of the background
*
* \param sampler Texture sampler of the background
*/
void SkyboxBackground::SetTextureSampler(const TextureSampler& sampler) void SkyboxBackground::SetTextureSampler(const TextureSampler& sampler)
{ {
m_sampler = sampler; m_sampler = sampler;
} }
/*!
* \brief Creates a new skybox background from the arguments
* \return A reference to the newly created skybox background
*
* \param args Arguments for the skybox background
*/
template<typename... Args> template<typename... Args>
SkyboxBackgroundRef SkyboxBackground::New(Args&&... args) SkyboxBackgroundRef SkyboxBackground::New(Args&&... args)
{ {

View File

@ -8,6 +8,10 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a Sprite object by default
*/
inline Sprite::Sprite() : inline Sprite::Sprite() :
m_color(Color::White), m_color(Color::White),
m_textureCoords(0.f, 0.f, 1.f, 1.f), m_textureCoords(0.f, 0.f, 1.f, 1.f),
@ -16,6 +20,12 @@ namespace Nz
SetDefaultMaterial(); SetDefaultMaterial();
} }
/*!
* \brief Constructs a Sprite object with a reference to a material
*
* \param material Reference to a material
*/
inline Sprite::Sprite(MaterialRef material) : inline Sprite::Sprite(MaterialRef material) :
m_color(Color::White), m_color(Color::White),
m_textureCoords(0.f, 0.f, 1.f, 1.f), m_textureCoords(0.f, 0.f, 1.f, 1.f),
@ -24,6 +34,12 @@ namespace Nz
SetMaterial(std::move(material), true); SetMaterial(std::move(material), true);
} }
/*!
* \brief Constructs a Sprite object with a pointer to a texture
*
* \param texture Pointer to a texture
*/
inline Sprite::Sprite(Texture* texture) : inline Sprite::Sprite(Texture* texture) :
m_color(Color::White), m_color(Color::White),
m_textureCoords(0.f, 0.f, 1.f, 1.f), m_textureCoords(0.f, 0.f, 1.f, 1.f),
@ -32,6 +48,12 @@ namespace Nz
SetTexture(texture, true); SetTexture(texture, true);
} }
/*!
* \brief Constructs a Sprite object by assignation
*
* \param sprite Sprite to copy into this
*/
inline Sprite::Sprite(const Sprite& sprite) : inline Sprite::Sprite(const Sprite& sprite) :
InstancedRenderable(sprite), InstancedRenderable(sprite),
m_color(sprite.m_color), m_color(sprite.m_color),
@ -41,26 +63,52 @@ namespace Nz
{ {
} }
/*!
* \brief Gets the color of the sprite
* \return Current color
*/
inline const Color& Sprite::GetColor() const inline const Color& Sprite::GetColor() const
{ {
return m_color; return m_color;
} }
/*!
* \brief Gets the material of the sprite
* \return Current material
*/
inline const MaterialRef& Sprite::GetMaterial() const inline const MaterialRef& Sprite::GetMaterial() const
{ {
return m_material; return m_material;
} }
/*!
* \brief Gets the size of the sprite
* \return Current size
*/
inline const Vector2f& Sprite::GetSize() const inline const Vector2f& Sprite::GetSize() const
{ {
return m_size; return m_size;
} }
/*!
* \brief Gets the texture coordinates of the sprite
* \return Current texture coordinates
*/
inline const Rectf& Sprite::GetTextureCoords() const inline const Rectf& Sprite::GetTextureCoords() const
{ {
return m_textureCoords; return m_textureCoords;
} }
/*!
* \brief Sets the color of the billboard
*
* \param color Color for the billboard
*/
inline void Sprite::SetColor(const Color& color) inline void Sprite::SetColor(const Color& color)
{ {
m_color = color; m_color = color;
@ -68,6 +116,10 @@ namespace Nz
InvalidateVertices(); InvalidateVertices();
} }
/*!
* \brief Sets the default material of the sprite (just default material)
*/
inline void Sprite::SetDefaultMaterial() inline void Sprite::SetDefaultMaterial()
{ {
MaterialRef material = Material::New(); MaterialRef material = Material::New();
@ -77,6 +129,13 @@ namespace Nz
SetMaterial(std::move(material)); SetMaterial(std::move(material));
} }
/*!
* \brief Sets the material of the sprite
*
* \param material Material for the sprite
* \param resizeSprite Should sprite be resized to the material size (diffuse map)
*/
inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite) inline void Sprite::SetMaterial(MaterialRef material, bool resizeSprite)
{ {
m_material = std::move(material); m_material = std::move(material);
@ -88,6 +147,12 @@ namespace Nz
} }
} }
/*!
* \brief Sets the size of the sprite
*
* \param size Size for the sprite
*/
inline void Sprite::SetSize(const Vector2f& size) inline void Sprite::SetSize(const Vector2f& size)
{ {
m_size = size; m_size = size;
@ -97,11 +162,25 @@ namespace Nz
InvalidateVertices(); InvalidateVertices();
} }
/*!
* \brief Sets the size of the sprite
*
* \param sizeX Size in X for the sprite
* \param sizeY Size in Y for the sprite
*/
inline void Sprite::SetSize(float sizeX, float sizeY) inline void Sprite::SetSize(float sizeX, float sizeY)
{ {
SetSize(Vector2f(sizeX, sizeY)); SetSize(Vector2f(sizeX, sizeY));
} }
/*!
* \brief Sets the texture of the sprite
*
* \param texture Texture for the sprite
* \param resizeSprite Should sprite be resized to the texture size
*/
inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite) inline void Sprite::SetTexture(TextureRef texture, bool resizeSprite)
{ {
if (!m_material) if (!m_material)
@ -115,12 +194,27 @@ namespace Nz
m_material->SetDiffuseMap(std::move(texture)); m_material->SetDiffuseMap(std::move(texture));
} }
/*!
* \brief Sets the texture coordinates of the sprite
*
* \param coords Texture coordinates
*/
inline void Sprite::SetTextureCoords(const Rectf& coords) inline void Sprite::SetTextureCoords(const Rectf& coords)
{ {
m_textureCoords = coords; m_textureCoords = coords;
InvalidateVertices(); InvalidateVertices();
} }
/*!
* \brief Sets the texture rectangle of the sprite
*
* \param rect Rectangles symbolizing the size of the texture
*
* \remark Produces a NazaraAssert if material is invalid
* \remark Produces a NazaraAssert if material has no diffuse map
*/
inline void Sprite::SetTextureRect(const Rectui& rect) inline void Sprite::SetTextureRect(const Rectui& rect)
{ {
NazaraAssert(m_material, "Sprite has no material"); NazaraAssert(m_material, "Sprite has no material");
@ -134,6 +228,13 @@ namespace Nz
SetTextureCoords(Rectf(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height)); SetTextureCoords(Rectf(invWidth * rect.x, invHeight * rect.y, invWidth * rect.width, invHeight * rect.height));
} }
/*!
* \brief Sets the current sprite with the content of the other one
* \return A reference to this
*
* \param sprite The other Sprite
*/
inline Sprite& Sprite::operator=(const Sprite& sprite) inline Sprite& Sprite::operator=(const Sprite& sprite)
{ {
InstancedRenderable::operator=(sprite); InstancedRenderable::operator=(sprite);
@ -143,18 +244,29 @@ namespace Nz
m_textureCoords = sprite.m_textureCoords; m_textureCoords = sprite.m_textureCoords;
m_size = sprite.m_size; m_size = sprite.m_size;
// On ne copie pas les sommets finaux car il est très probable que nos paramètres soient modifiés et qu'ils doivent être régénérés de toute façon // We do not copy final vertices because it's highly probable that our parameters are modified and they must be regenerated
InvalidateBoundingVolume(); InvalidateBoundingVolume();
InvalidateVertices(); InvalidateVertices();
return *this; return *this;
} }
/*!
* \brief Invalidates the vertices
*/
inline void Sprite::InvalidateVertices() inline void Sprite::InvalidateVertices()
{ {
InvalidateInstanceData(0); InvalidateInstanceData(0);
} }
/*!
* \brief Creates a new sprite from the arguments
* \return A reference to the newly created sprite
*
* \param args Arguments for the sprite
*/
template<typename... Args> template<typename... Args>
SpriteRef Sprite::New(Args&&... args) SpriteRef Sprite::New(Args&&... args)
{ {

View File

@ -7,6 +7,10 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a TextSprite object by default
*/
inline TextSprite::TextSprite() : inline TextSprite::TextSprite() :
m_color(Color::White), m_color(Color::White),
m_scale(1.f) m_scale(1.f)
@ -14,12 +18,24 @@ namespace Nz
SetDefaultMaterial(); SetDefaultMaterial();
} }
/*!
* \brief Constructs a TextSprite object with a drawer
*
* \param drawer Drawer used to compose text on the sprite
*/
inline TextSprite::TextSprite(const AbstractTextDrawer& drawer) : inline TextSprite::TextSprite(const AbstractTextDrawer& drawer) :
TextSprite() TextSprite()
{ {
Update(drawer); Update(drawer);
} }
/*!
* \brief Constructs a TextSprite object by assignation
*
* \param sprite TextSprite to copy into this
*/
inline TextSprite::TextSprite(const TextSprite& sprite) : inline TextSprite::TextSprite(const TextSprite& sprite) :
InstancedRenderable(sprite), InstancedRenderable(sprite),
m_renderInfos(sprite.m_renderInfos), m_renderInfos(sprite.m_renderInfos),
@ -40,6 +56,10 @@ namespace Nz
} }
} }
/*!
* \brief Clears the data
*/
inline void TextSprite::Clear() inline void TextSprite::Clear()
{ {
m_atlases.clear(); m_atlases.clear();
@ -48,21 +68,42 @@ namespace Nz
m_renderInfos.clear(); m_renderInfos.clear();
} }
/*!
* \brief Gets the color of the text sprite
* \return Current color
*/
inline const Color& TextSprite::GetColor() const inline const Color& TextSprite::GetColor() const
{ {
return m_color; return m_color;
} }
/*!
* \brief Gets the material of the text sprite
* \return Current material
*/
inline const MaterialRef& TextSprite::GetMaterial() const inline const MaterialRef& TextSprite::GetMaterial() const
{ {
return m_material; return m_material;
} }
/*!
* \brief Gets the current scale of the text sprite
* \return Current scale
*/
inline float TextSprite::GetScale() const inline float TextSprite::GetScale() const
{ {
return m_scale; return m_scale;
} }
/*!
* \brief Sets the color of the text sprite
*
* \param color Color for the text sprite
*/
inline void TextSprite::SetColor(const Color& color) inline void TextSprite::SetColor(const Color& color)
{ {
m_color = color; m_color = color;
@ -70,6 +111,11 @@ namespace Nz
InvalidateVertices(); InvalidateVertices();
} }
/*!
* \brief Sets the default material of the text sprite (just default material)
*/
inline void TextSprite::SetDefaultMaterial() inline void TextSprite::SetDefaultMaterial()
{ {
MaterialRef material = Material::New(); MaterialRef material = Material::New();
@ -83,11 +129,23 @@ namespace Nz
SetMaterial(material); SetMaterial(material);
} }
/*!
* \brief Sets the material of the text sprite
*
* \param material Material for the text sprite
*/
inline void TextSprite::SetMaterial(MaterialRef material) inline void TextSprite::SetMaterial(MaterialRef material)
{ {
m_material = std::move(material); m_material = std::move(material);
} }
/*!
* \brief Sets the current scale of the text sprite
*
* \param scale Scale of the text sprite
*/
inline void TextSprite::SetScale(float scale) inline void TextSprite::SetScale(float scale)
{ {
m_scale = scale; m_scale = scale;
@ -95,10 +153,12 @@ namespace Nz
InvalidateVertices(); InvalidateVertices();
} }
inline void TextSprite::InvalidateVertices() /*!
{ * \brief Sets the current text sprite with the content of the other one
InvalidateInstanceData(0); * \return A reference to this
} *
* \param text sprite The other TextSprite
*/
inline TextSprite& TextSprite::operator=(const TextSprite& text) inline TextSprite& TextSprite::operator=(const TextSprite& text)
{ {
@ -130,6 +190,22 @@ namespace Nz
return *this; return *this;
} }
/*!
* \brief Invalidates the vertices
*/
inline void TextSprite::InvalidateVertices()
{
InvalidateInstanceData(0);
}
/*!
* \brief Creates a new text sprite from the arguments
* \return A reference to the newly created text sprite
*
* \param args Arguments for the text sprite
*/
template<typename... Args> template<typename... Args>
TextSpriteRef TextSprite::New(Args&&... args) TextSpriteRef TextSprite::New(Args&&... args)
{ {

View File

@ -7,11 +7,22 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Gets the texture of the background
* \return Texture of the background
*/
inline const TextureRef& TextureBackground::GetTexture() const inline const TextureRef& TextureBackground::GetTexture() const
{ {
return m_texture; return m_texture;
} }
/*!
* \brief Sets the texture of the background
*
* \param texture Texture of the background
*/
inline void TextureBackground::SetTexture(TextureRef texture) inline void TextureBackground::SetTexture(TextureRef texture)
{ {
NazaraAssert(!texture || texture->IsValid(), "Invalid texture"); NazaraAssert(!texture || texture->IsValid(), "Invalid texture");
@ -19,6 +30,13 @@ namespace Nz
m_texture = std::move(texture); m_texture = std::move(texture);
} }
/*!
* \brief Creates a new texture background from the arguments
* \return A reference to the newly created texture background
*
* \param args Arguments for the texture background
*/
template<typename... Args> template<typename... Args>
TextureBackgroundRef TextureBackground::New(Args&&... args) TextureBackgroundRef TextureBackground::New(Args&&... args)
{ {

View File

@ -90,7 +90,7 @@ namespace Nz
// Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse // Appel de la fonction avec le nombre 32bits, si le résultat est non-nul nous avons la réponse
unsigned int log2 = IntegralLog2Pot<UInt32>(val); unsigned int log2 = IntegralLog2Pot<UInt32>(val);
if (log2) if (log2 || val == 1)
return log2 + i*8; return log2 + i*8;
} }

View File

@ -491,8 +491,8 @@ namespace Nz
* *
* \remark If volume is infinite, IntersectionSide_Intersecting is returned * \remark If volume is infinite, IntersectionSide_Intersecting is returned
* \remark If volume is null, IntersectionSide_Outside is returned * \remark If volume is null, IntersectionSide_Outside is returned
* \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and false is returned * \remark If enumeration of the volume is not defined in Extend, a NazaraError is thrown and IntersectionSide_Outside is returned
* \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and false is returned. This should not never happen for a user of the library * \remark If enumeration of the intersection is not defined in IntersectionSide, a NazaraError is thrown and IntersectionSide_Outside is returned. This should not never happen for a user of the library
*/ */
template<typename T> template<typename T>

View File

@ -485,7 +485,7 @@ namespace Nz
template<typename T> template<typename T>
T Sphere<T>::SquaredDistance(const Vector3<T>& point) const T Sphere<T>::SquaredDistance(const Vector3<T>& point) const
{ {
return Vector3f::Distance(point, GetPosition()) - radius * radius; return Vector3f::SquaredDistance(point, GetPosition() + (point - GetPosition()).Normalize() * radius);
} }
/*! /*!

View File

@ -6,31 +6,62 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Gets the last error
* \return Socket error
*/
inline SocketError AbstractSocket::GetLastError() const inline SocketError AbstractSocket::GetLastError() const
{ {
return m_lastError; return m_lastError;
} }
/*!
* \brief Gets the internal socket handle
* \return Socket handle
*/
inline SocketHandle AbstractSocket::GetNativeHandle() const inline SocketHandle AbstractSocket::GetNativeHandle() const
{ {
return m_handle; return m_handle;
} }
/*!
* \brief Gets the internal state
* \return Socket state
*/
inline SocketState AbstractSocket::GetState() const inline SocketState AbstractSocket::GetState() const
{ {
return m_state; return m_state;
} }
/*!
* \brief Gets the internal type
* \return Socket type
*/
inline SocketType AbstractSocket::GetType() const inline SocketType AbstractSocket::GetType() const
{ {
return m_type; return m_type;
} }
/*!
* \brief Checks whether the blocking is enabled
* \return true If successful
*/
inline bool AbstractSocket::IsBlockingEnabled() const inline bool AbstractSocket::IsBlockingEnabled() const
{ {
return m_isBlockingEnabled; return m_isBlockingEnabled;
} }
/*!
* \brief Updates the state of the socket
*
* \param newState Next state for the socket
*/
inline void AbstractSocket::UpdateState(SocketState newState) inline void AbstractSocket::UpdateState(SocketState newState)
{ {
if (m_state != newState) if (m_state != newState)

View File

@ -27,17 +27,22 @@
#ifndef NAZARA_CONFIG_NETWORK_HPP #ifndef NAZARA_CONFIG_NETWORK_HPP
#define NAZARA_CONFIG_NETWORK_HPP #define NAZARA_CONFIG_NETWORK_HPP
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci /*!
* \defgroup network (NazaraNetwork) Network module
* Network/System module including classes to handle networking elements...
*/
// Utilise le MemoryManager pour gérer les allocations dynamiques (détecte les leaks au prix d'allocations/libérations dynamiques plus lentes) /// Each modification of a paramater of the module needs a recompilation of the unit
// Use the MemoryManager to manage dynamic allocations (can detect memory leak but allocations/frees are slower)
#define NAZARA_NETWORK_MANAGE_MEMORY 0 #define NAZARA_NETWORK_MANAGE_MEMORY 0
// Active les tests de sécurité basés sur le code (Conseillé pour le développement) // Activate the security tests based on the code (Advised for development)
#define NAZARA_NETWORK_SAFE 1 #define NAZARA_NETWORK_SAFE 1
/// Chaque modification d'un paramètre ci-dessous implique une modification (souvent mineure) du code /// Each modification of a parameter following implies a modification (often minor) of the code
/// Vérification des valeurs et types de certaines constantes /// Checking the values and types of certain constants
#include <Nazara/Network/ConfigCheck.hpp> #include <Nazara/Network/ConfigCheck.hpp>
#if defined(NAZARA_STATIC) #if defined(NAZARA_STATIC)

View File

@ -7,11 +7,11 @@
#ifndef NAZARA_CONFIG_CHECK_NETWORK_HPP #ifndef NAZARA_CONFIG_CHECK_NETWORK_HPP
#define NAZARA_CONFIG_CHECK_NETWORK_HPP #define NAZARA_CONFIG_CHECK_NETWORK_HPP
/// Ce fichier sert à vérifier la valeur des constantes du fichier Config.hpp /// This file is used to check the constant values defined in Config.hpp
#include <type_traits> #include <type_traits>
// On force la valeur de MANAGE_MEMORY en mode debug // We fore the value of MANAGE_MEMORY in debug
#if defined(NAZARA_DEBUG) && !NAZARA_NETWORK_MANAGE_MEMORY #if defined(NAZARA_DEBUG) && !NAZARA_NETWORK_MANAGE_MEMORY
#undef NAZARA_NETWORK_MANAGE_MEMORY #undef NAZARA_NETWORK_MANAGE_MEMORY
#define NAZARA_NETWORK_MANAGE_MEMORY 0 #define NAZARA_NETWORK_MANAGE_MEMORY 0

View File

@ -2,7 +2,7 @@
// This file is part of the "Nazara Engine - Network module" // This file is part of the "Nazara Engine - Network module"
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
// On suppose que Debug.hpp a déjà été inclus, tout comme Config.hpp // We suppose that Debug.hpp is already included, same goes for Config.hpp
#if NAZARA_NETWORK_MANAGE_MEMORY #if NAZARA_NETWORK_MANAGE_MEMORY
#undef delete #undef delete
#undef new #undef new

View File

@ -9,11 +9,22 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a IpAddress object by default
*/
inline IpAddress::IpAddress() : inline IpAddress::IpAddress() :
m_isValid(false) m_isValid(false)
{ {
} }
/*!
* \brief Constructs a IpAddress object with an IP and a port
*
* \param ip IPv4 address
* \param port Port of the IP
*/
inline IpAddress::IpAddress(const IPv4& ip, UInt16 port) : inline IpAddress::IpAddress(const IPv4& ip, UInt16 port) :
m_ipv4(ip), m_ipv4(ip),
m_protocol(NetProtocol_IPv4), m_protocol(NetProtocol_IPv4),
@ -22,6 +33,13 @@ namespace Nz
{ {
} }
/*!
* \brief Constructs a IpAddress object with an IP and a port
*
* \param ip IPv6 address
* \param port Port of the IP
*/
inline IpAddress::IpAddress(const IPv6& ip, UInt16 port) : inline IpAddress::IpAddress(const IPv6& ip, UInt16 port) :
m_ipv6(ip), m_ipv6(ip),
m_protocol(NetProtocol_IPv6), m_protocol(NetProtocol_IPv6),
@ -30,46 +48,100 @@ namespace Nz
{ {
} }
/*!
* \brief Constructs a IpAddress object with an IP and a port
*
* \param ip IPv4 address (a.b.c.d)
* \param port Port of the IP
*/
inline IpAddress::IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port) : inline IpAddress::IpAddress(const UInt8& a, const UInt8& b, const UInt8& c, const UInt8& d, UInt16 port) :
IpAddress(IPv4{a, b, c, d}, port) IpAddress(IPv4{a, b, c, d}, port)
{ {
} }
/*!
* \brief Constructs a IpAddress object with an IP and a port
*
* \param ip IPv6 address (a.b.c.d.e.f.g.h)
* \param port Port of the IP
*/
inline IpAddress::IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port) : inline IpAddress::IpAddress(const UInt16& a, const UInt16& b, const UInt16& c, const UInt16& d, const UInt16& e, const UInt16& f, const UInt16& g, const UInt16& h, UInt16 port) :
IpAddress(IPv6{a, b, c, d, e, f, g, h}, port) IpAddress(IPv6{a, b, c, d, e, f, g, h}, port)
{ {
} }
/*!
* Constructs a IpAddress object with a C-string
*
* \param address Hostname or textual IP address
*/
inline IpAddress::IpAddress(const char* address) inline IpAddress::IpAddress(const char* address)
{ {
BuildFromAddress(address); BuildFromAddress(address);
} }
/*!
* Constructs a IpAddress object with a string
*
* \param address Hostname or textual IP address
*/
inline IpAddress::IpAddress(const String& address) inline IpAddress::IpAddress(const String& address)
{ {
BuildFromAddress(address.GetConstBuffer()); BuildFromAddress(address.GetConstBuffer());
} }
/*!
* \brief Gets the port
* \return Port attached to the IP address
*/
inline UInt16 IpAddress::GetPort() const inline UInt16 IpAddress::GetPort() const
{ {
return m_port; return m_port;
} }
/*!
* \brief Gets the net protocol
* \return Protocol attached to the IP address
*/
inline NetProtocol IpAddress::GetProtocol() const inline NetProtocol IpAddress::GetProtocol() const
{ {
return m_protocol; return m_protocol;
} }
/*!
* \brief Checks whether the IP address is valid
* \return true If successful
*/
inline bool IpAddress::IsValid() const inline bool IpAddress::IsValid() const
{ {
return m_isValid; return m_isValid;
} }
/*!
* \brief Sets the port
*
* \param port Port attached to the IP address
*/
inline void IpAddress::SetPort(UInt16 port) inline void IpAddress::SetPort(UInt16 port)
{ {
m_port = port; m_port = port;
} }
/*!
* \brief Converts IpAddress to IPv4
* \return Corresponding IPv4
*
* \remark Produces a NazaraAssert if net protocol is not IPv4
*/
inline IpAddress::IPv4 IpAddress::ToIPv4() const inline IpAddress::IPv4 IpAddress::ToIPv4() const
{ {
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4"); NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4");
@ -77,6 +149,13 @@ namespace Nz
return m_ipv4; return m_ipv4;
} }
/*!
* \brief Converts IpAddress to IPv6
* \return Corresponding IPv6
*
* \remark Produces a NazaraAssert if net protocol is not IPv6
*/
inline IpAddress::IPv6 IpAddress::ToIPv6() const inline IpAddress::IPv6 IpAddress::ToIPv6() const
{ {
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv6, "IP is not a valid IPv6"); NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv6, "IP is not a valid IPv6");
@ -84,6 +163,13 @@ namespace Nz
return m_ipv6; return m_ipv6;
} }
/*!
* \brief Converts IpAddress to UInt32
* \return Corresponding UInt32
*
* \remark Produces a NazaraAssert if net protocol is not IPv4
*/
inline UInt32 IpAddress::ToUInt32() const inline UInt32 IpAddress::ToUInt32() const
{ {
NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4"); NazaraAssert(m_isValid && m_protocol == NetProtocol_IPv4, "Address is not a valid IPv4");
@ -94,17 +180,40 @@ namespace Nz
UInt32(m_ipv4[3]) << 0; UInt32(m_ipv4[3]) << 0;
} }
/*!
* \brief Converts IpAddress to boolean
* \return true If IpAddress is valid
*
* \see IsValid
*/
inline IpAddress::operator bool() const inline IpAddress::operator bool() const
{ {
return IsValid(); return IsValid();
} }
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param address The address to output
*/
inline std::ostream& operator<<(std::ostream& out, const IpAddress& address) inline std::ostream& operator<<(std::ostream& out, const IpAddress& address)
{ {
out << "IpAddress(" << address.ToString() << ')'; out << "IpAddress(" << address.ToString() << ')';
return out; return out;
} }
/*!
* \brief Compares the IpAddress to other one
* \return true if the ip addresses are the same
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator==(const IpAddress& first, const IpAddress& second) inline bool operator==(const IpAddress& first, const IpAddress& second)
{ {
// We need to check the validity of each address before comparing them // We need to check the validity of each address before comparing them
@ -146,11 +255,27 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Compares the IpAddress to other one
* \return false if the ip addresses are the same
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator!=(const IpAddress& first, const IpAddress& second) inline bool operator!=(const IpAddress& first, const IpAddress& second)
{ {
return !operator==(first, second); return !operator==(first, second);
} }
/*!
* \brief Compares the IpAddress to other one
* \return true if this ip address is inferior to the other one
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator<(const IpAddress& first, const IpAddress& second) inline bool operator<(const IpAddress& first, const IpAddress& second)
{ {
// If the second address is invalid, there's no way we're lower than it // If the second address is invalid, there's no way we're lower than it
@ -196,16 +321,40 @@ namespace Nz
return false; //< Same address return false; //< Same address
} }
/*!
* \brief Compares the IpAddress to other one
* \return true if this ip address is inferior or equal to the other one
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator<=(const IpAddress& first, const IpAddress& second) inline bool operator<=(const IpAddress& first, const IpAddress& second)
{ {
return !operator<(second, first); return !operator<(second, first);
} }
/*!
* \brief Compares the IpAddress to other one
* \return true if this ip address is greather to the other one
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator>(const IpAddress& first, const IpAddress& second) inline bool operator>(const IpAddress& first, const IpAddress& second)
{ {
return second < first; return second < first;
} }
/*!
* \brief Compares the IpAddress to other one
* \return true if this ip address is greather or equal to the other one
*
* \param first First ip address to compare
* \param second Second ip address to compare with
*/
inline bool operator>=(const IpAddress& first, const IpAddress& second) inline bool operator>=(const IpAddress& first, const IpAddress& second)
{ {
return !operator<(first, second); return !operator<(first, second);
@ -217,6 +366,13 @@ namespace std
template<> template<>
struct hash<Nz::IpAddress> struct hash<Nz::IpAddress>
{ {
/*!
* \brief Converts IpAddress to hash
* \return Hash of the IpAddress
*
* \param ip IpAddress to hash
*/
size_t operator()(const Nz::IpAddress& ip) const size_t operator()(const Nz::IpAddress& ip) const
{ {
if (!ip) if (!ip)
@ -224,7 +380,7 @@ namespace std
// This is SDBM adapted for IP addresses, tested to generate the least collisions possible // This is SDBM adapted for IP addresses, tested to generate the least collisions possible
// (It doesn't mean it cannot be improved though) // (It doesn't mean it cannot be improved though)
std::size_t h = 0; std::size_t hash = 0;
switch (ip.GetProtocol()) switch (ip.GetProtocol())
{ {
case Nz::NetProtocol_Any: case Nz::NetProtocol_Any:
@ -233,20 +389,20 @@ namespace std
case Nz::NetProtocol_IPv4: case Nz::NetProtocol_IPv4:
{ {
h = ip.ToUInt32() + (h << 6) + (h << 16) - h; hash = ip.ToUInt32() + (hash << 6) + (hash << 16) - hash;
break; break;
} }
case Nz::NetProtocol_IPv6: case Nz::NetProtocol_IPv6:
{ {
Nz::IpAddress::IPv6 v6 = ip.ToIPv6(); Nz::IpAddress::IPv6 v6 = ip.ToIPv6();
for (std::size_t i = 0; i < v6.size(); i++) for (std::size_t i = 0; i < v6.size(); i++)
h = v6[i] + (h << 6) + (h << 16) - h; hash = v6[i] + (hash << 6) + (hash << 16) - hash;
break; break;
} }
} }
return ip.GetPort() + (h << 6) + (h << 16) - h; return ip.GetPort() + (hash << 6) + (hash << 16) - hash;
} }
}; };
} }

View File

@ -9,21 +9,46 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a NetPacket object by default
*/
inline NetPacket::NetPacket() : inline NetPacket::NetPacket() :
m_netCode(NetCode_Invalid) m_netCode(NetCode_Invalid)
{ {
} }
/*!
* \brief Constructs a NetPacket object with a packet number and a minimal capacity
*
* \param netCode Packet number
* \param minCapacity Minimal capacity of the packet
*/
inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity) inline NetPacket::NetPacket(UInt16 netCode, std::size_t minCapacity)
{ {
Reset(netCode, minCapacity); Reset(netCode, minCapacity);
} }
/*!
* \brief Constructs a NetPacket object with a packet number and raw memory
*
* \param netCode Packet number
* \param ptr Raw memory
* \param size Size of the memory
*/
inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size) inline NetPacket::NetPacket(UInt16 netCode, const void* ptr, std::size_t size)
{ {
Reset(netCode, ptr, size); Reset(netCode, ptr, size);
} }
/*!
* \brief Constructs a NetPacket object with another one by move semantic
*
* \param packet NetPacket to move into this
*/
inline NetPacket::NetPacket(NetPacket&& packet) : inline NetPacket::NetPacket(NetPacket&& packet) :
ByteStream(std::move(packet)), ByteStream(std::move(packet)),
m_buffer(std::move(packet.m_buffer)), m_buffer(std::move(packet.m_buffer)),
@ -35,12 +60,23 @@ namespace Nz
SetStream(&m_memoryStream); SetStream(&m_memoryStream);
} }
/*!
* \brief Destructs the object
*/
inline NetPacket::~NetPacket() inline NetPacket::~NetPacket()
{ {
FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it FlushBits(); //< Needs to be done here as the stream will be freed before ByteStream calls it
FreeStream(); FreeStream();
} }
/*!
* \brief Gets the raw buffer
* \return Constant raw buffer
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline const UInt8* NetPacket::GetConstData() const inline const UInt8* NetPacket::GetConstData() const
{ {
NazaraAssert(m_buffer, "Invalid buffer"); NazaraAssert(m_buffer, "Invalid buffer");
@ -48,6 +84,13 @@ namespace Nz
return m_buffer->GetConstBuffer(); return m_buffer->GetConstBuffer();
} }
/*!
* \brief Gets the raw buffer
* \return Raw buffer
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline UInt8* NetPacket::GetData() const inline UInt8* NetPacket::GetData() const
{ {
NazaraAssert(m_buffer, "Invalid buffer"); NazaraAssert(m_buffer, "Invalid buffer");
@ -55,6 +98,11 @@ namespace Nz
return m_buffer->GetBuffer(); return m_buffer->GetBuffer();
} }
/*!
* \brief Gets the size of the data
* \return Size of the data
*/
inline size_t NetPacket::GetDataSize() const inline size_t NetPacket::GetDataSize() const
{ {
if (m_buffer) if (m_buffer)
@ -63,22 +111,46 @@ namespace Nz
return 0; return 0;
} }
/*!
* \brief Gets the packet number
* \return Packet number
*/
inline UInt16 NetPacket::GetNetCode() const inline UInt16 NetPacket::GetNetCode() const
{ {
return m_netCode; return m_netCode;
} }
/*!
* \brief Resets the packet
*/
inline void NetPacket::Reset() inline void NetPacket::Reset()
{ {
FreeStream(); FreeStream();
} }
/*!
* \brief Resets the packet with a packet number and a minimal capacity
*
* \param netCode Packet number
* \param minCapacity Minimal capacity of the packet
*/
inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity) inline void NetPacket::Reset(UInt16 netCode, std::size_t minCapacity)
{ {
InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite); InitStream(HeaderSize + minCapacity, HeaderSize, OpenMode_ReadWrite);
m_netCode = netCode; m_netCode = netCode;
} }
/*!
* \brief Resets the packet with a packet number and raw memory
*
* \param netCode Packet number
* \param ptr Raw memory
* \param size Size of the memory
*/
inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size) inline void NetPacket::Reset(UInt16 netCode, const void* ptr, std::size_t size)
{ {
InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly); InitStream(HeaderSize + size, HeaderSize, OpenMode_ReadOnly);
@ -88,6 +160,14 @@ namespace Nz
m_netCode = netCode; m_netCode = netCode;
} }
/*!
* \brief Resizes the packet
*
* \param newSize Size for the resizing operation
*
* \remark Produces a NazaraAssert if internal buffer is invalid
*/
inline void NetPacket::Resize(std::size_t newSize) inline void NetPacket::Resize(std::size_t newSize)
{ {
NazaraAssert(m_buffer, "Invalid buffer"); NazaraAssert(m_buffer, "Invalid buffer");
@ -95,11 +175,24 @@ namespace Nz
m_buffer->Resize(newSize); m_buffer->Resize(newSize);
} }
/*!
* \brief Sets the packet number
*
* \param netCode Packet number
*/
inline void NetPacket::SetNetCode(UInt16 netCode) inline void NetPacket::SetNetCode(UInt16 netCode)
{ {
m_netCode = netCode; m_netCode = netCode;
} }
/*!
* \brief Moves the NetPacket into this
* \return A reference to this
*
* \param packet NetPacket to move in this
*/
inline NetPacket& Nz::NetPacket::operator=(NetPacket&& packet) inline NetPacket& Nz::NetPacket::operator=(NetPacket&& packet)
{ {
FreeStream(); FreeStream();

View File

@ -8,31 +8,66 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Closes the connection
*/
inline void RUdpConnection::Close() inline void RUdpConnection::Close()
{ {
m_socket.Close(); m_socket.Close();
} }
/*!
* \brief Disconnects the connection
*
* \see Close
*/
inline void RUdpConnection::Disconnect() inline void RUdpConnection::Disconnect()
{ {
Close(); Close();
} }
/*!
* \brief Gets the bound address
* \return IpAddress we are linked to
*/
inline IpAddress RUdpConnection::GetBoundAddress() const inline IpAddress RUdpConnection::GetBoundAddress() const
{ {
return m_socket.GetBoundAddress(); return m_socket.GetBoundAddress();
} }
/*!
* \brief Gets the port of the bound address
* \return Port we are linked to
*/
inline UInt16 RUdpConnection::GetBoundPort() const inline UInt16 RUdpConnection::GetBoundPort() const
{ {
return m_socket.GetBoundPort(); return m_socket.GetBoundPort();
} }
/*!
* \brief Gets the last error
* \return Socket error
*/
inline SocketError RUdpConnection::GetLastError() const inline SocketError RUdpConnection::GetLastError() const
{ {
return m_lastError; return m_lastError;
} }
/*!
* \brief Listens to a socket
* \return true If successfully bound
*
* \param protocol Net protocol to listen to
* \param port Port to listen to
*
* \remark Produces a NazaraAssert if protocol is unknown or any
*/
inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port) inline bool RUdpConnection::Listen(NetProtocol protocol, UInt16 port)
{ {
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO
@ -59,16 +94,36 @@ namespace Nz
return Listen(any); return Listen(any);
} }
/*!
* \brief Sets the protocol id
*
* \param protocolId Protocol ID like NNet
*/
inline void RUdpConnection::SetProtocolId(UInt32 protocolId) inline void RUdpConnection::SetProtocolId(UInt32 protocolId)
{ {
m_protocol = protocolId; m_protocol = protocolId;
} }
/*!
* \brief Sets the time before ack
*
* \param Time before acking to send many together (in ms)
*/
inline void RUdpConnection::SetTimeBeforeAck(UInt32 ms) inline void RUdpConnection::SetTimeBeforeAck(UInt32 ms)
{ {
m_forceAckSendTime = ms * 1000; //< Store in microseconds for easier handling m_forceAckSendTime = ms * 1000; //< Store in microseconds for easier handling
} }
/*!
* \brief Computes the difference of sequence
* \return Delta between the two sequences
*
* \param sequence First sequence
* \param sequence2 Second sequence
*/
inline unsigned int RUdpConnection::ComputeSequenceDifference(SequenceIndex sequence, SequenceIndex sequence2) inline unsigned int RUdpConnection::ComputeSequenceDifference(SequenceIndex sequence, SequenceIndex sequence2)
{ {
unsigned int difference; unsigned int difference;
@ -77,9 +132,16 @@ namespace Nz
else else
difference = sequence - sequence2; difference = sequence - sequence2;
return 0; return difference;
} }
/*!
* \brief Checks whether the peer has pending packets
* \return true If it is the case
*
* \param peer Data relative to the peer
*/
inline bool RUdpConnection::HasPendingPackets(PeerData& peer) inline bool RUdpConnection::HasPendingPackets(PeerData& peer)
{ {
for (unsigned int priority = PacketPriority_Highest; priority <= PacketPriority_Lowest; ++priority) for (unsigned int priority = PacketPriority_Highest; priority <= PacketPriority_Lowest; ++priority)
@ -87,13 +149,19 @@ namespace Nz
std::vector<PendingPacket>& pendingPackets = peer.pendingPackets[priority]; std::vector<PendingPacket>& pendingPackets = peer.pendingPackets[priority];
if (!pendingPackets.empty()) if (!pendingPackets.empty())
return true; return true;
pendingPackets.clear();
} }
return false; return false;
} }
/*!
* \brief Checks whether the ack is more recent
* \return true If it is the case
*
* \param ack First sequence
* \param ack2 Second sequence
*/
inline bool RUdpConnection::IsAckMoreRecent(SequenceIndex ack, SequenceIndex ack2) inline bool RUdpConnection::IsAckMoreRecent(SequenceIndex ack, SequenceIndex ack2)
{ {
constexpr SequenceIndex maxDifference = std::numeric_limits<SequenceIndex>::max() / 2; constexpr SequenceIndex maxDifference = std::numeric_limits<SequenceIndex>::max() / 2;
@ -106,6 +174,13 @@ namespace Nz
return false; ///< Same ack return false; ///< Same ack
} }
/*!
* \brief Checks whether the connection is reliable
* \return true If it is the case
*
* \remark Produces a NazaraError if enumeration is invalid
*/
inline bool RUdpConnection::IsReliable(PacketReliability reliability) inline bool RUdpConnection::IsReliable(PacketReliability reliability)
{ {
switch (reliability) switch (reliability)
@ -122,6 +197,14 @@ namespace Nz
return false; return false;
} }
/*!
* \brief Simulates the loss of packets on network
*
* \param packetLoss Ratio of packet loss according to bernoulli distribution
*
* \remark Produces a NazaraAssert if packetLoss is not in between 0.0 and 1.0
*/
inline void RUdpConnection::SimulateNetwork(double packetLoss) inline void RUdpConnection::SimulateNetwork(double packetLoss)
{ {
NazaraAssert(packetLoss >= 0.0 && packetLoss <= 1.0, "Packet loss must be in range [0..1]"); NazaraAssert(packetLoss >= 0.0 && packetLoss <= 1.0, "Packet loss must be in range [0..1]");

View File

@ -79,8 +79,8 @@ namespace Nz
PendingPacket m_pendingPacket; PendingPacket m_pendingPacket;
UInt64 m_keepAliveInterval; UInt64 m_keepAliveInterval;
UInt64 m_keepAliveTime; UInt64 m_keepAliveTime;
bool m_isKeepAliveEnabled;
bool m_isLowDelayEnabled; bool m_isLowDelayEnabled;
bool m_isKeepAliveEnabled;
}; };
} }

View File

@ -7,6 +7,10 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a TcpClient object by default
*/
inline TcpClient::TcpClient() : inline TcpClient::TcpClient() :
AbstractSocket(SocketType_TCP), AbstractSocket(SocketType_TCP),
Stream(StreamOption_Sequential), Stream(StreamOption_Sequential),
@ -17,31 +21,62 @@ namespace Nz
{ {
} }
/*!
* \brief Disconnects the connection
*
* \see Close
*/
inline void TcpClient::Disconnect() inline void TcpClient::Disconnect()
{ {
Close(); Close();
} }
/*!
* \brief Gets the interval between two keep alive pings
* \return Interval in milliseconds between two pings
*/
inline UInt64 TcpClient::GetKeepAliveInterval() const inline UInt64 TcpClient::GetKeepAliveInterval() const
{ {
return m_keepAliveInterval; return m_keepAliveInterval;
} }
/*!
* \brief Gets the time before expiration of connection
* \return Time in milliseconds before expiration
*/
inline UInt64 TcpClient::GetKeepAliveTime() const inline UInt64 TcpClient::GetKeepAliveTime() const
{ {
return m_keepAliveTime; return m_keepAliveTime;
} }
/*!
* \brief Gets the remote address
* \return Address of peer
*/
inline IpAddress TcpClient::GetRemoteAddress() const inline IpAddress TcpClient::GetRemoteAddress() const
{ {
return m_peerAddress; return m_peerAddress;
} }
/*!
* \brief Checks whether low delay is enabled
* \return true If it is the case
*/
inline bool TcpClient::IsLowDelayEnabled() const inline bool TcpClient::IsLowDelayEnabled() const
{ {
return m_isLowDelayEnabled; return m_isLowDelayEnabled;
} }
/*!
* \brief Checks whether the keep alive flag is enabled
* \return true If it is the case
*/
inline bool TcpClient::IsKeepAliveEnabled() const inline bool TcpClient::IsKeepAliveEnabled() const
{ {
return m_isKeepAliveEnabled; return m_isKeepAliveEnabled;

View File

@ -7,27 +7,58 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a TcpServer object by default
*/
inline TcpServer::TcpServer() : inline TcpServer::TcpServer() :
AbstractSocket(SocketType_TCP) AbstractSocket(SocketType_TCP)
{ {
} }
/*!
* \brief Constructs a TcpServer object with another one by move semantic
*
* \param tcpServer TcpServer to move into this
*/
inline TcpServer::TcpServer(TcpServer&& tcpServer) : inline TcpServer::TcpServer(TcpServer&& tcpServer) :
AbstractSocket(std::move(tcpServer)), AbstractSocket(std::move(tcpServer)),
m_boundAddress(std::move(tcpServer.m_boundAddress)) m_boundAddress(std::move(tcpServer.m_boundAddress))
{ {
} }
/*!
* \brief Gets the bound address
* \return IpAddress we are linked to
*/
inline IpAddress TcpServer::GetBoundAddress() const inline IpAddress TcpServer::GetBoundAddress() const
{ {
return m_boundAddress; return m_boundAddress;
} }
/*!
* \brief Gets the port of the bound address
* \return Port we are linked to
*/
inline UInt16 TcpServer::GetBoundPort() const inline UInt16 TcpServer::GetBoundPort() const
{ {
return m_boundAddress.GetPort(); return m_boundAddress.GetPort();
} }
/*!
* \brief Listens to a socket
* \return State of the socket
*
* \param protocol Net protocol to listen to
* \param port Port to listen to
* \param queueSize Size of the queue
*
* \remark Produces a NazaraAssert if protocol is unknown or any
*/
inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize) inline SocketState TcpServer::Listen(NetProtocol protocol, UInt16 port, unsigned int queueSize)
{ {
NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO NazaraAssert(protocol != NetProtocol_Any, "Any protocol not supported for Listen"); //< TODO

View File

@ -49,7 +49,6 @@ namespace Nz
void OnOpened() override; void OnOpened() override;
IpAddress m_boundAddress; IpAddress m_boundAddress;
SocketState m_state;
bool m_isBroadCastingEnabled; bool m_isBroadCastingEnabled;
}; };
} }

View File

@ -6,24 +6,46 @@
namespace Nz namespace Nz
{ {
/*!
* \brief Constructs a UdpSocket object by default
*/
inline UdpSocket::UdpSocket() : inline UdpSocket::UdpSocket() :
AbstractSocket(SocketType_UDP) AbstractSocket(SocketType_UDP)
{ {
} }
/*!
* \brief Constructs a UdpSocket object with a net protocol
*
* \param protocol Net protocol to use
*/
inline UdpSocket::UdpSocket(NetProtocol protocol) : inline UdpSocket::UdpSocket(NetProtocol protocol) :
UdpSocket() UdpSocket()
{ {
Create(protocol); Create(protocol);
} }
/*!
* \brief Constructs a UdpSocket object with another one by move semantic
*
* \param udpSocket UdpSocket to move into this
*/
inline UdpSocket::UdpSocket(UdpSocket&& udpSocket) : inline UdpSocket::UdpSocket(UdpSocket&& udpSocket) :
AbstractSocket(std::move(udpSocket)), AbstractSocket(std::move(udpSocket)),
m_boundAddress(std::move(udpSocket.m_boundAddress)), m_boundAddress(std::move(udpSocket.m_boundAddress))
m_state(udpSocket.m_state)
{ {
} }
/*!
* \brief Binds a specific port
* \return State of the socket
*
* \param port Port to bind
*/
inline SocketState UdpSocket::Bind(UInt16 port) inline SocketState UdpSocket::Bind(UInt16 port)
{ {
IpAddress any; IpAddress any;
@ -47,6 +69,13 @@ namespace Nz
return Bind(any); return Bind(any);
} }
/*!
* \brief Creates a UDP socket
* \return true If successful
*
* \param protocol Net protocol to use
*/
bool UdpSocket::Create(NetProtocol protocol) bool UdpSocket::Create(NetProtocol protocol)
{ {
NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol"); NazaraAssert(protocol != NetProtocol_Unknown, "Invalid protocol");
@ -54,21 +83,41 @@ namespace Nz
return Open(protocol); return Open(protocol);
} }
/*!
* \brief Gets the bound address
* \return IpAddress we are linked to
*/
inline IpAddress UdpSocket::GetBoundAddress() const inline IpAddress UdpSocket::GetBoundAddress() const
{ {
return m_boundAddress; return m_boundAddress;
} }
/*!
* \brief Gets the port of the bound address
* \return Port we are linked to
*/
inline UInt16 UdpSocket::GetBoundPort() const inline UInt16 UdpSocket::GetBoundPort() const
{ {
return m_boundAddress.GetPort(); return m_boundAddress.GetPort();
} }
/*!
* \brief Gets the state of the socket
* \return State of the socket
*/
inline SocketState UdpSocket::GetState() const inline SocketState UdpSocket::GetState() const
{ {
return m_state; return m_state;
} }
/*!
* \brief Checks whether the broadcasting is enabled
* \return true If it is the case
*/
inline bool UdpSocket::IsBroadcastingEnabled() const inline bool UdpSocket::IsBroadcastingEnabled() const
{ {
return m_isBroadCastingEnabled; return m_isBroadCastingEnabled;

View File

@ -41,6 +41,7 @@ namespace Nz
static constexpr const char* HeightTexturePath = "MatHeightTexturePath"; static constexpr const char* HeightTexturePath = "MatHeightTexturePath";
static constexpr const char* Lighting = "MatLighting"; static constexpr const char* Lighting = "MatLighting";
static constexpr const char* LineWidth = "MatLineWidth"; static constexpr const char* LineWidth = "MatLineWidth";
static constexpr const char* Name = "MatName";
static constexpr const char* NormalTexturePath = "MatNormalTexturePath"; static constexpr const char* NormalTexturePath = "MatNormalTexturePath";
static constexpr const char* PointSize = "MatPointSize"; static constexpr const char* PointSize = "MatPointSize";
static constexpr const char* ScissorTest = "MatScissorTest"; static constexpr const char* ScissorTest = "MatScissorTest";

View File

@ -29,8 +29,8 @@ namespace Nz
{ {
MeshParams(); // Vérifie que le storage par défaut est supporté (software autrement) MeshParams(); // Vérifie que le storage par défaut est supporté (software autrement)
// La mise à l'échelle éventuelle que subira le mesh // La transformation appliquée à tous les sommets du mesh
Vector3f scale = Vector3f::Unit(); Matrix4f matrix = Matrix4f::Identity();
// Si ceci sera le stockage utilisé par les buffers // Si ceci sera le stockage utilisé par les buffers
UInt32 storage = DataStorage_Hardware; UInt32 storage = DataStorage_Hardware;

View File

@ -209,7 +209,7 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
aiVector3D tangent = (iMesh->HasTangentsAndBitangents()) ? iMesh->mTangents[j] : aiVector3D(0.f, 1.f, 0.f); aiVector3D tangent = (iMesh->HasTangentsAndBitangents()) ? iMesh->mTangents[j] : aiVector3D(0.f, 1.f, 0.f);
aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f); aiVector3D uv = (iMesh->HasTextureCoords(0)) ? iMesh->mTextureCoords[0][j] : aiVector3D(0.f);
vertex->position = parameters.scale * Vector3f(position.x, position.y, position.z); vertex->position = parameters.matrix * Vector3f(position.x, position.y, position.z);
vertex->normal.Set(normal.x, normal.y, normal.z); vertex->normal.Set(normal.x, normal.y, normal.z);
vertex->tangent.Set(tangent.x, tangent.y, tangent.z); vertex->tangent.Set(tangent.x, tangent.y, tangent.z);
vertex->uv.Set(uv.x, uv.y); vertex->uv.Set(uv.x, uv.y);
@ -291,8 +291,12 @@ bool Load(Mesh* mesh, Stream& stream, const MeshParams& parameters)
ConvertTexture(aiTextureType_OPACITY, MaterialData::AlphaTexturePath); ConvertTexture(aiTextureType_OPACITY, MaterialData::AlphaTexturePath);
ConvertTexture(aiTextureType_SPECULAR, MaterialData::SpecularTexturePath, MaterialData::SpecularWrap); ConvertTexture(aiTextureType_SPECULAR, MaterialData::SpecularTexturePath, MaterialData::SpecularWrap);
aiString name;
if (aiGetMaterialString(aiMat, AI_MATKEY_NAME, &name) == aiReturn_SUCCESS)
matData.SetParameter(MaterialData::Name, String(name.data, name.length));
int iValue; int iValue;
if (aiGetMaterialInteger(aiMat, AI_MATKEY_TWOSIDED, &iValue)) if (aiGetMaterialInteger(aiMat, AI_MATKEY_TWOSIDED, &iValue) == aiReturn_SUCCESS)
matData.SetParameter(MaterialData::FaceCulling, !iValue); matData.SetParameter(MaterialData::FaceCulling, !iValue);
matIt = materials.insert(std::make_pair(iMesh->mMaterialIndex, std::make_pair(materials.size(), std::move(matData)))).first; matIt = materials.insert(std::make_pair(iMesh->mMaterialIndex, std::make_pair(materials.size(), std::move(matData)))).first;

View File

@ -16,6 +16,21 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup audio
* \class Nz::Audio
* \brief Audio class that represents the module initializer of Audio
*/
/*!
* \brief Gets the format of the audio
* \return AudioFormat Enumeration type for the format
*
* \param channelCount Number of channels
*
* \remark Produces a NazaraError if the number of channels is erroneous (3 or 5) and AudioFormat_Unknown is returned
*/
AudioFormat Audio::GetAudioFormat(unsigned int channelCount) AudioFormat Audio::GetAudioFormat(unsigned int channelCount)
{ {
switch (channelCount) switch (channelCount)
@ -34,11 +49,21 @@ namespace Nz
} }
} }
/*!
* \brief Gets the factor of the doppler effect
* \return Global factor of the doppler effect
*/
float Audio::GetDopplerFactor() float Audio::GetDopplerFactor()
{ {
return alGetFloat(AL_DOPPLER_FACTOR); return alGetFloat(AL_DOPPLER_FACTOR);
} }
/*!
* \brief Gets the global volume
* \return Float between [0, inf) with 100.f being the default
*/
float Audio::GetGlobalVolume() float Audio::GetGlobalVolume()
{ {
ALfloat gain = 0.f; ALfloat gain = 0.f;
@ -47,6 +72,13 @@ namespace Nz
return gain * 100.f; return gain * 100.f;
} }
/*!
* \brief Gets the direction of the listener
* \return Direction of the listener, in front of the listener
*
* \see GetListenerRotation
*/
Vector3f Audio::GetListenerDirection() Vector3f Audio::GetListenerDirection()
{ {
ALfloat orientation[6]; ALfloat orientation[6];
@ -55,6 +87,13 @@ namespace Nz
return Vector3f(orientation[0], orientation[1], orientation[2]); return Vector3f(orientation[0], orientation[1], orientation[2]);
} }
/*!
* \brief Gets the position of the listener
* \return Position of the listener
*
* \see GetListenerVelocity
*/
Vector3f Audio::GetListenerPosition() Vector3f Audio::GetListenerPosition()
{ {
Vector3f position; Vector3f position;
@ -63,6 +102,11 @@ namespace Nz
return position; return position;
} }
/*!
* \brief Gets the rotation of the listener
* \return Rotation of the listener
*/
Quaternionf Audio::GetListenerRotation() Quaternionf Audio::GetListenerRotation()
{ {
ALfloat orientation[6]; ALfloat orientation[6];
@ -73,6 +117,13 @@ namespace Nz
return Quaternionf::RotationBetween(Vector3f::Forward(), forward); return Quaternionf::RotationBetween(Vector3f::Forward(), forward);
} }
/*!
* \brief Gets the velocity of the listener
* \return Velocity of the listener
*
* \see GetListenerPosition
*/
Vector3f Audio::GetListenerVelocity() Vector3f Audio::GetListenerVelocity()
{ {
Vector3f velocity; Vector3f velocity;
@ -81,20 +132,33 @@ namespace Nz
return velocity; return velocity;
} }
/*!
* \brief Gets the speed of sound
* \return Speed of sound
*/
float Audio::GetSpeedOfSound() float Audio::GetSpeedOfSound()
{ {
return alGetFloat(AL_SPEED_OF_SOUND); return alGetFloat(AL_SPEED_OF_SOUND);
} }
/*!
* \brief Initializes the Audio module
* \return true if initialization is successful
*
* \remark Produces a NazaraError if initialization of modules Core, OpenAL or SoundBuffer failed
* \remark Produces a NazaraNotice
*/
bool Audio::Initialize() bool Audio::Initialize()
{ {
if (s_moduleReferenceCounter > 0) if (IsInitialized())
{ {
s_moduleReferenceCounter++; s_moduleReferenceCounter++;
return true; // Déjà initialisé return true; // Already initialized
} }
// Initialisation des dépendances // Initialisation of dependencies
if (!Core::Initialize()) if (!Core::Initialize())
{ {
NazaraError("Failed to initialize core module"); NazaraError("Failed to initialize core module");
@ -103,10 +167,10 @@ namespace Nz
s_moduleReferenceCounter++; s_moduleReferenceCounter++;
// Initialisation du module // Initialisation of the module
CallOnExit onExit(Audio::Uninitialize); CallOnExit onExit(Audio::Uninitialize);
// Initialisation d'OpenAL // Initialisation of OpenAL
if (!OpenAL::Initialize()) if (!OpenAL::Initialize())
{ {
NazaraError("Failed to initialize OpenAL"); NazaraError("Failed to initialize OpenAL");
@ -119,7 +183,7 @@ namespace Nz
return false; return false;
} }
// Définition de l'orientation par défaut // Definition of the orientation by default
SetListenerDirection(Vector3f::Forward()); SetListenerDirection(Vector3f::Forward());
// Loaders // Loaders
@ -131,6 +195,13 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Checks whether the format is supported by the engine
* \return true if it is the case
*
* \param format Format to check
*/
bool Audio::IsFormatSupported(AudioFormat format) bool Audio::IsFormatSupported(AudioFormat format)
{ {
if (format == AudioFormat_Unknown) if (format == AudioFormat_Unknown)
@ -139,21 +210,46 @@ namespace Nz
return OpenAL::AudioFormat[format] != 0; return OpenAL::AudioFormat[format] != 0;
} }
/*!
* \brief Checks whether the module is initialized
* \return true if module is initialized
*/
bool Audio::IsInitialized() bool Audio::IsInitialized()
{ {
return s_moduleReferenceCounter != 0; return s_moduleReferenceCounter != 0;
} }
/*!
* \brief Sets the factor of the doppler effect
*
* \param dopplerFactor Global factor of the doppler effect
*/
void Audio::SetDopplerFactor(float dopplerFactor) void Audio::SetDopplerFactor(float dopplerFactor)
{ {
alDopplerFactor(dopplerFactor); alDopplerFactor(dopplerFactor);
} }
/*!
* \brief Sets the global volume
*
* \param volume Float between [0, inf) with 100.f being the default
*/
void Audio::SetGlobalVolume(float volume) void Audio::SetGlobalVolume(float volume)
{ {
alListenerf(AL_GAIN, volume * 0.01f); alListenerf(AL_GAIN, volume * 0.01f);
} }
/*!
* \brief Sets the direction of the listener
*
* \param direction Direction of the listener, in front of the listener
*
* \see SetListenerDirection, SetListenerRotation
*/
void Audio::SetListenerDirection(const Vector3f& direction) void Audio::SetListenerDirection(const Vector3f& direction)
{ {
Vector3f up = Vector3f::Up(); Vector3f up = Vector3f::Up();
@ -167,6 +263,14 @@ namespace Nz
alListenerfv(AL_ORIENTATION, orientation); alListenerfv(AL_ORIENTATION, orientation);
} }
/*!
* \brief Sets the direction of the listener
*
* \param (dirX, dirY, dirZ) Direction of the listener, in front of the listener
*
* \see SetListenerDirection, SetListenerRotation
*/
void Audio::SetListenerDirection(float dirX, float dirY, float dirZ) void Audio::SetListenerDirection(float dirX, float dirY, float dirZ)
{ {
Vector3f up = Vector3f::Up(); Vector3f up = Vector3f::Up();
@ -180,16 +284,38 @@ namespace Nz
alListenerfv(AL_ORIENTATION, orientation); alListenerfv(AL_ORIENTATION, orientation);
} }
/*!
* \brief Sets the position of the listener
*
* \param position Position of the listener
*
* \see SetListenerVelocity
*/
void Audio::SetListenerPosition(const Vector3f& position) void Audio::SetListenerPosition(const Vector3f& position)
{ {
alListenerfv(AL_POSITION, position); alListenerfv(AL_POSITION, position);
} }
/*!
* \brief Sets the position of the listener
*
* \param (x, y, z) Position of the listener
*
* \see SetListenerVelocity
*/
void Audio::SetListenerPosition(float x, float y, float z) void Audio::SetListenerPosition(float x, float y, float z)
{ {
alListener3f(AL_POSITION, x, y, z); alListener3f(AL_POSITION, x, y, z);
} }
/*!
* \brief Sets the rotation of the listener
*
* \param rotation Rotation of the listener
*/
void Audio::SetListenerRotation(const Quaternionf& rotation) void Audio::SetListenerRotation(const Quaternionf& rotation)
{ {
Vector3f forward = rotation * Vector3f::Forward(); Vector3f forward = rotation * Vector3f::Forward();
@ -204,33 +330,61 @@ namespace Nz
alListenerfv(AL_ORIENTATION, orientation); alListenerfv(AL_ORIENTATION, orientation);
} }
/*!
* \brief Sets the velocity of the listener
*
* \param velocity Velocity of the listener
*
* \see SetListenerPosition
*/
void Audio::SetListenerVelocity(const Vector3f& velocity) void Audio::SetListenerVelocity(const Vector3f& velocity)
{ {
alListenerfv(AL_VELOCITY, velocity); alListenerfv(AL_VELOCITY, velocity);
} }
/*!
* \brief Sets the velocity of the listener
*
* \param (velX, velY, velZ) Velocity of the listener
*
* \see SetListenerPosition
*/
void Audio::SetListenerVelocity(float velX, float velY, float velZ) void Audio::SetListenerVelocity(float velX, float velY, float velZ)
{ {
alListener3f(AL_VELOCITY, velX, velY, velZ); alListener3f(AL_VELOCITY, velX, velY, velZ);
} }
/*!
* \brief Sets the speed of sound
*
* \param speed Speed of sound
*/
void Audio::SetSpeedOfSound(float speed) void Audio::SetSpeedOfSound(float speed)
{ {
alSpeedOfSound(speed); alSpeedOfSound(speed);
} }
/*!
* \brief Uninitializes the Audio module
*
* \remark Produces a NazaraNotice
*/
void Audio::Uninitialize() void Audio::Uninitialize()
{ {
if (s_moduleReferenceCounter != 1) if (s_moduleReferenceCounter != 1)
{ {
// Le module est soit encore utilisé, soit pas initialisé // The module is still in use, or can not be uninitialized
if (s_moduleReferenceCounter > 1) if (s_moduleReferenceCounter > 1)
s_moduleReferenceCounter--; s_moduleReferenceCounter--;
return; return;
} }
// Libération du module // Free of module
s_moduleReferenceCounter = 0; s_moduleReferenceCounter = 0;
// Loaders // Loaders
@ -241,7 +395,7 @@ namespace Nz
NazaraNotice("Uninitialized: Audio module"); NazaraNotice("Uninitialized: Audio module");
// Libération des dépendances // Free of dependencies
Core::Uninitialize(); Core::Uninitialize();
} }

View File

@ -14,6 +14,19 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup audio
* \class Nz::Music
* \brief Audio class that represents a music
*
* \remark Module Audio needs to be initialized to use this class
*/
/*!
* \brief Checks whether the parameters for the loading of the music are correct
* \return true If parameters are valid
*/
bool MusicParams::IsValid() const bool MusicParams::IsValid() const
{ {
return true; return true;
@ -32,11 +45,26 @@ namespace Nz
unsigned int sampleRate; unsigned int sampleRate;
}; };
/*!
* \brief Destructs the object and calls Destroy
*
* \see Destroy
*/
Music::~Music() Music::~Music()
{ {
Destroy(); Destroy();
} }
/*!
* \brief Creates a music with a sound stream
* \return true if creation was succesful
*
* \param soundStream Sound stream which is the source for the music
*
* \remark Produces a NazaraError if soundStream is invalid with NAZARA_AUDIO_SAFE defined
*/
bool Music::Create(SoundStream* soundStream) bool Music::Create(SoundStream* soundStream)
{ {
NazaraAssert(soundStream, "Invalid stream"); NazaraAssert(soundStream, "Invalid stream");
@ -48,7 +76,7 @@ namespace Nz
m_impl = new MusicImpl; m_impl = new MusicImpl;
m_impl->sampleRate = soundStream->GetSampleRate(); m_impl->sampleRate = soundStream->GetSampleRate();
m_impl->audioFormat = OpenAL::AudioFormat[format]; m_impl->audioFormat = OpenAL::AudioFormat[format];
m_impl->chunkSamples.resize(format * m_impl->sampleRate); // Une seconde de samples m_impl->chunkSamples.resize(format * m_impl->sampleRate); // One second of samples
m_impl->stream.reset(soundStream); m_impl->stream.reset(soundStream);
SetPlayingOffset(0); SetPlayingOffset(0);
@ -56,6 +84,10 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Destroys the current music and frees resources
*/
void Music::Destroy() void Music::Destroy()
{ {
if (m_impl) if (m_impl)
@ -67,6 +99,14 @@ namespace Nz
} }
} }
/*!
* \brief Enables the looping of the music
*
* \param loop Should music loop
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
void Music::EnableLooping(bool loop) void Music::EnableLooping(bool loop)
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -80,6 +120,13 @@ namespace Nz
m_impl->loop = loop; m_impl->loop = loop;
} }
/*!
* \brief Gets the duration of the music
* \return Duration of the music in milliseconds
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
UInt32 Music::GetDuration() const UInt32 Music::GetDuration() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -93,6 +140,13 @@ namespace Nz
return m_impl->stream->GetDuration(); return m_impl->stream->GetDuration();
} }
/*!
* \brief Gets the format of the music
* \return Enumeration of type AudioFormat (mono, stereo, ...)
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
AudioFormat Music::GetFormat() const AudioFormat Music::GetFormat() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -106,6 +160,13 @@ namespace Nz
return m_impl->stream->GetFormat(); return m_impl->stream->GetFormat();
} }
/*!
* \brief Gets the current offset in the music
* \return Offset in milliseconds (works with entire seconds)
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
UInt32 Music::GetPlayingOffset() const UInt32 Music::GetPlayingOffset() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -125,6 +186,13 @@ namespace Nz
return static_cast<UInt32>((1000ULL * (samples + (m_impl->processedSamples / m_impl->stream->GetFormat()))) / m_impl->sampleRate); return static_cast<UInt32>((1000ULL * (samples + (m_impl->processedSamples / m_impl->stream->GetFormat()))) / m_impl->sampleRate);
} }
/*!
* \brief Gets the number of samples in the music
* \return Count of samples (number of seconds * sample rate * channel count)
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
UInt32 Music::GetSampleCount() const UInt32 Music::GetSampleCount() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -138,6 +206,13 @@ namespace Nz
return m_impl->stream->GetSampleCount(); return m_impl->stream->GetSampleCount();
} }
/*!
* \brief Gets the rates of sample in the music
* \return Rate of sample in Hertz (Hz)
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
UInt32 Music::GetSampleRate() const UInt32 Music::GetSampleRate() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -151,6 +226,14 @@ namespace Nz
return m_impl->sampleRate; return m_impl->sampleRate;
} }
/*!
* \brief Gets the status of the music
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
*
* \remark If the music is not playing, Stopped is returned
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
SoundStatus Music::GetStatus() const SoundStatus Music::GetStatus() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -163,13 +246,20 @@ namespace Nz
SoundStatus status = GetInternalStatus(); SoundStatus status = GetInternalStatus();
// Pour compenser les éventuels retards (ou le laps de temps entre Play() et la mise en route du thread) // To compensate any delays (or the timelaps between Play() and the thread startup)
if (m_impl->streaming && status == SoundStatus_Stopped) if (m_impl->streaming && status == SoundStatus_Stopped)
status = SoundStatus_Playing; status = SoundStatus_Playing;
return status; return status;
} }
/*!
* \brief Checks whether the music is looping
* \return true if it is the case
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
bool Music::IsLooping() const bool Music::IsLooping() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -183,26 +273,61 @@ namespace Nz
return m_impl->loop; return m_impl->loop;
} }
/*!
* \brief Loads the music from file
* \return true if loading is successful
*
* \param filePath Path to the file
* \param params Parameters for the music
*/
bool Music::OpenFromFile(const String& filePath, const MusicParams& params) bool Music::OpenFromFile(const String& filePath, const MusicParams& params)
{ {
return MusicLoader::LoadFromFile(this, filePath, params); return MusicLoader::LoadFromFile(this, filePath, params);
} }
/*!
* \brief Loads the music from memory
* \return true if loading is successful
*
* \param data Raw memory
* \param size Size of the memory
* \param params Parameters for the music
*/
bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params) bool Music::OpenFromMemory(const void* data, std::size_t size, const MusicParams& params)
{ {
return MusicLoader::LoadFromMemory(this, data, size, params); return MusicLoader::LoadFromMemory(this, data, size, params);
} }
/*!
* \brief Loads the music from stream
* \return true if loading is successful
*
* \param stream Stream to the music
* \param params Parameters for the music
*/
bool Music::OpenFromStream(Stream& stream, const MusicParams& params) bool Music::OpenFromStream(Stream& stream, const MusicParams& params)
{ {
return MusicLoader::LoadFromStream(this, stream, params); return MusicLoader::LoadFromStream(this, stream, params);
} }
/*!
* \brief Pauses the music
*/
void Music::Pause() void Music::Pause()
{ {
alSourcePause(m_source); alSourcePause(m_source);
} }
/*!
* \brief Plays the music
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
void Music::Play() void Music::Play()
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -238,6 +363,14 @@ namespace Nz
} }
} }
/*!
* \brief Sets the playing offset for the music
*
* \param offset Offset in the music in milliseconds
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
void Music::SetPlayingOffset(UInt32 offset) void Music::SetPlayingOffset(UInt32 offset)
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -260,6 +393,12 @@ namespace Nz
Play(); Play();
} }
/*!
* \brief Stops the music
*
* \remark Produces a NazaraError if there is no music with NAZARA_AUDIO_SAFE defined
*/
void Music::Stop() void Music::Stop()
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -277,6 +416,13 @@ namespace Nz
} }
} }
/*!
* \brief Fills the buffer and queues it up
* \return true if operation was successful
*
* \param buffer Index of the buffer
*/
bool Music::FillAndQueueBuffer(unsigned int buffer) bool Music::FillAndQueueBuffer(unsigned int buffer)
{ {
unsigned int sampleCount = m_impl->chunkSamples.size(); unsigned int sampleCount = m_impl->chunkSamples.size();
@ -304,27 +450,31 @@ namespace Nz
alSourceQueueBuffers(m_source, 1, &buffer); alSourceQueueBuffers(m_source, 1, &buffer);
} }
return sampleRead != sampleCount; // Fin du stream (N'arrive pas en cas de loop) return sampleRead != sampleCount; // End of stream (Does not happen when looping)
} }
/*!
* \brief Thread function for the music
*/
void Music::MusicThread() void Music::MusicThread()
{ {
// Allocation des buffers de streaming // Allocation of streaming buffers
ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT]; ALuint buffers[NAZARA_AUDIO_STREAMED_BUFFER_COUNT];
alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers); alGenBuffers(NAZARA_AUDIO_STREAMED_BUFFER_COUNT, buffers);
for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i) for (unsigned int i = 0; i < NAZARA_AUDIO_STREAMED_BUFFER_COUNT; ++i)
{ {
if (FillAndQueueBuffer(buffers[i])) if (FillAndQueueBuffer(buffers[i]))
break; // Nous avons atteint la fin du stream, inutile de rajouter des buffers break; // We have reached the end of the stream, there is no use to add new buffers
} }
alSourcePlay(m_source); alSourcePlay(m_source);
// Boucle de lecture (remplissage de nouveaux buffers au fur et à mesure) // Reading loop (Filling new buffers as playing)
while (m_impl->streaming) while (m_impl->streaming)
{ {
// La lecture s'est arrêtée, nous avons atteint la fin du stream // The reading has stopped, we have reached the end of the stream
SoundStatus status = GetInternalStatus(); SoundStatus status = GetInternalStatus();
if (status == SoundStatus_Stopped) if (status == SoundStatus_Stopped)
{ {
@ -334,7 +484,7 @@ namespace Nz
Nz::LockGuard lock(m_impl->bufferLock); Nz::LockGuard lock(m_impl->bufferLock);
// On traite les buffers lus // We treat read buffers
ALint processedCount = 0; ALint processedCount = 0;
alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount); alGetSourcei(m_source, AL_BUFFERS_PROCESSED, &processedCount);
while (processedCount--) while (processedCount--)
@ -355,14 +505,14 @@ namespace Nz
lock.Unlock(); lock.Unlock();
// On retourne dormir un peu // We go back to sleep
Thread::Sleep(50); Thread::Sleep(50);
} }
// Arrêt de la lecture du son (dans le cas où ça ne serait pas déjà fait) // Stop playing of the sound (in the case where it has not been already done)
alSourceStop(m_source); alSourceStop(m_source);
// On supprime les buffers du stream // We delete buffers from the stream
ALint queuedBufferCount; ALint queuedBufferCount;
alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount); alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queuedBufferCount);

View File

@ -23,6 +23,14 @@ namespace Nz
ALCcontext* s_context = nullptr; ALCcontext* s_context = nullptr;
unsigned int s_version; unsigned int s_version;
/*!
* \brief Parses the devices
* \return Number of devices
*
* \param deviceString String for the device (input / output)
* \param devices List of names of the devices
*/
std::size_t ParseDevices(const char* deviceString, std::vector<String>& devices) std::size_t ParseDevices(const char* deviceString, std::vector<String>& devices)
{ {
if (!deviceString) if (!deviceString)
@ -41,35 +49,77 @@ namespace Nz
} }
} }
/*!
* \ingroup audio
* \class Nz::OpenAL
* \brief Audio class that represents the link with OpenAL
*
* \remark This class is meant to be used by Module Audio
*/
/*!
* \brief Gets the entry for the function name
* \return Pointer to the function
*
* \param entryPoint Name of the entry
*
* \remark This does not produces a NazaraError if entry does not exist
*/
OpenALFunc OpenAL::GetEntry(const String& entryPoint) OpenALFunc OpenAL::GetEntry(const String& entryPoint)
{ {
return LoadEntry(entryPoint.GetConstBuffer(), false); return LoadEntry(entryPoint.GetConstBuffer(), false);
} }
/*!
* \brief Gets the name of the renderer
* \return Name of the renderer
*/
String OpenAL::GetRendererName() String OpenAL::GetRendererName()
{ {
return s_rendererName; return s_rendererName;
} }
/*!
* \brief Gets the name of the vendor
* \return Name of the vendor
*/
String OpenAL::GetVendorName() String OpenAL::GetVendorName()
{ {
return s_vendorName; return s_vendorName;
} }
/*!
* \brief Gets the version of OpenAL
* \return Version of OpenAL
*/
unsigned int OpenAL::GetVersion() unsigned int OpenAL::GetVersion()
{ {
return s_version; return s_version;
} }
/*!
* \brief Initializes the module OpenAL
* \return true if initialization is successful
*
* \param openDevice True to get information from the device
*
* \remark Produces a NazaraError if one of the entry failed
* \remark Produces a NazaraError if opening device failed with openDevice parameter set to true
*/
bool OpenAL::Initialize(bool openDevice) bool OpenAL::Initialize(bool openDevice)
{ {
if (s_library.IsLoaded()) if (IsInitialized())
return true; return true;
#if defined(NAZARA_PLATFORM_WINDOWS) #if defined(NAZARA_PLATFORM_WINDOWS)
///FIXME: Est-ce qu'OpenAL Soft est une meilleure implémentation que Creative ? ///FIXME: Is OpenAL Soft a better implementation than Creative ?
/// Si on pouvait se résigner à utiliser OpenAL Soft tout le temps, cela nous permettrait d'utiliser les extensions sonores /// If we could use OpenAL Soft everytime, this would allow us to use sonorous extensions
/// et de donner plus de possibilités techniques au niveau de l'audio. /// and give us more technical possibilities with audio
const char* libs[] = { const char* libs[] = {
"soft_oal.dll", "soft_oal.dll",
"wrap_oal.dll", "wrap_oal.dll",
@ -217,11 +267,23 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Checks whether the module is initialized
* \return true if it is the case
*/
bool OpenAL::IsInitialized() bool OpenAL::IsInitialized()
{ {
return s_library.IsLoaded(); return s_library.IsLoaded();
} }
/*!
* \brief Queries the input devices
* \return Number of devices
*
* \param devices List of names of the input devices
*/
std::size_t OpenAL::QueryInputDevices(std::vector<String>& devices) std::size_t OpenAL::QueryInputDevices(std::vector<String>& devices)
{ {
const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER)); const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_CAPTURE_DEVICE_SPECIFIER));
@ -231,6 +293,13 @@ namespace Nz
return ParseDevices(deviceString, devices); return ParseDevices(deviceString, devices);
} }
/*!
* \brief Queries the output devices
* \return Number of devices
*
* \param devices List of names of the output devices
*/
std::size_t OpenAL::QueryOutputDevices(std::vector<String>& devices) std::size_t OpenAL::QueryOutputDevices(std::vector<String>& devices)
{ {
const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER)); const char* deviceString = reinterpret_cast<const char*>(alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER));
@ -240,6 +309,13 @@ namespace Nz
return ParseDevices(deviceString, devices); return ParseDevices(deviceString, devices);
} }
/*!
* \brief Sets the active device
* \return true if device is successfully opened
*
* \param deviceName Name of the device
*/
bool OpenAL::SetDevice(const String& deviceName) bool OpenAL::SetDevice(const String& deviceName)
{ {
s_deviceName = deviceName; s_deviceName = deviceName;
@ -253,6 +329,10 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Uninitializes the module
*/
void OpenAL::Uninitialize() void OpenAL::Uninitialize()
{ {
CloseDevice(); CloseDevice();
@ -262,8 +342,14 @@ namespace Nz
s_library.Unload(); s_library.Unload();
} }
///ATTENTION: La valeur entière est le nombre de canaux possédés par ce format ///WARNING: The integer value is the number of canals owned by the format
ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Valeur ajoutées au chargement d'OpenAL ALenum OpenAL::AudioFormat[AudioFormat_Max+1] = {0}; // Added values with loading of OpenAL
/*!
* \brief Closes the device
*
* \remark Produces a NazaraWarning if you try to close an active device
*/
void OpenAL::CloseDevice() void OpenAL::CloseDevice()
{ {
@ -277,24 +363,31 @@ namespace Nz
} }
if (!alcCloseDevice(s_device)) if (!alcCloseDevice(s_device))
// Nous n'avons pas pu fermer le device, ce qui signifie qu'il est en cours d'utilisation // We could not close the close, this means that it's still in use
NazaraWarning("Failed to close device"); NazaraWarning("Failed to close device");
s_device = nullptr; s_device = nullptr;
} }
} }
/*!
* \brief Opens the device
* \return true if open is successful
*
* \remark Produces a NazaraError if it could not create the context
*/
bool OpenAL::OpenDevice() bool OpenAL::OpenDevice()
{ {
// Initialisation du module // Initialisation of the module
s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // On choisit le device par défaut s_device = alcOpenDevice(s_deviceName.IsEmpty() ? nullptr : s_deviceName.GetConstBuffer()); // We choose the default device
if (!s_device) if (!s_device)
{ {
NazaraError("Failed to open default device"); NazaraError("Failed to open default device");
return false; return false;
} }
// Un seul contexte nous suffira // One context is enough
s_context = alcCreateContext(s_device, nullptr); s_context = alcCreateContext(s_device, nullptr);
if (!s_context) if (!s_context)
{ {
@ -341,7 +434,7 @@ namespace Nz
s_version = 0; s_version = 0;
} }
// On complète le tableau de formats // We complete the formats table
AudioFormat[AudioFormat_Mono] = AL_FORMAT_MONO16; AudioFormat[AudioFormat_Mono] = AL_FORMAT_MONO16;
AudioFormat[AudioFormat_Stereo] = AL_FORMAT_STEREO16; AudioFormat[AudioFormat_Stereo] = AL_FORMAT_STEREO16;
@ -359,6 +452,16 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Loads the entry for the function name
* \return Pointer to the function
*
* \param name Name of the entry
* \param throwException Should throw exception if failed ?
*
* \remark Produces a std::runtime_error if entry does not exist and throwException is set to true
*/
OpenALFunc OpenAL::LoadEntry(const char* name, bool throwException) OpenALFunc OpenAL::LoadEntry(const char* name, bool throwException)
{ {
OpenALFunc entry = reinterpret_cast<OpenALFunc>(s_library.GetSymbol(name)); OpenALFunc entry = reinterpret_cast<OpenALFunc>(s_library.GetSymbol(name));

View File

@ -14,32 +14,76 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup audio
* \class Nz::Sound
* \brief Audio class that represents a sound
*
* \remark Module Audio needs to be initialized to use this class
*/
/*!
* \brief Constructs a Sound object
*
* \param soundBuffer Buffer to read sound from
*/
Sound::Sound(const SoundBuffer* soundBuffer) Sound::Sound(const SoundBuffer* soundBuffer)
{ {
SetBuffer(soundBuffer); SetBuffer(soundBuffer);
} }
/*!
* \brief Constructs a Sound object which is a copy of another
*
* \param sound Sound to copy
*/
Sound::Sound(const Sound& sound) : Sound::Sound(const Sound& sound) :
SoundEmitter(sound) SoundEmitter(sound)
{ {
SetBuffer(sound.m_buffer); SetBuffer(sound.m_buffer);
} }
/*!
* \brief Destructs the object and calls Stop
*
* \see Stop
*/
Sound::~Sound() Sound::~Sound()
{ {
Stop(); Stop();
} }
/*!
* \brief Enables the looping of the music
*
* \param loop Should sound loop
*/
void Sound::EnableLooping(bool loop) void Sound::EnableLooping(bool loop)
{ {
alSourcei(m_source, AL_LOOPING, loop); alSourcei(m_source, AL_LOOPING, loop);
} }
/*!
* \brief Gets the internal buffer
* \return Internal buffer
*/
const SoundBuffer* Sound::GetBuffer() const const SoundBuffer* Sound::GetBuffer() const
{ {
return m_buffer; return m_buffer;
} }
/*!
* \brief Gets the duration of the sound
* \return Duration of the music in milliseconds
*
* \remark Produces a NazaraError if there is no buffer
*/
UInt32 Sound::GetDuration() const UInt32 Sound::GetDuration() const
{ {
NazaraAssert(m_buffer, "Invalid sound buffer"); NazaraAssert(m_buffer, "Invalid sound buffer");
@ -47,6 +91,11 @@ namespace Nz
return m_buffer->GetDuration(); return m_buffer->GetDuration();
} }
/*!
* \brief Gets the current offset in the sound
* \return Offset in milliseconds (works with entire seconds)
*/
UInt32 Sound::GetPlayingOffset() const UInt32 Sound::GetPlayingOffset() const
{ {
ALint samples = 0; ALint samples = 0;
@ -55,11 +104,21 @@ namespace Nz
return static_cast<UInt32>(1000ULL * samples / m_buffer->GetSampleRate()); return static_cast<UInt32>(1000ULL * samples / m_buffer->GetSampleRate());
} }
/*!
* \brief Gets the status of the music
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
*/
SoundStatus Sound::GetStatus() const SoundStatus Sound::GetStatus() const
{ {
return GetInternalStatus(); return GetInternalStatus();
} }
/*!
* \brief Checks whether the sound is looping
* \return true if it is the case
*/
bool Sound::IsLooping() const bool Sound::IsLooping() const
{ {
ALint loop; ALint loop;
@ -68,16 +127,36 @@ namespace Nz
return loop != AL_FALSE; return loop != AL_FALSE;
} }
/*!
* \brief Checks whether the sound is playable
* \return true if it is the case
*/
bool Sound::IsPlayable() const bool Sound::IsPlayable() const
{ {
return m_buffer != nullptr; return m_buffer != nullptr;
} }
/*!
* \brief Checks whether the sound is playing
* \return true if it is the case
*/
bool Sound::IsPlaying() const bool Sound::IsPlaying() const
{ {
return GetStatus() == SoundStatus_Playing; return GetStatus() == SoundStatus_Playing;
} }
/*!
* \brief Loads the sound from file
* \return true if loading is successful
*
* \param filePath Path to the file
* \param params Parameters for the sound
*
* \remark Produces a NazaraError if loading failed
*/
bool Sound::LoadFromFile(const String& filePath, const SoundBufferParams& params) bool Sound::LoadFromFile(const String& filePath, const SoundBufferParams& params)
{ {
SoundBufferRef buffer = SoundBuffer::New(); SoundBufferRef buffer = SoundBuffer::New();
@ -91,6 +170,17 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Loads the sound from memory
* \return true if loading is successful
*
* \param data Raw memory
* \param size Size of the memory
* \param params Parameters for the sound
*
* \remark Produces a NazaraError if loading failed
*/
bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) bool Sound::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
{ {
SoundBufferRef buffer = SoundBuffer::New(); SoundBufferRef buffer = SoundBuffer::New();
@ -104,6 +194,16 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Loads the sound from stream
* \return true if loading is successful
*
* \param stream Stream to the sound
* \param params Parameters for the sound
*
* \remark Produces a NazaraError if loading failed
*/
bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params) bool Sound::LoadFromStream(Stream& stream, const SoundBufferParams& params)
{ {
SoundBufferRef buffer = SoundBuffer::New(); SoundBufferRef buffer = SoundBuffer::New();
@ -117,15 +217,25 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Pauses the sound
*/
void Sound::Pause() void Sound::Pause()
{ {
alSourcePause(m_source); alSourcePause(m_source);
} }
/*!
* \brief Plays the music
*
* \remark Produces a NazaraError if the sound is not playable with NAZARA_AUDIO_SAFE defined
*/
void Sound::Play() void Sound::Play()
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
if (!m_buffer) if (!IsPlayable())
{ {
NazaraError("Invalid sound buffer"); NazaraError("Invalid sound buffer");
return; return;
@ -135,6 +245,14 @@ namespace Nz
alSourcePlay(m_source); alSourcePlay(m_source);
} }
/*!
* \brief Sets the internal buffer
*
* \param buffer Internal buffer
*
* \remark Produces a NazaraError if buffer is invalid with NAZARA_AUDIO_SAFE defined
*/
void Sound::SetBuffer(const SoundBuffer* buffer) void Sound::SetBuffer(const SoundBuffer* buffer)
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -158,11 +276,21 @@ namespace Nz
alSourcei(m_source, AL_BUFFER, AL_NONE); alSourcei(m_source, AL_BUFFER, AL_NONE);
} }
/*!
* \brief Sets the playing offset for the sound
*
* \param offset Offset in the sound in milliseconds
*/
void Sound::SetPlayingOffset(UInt32 offset) void Sound::SetPlayingOffset(UInt32 offset)
{ {
alSourcei(m_source, AL_SAMPLE_OFFSET, static_cast<ALint>(offset/1000.f * m_buffer->GetSampleRate())); alSourcei(m_source, AL_SAMPLE_OFFSET, static_cast<ALint>(offset/1000.f * m_buffer->GetSampleRate()));
} }
/*!
* \brief Stops the sound
*/
void Sound::Stop() void Sound::Stop()
{ {
alSourceStop(m_source); alSourceStop(m_source);

View File

@ -12,10 +12,23 @@
#include <stdexcept> #include <stdexcept>
#include <Nazara/Audio/Debug.hpp> #include <Nazara/Audio/Debug.hpp>
///FIXME: Adapter la création ///FIXME: Adapt the creation
namespace Nz namespace Nz
{ {
/*!
* \ingroup audio
* \class Nz::SoundBuffer
* \brief Audio class that represents a buffer for sound
*
* \remark Module Audio needs to be initialized to use this class
*/
/*!
* \brief Checks whether the parameters for the buffer' sound are correct
* \return true If parameters are valid
*/
bool SoundBufferParams::IsValid() const bool SoundBufferParams::IsValid() const
{ {
return true; return true;
@ -31,6 +44,20 @@ namespace Nz
UInt32 sampleRate; UInt32 sampleRate;
}; };
/*!
* \brief Constructs a SoundBuffer object
*
* \param format Format for the audio
* \param sampleCount Number of samples
* \param sampleRate Rate of samples
* \param samples Samples raw data
*
* \remark Produces a NazaraError if creation went wrong with NAZARA_AUDIO_SAFE defined
* \remark Produces a std::runtime_error if creation went wrong with NAZARA_AUDIO_SAFE defined
*
* \see Create
*/
SoundBuffer::SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples) SoundBuffer::SoundBuffer(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples)
{ {
Create(format, sampleCount, sampleRate, samples); Create(format, sampleCount, sampleRate, samples);
@ -44,6 +71,12 @@ namespace Nz
#endif #endif
} }
/*!
* \brief Destructs the object and calls Destroy
*
* \see Destroy
*/
SoundBuffer::~SoundBuffer() SoundBuffer::~SoundBuffer()
{ {
OnSoundBufferRelease(this); OnSoundBufferRelease(this);
@ -51,6 +84,19 @@ namespace Nz
Destroy(); Destroy();
} }
/*!
* \brief Creates the SoundBuffer object
* \return true if creation is successful
*
* \param format Format for the audio
* \param sampleCount Number of samples
* \param sampleRate Rate of samples
* \param samples Samples raw data
*
* \remark Produces a NazaraError if creation went wrong with NAZARA_AUDIO_SAFE defined,
* this could happen if parameters are invalid or creation of OpenAL buffers failed
*/
bool SoundBuffer::Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples) bool SoundBuffer::Create(AudioFormat format, unsigned int sampleCount, unsigned int sampleRate, const Int16* samples)
{ {
Destroy(); Destroy();
@ -81,7 +127,7 @@ namespace Nz
} }
#endif #endif
// On vide le stack d'erreurs // We empty the error stack
while (alGetError() != AL_NO_ERROR); while (alGetError() != AL_NO_ERROR);
ALuint buffer; ALuint buffer;
@ -115,6 +161,10 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Destroys the current sound buffer and frees resources
*/
void SoundBuffer::Destroy() void SoundBuffer::Destroy()
{ {
if (m_impl) if (m_impl)
@ -126,6 +176,13 @@ namespace Nz
} }
} }
/*!
* \brief Gets the duration of the sound buffer
* \return Duration of the sound buffer in milliseconds
*
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
*/
UInt32 SoundBuffer::GetDuration() const UInt32 SoundBuffer::GetDuration() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -139,6 +196,13 @@ namespace Nz
return m_impl->duration; return m_impl->duration;
} }
/*!
* \brief Gets the format of the sound buffer
* \return Enumeration of type AudioFormat (mono, stereo, ...)
*
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
*/
AudioFormat SoundBuffer::GetFormat() const AudioFormat SoundBuffer::GetFormat() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -152,6 +216,13 @@ namespace Nz
return m_impl->format; return m_impl->format;
} }
/*!
* \brief Gets the internal raw samples
* \return Pointer to raw data
*
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
*/
const Int16* SoundBuffer::GetSamples() const const Int16* SoundBuffer::GetSamples() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -165,6 +236,13 @@ namespace Nz
return m_impl->samples.get(); return m_impl->samples.get();
} }
/*!
* \brief Gets the number of samples in the sound buffer
* \return Count of samples (number of seconds * sample rate * channel count)
*
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
*/
unsigned int SoundBuffer::GetSampleCount() const unsigned int SoundBuffer::GetSampleCount() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -178,6 +256,13 @@ namespace Nz
return m_impl->sampleCount; return m_impl->sampleCount;
} }
/*!
* \brief Gets the rates of sample in the sound buffer
* \return Rate of sample in Hertz (Hz)
*
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
*/
unsigned int SoundBuffer::GetSampleRate() const unsigned int SoundBuffer::GetSampleRate() const
{ {
#if NAZARA_AUDIO_SAFE #if NAZARA_AUDIO_SAFE
@ -191,31 +276,75 @@ namespace Nz
return m_impl->sampleRate; return m_impl->sampleRate;
} }
/*!
* \brief Checks whether the sound buffer is valid
* \return true if it is the case
*/
bool SoundBuffer::IsValid() const bool SoundBuffer::IsValid() const
{ {
return m_impl != nullptr; return m_impl != nullptr;
} }
/*!
* \brief Loads the sound buffer from file
* \return true if loading is successful
*
* \param filePath Path to the file
* \param params Parameters for the sound buffer
*/
bool SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params) bool SoundBuffer::LoadFromFile(const String& filePath, const SoundBufferParams& params)
{ {
return SoundBufferLoader::LoadFromFile(this, filePath, params); return SoundBufferLoader::LoadFromFile(this, filePath, params);
} }
/*!
* \brief Loads the sound buffer from memory
* \return true if loading is successful
*
* \param data Raw memory
* \param size Size of the memory
* \param params Parameters for the sound buffer
*/
bool SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params) bool SoundBuffer::LoadFromMemory(const void* data, std::size_t size, const SoundBufferParams& params)
{ {
return SoundBufferLoader::LoadFromMemory(this, data, size, params); return SoundBufferLoader::LoadFromMemory(this, data, size, params);
} }
/*!
* \brief Loads the sound buffer from stream
* \return true if loading is successful
*
* \param stream Stream to the sound buffer
* \param params Parameters for the sound buffer
*/
bool SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params) bool SoundBuffer::LoadFromStream(Stream& stream, const SoundBufferParams& params)
{ {
return SoundBufferLoader::LoadFromStream(this, stream, params); return SoundBufferLoader::LoadFromStream(this, stream, params);
} }
/*!
* \brief Checks whether the format is supported by the engine
* \return true if it is the case
*
* \param format Format to check
*/
bool SoundBuffer::IsFormatSupported(AudioFormat format) bool SoundBuffer::IsFormatSupported(AudioFormat format)
{ {
return Audio::IsFormatSupported(format); return Audio::IsFormatSupported(format);
} }
/*!
* \brief Gets the internal OpenAL buffer
* \return The index of the OpenAL buffer
*
* \remark Produces a NazaraError if there is no sound buffer with NAZARA_AUDIO_SAFE defined
*/
unsigned int SoundBuffer::GetOpenALBuffer() const unsigned int SoundBuffer::GetOpenALBuffer() const
{ {
#ifdef NAZARA_DEBUG #ifdef NAZARA_DEBUG
@ -229,6 +358,13 @@ namespace Nz
return m_impl->buffer; return m_impl->buffer;
} }
/*!
* \brief Initializes the libraries and managers
* \return true if initialization is successful
*
* \remark Produces a NazaraError if sub-initialization failed
*/
bool SoundBuffer::Initialize() bool SoundBuffer::Initialize()
{ {
if (!SoundBufferLibrary::Initialize()) if (!SoundBufferLibrary::Initialize())
@ -246,6 +382,10 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Uninitializes the libraries and managers
*/
void SoundBuffer::Uninitialize() void SoundBuffer::Uninitialize()
{ {
SoundBufferManager::Uninitialize(); SoundBufferManager::Uninitialize();

View File

@ -11,11 +11,32 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup audio
* \class Nz::SoundEmitter
* \brief Audio class that represents a sound source, that emits sound
*
* \remark Module Audio needs to be initialized to use this class
* \remark This class is abstract
*/
/*!
* \brief Constructs a SoundEmitter object
*/
SoundEmitter::SoundEmitter() SoundEmitter::SoundEmitter()
{ {
alGenSources(1, &m_source); alGenSources(1, &m_source);
} }
/*!
* \brief Constructs a SoundEmitter object which is a copy of another
*
* \param emitter SoundEmitter to copy
*
* \remark Position and velocity are not copied
*/
SoundEmitter::SoundEmitter(const SoundEmitter& emitter) SoundEmitter::SoundEmitter(const SoundEmitter& emitter)
{ {
alGenSources(1, &m_source); alGenSources(1, &m_source);
@ -23,20 +44,35 @@ namespace Nz
SetAttenuation(emitter.GetAttenuation()); SetAttenuation(emitter.GetAttenuation());
SetMinDistance(emitter.GetMinDistance()); SetMinDistance(emitter.GetMinDistance());
SetPitch(emitter.GetPitch()); SetPitch(emitter.GetPitch());
// Pas de copie de position ou de vitesse // No copy for position or velocity
SetVolume(emitter.GetVolume()); SetVolume(emitter.GetVolume());
} }
/*!
* \brief Destructs the object
*/
SoundEmitter::~SoundEmitter() SoundEmitter::~SoundEmitter()
{ {
alDeleteSources(1, &m_source); alDeleteSources(1, &m_source);
} }
/*!
* \brief Enables spatialization
*
* \param spatialization True if spatialization is enabled
*/
void SoundEmitter::EnableSpatialization(bool spatialization) void SoundEmitter::EnableSpatialization(bool spatialization)
{ {
alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization); alSourcei(m_source, AL_SOURCE_RELATIVE, !spatialization);
} }
/*!
* \brief Gets the attenuation
* \return Amount that your sound will drop off as by the inverse square law
*/
float SoundEmitter::GetAttenuation() const float SoundEmitter::GetAttenuation() const
{ {
ALfloat attenuation; ALfloat attenuation;
@ -45,6 +81,11 @@ namespace Nz
return attenuation; return attenuation;
} }
/*!
* \brief Gets the minimum distance to hear
* \return Distance to begin to hear
*/
float SoundEmitter::GetMinDistance() const float SoundEmitter::GetMinDistance() const
{ {
ALfloat distance; ALfloat distance;
@ -53,6 +94,11 @@ namespace Nz
return distance; return distance;
} }
/*!
* \brief Gets the pitch
* \return Pitch of the sound
*/
float SoundEmitter::GetPitch() const float SoundEmitter::GetPitch() const
{ {
ALfloat pitch; ALfloat pitch;
@ -61,6 +107,11 @@ namespace Nz
return pitch; return pitch;
} }
/*!
* \brief Gets the position of the emitter
* \return Position of the sound
*/
Vector3f SoundEmitter::GetPosition() const Vector3f SoundEmitter::GetPosition() const
{ {
Vector3f position; Vector3f position;
@ -69,6 +120,11 @@ namespace Nz
return position; return position;
} }
/*!
* \brief Gets the velocity of the emitter
* \return Velocity of the sound
*/
Vector3f SoundEmitter::GetVelocity() const Vector3f SoundEmitter::GetVelocity() const
{ {
Vector3f velocity; Vector3f velocity;
@ -77,6 +133,11 @@ namespace Nz
return velocity; return velocity;
} }
/*!
* \brief Gets the volume of the emitter
* \param volume Float between [0, inf) with 100.f being the default
*/
float SoundEmitter::GetVolume() const float SoundEmitter::GetVolume() const
{ {
ALfloat gain; ALfloat gain;
@ -85,6 +146,11 @@ namespace Nz
return gain * 100.f; return gain * 100.f;
} }
/*!
* \brief Checks whether the sound emitter has spatialization enabled
* \return true if it the case
*/
bool SoundEmitter::IsSpatialized() const bool SoundEmitter::IsSpatialized() const
{ {
ALint relative; ALint relative;
@ -93,46 +159,99 @@ namespace Nz
return relative == AL_FALSE; return relative == AL_FALSE;
} }
/*!
* \brief Sets the attenuation
*
* \param attenuation Amount that your sound will drop off as by the inverse square law
*/
void SoundEmitter::SetAttenuation(float attenuation) void SoundEmitter::SetAttenuation(float attenuation)
{ {
alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation); alSourcef(m_source, AL_ROLLOFF_FACTOR, attenuation);
} }
/*!
* \brief Sets the minimum distance to hear
*
* \param minDistance to begin to hear
*/
void SoundEmitter::SetMinDistance(float minDistance) void SoundEmitter::SetMinDistance(float minDistance)
{ {
alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance); alSourcef(m_source, AL_REFERENCE_DISTANCE, minDistance);
} }
/*!
* \brief Sets the pitch
*
* \param pitch of the sound
*/
void SoundEmitter::SetPitch(float pitch) void SoundEmitter::SetPitch(float pitch)
{ {
alSourcef(m_source, AL_PITCH, pitch); alSourcef(m_source, AL_PITCH, pitch);
} }
/*!
* \brief Sets the position of the emitter
*
* \param position Position of the sound
*/
void SoundEmitter::SetPosition(const Vector3f& position) void SoundEmitter::SetPosition(const Vector3f& position)
{ {
alSourcefv(m_source, AL_POSITION, position); alSourcefv(m_source, AL_POSITION, position);
} }
/*!
* \brief Sets the position of the emitter
*
* \param position Position of the sound with (x, y, z)
*/
void SoundEmitter::SetPosition(float x, float y, float z) void SoundEmitter::SetPosition(float x, float y, float z)
{ {
alSource3f(m_source, AL_POSITION, x, y, z); alSource3f(m_source, AL_POSITION, x, y, z);
} }
/*!
* \brief Sets the velocity of the emitter
*
* \param velocity Velocity of the sound
*/
void SoundEmitter::SetVelocity(const Vector3f& velocity) void SoundEmitter::SetVelocity(const Vector3f& velocity)
{ {
alSourcefv(m_source, AL_VELOCITY, velocity); alSourcefv(m_source, AL_VELOCITY, velocity);
} }
/*!
* \brief Sets the velocity of the emitter
*
* \param velocity Velocity with (velX, velY, velZ)
*/
void SoundEmitter::SetVelocity(float velX, float velY, float velZ) void SoundEmitter::SetVelocity(float velX, float velY, float velZ)
{ {
alSource3f(m_source, AL_VELOCITY, velX, velY, velZ); alSource3f(m_source, AL_VELOCITY, velX, velY, velZ);
} }
/*!
* \brief Sets the volume of the emitter
*
* \param volume Float between [0, inf) with 100.f being the default
*/
void SoundEmitter::SetVolume(float volume) void SoundEmitter::SetVolume(float volume)
{ {
alSourcef(m_source, AL_GAIN, volume * 0.01f); alSourcef(m_source, AL_GAIN, volume * 0.01f);
} }
/*!
* \brief Gets the status of the sound emitter
* \return Enumeration of type SoundStatus (Playing, Stopped, ...)
*/
SoundStatus SoundEmitter::GetInternalStatus() const SoundStatus SoundEmitter::GetInternalStatus() const
{ {
ALint state; ALint state;

View File

@ -6,5 +6,13 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup audio
* \class Nz::SoundStream
* \brief Audio class that represents a sound stream
*
* \remark This class is abstract
*/
SoundStream::~SoundStream() = default; SoundStream::~SoundStream() = default;
} }

View File

@ -28,7 +28,7 @@ namespace Nz
bool Core::Initialize() bool Core::Initialize()
{ {
if (s_moduleReferenceCounter > 0) if (IsInitialized())
{ {
s_moduleReferenceCounter++; s_moduleReferenceCounter++;
return true; // Already initialized return true; // Already initialized

View File

@ -906,5 +906,5 @@ namespace Nz
} }
return true; return true;
} };
} }

View File

@ -607,6 +607,54 @@ namespace Nz
parameter.value.ptrVal = value; parameter.value.ptrVal = value;
} }
/*!
* \brief Gives a string representation
* \return A string representation of the object: "ParameterList(Name: Type(value), ...)"
*/
String ParameterList::ToString() const
{
StringStream ss;
ss << "ParameterList(";
for (auto it = m_parameters.cbegin(); it != m_parameters.cend();)
{
ss << it->first << ": ";
switch (it->second.type)
{
case ParameterType_Boolean:
ss << "Boolean(" << String::Boolean(it->second.value.boolVal) << ")";
break;
case ParameterType_Color:
ss << "Color(" << it->second.value.colorVal.ToString() << ")";
break;
case ParameterType_Float:
ss << "Float(" << it->second.value.floatVal << ")";
break;
case ParameterType_Integer:
ss << "Integer(" << it->second.value.intVal << ")";
break;
case ParameterType_String:
ss << "String(" << it->second.value.stringVal << ")";
break;
case ParameterType_Pointer:
ss << "Pointer(" << String::Pointer(it->second.value.ptrVal) << ")";
break;
case ParameterType_Userdata:
ss << "Userdata(" << String::Pointer(it->second.value.userdataVal->ptr) << ")";
break;
case ParameterType_None:
ss << "None";
break;
}
if (++it != m_parameters.cend())
ss << ", ";
}
ss << ")";
return ss;
}
/*! /*!
* \brief Sets a userdata parameter named `name` * \brief Sets a userdata parameter named `name`
* *
@ -724,3 +772,17 @@ namespace Nz
} }
} }
} }
/*!
* \brief Output operator
* \return The stream
*
* \param out The stream
* \param parameterList The ParameterList to output
*/
std::ostream& operator<<(std::ostream& out, const Nz::ParameterList& parameterList)
{
out << parameterList.ToString();
return out;
}

View File

@ -143,7 +143,18 @@ namespace Nz
return false; return false;
} }
mode_t permissions; // TODO : get permission from first file mode_t permissions;
struct stat sb;
if (fstat(fd1, &sb) == -1) // get permission from first file
{
NazaraWarning("Could not get permissions of source file");
permissions = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
}
else
{
permissions = sb.st_mode & ~S_IFMT; // S_IFMT: bit mask for the file type bit field -> ~S_IFMT: general permissions
}
int fd2 = open64(targetPath.GetConstBuffer(), O_WRONLY | O_TRUNC, permissions); int fd2 = open64(targetPath.GetConstBuffer(), O_WRONLY | O_TRUNC, permissions);
if (fd2 == -1) if (fd2 == -1)
{ {

View File

@ -7,6 +7,14 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup graphics
* \class Nz::AbstractBackground
* \brief Graphics class that represents the background for our scene
*
* \remark This class is abstract
*/
AbstractBackground::~AbstractBackground() = default; AbstractBackground::~AbstractBackground() = default;
BackgroundLibrary::LibraryMap AbstractBackground::s_library; BackgroundLibrary::LibraryMap AbstractBackground::s_library;

View File

@ -7,23 +7,55 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup graphics
* \class Nz::AbstractRenderQueue
* \brief Graphics class that represents the rendering queue for our scene
*
* \remark This class is abstract
*/
AbstractRenderQueue::~AbstractRenderQueue() = default; AbstractRenderQueue::~AbstractRenderQueue() = default;
/*!
* \brief Adds a directional light to the rendering queue
*
* \param light Directional light
*/
void AbstractRenderQueue::AddDirectionalLight(const DirectionalLight& light) void AbstractRenderQueue::AddDirectionalLight(const DirectionalLight& light)
{ {
directionalLights.push_back(light); directionalLights.push_back(light);
} }
/*!
* \brief Adds a point light to the rendering queue
*
* \param light Point light
*/
void AbstractRenderQueue::AddPointLight(const PointLight& light) void AbstractRenderQueue::AddPointLight(const PointLight& light)
{ {
pointLights.push_back(light); pointLights.push_back(light);
} }
/*!
* \brief Adds a spot light to the rendering queue
*
* \param light Spot light
*/
void AbstractRenderQueue::AddSpotLight(const SpotLight& light) void AbstractRenderQueue::AddSpotLight(const SpotLight& light)
{ {
spotLights.push_back(light); spotLights.push_back(light);
} }
/*!
* \brief Clears the rendering queue
*
* \param fully Should everything be cleared ?
*/
void AbstractRenderQueue::Clear(bool fully) void AbstractRenderQueue::Clear(bool fully)
{ {
NazaraUnused(fully); NazaraUnused(fully);

View File

@ -10,6 +10,18 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup graphics
* \class Nz::AbstractRenderTechnique
* \brief Graphics class that represents the rendering technique for our scene
*
* \remark This class is abstract
*/
/*!
* \brief Constructs a AbstractRenderTechnique object
*/
AbstractRenderTechnique::AbstractRenderTechnique() : AbstractRenderTechnique::AbstractRenderTechnique() :
m_instancingEnabled(true) m_instancingEnabled(true)
{ {
@ -17,16 +29,34 @@ namespace Nz
AbstractRenderTechnique::~AbstractRenderTechnique() = default; AbstractRenderTechnique::~AbstractRenderTechnique() = default;
/*!
* \brief Enables the instancing
*
* \param instancing Should instancing be enabled
*
* \remark This may improve performances
*/
void AbstractRenderTechnique::EnableInstancing(bool instancing) void AbstractRenderTechnique::EnableInstancing(bool instancing)
{ {
m_instancingEnabled = instancing; m_instancingEnabled = instancing;
} }
/*!
* \brief Gets the name of the actual technique
* \return Name of the technique being used
*/
String AbstractRenderTechnique::GetName() const String AbstractRenderTechnique::GetName() const
{ {
return RenderTechniques::ToString(GetType()); return RenderTechniques::ToString(GetType());
} }
/*!
* \brief Checks whether the instancing is enabled
* \return true If it is the case
*/
bool AbstractRenderTechnique::IsInstancingEnabled() const bool AbstractRenderTechnique::IsInstancingEnabled() const
{ {
return m_instancingEnabled; return m_instancingEnabled;

View File

@ -7,5 +7,13 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup graphics
* \class Nz::AbstractViewer
* \brief Graphics class that represents the viewer for our scene
*
* \remark This class is abstract
*/
AbstractViewer::~AbstractViewer() = default; AbstractViewer::~AbstractViewer() = default;
} }

View File

@ -12,6 +12,19 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup graphics
* \class Nz::Billboard
* \brief Graphics class that represents a billboard, a 2D surface which simulates a 3D object
*/
/*!
* \brief Adds this billboard to the render queue
*
* \param renderQueue Queue to be added
* \param instanceData Data used for instance
*/
void Billboard::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const void Billboard::AddToRenderQueue(AbstractRenderQueue* renderQueue, const InstanceData& instanceData) const
{ {
if (!m_material) if (!m_material)
@ -20,6 +33,10 @@ namespace Nz
renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color); renderQueue->AddBillboard(instanceData.renderOrder, m_material, instanceData.transformMatrix.GetTranslation(), m_size, m_sinCos, m_color);
} }
/*
* \brief Makes the bounding volume of this billboard
*/
void Billboard::MakeBoundingVolume() const void Billboard::MakeBoundingVolume() const
{ {
constexpr float sqrt2 = float(M_SQRT2); constexpr float sqrt2 = float(M_SQRT2);

View File

@ -11,6 +11,11 @@ namespace Nz
{ {
namespace namespace
{ {
/*!
* \brief Defines render states
* \return RenderStates for the color background
*/
RenderStates BuildRenderStates() RenderStates BuildRenderStates()
{ {
RenderStates states; RenderStates states;
@ -24,6 +29,18 @@ namespace Nz
} }
} }
/*!
* \ingroup graphics
* \class Nz::ColorBackground
* \brief Graphics class that represents a background with uniform color
*/
/*!
* \brief Constructs a ColorBackground object with a color
*
* \param color Uniform color (by default Black)
*/
ColorBackground::ColorBackground(const Color& color) : ColorBackground::ColorBackground(const Color& color) :
m_color(color) m_color(color)
{ {
@ -38,6 +55,12 @@ namespace Nz
m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth"); m_vertexDepthUniform = shader->GetUniformLocation("VertexDepth");
} }
/*!
* \brief Draws this relatively to the viewer
*
* \param viewer Viewer for the background
*/
void ColorBackground::Draw(const AbstractViewer* viewer) const void ColorBackground::Draw(const AbstractViewer* viewer) const
{ {
NazaraUnused(viewer); NazaraUnused(viewer);
@ -55,16 +78,32 @@ namespace Nz
Renderer::DrawFullscreenQuad(); Renderer::DrawFullscreenQuad();
} }
/*!
* \brief Gets the background type
* \return Type of background
*/
BackgroundType ColorBackground::GetBackgroundType() const BackgroundType ColorBackground::GetBackgroundType() const
{ {
return BackgroundType_Color; return BackgroundType_Color;
} }
/*!
* \brief Gets the color of the background
* \return Background color
*/
Color ColorBackground::GetColor() const Color ColorBackground::GetColor() const
{ {
return m_color; return m_color;
} }
/*!
* \brief Sets the color of the background
*
* \param color Background color
*/
void ColorBackground::SetColor(const Color& color) void ColorBackground::SetColor(const Color& color)
{ {
m_color = color; m_color = color;

View File

@ -9,6 +9,16 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup graphics
* \class Nz::DeferredBloomPass
* \brief Graphics class that represents the pass for bloom in deferred rendering
*/
/*!
* \brief Constructs a DeferredBloomPass object by default
*/
DeferredBloomPass::DeferredBloomPass() : DeferredBloomPass::DeferredBloomPass() :
m_uniformUpdated(false), m_uniformUpdated(false),
m_brightLuminance(0.8f), m_brightLuminance(0.8f),
@ -32,26 +42,55 @@ namespace Nz
DeferredBloomPass::~DeferredBloomPass() = default; DeferredBloomPass::~DeferredBloomPass() = default;
/*!
* \brief Gets the number of pass for blur
* \return Number of pass for blur
*/
unsigned int DeferredBloomPass::GetBlurPassCount() const unsigned int DeferredBloomPass::GetBlurPassCount() const
{ {
return m_blurPassCount; return m_blurPassCount;
} }
/*!
* \brief Gets the coefficiant for luminosity
* \return Luminosity of bright elements
*/
float DeferredBloomPass::GetBrightLuminance() const float DeferredBloomPass::GetBrightLuminance() const
{ {
return m_brightLuminance; return m_brightLuminance;
} }
/*!
* \brief Gets the coefficiant for the middle grey
* \return Luminosity of grey elements
*/
float DeferredBloomPass::GetBrightMiddleGrey() const float DeferredBloomPass::GetBrightMiddleGrey() const
{ {
return m_brightMiddleGrey; return m_brightMiddleGrey;
} }
/*!
* \brief Gets the coefficiant for things to be bright
* \return Threshold for bright elements
*/
float DeferredBloomPass::GetBrightThreshold() const float DeferredBloomPass::GetBrightThreshold() const
{ {
return m_brightThreshold; return m_brightThreshold;
} }
/*!
* \brief Gets the ith texture
* \return Texture computed
*
* \param i Index of the texture
*
* \remark Produces a NazaraError with NAZARA_GRAPHICS_SAFE defined if index is invalid
*/
Texture* DeferredBloomPass::GetTexture(unsigned int i) const Texture* DeferredBloomPass::GetTexture(unsigned int i) const
{ {
#if NAZARA_GRAPHICS_SAFE #if NAZARA_GRAPHICS_SAFE
@ -65,7 +104,16 @@ namespace Nz
return m_bloomTextures[i]; return m_bloomTextures[i];
} }
bool DeferredBloomPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const /*!
* \brief Processes the work on the data while working with textures
* \return true
*
* \param sceneData Data for the scene
* \param firstWorkTexture Index of the first texture to work with
* \param firstWorkTexture Index of the second texture to work with
*/
bool DeferredBloomPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
{ {
NazaraUnused(sceneData); NazaraUnused(sceneData);
@ -124,6 +172,13 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Resizes the texture sizes
* \return true If successful
*
* \param dimensions Dimensions for the compute texture
*/
bool DeferredBloomPass::Resize(const Vector2ui& dimensions) bool DeferredBloomPass::Resize(const Vector2ui& dimensions)
{ {
DeferredRenderPass::Resize(dimensions); DeferredRenderPass::Resize(dimensions);
@ -145,23 +200,47 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Sets the number of pass for blur
*
* \param passCount Number of pass for blur
*/
void DeferredBloomPass::SetBlurPassCount(unsigned int passCount) void DeferredBloomPass::SetBlurPassCount(unsigned int passCount)
{ {
m_blurPassCount = passCount; // N'est pas une uniforme m_blurPassCount = passCount; // N'est pas une uniforme
} }
/*!
* \brief Sets the coefficiant for luminosity
*
* \param luminance Luminosity of bright elements
*/
void DeferredBloomPass::SetBrightLuminance(float luminance) void DeferredBloomPass::SetBrightLuminance(float luminance)
{ {
m_brightLuminance = luminance; m_brightLuminance = luminance;
m_uniformUpdated = false; m_uniformUpdated = false;
} }
/*!
* \brief Sets the coefficiant for the middle grey
*
* \param middleGrey Luminosity of grey elements
*/
void DeferredBloomPass::SetBrightMiddleGrey(float middleGrey) void DeferredBloomPass::SetBrightMiddleGrey(float middleGrey)
{ {
m_brightMiddleGrey = middleGrey; m_brightMiddleGrey = middleGrey;
m_uniformUpdated = false; m_uniformUpdated = false;
} }
/*!
* \brief Sets the coefficiant for things to be bright
*
* \param threshold Threshold for bright elements
*/
void DeferredBloomPass::SetBrightThreshold(float threshold) void DeferredBloomPass::SetBrightThreshold(float threshold)
{ {
m_brightThreshold = threshold; m_brightThreshold = threshold;

View File

@ -13,6 +13,10 @@ namespace Nz
{ {
namespace namespace
{ {
/*!
* \brief Builds the shader for the depth of field
* \return Reference to the shader newly created
*/
// http://digitalerr0r.wordpress.com/2009/05/16/xna-shader-programming-tutorial-20-depth-of-field/ // http://digitalerr0r.wordpress.com/2009/05/16/xna-shader-programming-tutorial-20-depth-of-field/
ShaderRef BuildDepthOfFieldShader() ShaderRef BuildDepthOfFieldShader()
{ {
@ -92,6 +96,16 @@ namespace Nz
} }
} }
/*!
* \ingroup graphics
* \class Nz::DeferredDOFPass
* \brief Graphics class that represents the pass for depth of field in deferred rendering
*/
/*!
* \brief Constructs a DeferredDOFPass object by default
*/
DeferredDOFPass::DeferredDOFPass() DeferredDOFPass::DeferredDOFPass()
{ {
m_dofShader = BuildDepthOfFieldShader(); m_dofShader = BuildDepthOfFieldShader();
@ -118,7 +132,16 @@ namespace Nz
DeferredDOFPass::~DeferredDOFPass() = default; DeferredDOFPass::~DeferredDOFPass() = default;
bool DeferredDOFPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const /*!
* \brief Processes the work on the data while working with textures
* \return true
*
* \param sceneData Data for the scene
* \param firstWorkTexture Index of the first texture to work with
* \param firstWorkTexture Index of the second texture to work with
*/
bool DeferredDOFPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
{ {
NazaraUnused(sceneData); NazaraUnused(sceneData);
@ -162,6 +185,13 @@ namespace Nz
return true; return true;
} }
/*!
* \brief Resizes the texture sizes
* \return true If successful
*
* \param dimensions Dimensions for the compute texture
*/
bool DeferredDOFPass::Resize(const Vector2ui& dimensions) bool DeferredDOFPass::Resize(const Vector2ui& dimensions)
{ {
DeferredRenderPass::Resize(dimensions); DeferredRenderPass::Resize(dimensions);

View File

@ -10,6 +10,16 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup graphics
* \class Nz::DeferredFXAAPass
* \brief Graphics class that represents the pass for FXAA in deferred rendering
*/
/*!
* \brief Constructs a DeferredFXAAPass object by default
*/
DeferredFXAAPass::DeferredFXAAPass() DeferredFXAAPass::DeferredFXAAPass()
{ {
m_fxaaShader = ShaderLibrary::Get("DeferredFXAA"); m_fxaaShader = ShaderLibrary::Get("DeferredFXAA");
@ -23,7 +33,16 @@ namespace Nz
DeferredFXAAPass::~DeferredFXAAPass() = default; DeferredFXAAPass::~DeferredFXAAPass() = default;
bool DeferredFXAAPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const /*!
* \brief Processes the work on the data while working with textures
* \return true
*
* \param sceneData Data for the scene
* \param firstWorkTexture Index of the first texture to work with
* \param firstWorkTexture Index of the second texture to work with
*/
bool DeferredFXAAPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
{ {
NazaraUnused(sceneData); NazaraUnused(sceneData);

View File

@ -10,6 +10,16 @@
namespace Nz namespace Nz
{ {
/*!
* \ingroup graphics
* \class Nz::DeferredFinalPass
* \brief Graphics class that represents the final pass in deferred rendering
*/
/*!
* \brief Constructs a DeferredFinalPass object by default
*/
DeferredFinalPass::DeferredFinalPass() DeferredFinalPass::DeferredFinalPass()
{ {
m_pointSampler.SetAnisotropyLevel(1); m_pointSampler.SetAnisotropyLevel(1);
@ -34,7 +44,16 @@ namespace Nz
DeferredFinalPass::~DeferredFinalPass() = default; DeferredFinalPass::~DeferredFinalPass() = default;
bool DeferredFinalPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned secondWorkTexture) const /*!
* \brief Processes the work on the data while working with textures
* \return true
*
* \param sceneData Data for the scene
* \param firstWorkTexture Index of the first texture to work with
* \param firstWorkTexture Index of the second texture to work with
*/
bool DeferredFinalPass::Process(const SceneData& sceneData, unsigned int firstWorkTexture, unsigned int secondWorkTexture) const
{ {
NazaraAssert(sceneData.viewer, "Invalid viewer"); NazaraAssert(sceneData.viewer, "Invalid viewer");

Some files were not shown because too many files have changed in this diff Show More