Adding Project Files
This commit is contained in:
+350
@@ -0,0 +1,350 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.28307.852
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "OpenWindow", "OpenWindow\OpenWindow.vcxproj", "{42971E68-F861-4D45-9DA6-F5E163705584}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{42971E68-F861-4D45-9DA6-F5E163705584}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{42971E68-F861-4D45-9DA6-F5E163705584}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{42971E68-F861-4D45-9DA6-F5E163705584}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
|
{42971E68-F861-4D45-9DA6-F5E163705584}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{42971E68-F861-4D45-9DA6-F5E163705584}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{42971E68-F861-4D45-9DA6-F5E163705584}.Release|x64.Build.0 = Release|x64
|
||||||
|
{42971E68-F861-4D45-9DA6-F5E163705584}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
{42971E68-F861-4D45-9DA6-F5E163705584}.Release|x86.Build.0 = Release|Win32
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {E8F2DE00-C3E8-4801-B6A2-84B81D8359A9}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -0,0 +1,135 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>15.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{42971E68-F861-4D45-9DA6-F5E163705584}</ProjectGuid>
|
||||||
|
<RootNamespace>OpenWindow</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.18362.0</WindowsTargetPlatformVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup />
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="geometry.cpp" />
|
||||||
|
<ClCompile Include="main.cpp" />
|
||||||
|
<ClCompile Include="model.cpp" />
|
||||||
|
<ClCompile Include="renderer.cpp" />
|
||||||
|
<ClCompile Include="tgaimage.cpp" />
|
||||||
|
<ClCompile Include="util_window.cpp" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="geometry.h" />
|
||||||
|
<ClInclude Include="model.h" />
|
||||||
|
<ClInclude Include="renderer.h" />
|
||||||
|
<ClInclude Include="tgaimage.h" />
|
||||||
|
<ClInclude Include="util_window.h" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="util_window.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="main.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="geometry.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="model.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="tgaimage.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="renderer.cpp">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClInclude Include="util_window.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="geometry.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="model.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="tgaimage.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="renderer.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
|||||||
|
#include "geometry.h"
|
||||||
|
|
||||||
|
template <> template <> vec<3,int> ::vec(const vec<3,float> &v) : x(int(v.x+.5f)),y(int(v.y+.5f)),z(int(v.z+.5f)) {}
|
||||||
|
template <> template <> vec<3,float>::vec(const vec<3,int> &v) : x(v.x),y(v.y),z(v.z) {}
|
||||||
|
template <> template <> vec<2,int> ::vec(const vec<2,float> &v) : x(int(v.x+.5f)),y(int(v.y+.5f)) {}
|
||||||
|
template <> template <> vec<2,float>::vec(const vec<2,int> &v) : x(v.x),y(v.y) {}
|
||||||
|
|
||||||
@@ -0,0 +1,237 @@
|
|||||||
|
#ifndef __GEOMETRY_H__
|
||||||
|
#define __GEOMETRY_H__
|
||||||
|
#include <cmath>
|
||||||
|
#include <vector>
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
template<size_t DimCols,size_t DimRows,typename T> class mat;
|
||||||
|
|
||||||
|
template <size_t DIM, typename T> struct vec {
|
||||||
|
vec() { for (size_t i=DIM; i--; data_[i] = T()); }
|
||||||
|
T& operator[](const size_t i) { assert(i<DIM); return data_[i]; }
|
||||||
|
const T& operator[](const size_t i) const { assert(i<DIM); return data_[i]; }
|
||||||
|
private:
|
||||||
|
T data_[DIM];
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T> struct vec<2,T> {
|
||||||
|
vec() : x(T()), y(T()) {}
|
||||||
|
vec(T X, T Y) : x(X), y(Y) {}
|
||||||
|
template <class U> vec<2,T>(const vec<2,U> &v);
|
||||||
|
T& operator[](const size_t i) { assert(i<2); return i<=0 ? x : y; }
|
||||||
|
const T& operator[](const size_t i) const { assert(i<2); return i<=0 ? x : y; }
|
||||||
|
|
||||||
|
T x,y;
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T> struct vec<3,T> {
|
||||||
|
vec() : x(T()), y(T()), z(T()) {}
|
||||||
|
vec(T X, T Y, T Z) : x(X), y(Y), z(Z) {}
|
||||||
|
vec(vec<4, T> v) : x(v.x/v.w), y(v.y/v.w), z(v.z/v.w) {}
|
||||||
|
template <class U> vec<3,T>(const vec<3,U> &v);
|
||||||
|
T& operator[](const size_t i) { assert(i<3); return i<=0 ? x : (1==i ? y : z); }
|
||||||
|
const T& operator[](const size_t i) const { assert(i<3); return i<=0 ? x : (1==i ? y : z); }
|
||||||
|
float norm() { return std::sqrt(x*x+y*y+z*z); }
|
||||||
|
vec<3,T> & normalize(T l=1) { *this = (*this)*(l/norm()); return *this; }
|
||||||
|
|
||||||
|
T x,y,z;
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template <typename T> struct vec<4,T> {
|
||||||
|
vec() : x(T()), y(T()), z(T()), w(T()) {}
|
||||||
|
vec(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) {}
|
||||||
|
vec(vec<3, T> v) : x(v.x), y(v.y), z(v.z), w(1) {}
|
||||||
|
template <class U> vec<4,T>(const vec<4,U> &v);
|
||||||
|
T& operator[](const size_t i) { assert(i<4); return i<=0 ? x : (1==i ? y : (2==i ? z : w)); }
|
||||||
|
const T& operator[](const size_t i) const { assert(i<4); return i<=0 ? x : (1==i ? y : (2==i ? z : w)); }
|
||||||
|
float norm() { return std::sqrt(x*x+y*y+z*z+w*w); }
|
||||||
|
vec<4,T> & normalize(T l=1) { *this = (*this)*(l/norm()); return *this; }
|
||||||
|
|
||||||
|
T x,y,z,w;
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<size_t DIM,typename T> T operator*(const vec<DIM,T>& lhs, const vec<DIM,T>& rhs) {
|
||||||
|
T ret = T();
|
||||||
|
for (size_t i=DIM; i--; ret+=lhs[i]*rhs[i]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<size_t DIM,typename T>vec<DIM,T> operator+(vec<DIM,T> lhs, const vec<DIM,T>& rhs) {
|
||||||
|
for (size_t i=DIM; i--; lhs[i]+=rhs[i]);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t DIM,typename T>vec<DIM,T> operator-(vec<DIM,T> lhs, const vec<DIM,T>& rhs) {
|
||||||
|
for (size_t i=DIM; i--; lhs[i]-=rhs[i]);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t DIM,typename T,typename U> vec<DIM,T> operator*(vec<DIM,T> lhs, const U& rhs) {
|
||||||
|
for (size_t i=DIM; i--; lhs[i]*=rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t DIM,typename T,typename U> vec<DIM,T> operator/(vec<DIM,T> lhs, const U& rhs) {
|
||||||
|
for (size_t i=DIM; i--; lhs[i]/=rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t LEN,size_t DIM,typename T> vec<LEN,T> embed(const vec<DIM,T> &v, T fill=1) {
|
||||||
|
vec<LEN,T> ret;
|
||||||
|
for (size_t i=LEN; i--; ret[i]=(i<DIM?v[i]:fill));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t LEN,size_t DIM, typename T> vec<LEN,T> proj(const vec<DIM,T> &v) {
|
||||||
|
vec<LEN,T> ret;
|
||||||
|
for (size_t i=LEN; i--; ret[i]=v[i]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> vec<3,T> cross(vec<3,T> v1, vec<3,T> v2) {
|
||||||
|
return vec<3,T>(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t DIM, typename T> std::ostream& operator<<(std::ostream& out, vec<DIM,T>& v) {
|
||||||
|
for(unsigned int i=0; i<DIM; i++) {
|
||||||
|
out << v[i] << " " ;
|
||||||
|
}
|
||||||
|
return out ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<size_t DIM,typename T> struct dt {
|
||||||
|
static T det(const mat<DIM,DIM,T>& src) {
|
||||||
|
T ret=0;
|
||||||
|
for (size_t i=DIM; i--; ret += src[0][i]*src.cofactor(0,i));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T> struct dt<1,T> {
|
||||||
|
static T det(const mat<1,1,T>& src) {
|
||||||
|
return src[0][0];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<size_t DimRows,size_t DimCols,typename T> class mat {
|
||||||
|
vec<DimCols,T> rows[DimRows];
|
||||||
|
public:
|
||||||
|
mat() {}
|
||||||
|
|
||||||
|
vec<DimCols,T>& operator[] (const size_t idx) {
|
||||||
|
assert(idx<DimRows);
|
||||||
|
return rows[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
const vec<DimCols,T>& operator[] (const size_t idx) const {
|
||||||
|
assert(idx<DimRows);
|
||||||
|
return rows[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
vec<DimRows,T> col(const size_t idx) const {
|
||||||
|
assert(idx<DimCols);
|
||||||
|
vec<DimRows,T> ret;
|
||||||
|
for (size_t i=DimRows; i--; ret[i]=rows[i][idx]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_col(size_t idx, vec<DimRows,T> v) {
|
||||||
|
assert(idx<DimCols);
|
||||||
|
for (size_t i=DimRows; i--; rows[i][idx]=v[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static mat<DimRows,DimCols,T> identity() {
|
||||||
|
mat<DimRows,DimCols,T> ret;
|
||||||
|
for (size_t i=DimRows; i--; )
|
||||||
|
for (size_t j=DimCols;j--; ret[i][j]=(i==j));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
T det() const {
|
||||||
|
return dt<DimCols,T>::det(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat<DimRows-1,DimCols-1,T> get_minor(size_t row, size_t col) const {
|
||||||
|
mat<DimRows-1,DimCols-1,T> ret;
|
||||||
|
for (size_t i=DimRows-1; i--; )
|
||||||
|
for (size_t j=DimCols-1;j--; ret[i][j]=rows[i<row?i:i+1][j<col?j:j+1]);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
T cofactor(size_t row, size_t col) const {
|
||||||
|
return get_minor(row,col).det()*((row+col)%2 ? -1 : 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
mat<DimRows,DimCols,T> adjugate() const {
|
||||||
|
mat<DimRows,DimCols,T> ret;
|
||||||
|
for (size_t i=DimRows; i--; )
|
||||||
|
for (size_t j=DimCols; j--; ret[i][j]=cofactor(i,j));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat<DimRows,DimCols,T> invert_transpose() {
|
||||||
|
mat<DimRows,DimCols,T> ret = adjugate();
|
||||||
|
T tmp = ret[0]*rows[0];
|
||||||
|
return ret/tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
mat<DimRows,DimCols,T> invert() {
|
||||||
|
return invert_transpose().transpose();
|
||||||
|
}
|
||||||
|
|
||||||
|
mat<DimCols,DimRows,T> transpose() {
|
||||||
|
mat<DimCols,DimRows,T> ret;
|
||||||
|
for (size_t i=DimCols; i--; ret[i]=this->col(i));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
template<size_t DimRows,size_t DimCols,typename T> vec<DimRows,T> operator*(const mat<DimRows,DimCols,T>& lhs, const vec<DimCols,T>& rhs) {
|
||||||
|
vec<DimRows,T> ret;
|
||||||
|
for (size_t i=DimRows; i--; ret[i]=lhs[i]*rhs);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t R1,size_t C1,size_t C2,typename T>mat<R1,C2,T> operator*(const mat<R1,C1,T>& lhs, const mat<C1,C2,T>& rhs) {
|
||||||
|
mat<R1,C2,T> result;
|
||||||
|
for (size_t i=R1; i--; )
|
||||||
|
for (size_t j=C2; j--; result[i][j]=lhs[i]*rhs.col(j));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<size_t DimRows,size_t DimCols,typename T>mat<DimCols,DimRows,T> operator/(mat<DimRows,DimCols,T> lhs, const T& rhs) {
|
||||||
|
for (size_t i=DimRows; i--; lhs[i]=lhs[i]/rhs);
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <size_t DimRows,size_t DimCols,class T> std::ostream& operator<<(std::ostream& out, mat<DimRows,DimCols,T>& m) {
|
||||||
|
for (size_t i=0; i<DimRows; i++) out << m[i] << std::endl;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef vec<2, float> Vec2f;
|
||||||
|
typedef vec<2, int> Vec2i;
|
||||||
|
typedef vec<3, float> Vec3f;
|
||||||
|
typedef vec<3, int> Vec3i;
|
||||||
|
typedef vec<4, float> Vec4f;
|
||||||
|
typedef mat<4,4,float> Matrix;
|
||||||
|
#endif //__GEOMETRY_H__
|
||||||
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
//#include <iostream>
|
||||||
|
#include "util_window.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "ctime"
|
||||||
|
|
||||||
|
const int width = 800;
|
||||||
|
const int height = 800;
|
||||||
|
|
||||||
|
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||||
|
{
|
||||||
|
HWND hwnd;
|
||||||
|
MSG Msg;
|
||||||
|
|
||||||
|
hwnd = create_window(width, height, hInstance);
|
||||||
|
ShowWindow(hwnd, nCmdShow);
|
||||||
|
|
||||||
|
char debug_str[100];
|
||||||
|
|
||||||
|
clock_t first_time = clock();
|
||||||
|
render();
|
||||||
|
clock_t end_time = clock();
|
||||||
|
Update();
|
||||||
|
|
||||||
|
sprintf_s(debug_str, "%f\n", (double)(end_time - first_time) / CLOCKS_PER_SEC);
|
||||||
|
OutputDebugString(debug_str);
|
||||||
|
|
||||||
|
while (GetMessage(&Msg, NULL, 0, 0))
|
||||||
|
{
|
||||||
|
TranslateMessage(&Msg);
|
||||||
|
DispatchMessage(&Msg);
|
||||||
|
}
|
||||||
|
return Msg.wParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
|
{
|
||||||
|
switch (message)
|
||||||
|
{
|
||||||
|
case WM_RBUTTONDOWN:
|
||||||
|
break;
|
||||||
|
case WM_LBUTTONDOWN:
|
||||||
|
Update();
|
||||||
|
break;
|
||||||
|
case WM_CLOSE:
|
||||||
|
DestroyWindow(hwnd);
|
||||||
|
break;
|
||||||
|
case WM_DESTROY:
|
||||||
|
PostQuitMessage(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include "model.h"
|
||||||
|
|
||||||
|
#define PI 3.14159265358979323846
|
||||||
|
#define DEG2RAD PI/180
|
||||||
|
|
||||||
|
Model::Model(const char *filename) : verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(), specularmap_() {
|
||||||
|
std::ifstream in;
|
||||||
|
Transform = Matrix::identity();
|
||||||
|
Rotation = Matrix::identity();
|
||||||
|
Scale = Matrix::identity();
|
||||||
|
Translation = Matrix::identity();
|
||||||
|
in.open (filename, std::ifstream::in);
|
||||||
|
if (in.fail()) return;
|
||||||
|
std::string line;
|
||||||
|
while (!in.eof()) {
|
||||||
|
std::getline(in, line);
|
||||||
|
std::istringstream iss(line.c_str());
|
||||||
|
char trash;
|
||||||
|
if (!line.compare(0, 2, "v ")) {
|
||||||
|
iss >> trash;
|
||||||
|
Vec3f v;
|
||||||
|
for (int i=0;i<3;i++) iss >> v[i];
|
||||||
|
verts_.push_back(v);
|
||||||
|
} else if (!line.compare(0, 3, "vn ")) {
|
||||||
|
iss >> trash >> trash;
|
||||||
|
Vec3f n;
|
||||||
|
for (int i=0;i<3;i++) iss >> n[i];
|
||||||
|
norms_.push_back(n);
|
||||||
|
} else if (!line.compare(0, 3, "vt ")) {
|
||||||
|
iss >> trash >> trash;
|
||||||
|
Vec2f uv;
|
||||||
|
for (int i=0;i<2;i++) iss >> uv[i];
|
||||||
|
uv_.push_back(uv);
|
||||||
|
} else if (!line.compare(0, 2, "f ")) {
|
||||||
|
std::vector<Vec3i> f;
|
||||||
|
Vec3i tmp;
|
||||||
|
iss >> trash;
|
||||||
|
while (iss >> tmp[0] >> trash >> tmp[1] >> trash >> tmp[2]) {
|
||||||
|
for (int i=0; i<3; i++) tmp[i]--; // in wavefront obj all indices start at 1, not zero
|
||||||
|
f.push_back(tmp);
|
||||||
|
}
|
||||||
|
faces_.push_back(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << " vt# " << uv_.size() << " vn# " << norms_.size() << std::endl;
|
||||||
|
load_texture(filename, "_diffuse.tga", diffusemap_);
|
||||||
|
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
||||||
|
//load_texture(filename, "_spec.tga", specularmap_);
|
||||||
|
}
|
||||||
|
|
||||||
|
Model::~Model() {}
|
||||||
|
|
||||||
|
void Model::ApplyTransform() {
|
||||||
|
Transform = Translation * Scale * Rotation;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::translate(Vec3f tr) {
|
||||||
|
Translation[0][3] += tr.x;
|
||||||
|
Translation[1][3] += tr.y;
|
||||||
|
Translation[2][3] += tr.z;
|
||||||
|
}
|
||||||
|
void Model::rotate(Vec3f rot) {
|
||||||
|
rot = rot * DEG2RAD;
|
||||||
|
|
||||||
|
Rotation[0][0] = cosf(rot.y) * cosf(rot.z);
|
||||||
|
Rotation[0][1] = -cosf(rot.y) * sinf(rot.z);
|
||||||
|
Rotation[0][2] = sinf(rot.y);
|
||||||
|
Rotation[1][0] = sinf(rot.x)*sinf(rot.y)*cosf(rot.z) + cosf(rot.x) * sinf(rot.z);
|
||||||
|
Rotation[1][1] = -sinf(rot.x)*sinf(rot.y)*sinf(rot.z) + cosf(rot.x) * cosf(rot.z);
|
||||||
|
Rotation[1][2] = -sinf(rot.x)*cosf(rot.y);
|
||||||
|
Rotation[2][0] = -cosf(rot.x)*sinf(rot.y)*cosf(rot.z) + sinf(rot.x) * sinf(rot.z);
|
||||||
|
Rotation[2][1] = cosf(rot.x)*sinf(rot.y)*sinf(rot.z) + sinf(rot.x) * cosf(rot.z);
|
||||||
|
Rotation[2][2] = cosf(rot.x)*cosf(rot.y);
|
||||||
|
}
|
||||||
|
void Model::scale(Vec3f scl) {
|
||||||
|
Scale[0][0] = scl.x;
|
||||||
|
Scale[1][1] = scl.y;
|
||||||
|
Scale[2][2] = scl.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Model::nverts() {
|
||||||
|
return (int)verts_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Model::nfaces() {
|
||||||
|
return (int)faces_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<int> Model::face(int idx) {
|
||||||
|
std::vector<int> face;
|
||||||
|
for (int i=0; i<(int)faces_[idx].size(); i++) face.push_back(faces_[idx][i][0]);
|
||||||
|
return face;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f Model::vert(int i) {
|
||||||
|
return verts_[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f Model::vert(int iface, int nthvert) {
|
||||||
|
return verts_[faces_[iface][nthvert][0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Model::load_texture(std::string filename, const char *suffix, TGAImage &img) {
|
||||||
|
std::string texfile(filename);
|
||||||
|
size_t dot = texfile.find_last_of(".");
|
||||||
|
if (dot!=std::string::npos) {
|
||||||
|
texfile = texfile.substr(0,dot) + std::string(suffix);
|
||||||
|
std::cerr << "texture file " << texfile << " loading " << (img.read_tga_file(texfile.c_str()) ? "ok" : "failed") << std::endl;
|
||||||
|
img.flip_vertically();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TGAColor Model::diffuse(Vec2f uvf) {
|
||||||
|
Vec2i uv(uvf[0]*diffusemap_.get_width(), uvf[1]*diffusemap_.get_height());
|
||||||
|
return diffusemap_.get(uv[0], uv[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f Model::normal(Vec2f uvf) {
|
||||||
|
Vec2i uv(uvf[0]*normalmap_.get_width(), uvf[1]*normalmap_.get_height());
|
||||||
|
TGAColor c = normalmap_.get(uv[0], uv[1]);
|
||||||
|
Vec3f res;
|
||||||
|
for (int i=0; i<3; i++)
|
||||||
|
res[2-i] = (float)c[i]/255.f*2.f - 1.f;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec2f Model::uv(int iface, int nthvert) {
|
||||||
|
return uv_[faces_[iface][nthvert][1]];
|
||||||
|
}
|
||||||
|
|
||||||
|
float Model::specular(Vec2f uvf) {
|
||||||
|
Vec2i uv(uvf[0]*specularmap_.get_width(), uvf[1]*specularmap_.get_height());
|
||||||
|
return specularmap_.get(uv[0], uv[1])[0]/1.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f Model::normal(int iface, int nthvert) {
|
||||||
|
int idx = faces_[iface][nthvert][2];
|
||||||
|
return norms_[idx].normalize();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef __MODEL_H__
|
||||||
|
#define __MODEL_H__
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
#include "geometry.h"
|
||||||
|
#include "tgaimage.h"
|
||||||
|
|
||||||
|
class Model {
|
||||||
|
private:
|
||||||
|
std::vector<Vec3f> verts_;
|
||||||
|
std::vector<std::vector<Vec3i> > faces_; // attention, this Vec3i means vertex/uv/normal
|
||||||
|
std::vector<Vec3f> norms_;
|
||||||
|
std::vector<Vec2f> uv_;
|
||||||
|
TGAImage diffusemap_;
|
||||||
|
TGAImage normalmap_;
|
||||||
|
TGAImage specularmap_;
|
||||||
|
void load_texture(std::string filename, const char *suffix, TGAImage &img);
|
||||||
|
public:
|
||||||
|
Model(const char *filename);
|
||||||
|
~Model();
|
||||||
|
int nverts();
|
||||||
|
int nfaces();
|
||||||
|
Vec3f normal(int iface, int nthvert);
|
||||||
|
Vec3f normal(Vec2f uv);
|
||||||
|
Vec3f vert(int i);
|
||||||
|
Vec3f vert(int iface, int nthvert);
|
||||||
|
Vec2f uv(int iface, int nthvert);
|
||||||
|
Matrix Transform;
|
||||||
|
Matrix Rotation;
|
||||||
|
Matrix Scale;
|
||||||
|
Matrix Translation;
|
||||||
|
void translate(Vec3f tr);
|
||||||
|
void rotate(Vec3f rot);
|
||||||
|
void scale(Vec3f scl);
|
||||||
|
void ApplyTransform();
|
||||||
|
TGAColor diffuse(Vec2f uv);
|
||||||
|
float specular(Vec2f uv);
|
||||||
|
std::vector<int> face(int idx);
|
||||||
|
};
|
||||||
|
#endif //__MODEL_H__
|
||||||
|
|
||||||
Binary file not shown.
@@ -0,0 +1,232 @@
|
|||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <limits>
|
||||||
|
#include "tgaimage.h"
|
||||||
|
#include "model.h"
|
||||||
|
#include "geometry.h"
|
||||||
|
#include "renderer.h"
|
||||||
|
#include "util_window.h"
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
const TGAColor white = TGAColor(255, 255, 255, 255);
|
||||||
|
const TGAColor red = TGAColor(255, 0, 0, 255);
|
||||||
|
const TGAColor green = TGAColor(0, 255, 0, 255);
|
||||||
|
const TGAColor blue = TGAColor(0, 0, 255, 255);
|
||||||
|
|
||||||
|
const int depth = 255;
|
||||||
|
|
||||||
|
float* z_buffer;
|
||||||
|
Vec3f light_dir = Vec3f(0, 0, 1).normalize();
|
||||||
|
Vec3f eye(0, 0, 3);
|
||||||
|
Vec3f center(0, 0, 0);
|
||||||
|
|
||||||
|
Matrix viewport(int x, int y, int w, int h) {
|
||||||
|
Matrix m = Matrix::identity();
|
||||||
|
m[0][3] = x + w / 2.f;
|
||||||
|
m[1][3] = y + h / 2.f;
|
||||||
|
m[2][3] = depth / 2.f;
|
||||||
|
|
||||||
|
m[0][0] = w / 2.f;
|
||||||
|
m[1][1] = h / 2.f;
|
||||||
|
m[2][2] = depth / 2.f;
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
void line(Vec2i p0, Vec2i p1, TGAImage &image, TGAColor color)
|
||||||
|
{
|
||||||
|
bool steep = false;
|
||||||
|
|
||||||
|
if (std::abs(p0[0] - p1[0]) < std::abs(p0[1] - p1[1])) {
|
||||||
|
std::swap(p0[0], p0[1]);
|
||||||
|
std::swap(p1[0], p1[1]);
|
||||||
|
steep = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p0[0] > p1[0]) {
|
||||||
|
std::swap(p0[0], p1[0]);
|
||||||
|
std::swap(p0[1], p1[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dx = p1[0] - p0[0];
|
||||||
|
int dy = p1[1] - p0[1];
|
||||||
|
int derror2 = std::abs(dy) * 2;
|
||||||
|
int error2 = 0;
|
||||||
|
int y = p0[1];
|
||||||
|
int y_step = p1[1] > p0[1] ? 1 : -1;
|
||||||
|
int dx_2 = 2 * dx;
|
||||||
|
|
||||||
|
for (int x = p0[0]; x <= p1[0]; x++) {
|
||||||
|
if (steep) {
|
||||||
|
image.set(y, x, color);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
image.set(x, y, color);
|
||||||
|
}
|
||||||
|
error2 += derror2;
|
||||||
|
if (error2 > dx) {
|
||||||
|
y += (y_step);
|
||||||
|
error2 -= dx_2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f barycentric(Vec3f* pts, Vec3f P)
|
||||||
|
{
|
||||||
|
Vec3f u = cross(
|
||||||
|
Vec3f(pts[2][0] - pts[0][0], pts[1][0] - pts[0][0], pts[0][0] - P[0]), // AC_x, AB_x, distance_x
|
||||||
|
Vec3f(pts[2][1] - pts[0][1], pts[1][1] - pts[0][1], pts[0][1] - P[1]) // AC_y, AB_y, distance_y
|
||||||
|
);
|
||||||
|
|
||||||
|
if (std::abs(u[2]) < 1) return Vec3f(-1, 1, 1);
|
||||||
|
return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void triangle(
|
||||||
|
Vec3f* pts, // Needed
|
||||||
|
Model* model, // Should be removed
|
||||||
|
Vec2f* diff_pts, // Should be removed
|
||||||
|
float* intensities,
|
||||||
|
Vec3f camera_pos) // Not really sure yet
|
||||||
|
{
|
||||||
|
|
||||||
|
if (pts[0].y == pts[1].y && pts[0].y == pts[2].y) return; // i dont care about degenerate triangles
|
||||||
|
if (pts[0].y > pts[1].y) {
|
||||||
|
std::swap(pts[0], pts[1]);
|
||||||
|
std::swap(diff_pts[0], diff_pts[1]);
|
||||||
|
std::swap(intensities[0], intensities[1]);
|
||||||
|
}
|
||||||
|
if (pts[0].y > pts[2].y) {
|
||||||
|
std::swap(pts[0], pts[2]);
|
||||||
|
std::swap(diff_pts[0], diff_pts[2]);
|
||||||
|
std::swap(intensities[0], intensities[2]);
|
||||||
|
}
|
||||||
|
if (pts[1].y > pts[2].y) {
|
||||||
|
std::swap(pts[1], pts[2]);
|
||||||
|
std::swap(diff_pts[1], diff_pts[2]);
|
||||||
|
std::swap(intensities[1], intensities[2]);
|
||||||
|
}
|
||||||
|
Vec2i bounding_box_min(screen_width - 1, screen_height - 1);
|
||||||
|
Vec2i bounding_box_max(0, 0);
|
||||||
|
Vec2i clamp(screen_width - 1, screen_height - 1);
|
||||||
|
TGAColor color = white;
|
||||||
|
|
||||||
|
for(int i = 0; i < 3; i++) {
|
||||||
|
for(int j =0; j < 2; j++) {
|
||||||
|
bounding_box_min[j] = std::fmax(0, std::fmin(bounding_box_min[j], (int)pts[i][j]));
|
||||||
|
bounding_box_max[j] = std::fmin(clamp[j], std::fmax(bounding_box_max[j], (int)pts[i][j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3f P;
|
||||||
|
for(P.x = bounding_box_min.x; P.x <= bounding_box_max.x; P.x++) {
|
||||||
|
for(P.y = bounding_box_min.y; P.y <= bounding_box_max.y; P.y++) {
|
||||||
|
Vec3f bc_coord = barycentric(pts, P);
|
||||||
|
if(bc_coord.x < 0 || bc_coord.y < 0 || bc_coord.z < 0) continue;
|
||||||
|
|
||||||
|
|
||||||
|
float intensity =
|
||||||
|
intensities[0]
|
||||||
|
+ (intensities[1] - intensities[0]) * bc_coord[1]
|
||||||
|
+ (intensities[2] - intensities[0]) * bc_coord[2];
|
||||||
|
|
||||||
|
|
||||||
|
// Interpolating Z using the barycentric coordinates
|
||||||
|
P.z = 0;
|
||||||
|
for(int i = 0; i < 3; i++) P.z += pts[i][2] * bc_coord[i];
|
||||||
|
|
||||||
|
// Coloring according to the Z-Buffer
|
||||||
|
if (P.z > z_buffer[(int)(P.x + P.y * screen_width)])
|
||||||
|
{
|
||||||
|
z_buffer[(int)(P.x + P.y * screen_width)] = P.z;
|
||||||
|
|
||||||
|
// If diff_pts (Diffusemap Points) were passed, then find the
|
||||||
|
// color of the current pixel
|
||||||
|
if(diff_pts) {
|
||||||
|
Vec2f diff_pt =
|
||||||
|
diff_pts[0]
|
||||||
|
+ (diff_pts[1] - diff_pts[0]) * bc_coord[1]
|
||||||
|
+ (diff_pts[2] - diff_pts[0]) * bc_coord[2];
|
||||||
|
|
||||||
|
color = model->diffuse(diff_pt);
|
||||||
|
}
|
||||||
|
color = color * intensity;
|
||||||
|
set_pixel(P.x, P.y, color_to_int(color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int color_to_int(TGAColor col) {
|
||||||
|
return (col[2] << 16) | (col[1] << 8) | col[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_zbuffer()
|
||||||
|
{
|
||||||
|
z_buffer = new float[screen_width*screen_height];
|
||||||
|
for (int i = 0; i < screen_width * screen_height; i++)
|
||||||
|
z_buffer[i] = INT_MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) {
|
||||||
|
Vec3f z = (eye - center).normalize();
|
||||||
|
Vec3f x = cross(up, z).normalize();
|
||||||
|
Vec3f y = cross(z, x).normalize();
|
||||||
|
Matrix Minv = Matrix::identity();
|
||||||
|
Matrix Tr = Matrix::identity();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
Minv[0][i] = x[i];
|
||||||
|
Minv[1][i] = y[i];
|
||||||
|
Minv[2][i] = z[i];
|
||||||
|
Tr[i][3] = -center[i];
|
||||||
|
}
|
||||||
|
return Minv * Tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render()
|
||||||
|
{
|
||||||
|
Model* model = new Model("african_head.obj");
|
||||||
|
|
||||||
|
Matrix ViewPort = viewport(screen_width / 8, screen_height / 8, screen_width * 3 / 4, screen_height * 3 / 4);
|
||||||
|
Matrix Projection = Matrix::identity();
|
||||||
|
Matrix ModelView = lookat(eye, center, Vec3f(0, 1, 0));
|
||||||
|
|
||||||
|
Projection[3][2] = -1.f / (eye - center).norm();
|
||||||
|
|
||||||
|
model->rotate(Vec3f(0, 0, 90));
|
||||||
|
model->scale(Vec3f(0.5, 0.5, 0.5));
|
||||||
|
model->translate(Vec3f(0.5, 0.5, -1));
|
||||||
|
|
||||||
|
model->ApplyTransform();
|
||||||
|
|
||||||
|
Matrix z = ViewPort * Projection * ModelView * model->Transform;
|
||||||
|
|
||||||
|
init_zbuffer();
|
||||||
|
for (int i = 0; i < model->nfaces(); i++)
|
||||||
|
{
|
||||||
|
std::vector<int> face = model->face(i);
|
||||||
|
Vec3f screen_coords[3];
|
||||||
|
Vec3f world_coords[3];
|
||||||
|
Vec2f diffuse_coords[3];
|
||||||
|
float intensities[3];
|
||||||
|
|
||||||
|
for (int j = 0; j < 3; j++)
|
||||||
|
{
|
||||||
|
Vec3f v = model->vert(face[j]);
|
||||||
|
Vec4f v4(v);
|
||||||
|
Vec3f coord(z * v4);
|
||||||
|
|
||||||
|
screen_coords[j] = coord;
|
||||||
|
world_coords[j] = v;
|
||||||
|
diffuse_coords[j] = model->uv(i, j);
|
||||||
|
intensities[j] = model->normal(i, j) * light_dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
triangle(screen_coords, model, diffuse_coords, intensities, Vec3f(0, 0, 5));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete model;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef RENDERER_HEADER
|
||||||
|
#define RENDERER_HEADER
|
||||||
|
#include "tgaimage.h"
|
||||||
|
|
||||||
|
void render();
|
||||||
|
int color_to_int(TGAColor col);
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,356 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "tgaimage.h"
|
||||||
|
|
||||||
|
TGAImage::TGAImage() : data(NULL), width(0), height(0), bytespp(0) {}
|
||||||
|
|
||||||
|
TGAImage::TGAImage(int w, int h, int bpp) : data(NULL), width(w), height(h), bytespp(bpp) {
|
||||||
|
unsigned long nbytes = width*height*bytespp;
|
||||||
|
data = new unsigned char[nbytes];
|
||||||
|
memset(data, 0, nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
TGAImage::TGAImage(const TGAImage &img) : data(NULL), width(img.width), height(img.height), bytespp(img.bytespp) {
|
||||||
|
unsigned long nbytes = width*height*bytespp;
|
||||||
|
data = new unsigned char[nbytes];
|
||||||
|
memcpy(data, img.data, nbytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
TGAImage::~TGAImage() {
|
||||||
|
if (data) delete [] data;
|
||||||
|
}
|
||||||
|
|
||||||
|
TGAImage & TGAImage::operator =(const TGAImage &img) {
|
||||||
|
if (this != &img) {
|
||||||
|
if (data) delete [] data;
|
||||||
|
width = img.width;
|
||||||
|
height = img.height;
|
||||||
|
bytespp = img.bytespp;
|
||||||
|
unsigned long nbytes = width*height*bytespp;
|
||||||
|
data = new unsigned char[nbytes];
|
||||||
|
memcpy(data, img.data, nbytes);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGAImage::read_tga_file(const char *filename) {
|
||||||
|
if (data) delete [] data;
|
||||||
|
data = NULL;
|
||||||
|
std::ifstream in;
|
||||||
|
in.open (filename, std::ios::binary);
|
||||||
|
if (!in.is_open()) {
|
||||||
|
std::cerr << "can't open file " << filename << "\n";
|
||||||
|
in.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TGA_Header header;
|
||||||
|
in.read((char *)&header, sizeof(header));
|
||||||
|
if (!in.good()) {
|
||||||
|
in.close();
|
||||||
|
std::cerr << "an error occured while reading the header\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
width = header.width;
|
||||||
|
height = header.height;
|
||||||
|
bytespp = header.bitsperpixel>>3;
|
||||||
|
if (width<=0 || height<=0 || (bytespp!=GRAYSCALE && bytespp!=RGB && bytespp!=RGBA)) {
|
||||||
|
in.close();
|
||||||
|
std::cerr << "bad bpp (or width/height) value\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
unsigned long nbytes = bytespp*width*height;
|
||||||
|
data = new unsigned char[nbytes];
|
||||||
|
if (3==header.datatypecode || 2==header.datatypecode) {
|
||||||
|
in.read((char *)data, nbytes);
|
||||||
|
if (!in.good()) {
|
||||||
|
in.close();
|
||||||
|
std::cerr << "an error occured while reading the data\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (10==header.datatypecode||11==header.datatypecode) {
|
||||||
|
if (!load_rle_data(in)) {
|
||||||
|
in.close();
|
||||||
|
std::cerr << "an error occured while reading the data\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
in.close();
|
||||||
|
std::cerr << "unknown file format " << (int)header.datatypecode << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!(header.imagedescriptor & 0x20)) {
|
||||||
|
flip_vertically();
|
||||||
|
}
|
||||||
|
if (header.imagedescriptor & 0x10) {
|
||||||
|
flip_horizontally();
|
||||||
|
}
|
||||||
|
std::cerr << width << "x" << height << "/" << bytespp*8 << "\n";
|
||||||
|
in.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGAImage::load_rle_data(std::ifstream &in) {
|
||||||
|
unsigned long pixelcount = width*height;
|
||||||
|
unsigned long currentpixel = 0;
|
||||||
|
unsigned long currentbyte = 0;
|
||||||
|
TGAColor colorbuffer;
|
||||||
|
do {
|
||||||
|
unsigned char chunkheader = 0;
|
||||||
|
chunkheader = in.get();
|
||||||
|
if (!in.good()) {
|
||||||
|
std::cerr << "an error occured while reading the data\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (chunkheader<128) {
|
||||||
|
chunkheader++;
|
||||||
|
for (int i=0; i<chunkheader; i++) {
|
||||||
|
in.read((char *)colorbuffer.bgra, bytespp);
|
||||||
|
if (!in.good()) {
|
||||||
|
std::cerr << "an error occured while reading the header\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int t=0; t<bytespp; t++)
|
||||||
|
data[currentbyte++] = colorbuffer.bgra[t];
|
||||||
|
currentpixel++;
|
||||||
|
if (currentpixel>pixelcount) {
|
||||||
|
std::cerr << "Too many pixels read\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chunkheader -= 127;
|
||||||
|
in.read((char *)colorbuffer.bgra, bytespp);
|
||||||
|
if (!in.good()) {
|
||||||
|
std::cerr << "an error occured while reading the header\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (int i=0; i<chunkheader; i++) {
|
||||||
|
for (int t=0; t<bytespp; t++)
|
||||||
|
data[currentbyte++] = colorbuffer.bgra[t];
|
||||||
|
currentpixel++;
|
||||||
|
if (currentpixel>pixelcount) {
|
||||||
|
std::cerr << "Too many pixels read\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (currentpixel < pixelcount);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGAImage::write_tga_file(const char *filename, bool rle) {
|
||||||
|
unsigned char developer_area_ref[4] = {0, 0, 0, 0};
|
||||||
|
unsigned char extension_area_ref[4] = {0, 0, 0, 0};
|
||||||
|
unsigned char footer[18] = {'T','R','U','E','V','I','S','I','O','N','-','X','F','I','L','E','.','\0'};
|
||||||
|
std::ofstream out;
|
||||||
|
out.open (filename, std::ios::binary);
|
||||||
|
if (!out.is_open()) {
|
||||||
|
std::cerr << "can't open file " << filename << "\n";
|
||||||
|
out.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TGA_Header header;
|
||||||
|
memset((void *)&header, 0, sizeof(header));
|
||||||
|
header.bitsperpixel = bytespp<<3;
|
||||||
|
header.width = width;
|
||||||
|
header.height = height;
|
||||||
|
header.datatypecode = (bytespp==GRAYSCALE?(rle?11:3):(rle?10:2));
|
||||||
|
header.imagedescriptor = 0x20; // top-left origin
|
||||||
|
out.write((char *)&header, sizeof(header));
|
||||||
|
if (!out.good()) {
|
||||||
|
out.close();
|
||||||
|
std::cerr << "can't dump the tga file\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!rle) {
|
||||||
|
out.write((char *)data, width*height*bytespp);
|
||||||
|
if (!out.good()) {
|
||||||
|
std::cerr << "can't unload raw data\n";
|
||||||
|
out.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!unload_rle_data(out)) {
|
||||||
|
out.close();
|
||||||
|
std::cerr << "can't unload rle data\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out.write((char *)developer_area_ref, sizeof(developer_area_ref));
|
||||||
|
if (!out.good()) {
|
||||||
|
std::cerr << "can't dump the tga file\n";
|
||||||
|
out.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out.write((char *)extension_area_ref, sizeof(extension_area_ref));
|
||||||
|
if (!out.good()) {
|
||||||
|
std::cerr << "can't dump the tga file\n";
|
||||||
|
out.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out.write((char *)footer, sizeof(footer));
|
||||||
|
if (!out.good()) {
|
||||||
|
std::cerr << "can't dump the tga file\n";
|
||||||
|
out.close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: it is not necessary to break a raw chunk for two equal pixels (for the matter of the resulting size)
|
||||||
|
bool TGAImage::unload_rle_data(std::ofstream &out) {
|
||||||
|
const unsigned char max_chunk_length = 128;
|
||||||
|
unsigned long npixels = width*height;
|
||||||
|
unsigned long curpix = 0;
|
||||||
|
while (curpix<npixels) {
|
||||||
|
unsigned long chunkstart = curpix*bytespp;
|
||||||
|
unsigned long curbyte = curpix*bytespp;
|
||||||
|
unsigned char run_length = 1;
|
||||||
|
bool raw = true;
|
||||||
|
while (curpix+run_length<npixels && run_length<max_chunk_length) {
|
||||||
|
bool succ_eq = true;
|
||||||
|
for (int t=0; succ_eq && t<bytespp; t++) {
|
||||||
|
succ_eq = (data[curbyte+t]==data[curbyte+t+bytespp]);
|
||||||
|
}
|
||||||
|
curbyte += bytespp;
|
||||||
|
if (1==run_length) {
|
||||||
|
raw = !succ_eq;
|
||||||
|
}
|
||||||
|
if (raw && succ_eq) {
|
||||||
|
run_length--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!raw && !succ_eq) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
run_length++;
|
||||||
|
}
|
||||||
|
curpix += run_length;
|
||||||
|
out.put(raw?run_length-1:run_length+127);
|
||||||
|
if (!out.good()) {
|
||||||
|
std::cerr << "can't dump the tga file\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out.write((char *)(data+chunkstart), (raw?run_length*bytespp:bytespp));
|
||||||
|
if (!out.good()) {
|
||||||
|
std::cerr << "can't dump the tga file\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TGAColor TGAImage::get(int x, int y) {
|
||||||
|
if (!data || x<0 || y<0 || x>=width || y>=height) {
|
||||||
|
return TGAColor();
|
||||||
|
}
|
||||||
|
return TGAColor(data+(x+y*width)*bytespp, bytespp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGAImage::set(int x, int y, TGAColor &c) {
|
||||||
|
if (!data || x<0 || y<0 || x>=width || y>=height) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(data+(x+y*width)*bytespp, c.bgra, bytespp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGAImage::set(int x, int y, const TGAColor &c) {
|
||||||
|
if (!data || x<0 || y<0 || x>=width || y>=height) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(data+(x+y*width)*bytespp, c.bgra, bytespp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TGAImage::get_bytespp() {
|
||||||
|
return bytespp;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TGAImage::get_width() {
|
||||||
|
return width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int TGAImage::get_height() {
|
||||||
|
return height;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGAImage::flip_horizontally() {
|
||||||
|
if (!data) return false;
|
||||||
|
int half = width>>1;
|
||||||
|
for (int i=0; i<half; i++) {
|
||||||
|
for (int j=0; j<height; j++) {
|
||||||
|
TGAColor c1 = get(i, j);
|
||||||
|
TGAColor c2 = get(width-1-i, j);
|
||||||
|
set(i, j, c2);
|
||||||
|
set(width-1-i, j, c1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGAImage::flip_vertically() {
|
||||||
|
if (!data) return false;
|
||||||
|
unsigned long bytes_per_line = width*bytespp;
|
||||||
|
unsigned char *line = new unsigned char[bytes_per_line];
|
||||||
|
int half = height>>1;
|
||||||
|
for (int j=0; j<half; j++) {
|
||||||
|
unsigned long l1 = j*bytes_per_line;
|
||||||
|
unsigned long l2 = (height-1-j)*bytes_per_line;
|
||||||
|
memmove((void *)line, (void *)(data+l1), bytes_per_line);
|
||||||
|
memmove((void *)(data+l1), (void *)(data+l2), bytes_per_line);
|
||||||
|
memmove((void *)(data+l2), (void *)line, bytes_per_line);
|
||||||
|
}
|
||||||
|
delete [] line;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char *TGAImage::buffer() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TGAImage::clear() {
|
||||||
|
memset((void *)data, 0, width*height*bytespp);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TGAImage::scale(int w, int h) {
|
||||||
|
if (w<=0 || h<=0 || !data) return false;
|
||||||
|
unsigned char *tdata = new unsigned char[w*h*bytespp];
|
||||||
|
int nscanline = 0;
|
||||||
|
int oscanline = 0;
|
||||||
|
int erry = 0;
|
||||||
|
unsigned long nlinebytes = w*bytespp;
|
||||||
|
unsigned long olinebytes = width*bytespp;
|
||||||
|
for (int j=0; j<height; j++) {
|
||||||
|
int errx = width-w;
|
||||||
|
int nx = -bytespp;
|
||||||
|
int ox = -bytespp;
|
||||||
|
for (int i=0; i<width; i++) {
|
||||||
|
ox += bytespp;
|
||||||
|
errx += w;
|
||||||
|
while (errx>=(int)width) {
|
||||||
|
errx -= width;
|
||||||
|
nx += bytespp;
|
||||||
|
memcpy(tdata+nscanline+nx, data+oscanline+ox, bytespp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
erry += h;
|
||||||
|
oscanline += olinebytes;
|
||||||
|
while (erry>=(int)height) {
|
||||||
|
if (erry>=(int)height<<1) // it means we jump over a scanline
|
||||||
|
memcpy(tdata+nscanline+nlinebytes, tdata+nscanline, nlinebytes);
|
||||||
|
erry -= height;
|
||||||
|
nscanline += nlinebytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete [] data;
|
||||||
|
data = tdata;
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#ifndef __IMAGE_H__
|
||||||
|
#define __IMAGE_H__
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
|
#pragma pack(push,1)
|
||||||
|
struct TGA_Header {
|
||||||
|
char idlength;
|
||||||
|
char colormaptype;
|
||||||
|
char datatypecode;
|
||||||
|
short colormaporigin;
|
||||||
|
short colormaplength;
|
||||||
|
char colormapdepth;
|
||||||
|
short x_origin;
|
||||||
|
short y_origin;
|
||||||
|
short width;
|
||||||
|
short height;
|
||||||
|
char bitsperpixel;
|
||||||
|
char imagedescriptor;
|
||||||
|
};
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
struct TGAColor {
|
||||||
|
unsigned char bgra[4];
|
||||||
|
unsigned char bytespp;
|
||||||
|
|
||||||
|
TGAColor() : bgra(), bytespp(1) {
|
||||||
|
for (int i=0; i<4; i++) bgra[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TGAColor(unsigned char R, unsigned char G, unsigned char B, unsigned char A=255) : bgra(), bytespp(4) {
|
||||||
|
bgra[0] = B;
|
||||||
|
bgra[1] = G;
|
||||||
|
bgra[2] = R;
|
||||||
|
bgra[3] = A;
|
||||||
|
}
|
||||||
|
|
||||||
|
TGAColor(unsigned char v) : bgra(), bytespp(1) {
|
||||||
|
for (int i=0; i<4; i++) bgra[i] = 0;
|
||||||
|
bgra[0] = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TGAColor(const unsigned char *p, unsigned char bpp) : bgra(), bytespp(bpp) {
|
||||||
|
for (int i=0; i<(int)bpp; i++) {
|
||||||
|
bgra[i] = p[i];
|
||||||
|
}
|
||||||
|
for (int i=bpp; i<4; i++) {
|
||||||
|
bgra[i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char& operator[](const int i) { return bgra[i]; }
|
||||||
|
|
||||||
|
TGAColor operator *(float intensity) const {
|
||||||
|
TGAColor res = *this;
|
||||||
|
intensity = (intensity>1.f?1.f:(intensity<0.f?0.f:intensity));
|
||||||
|
for (int i=0; i<4; i++) res.bgra[i] = bgra[i]*intensity;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class TGAImage {
|
||||||
|
protected:
|
||||||
|
unsigned char* data;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
int bytespp;
|
||||||
|
|
||||||
|
bool load_rle_data(std::ifstream &in);
|
||||||
|
bool unload_rle_data(std::ofstream &out);
|
||||||
|
public:
|
||||||
|
enum Format {
|
||||||
|
GRAYSCALE=1, RGB=3, RGBA=4
|
||||||
|
};
|
||||||
|
|
||||||
|
TGAImage();
|
||||||
|
TGAImage(int w, int h, int bpp);
|
||||||
|
TGAImage(const TGAImage &img);
|
||||||
|
bool read_tga_file(const char *filename);
|
||||||
|
bool write_tga_file(const char *filename, bool rle=true);
|
||||||
|
bool flip_horizontally();
|
||||||
|
bool flip_vertically();
|
||||||
|
bool scale(int w, int h);
|
||||||
|
TGAColor get(int x, int y);
|
||||||
|
bool set(int x, int y, TGAColor &c);
|
||||||
|
bool set(int x, int y, const TGAColor &c);
|
||||||
|
~TGAImage();
|
||||||
|
TGAImage & operator =(const TGAImage &img);
|
||||||
|
int get_width();
|
||||||
|
int get_height();
|
||||||
|
int get_bytespp();
|
||||||
|
unsigned char *buffer();
|
||||||
|
void clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //__IMAGE_H__
|
||||||
|
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
#include "util_window.h"
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
const char* wnd_class_name = "Renderer To-Be";
|
||||||
|
void* pixels;
|
||||||
|
char* pixel_data;
|
||||||
|
BITMAPINFO info;
|
||||||
|
HBITMAP hbm;
|
||||||
|
const int BITCOUNT_PER_PIXEL = 24;
|
||||||
|
const int title_height = 39;
|
||||||
|
int screen_width = 0;
|
||||||
|
int screen_height = 0;
|
||||||
|
long long bytes_per_row;
|
||||||
|
bool screen_changed = false;
|
||||||
|
HDC hdc;
|
||||||
|
HDRAWDIB hdd;
|
||||||
|
HDC bitmap_dc;
|
||||||
|
HGDIOBJ old_obj;
|
||||||
|
|
||||||
|
HWND create_window(int width, int height, HINSTANCE &hInstance) {
|
||||||
|
HWND hWnd;
|
||||||
|
WNDCLASSEX wnd_class = { 0 };
|
||||||
|
init_wnd_class(wnd_class, hInstance);
|
||||||
|
|
||||||
|
RegisterClassEx(&wnd_class);
|
||||||
|
|
||||||
|
screen_width = width;
|
||||||
|
screen_height = height;
|
||||||
|
create_hwnd(hWnd, hInstance);
|
||||||
|
init(hWnd);
|
||||||
|
|
||||||
|
return hWnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void init(HWND &hWnd) {
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||||
|
info.bmiHeader.biWidth = screen_width;
|
||||||
|
info.bmiHeader.biHeight = screen_height;
|
||||||
|
info.bmiHeader.biPlanes = 1;
|
||||||
|
info.bmiHeader.biBitCount = BITCOUNT_PER_PIXEL;
|
||||||
|
info.bmiHeader.biCompression = BI_RGB;
|
||||||
|
|
||||||
|
hdc = GetDC(hWnd);
|
||||||
|
pixels = NULL;
|
||||||
|
hbm = CreateDIBSection(hdc, &info, DIB_RGB_COLORS, &pixels, NULL, 0);
|
||||||
|
pixel_data = (char*)pixels;
|
||||||
|
|
||||||
|
hdd = DrawDibOpen();
|
||||||
|
|
||||||
|
bitmap_dc = CreateCompatibleDC(hdc);
|
||||||
|
old_obj = SelectObject(bitmap_dc, hbm);
|
||||||
|
bytes_per_row = ceil(screen_width * 0.03) * 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_hwnd(HWND &hwnd, HINSTANCE &hInstance)
|
||||||
|
{
|
||||||
|
hwnd = CreateWindowEx(
|
||||||
|
WS_EX_CLIENTEDGE,
|
||||||
|
TEXT(wnd_class_name),
|
||||||
|
TEXT("Renderer To-be"), // window caption
|
||||||
|
WS_OVERLAPPEDWINDOW, // window style
|
||||||
|
0, // initial x position
|
||||||
|
0, // initial y position
|
||||||
|
screen_width + 16, // Some weird horizontal dead pixels
|
||||||
|
screen_height + title_height,
|
||||||
|
NULL, // parent window handle
|
||||||
|
NULL, // window menu handle
|
||||||
|
hInstance, // program instance handle
|
||||||
|
NULL); // creation parameters
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_wnd_class(WNDCLASSEX &wndClass, HINSTANCE &hInstance) {
|
||||||
|
wndClass.cbSize = sizeof(WNDCLASSEX);
|
||||||
|
wndClass.style = 0;
|
||||||
|
wndClass.lpfnWndProc = WndProc;
|
||||||
|
wndClass.cbClsExtra = 0;
|
||||||
|
wndClass.cbWndExtra = 0;
|
||||||
|
wndClass.hInstance = hInstance;
|
||||||
|
wndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||||
|
wndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||||
|
wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||||
|
wndClass.lpszMenuName = NULL;
|
||||||
|
wndClass.lpszClassName = TEXT(wnd_class_name);
|
||||||
|
wndClass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_window() {
|
||||||
|
DrawDibEnd(hdd);
|
||||||
|
DrawDibClose(hdd);
|
||||||
|
SelectObject(bitmap_dc, old_obj);
|
||||||
|
DeleteDC(hdc);
|
||||||
|
DeleteDC(bitmap_dc);
|
||||||
|
DeleteObject(hbm);
|
||||||
|
DeleteObject(old_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void set_pixel(unsigned int x, unsigned int y, unsigned int color) {
|
||||||
|
unsigned long pixel_index = y * bytes_per_row + x * 3;
|
||||||
|
|
||||||
|
pixel_data[pixel_index + 0] = (char)(color >> 0);
|
||||||
|
pixel_data[pixel_index + 1] = (char)(color >> 8);
|
||||||
|
pixel_data[pixel_index + 2] = (char)(color >> 16);
|
||||||
|
|
||||||
|
if (!screen_changed)
|
||||||
|
screen_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Update() {
|
||||||
|
DrawDibDraw(hdd, hdc, 0, 0, screen_width, screen_height, &info.bmiHeader, pixels, 0, 0, screen_width, screen_height, 0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
#ifndef UTIL_HEADER
|
||||||
|
#define UTIL_HEADER
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <Vfw.h>
|
||||||
|
#pragma comment(lib, "Vfw32.lib")
|
||||||
|
|
||||||
|
extern const char* wnd_class_name;
|
||||||
|
extern void* pixels;
|
||||||
|
extern char* pixel_data;
|
||||||
|
extern BITMAPINFO info;
|
||||||
|
extern HBITMAP hbm;
|
||||||
|
extern const int BITCOUNT_PER_PIXEL;
|
||||||
|
extern const int title_height;
|
||||||
|
extern long long bytes_per_row;
|
||||||
|
extern bool screen_changed;
|
||||||
|
extern HDC hdc;
|
||||||
|
extern HDRAWDIB hdd;
|
||||||
|
extern HDC bitmap_dc;
|
||||||
|
extern HGDIOBJ old_obj;
|
||||||
|
extern int screen_width;
|
||||||
|
extern int screen_height;
|
||||||
|
|
||||||
|
|
||||||
|
void init(HWND &hWnd);
|
||||||
|
void destroy_window();
|
||||||
|
HWND create_window(int width, int height, HINSTANCE &hInstance);
|
||||||
|
void create_hwnd(HWND &hwnd, HINSTANCE &hInstance);
|
||||||
|
void init_wnd_class(WNDCLASSEX &wndClass, HINSTANCE &hInstance);
|
||||||
|
void set_pixel(unsigned int x, unsigned int y, unsigned int color);
|
||||||
|
void Update();
|
||||||
|
|
||||||
|
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user