Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b1546cb54 | |||
| 26a7e48784 | |||
| b936db0ce9 | |||
| b51c63ea0c | |||
| ad56096eb3 | |||
| 2f5437396c |
@@ -13,9 +13,6 @@
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "COLLADA.h"
|
||||
|
||||
COLLADA::COLLADA(const char* filename)
|
||||
{
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(filename);
|
||||
tinyxml2::XMLElement* xml = doc.FirstChildElement("COLLADA");
|
||||
m_GeometryLibrary = GeometryLibrary(xml->FirstChildElement("library_geometries"));
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
#include "GeometryLibrary.h"
|
||||
class COLLADA
|
||||
{
|
||||
private:
|
||||
GeometryLibrary m_GeometryLibrary;
|
||||
//ImagesLibrary m_ImagesLibrary;
|
||||
//EffectsLibrary m_EffectsLibrary;
|
||||
//MaterialLibrary m_MaterialLibrary;
|
||||
//ControllerLibrary m_ControllerLibrary;
|
||||
//AnimationLibrary m_AnimationLibrary;
|
||||
VisualSceneLibrary m_VisualSceneLibrary;
|
||||
|
||||
public:
|
||||
COLLADA() = default;
|
||||
COLLADA(const char* filename);
|
||||
};
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "ColladaModel.h"
|
||||
|
||||
#define PI 3.14159265358979323846
|
||||
#define DEG2RAD PI/180
|
||||
|
||||
ColladaModel::ColladaModel(const char* filename) : faces_(), vertices_(), normals_()
|
||||
{
|
||||
Transform = Matrix::identity();
|
||||
Rotation = Matrix::identity();
|
||||
Scale = Matrix::identity();
|
||||
Translation = Matrix::identity();
|
||||
|
||||
tinyxml2::XMLDocument doc;
|
||||
doc.LoadFile(filename);
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////faces//////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
face_count = 0;
|
||||
tinyxml2::XMLElement* xml_face = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("triangles");
|
||||
xml_face->QueryIntAttribute("count", &face_count); //get count
|
||||
std::stringstream str_triangle(xml_face->FirstChildElement("p")->GetText()); //get values as a string
|
||||
|
||||
for (int i = 0; i < face_count; i++)
|
||||
{
|
||||
faces_.push_back(std::vector<Vec3i>());
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
Vec3i temp;
|
||||
str_triangle >> temp.x;
|
||||
str_triangle >> temp.y;
|
||||
str_triangle >> temp.z;
|
||||
faces_[i].push_back(temp);
|
||||
}
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////vertex/////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
vertex_count = 0;
|
||||
tinyxml2::XMLElement* xml_vertex = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("source")->FirstChildElement("float_array");
|
||||
xml_vertex->QueryIntAttribute("count", &vertex_count);
|
||||
std::stringstream str_vertex(xml_vertex->GetText());
|
||||
|
||||
for (int i = 0; i < vertex_count / 3; i++)
|
||||
{
|
||||
Vec3f temp;
|
||||
str_vertex >> temp.x;
|
||||
str_vertex >> temp.y;
|
||||
str_vertex >> temp.z;
|
||||
vertices_.push_back(temp);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////normal////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
normal_count = 0;
|
||||
tinyxml2::XMLElement* xml_normal = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("source")->NextSiblingElement()->FirstChildElement("float_array");
|
||||
xml_normal->QueryIntAttribute("count", &normal_count);
|
||||
std::stringstream str_normal(xml_normal->GetText());
|
||||
|
||||
for (int i = 0; i < normal_count / 3; i++)
|
||||
{
|
||||
Vec3f temp;
|
||||
str_normal >> temp.x;
|
||||
str_normal >> temp.y;
|
||||
str_normal >> temp.z;
|
||||
normals_.push_back(temp);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
texcoord_count = 0;
|
||||
tinyxml2::XMLElement* xml_texture = doc.FirstChildElement("COLLADA")->FirstChildElement("library_geometries")->FirstChildElement("geometry")->FirstChildElement("mesh")->FirstChildElement("source")->NextSiblingElement()->NextSiblingElement()->FirstChildElement("float_array");
|
||||
xml_texture->QueryIntAttribute("count", &texcoord_count);
|
||||
std::stringstream str_texcoord(xml_texture->GetText());
|
||||
|
||||
for (int i = 0; i < texcoord_count / 2; i++)
|
||||
{
|
||||
Vec2f temp;
|
||||
str_texcoord >> temp.x;
|
||||
str_texcoord >> temp.y;
|
||||
textureco_.push_back(temp);
|
||||
}
|
||||
|
||||
load_texture(filename, "_diffuse.tga", diffusemap_);
|
||||
load_texture(filename, "_nm_tangent.tga", normalmap_);
|
||||
}
|
||||
|
||||
ColladaModel::~ColladaModel() {
|
||||
}
|
||||
|
||||
void ColladaModel::ApplyTransform() {
|
||||
Transform = Translation * Scale * Rotation;
|
||||
}
|
||||
|
||||
void ColladaModel::translate(Vec3f tr) {
|
||||
Translation[0][3] += tr.x;
|
||||
Translation[1][3] += tr.y;
|
||||
Translation[2][3] += tr.z;
|
||||
}
|
||||
void ColladaModel::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 ColladaModel::scale(Vec3f scl) {
|
||||
Scale[0][0] = scl.x;
|
||||
Scale[1][1] = scl.y;
|
||||
Scale[2][2] = scl.z;
|
||||
}
|
||||
|
||||
int ColladaModel::nfaces() {
|
||||
return face_count;
|
||||
}
|
||||
int ColladaModel::nvertices() {
|
||||
return vertex_count;
|
||||
}
|
||||
|
||||
std::vector<int> ColladaModel::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 ColladaModel::vertix(int i) {
|
||||
return vertices_[i];
|
||||
}
|
||||
|
||||
Vec3f ColladaModel::vertix(int iface, int nthvert) {
|
||||
return vertices_[faces_[iface][nthvert][0]];
|
||||
}
|
||||
|
||||
void ColladaModel::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 ColladaModel::diffuse(Vec2f uvf) {
|
||||
Vec2i uv(uvf[0] * diffusemap_.get_width(), uvf[1] * diffusemap_.get_height());
|
||||
return diffusemap_.get(uv[0], uv[1]);
|
||||
}
|
||||
|
||||
Vec3f ColladaModel::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 ColladaModel::uv(int iface, int nthvert) {
|
||||
return textureco_[faces_[iface][nthvert][2]];
|
||||
}
|
||||
|
||||
float ColladaModel::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 ColladaModel::normal(int iface, int nthvert) {
|
||||
int idx = faces_[iface][nthvert][1];
|
||||
return normals_[idx].normalize();
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
#ifndef __MODEL_s__
|
||||
#define __MODEL_s__
|
||||
#pragma once
|
||||
|
||||
#include "ColladaModel.h"
|
||||
#include "tinyxml2.h"
|
||||
#include "geometry.h"
|
||||
#include "tgaimage.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
class ColladaModel {
|
||||
private:
|
||||
int face_count;
|
||||
int vertex_count;
|
||||
int normal_count;
|
||||
int texcoord_count;
|
||||
|
||||
std::vector<std::vector<Vec3i> > faces_; //vertex/normal/uv
|
||||
std::vector<Vec3f> vertices_;
|
||||
std::vector<Vec3f> normals_;
|
||||
std::vector<Vec2f> textureco_;
|
||||
|
||||
TGAImage diffusemap_;
|
||||
TGAImage normalmap_;
|
||||
TGAImage specularmap_;
|
||||
|
||||
void load_texture(std::string filename, const char* suffix, TGAImage& img);
|
||||
public:
|
||||
ColladaModel(const char* filename);
|
||||
~ColladaModel();
|
||||
|
||||
int nfaces();
|
||||
int nvertices();
|
||||
|
||||
Vec3f vertix(int iface, int nthvert);
|
||||
Vec3f vertix(int i);
|
||||
|
||||
Vec3f normal(int iface, int nthvert);
|
||||
Vec3f normal(Vec2f uv);
|
||||
|
||||
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
|
||||
@@ -1,9 +0,0 @@
|
||||
#include "GeometryLibrary.h"
|
||||
|
||||
GeometryLibrary::GeometryLibrary(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
auto xm = xml;
|
||||
auto g = Geometry(xml->FirstChildElement("geometry"));
|
||||
m_Geometries.push_back(g);
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include "geometry.h"
|
||||
|
||||
class GeometryLibrary
|
||||
{
|
||||
std::vector<Geometry> m_Geometries;
|
||||
|
||||
public:
|
||||
GeometryLibrary() = default;
|
||||
GeometryLibrary(tinyxml2::XMLElement * xml);
|
||||
};
|
||||
|
||||
class VisualSceneLibrary
|
||||
{
|
||||
Visualscene m_visual_scene;
|
||||
|
||||
public:
|
||||
VisualSceneLibrary() = default;
|
||||
VisualSceneLibrary(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
|
||||
@@ -22,32 +22,32 @@
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{42971E68-F861-4D45-9DA6-F5E163705584}</ProjectGuid>
|
||||
<RootNamespace>OpenWindow</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
<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>v142</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<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>v142</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<PlatformToolset>v141</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
@@ -115,28 +115,22 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="COLLADA.cpp" />
|
||||
<ClCompile Include="ColladaModel.cpp" />
|
||||
<ClCompile Include="data.cpp" />
|
||||
<ClCompile Include="camera.cpp" />
|
||||
<ClCompile Include="geometry.cpp" />
|
||||
<ClCompile Include="GeometryLibrary.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="model.cpp" />
|
||||
<ClCompile Include="renderer.cpp" />
|
||||
<ClCompile Include="tgaimage.cpp" />
|
||||
<ClCompile Include="tinyxml2.cpp" />
|
||||
<ClCompile Include="util_renderer.cpp" />
|
||||
<ClCompile Include="util_window.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="COLLADA.h" />
|
||||
<ClInclude Include="ColladaModel.h" />
|
||||
<ClInclude Include="data.h" />
|
||||
<ClInclude Include="geometry.h" />
|
||||
<ClInclude Include="GeometryLibrary.h" />
|
||||
<ClInclude Include="camera.h" />
|
||||
<ClInclude Include="model.h" />
|
||||
<ClInclude Include="renderer.h" />
|
||||
<ClInclude Include="tgaimage.h" />
|
||||
<ClInclude Include="tinyxml2.h" />
|
||||
<ClInclude Include="util_renderer.h" />
|
||||
<ClInclude Include="util_window.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -33,19 +33,10 @@
|
||||
<ClCompile Include="renderer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ColladaModel.cpp">
|
||||
<ClCompile Include="camera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tinyxml2.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="COLLADA.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="GeometryLibrary.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="data.cpp">
|
||||
<ClCompile Include="util_renderer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -65,19 +56,10 @@
|
||||
<ClInclude Include="renderer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ColladaModel.h">
|
||||
<ClInclude Include="camera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tinyxml2.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="COLLADA.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="GeometryLibrary.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="data.h">
|
||||
<ClInclude Include="util_renderer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
File diff suppressed because one or more lines are too long
Binary file not shown.
@@ -0,0 +1,121 @@
|
||||
#include "camera.h"
|
||||
|
||||
Camera::Camera()
|
||||
{
|
||||
fov = 30;
|
||||
position = Vec3f(0, 0, 0);
|
||||
rotation = Vec3f(0, 0, 0);
|
||||
up = Vec3f(0, 0, 0);
|
||||
right = Vec3f(0, 0, 0);
|
||||
forward = Vec3f(0, 0, 0);
|
||||
|
||||
near_plane = 0;
|
||||
far_plane = 15;
|
||||
horizontal_camera_speed = 0.5;
|
||||
vertical_camera_speed = 0.5;
|
||||
vertical_camera_clamp_up = 90;
|
||||
vertical_camera_clamp_down = -90;
|
||||
movement_speed = 1.f;
|
||||
}
|
||||
|
||||
Vec3f Camera::GetForward() {
|
||||
return forward;
|
||||
}
|
||||
|
||||
void Camera::Move(Vec3f move_vec) {
|
||||
position = position + move_vec;
|
||||
}
|
||||
|
||||
void Camera::SetPosition(Vec3f pos) {
|
||||
position = pos;
|
||||
}
|
||||
void Camera::Rotate(Vec3f rot_vec) {
|
||||
rotation = rotation + rot_vec;
|
||||
}
|
||||
void Camera::SetRotation(Vec3f rot) {
|
||||
rotation = rot;
|
||||
}
|
||||
void Camera::SetFOV(int angle) {
|
||||
fov = angle;
|
||||
}
|
||||
void Camera::SetVerticalRotSpeed(float speed) {
|
||||
vertical_camera_speed = speed;
|
||||
}
|
||||
void Camera::SetHorizontalRotSpeed(float speed) {
|
||||
horizontal_camera_speed = speed;
|
||||
}
|
||||
void Camera::SetClampRotUp(float angle) {
|
||||
vertical_camera_clamp_up = angle;
|
||||
}
|
||||
void Camera::SetClampRotDown(float angle) {
|
||||
vertical_camera_clamp_down = angle;
|
||||
}
|
||||
void Camera::SetNearPlane(float near_val) {
|
||||
near_plane = near_val;
|
||||
}
|
||||
void Camera::SetFarPlane(float far_val) {
|
||||
far_plane = far_val;
|
||||
}
|
||||
|
||||
void Camera::rotate_hor(float d_angle) {
|
||||
rotation.y += d_angle * horizontal_camera_speed;
|
||||
}
|
||||
void Camera::rotate_ver(float d_angle) {
|
||||
rotation.x += d_angle * vertical_camera_speed;
|
||||
rotation.x = std::fmin(rotation.x, vertical_camera_clamp_up);
|
||||
rotation.x = std::fmax(rotation.x, vertical_camera_clamp_down);
|
||||
}
|
||||
|
||||
|
||||
void Camera::move_camera_left() {
|
||||
position = position - right * movement_speed;
|
||||
}
|
||||
void Camera::move_camera_right() {
|
||||
position = position + right * movement_speed;
|
||||
}
|
||||
void Camera::move_camera_forward() {
|
||||
position = position + forward * movement_speed;
|
||||
}
|
||||
void Camera::move_camera_backward() {
|
||||
position = position - forward * movement_speed;
|
||||
}
|
||||
void Camera::rise() {
|
||||
position = position + Vec3f(0, movement_speed, 0);
|
||||
}
|
||||
void Camera::fall() {
|
||||
position = position - Vec3f(0, movement_speed, 0);
|
||||
}
|
||||
|
||||
void Camera::SetMovementSpeed(float speed) {
|
||||
movement_speed = speed;
|
||||
}
|
||||
|
||||
void Camera::ApplyChanges() {
|
||||
forward = Vec3f(sin(rotation.y * DEG2RAD), -sin(rotation.x * DEG2RAD), -cosf(rotation.y*DEG2RAD) * cosf(rotation.x*DEG2RAD)).normalize();
|
||||
right = Vec3f(cos(rotation.y*DEG2RAD), 0, sin(rotation.y * DEG2RAD)).normalize();
|
||||
up = cross(right, forward).normalize();
|
||||
}
|
||||
|
||||
Matrix Camera::GetModelViewMatrix() {
|
||||
Vec3f center = position + forward;
|
||||
Vec3f z = forward * -1;
|
||||
Matrix Minv = Matrix::identity();
|
||||
Matrix Tr = Matrix::identity();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
Minv[0][i] = right[i];
|
||||
Minv[1][i] = up[i];
|
||||
Minv[2][i] = z[i];
|
||||
Tr[i][3] = -center[i];
|
||||
}
|
||||
return Minv * Tr;
|
||||
}
|
||||
|
||||
Matrix Camera::GetProjectionMatrix() {
|
||||
Matrix Projection = Matrix::identity();
|
||||
Projection[0][0] = 1 / tan(fov * DEG2RAD);
|
||||
Projection[1][1] = 1 / tan(fov * DEG2RAD);
|
||||
Projection[2][2] = (far_plane + near_plane) / (far_plane - near_plane);
|
||||
Projection[2][3] = (-2 * far_plane * near_plane) / (far_plane - near_plane);
|
||||
Projection[3][2] = -1;
|
||||
return Projection;
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef __CAMERA_HEADER__
|
||||
#define __CAMERA_HEADER__
|
||||
#include "geometry.h"
|
||||
|
||||
class Camera {
|
||||
private:
|
||||
Vec3f position;
|
||||
Vec3f rotation;
|
||||
Vec3f up;
|
||||
Vec3f right;
|
||||
Vec3f forward;
|
||||
float fov;
|
||||
float near_plane;
|
||||
float far_plane;
|
||||
float horizontal_camera_speed;
|
||||
float vertical_camera_speed;
|
||||
float vertical_camera_clamp_up;
|
||||
float vertical_camera_clamp_down;
|
||||
float movement_speed;
|
||||
|
||||
public:
|
||||
Camera();
|
||||
void SetPosition(Vec3f pos);
|
||||
void SetRotation(Vec3f rot);
|
||||
void Move(Vec3f move_vec);
|
||||
void Rotate(Vec3f rot_vec);
|
||||
void SetFOV(int angle);
|
||||
void SetNearPlane(float near_val);
|
||||
void SetFarPlane(float far_val);
|
||||
void SetVerticalRotSpeed(float speed);
|
||||
void SetHorizontalRotSpeed(float speed);
|
||||
void SetClampRotUp(float angle);
|
||||
void SetClampRotDown(float angle);
|
||||
void SetMovementSpeed(float speed);
|
||||
Vec3f GetForward();
|
||||
|
||||
void rotate_hor(float d_angle);
|
||||
void rotate_ver(float d_angle);
|
||||
void move_camera_left();
|
||||
void move_camera_right();
|
||||
void move_camera_forward();
|
||||
void move_camera_backward();
|
||||
void rise();
|
||||
void fall();
|
||||
|
||||
void ApplyChanges();
|
||||
Matrix GetModelViewMatrix();
|
||||
Matrix GetProjectionMatrix();
|
||||
};
|
||||
#endif
|
||||
@@ -1,187 +0,0 @@
|
||||
#include "data.h"
|
||||
|
||||
Float_Array::Float_Array(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
xml->QueryIntAttribute("count", (int*)&m_Count);
|
||||
|
||||
const char* ch;
|
||||
xml->QueryStringAttribute("count", &ch);
|
||||
std::string s(ch);
|
||||
m_ID = s;
|
||||
|
||||
std::stringstream str(xml->GetText());
|
||||
m_Floats = new float[m_Count];
|
||||
|
||||
for (int i = 0; i < m_Count; i++)
|
||||
{
|
||||
str >> m_Floats[i];
|
||||
}
|
||||
float f = m_Floats[55358];
|
||||
}
|
||||
|
||||
Name_Array::Name_Array(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
xml->QueryIntAttribute("count", (int*)&m_Count);
|
||||
|
||||
const char* ch;
|
||||
xml->QueryStringAttribute("count", &ch);
|
||||
std::string s(ch);
|
||||
m_ID = s;
|
||||
|
||||
std::stringstream str(xml->GetText());
|
||||
for (int i = 0; i < m_Count; i++)
|
||||
{
|
||||
str >> m_Names[i];
|
||||
}
|
||||
}
|
||||
|
||||
Param::Param(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
const char* ch;
|
||||
xml->QueryStringAttribute("name", &ch);
|
||||
std::string s(ch);
|
||||
m_Name = s;
|
||||
|
||||
const char* ch1;
|
||||
xml->QueryStringAttribute("type", &ch1);
|
||||
std::string s1(ch1);
|
||||
m_Type = s1;
|
||||
}
|
||||
|
||||
Accessor::Accessor(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
const char* ch;
|
||||
xml->QueryStringAttribute("source", &ch);
|
||||
std::string s(ch);
|
||||
m_Source = s;
|
||||
|
||||
xml->QueryIntAttribute("count", (int*)&m_Count);
|
||||
|
||||
xml->QueryIntAttribute("stride", (int*)&m_Stride);
|
||||
|
||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("param"); child != NULL; child = child->NextSiblingElement("param"))
|
||||
{
|
||||
Param p(child);
|
||||
m_Params.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
Technique_Common::Technique_Common(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
m_Accessor = Accessor(xml->FirstChildElement("accessor"));
|
||||
}
|
||||
|
||||
Source::Source(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
const char* ch;
|
||||
xml->QueryStringAttribute("id", &ch);
|
||||
std::string s(ch);
|
||||
m_ID = s;
|
||||
|
||||
tinyxml2::XMLElement* fa = xml->FirstChildElement("float_array");
|
||||
if (fa != NULL)
|
||||
{
|
||||
m_Float_Array = Float_Array(fa);
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* na = xml->FirstChildElement("Name_array");
|
||||
if (na != NULL)
|
||||
{
|
||||
m_Name_Array = Name_Array(na);
|
||||
}
|
||||
|
||||
m_TechniqueCommon = Technique_Common(xml->FirstChildElement("technique_common"));
|
||||
}
|
||||
|
||||
Input::Input(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
const char* ch;
|
||||
xml->QueryStringAttribute("semantic", &ch);
|
||||
std::string s(ch);
|
||||
m_Semantic = s;
|
||||
|
||||
const char* ch1;
|
||||
xml->QueryStringAttribute("source", &ch1);
|
||||
std::string s1(ch1);
|
||||
m_Source = s1;
|
||||
|
||||
if (xml->FindAttribute("offset"))
|
||||
{
|
||||
const char* ch2;
|
||||
xml->QueryStringAttribute("offset", &ch2);
|
||||
std::string s2(ch2);
|
||||
m_Offset = s2;
|
||||
}
|
||||
|
||||
if (xml->FindAttribute("set"))
|
||||
{
|
||||
const char* ch3;
|
||||
xml->QueryStringAttribute("set", &ch3);
|
||||
std::string s3(ch3);
|
||||
m_Set = s3;
|
||||
}
|
||||
}
|
||||
|
||||
Vertices::Vertices(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
const char* ch;
|
||||
xml->QueryStringAttribute("id", &ch);
|
||||
std::string s(ch);
|
||||
m_ID = s;
|
||||
|
||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("input"); child != NULL; child = child->NextSiblingElement("input"))
|
||||
{
|
||||
Input in(child);
|
||||
m_Inputs.push_back(in);
|
||||
}
|
||||
}
|
||||
|
||||
P::P(tinyxml2::XMLElement* xml, unsigned int count)
|
||||
{
|
||||
m_Count = count;
|
||||
std::stringstream str(xml->GetText());
|
||||
m_Indices = new unsigned short[count * 9];
|
||||
for (int i = 0; i < count * 9; i++)
|
||||
{
|
||||
str >> m_Indices[i];
|
||||
}
|
||||
}
|
||||
|
||||
Triangles::Triangles(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
xml->QueryIntAttribute("count", (int*)&m_Count);
|
||||
|
||||
const char* ch;
|
||||
xml->QueryStringAttribute("count", &ch);
|
||||
std::string s(ch);
|
||||
m_Material = s;
|
||||
|
||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("input"); child != NULL; child = child->NextSiblingElement("input"))
|
||||
{
|
||||
Input in(child);
|
||||
m_Inputs.push_back(in);
|
||||
}
|
||||
|
||||
tinyxml2::XMLElement* mp = xml->FirstChildElement("p");
|
||||
if (mp != NULL)
|
||||
{
|
||||
m_P = P(mp, m_Count);
|
||||
}
|
||||
}
|
||||
|
||||
Mesh::Mesh(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("source"); child != NULL; child = child->NextSiblingElement("source"))
|
||||
{
|
||||
Source sc(child);
|
||||
m_Sources.push_back(sc);
|
||||
}
|
||||
|
||||
m_Vertices = Vertices(xml->FirstChildElement("vertices"));
|
||||
|
||||
for (tinyxml2::XMLElement* child = xml->FirstChildElement("triangles"); child != NULL; child = child->NextSiblingElement("triangles"))
|
||||
{
|
||||
Triangles tr(child);
|
||||
m_Triangles.push_back(tr);
|
||||
}
|
||||
}
|
||||
@@ -1,137 +0,0 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "tinyxml2.h"
|
||||
//----------------------------------------------//
|
||||
class Float_Array
|
||||
{
|
||||
unsigned int m_Count;
|
||||
std::string m_ID;
|
||||
float* m_Floats;
|
||||
|
||||
public:
|
||||
Float_Array() = default;
|
||||
Float_Array(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Name_Array
|
||||
{
|
||||
unsigned int m_Count;
|
||||
std::string m_ID;
|
||||
std::string* m_Names;
|
||||
public:
|
||||
Name_Array() = default;
|
||||
Name_Array(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Param
|
||||
{
|
||||
std::string m_Name;
|
||||
std::string m_Type;
|
||||
public:
|
||||
Param() = default;
|
||||
Param(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Accessor
|
||||
{
|
||||
std::string m_Source;
|
||||
unsigned int m_Count;
|
||||
unsigned int m_Stride;
|
||||
std::vector<Param> m_Params;
|
||||
public:
|
||||
Accessor () = default;
|
||||
Accessor(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Technique_Common
|
||||
{
|
||||
Accessor m_Accessor;
|
||||
public:
|
||||
Technique_Common() = default;
|
||||
Technique_Common(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Source
|
||||
{
|
||||
std::string m_ID;
|
||||
Float_Array m_Float_Array;
|
||||
Name_Array m_Name_Array;
|
||||
Technique_Common m_TechniqueCommon;
|
||||
public:
|
||||
Source() = default;
|
||||
Source(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Input
|
||||
{
|
||||
std::string m_Semantic;
|
||||
std::string m_Source;
|
||||
std::string m_Offset;
|
||||
std::string m_Set;
|
||||
public:
|
||||
Input() = default;
|
||||
Input(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Vertices
|
||||
{
|
||||
std::string m_ID;
|
||||
std::vector<Input> m_Inputs;
|
||||
public:
|
||||
Vertices() = default;
|
||||
Vertices(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class P
|
||||
{
|
||||
unsigned int m_Count;
|
||||
unsigned short* m_Indices;
|
||||
public:
|
||||
P() = default;
|
||||
P(tinyxml2::XMLElement* xml, unsigned int count);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Triangles
|
||||
{
|
||||
unsigned int m_Count;
|
||||
std::string m_Material;
|
||||
std::vector<Input> m_Inputs;
|
||||
P m_P;
|
||||
public:
|
||||
Triangles() = default;
|
||||
Triangles(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Mesh
|
||||
{
|
||||
std::vector<Source> m_Sources;
|
||||
Vertices m_Vertices;
|
||||
std::vector<Triangles> m_Triangles;
|
||||
public:
|
||||
Mesh() = default;
|
||||
Mesh(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Node
|
||||
{
|
||||
std::string m_ID;
|
||||
std::string m_name;
|
||||
std::string m_type;
|
||||
std::string m_sid;
|
||||
public:
|
||||
Node() = default;
|
||||
Node(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
class Matrix
|
||||
{
|
||||
std::string m_sid;
|
||||
public:
|
||||
Node() = default;
|
||||
Node(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
//----------------------------------------------//
|
||||
@@ -5,7 +5,3 @@ template <> template <> vec<3,float>::vec(const vec<3,int> &v) : x(v.x),y(v.y)
|
||||
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) {}
|
||||
|
||||
Geometry::Geometry(tinyxml2::XMLElement* xml)
|
||||
{
|
||||
m_Mesh = Mesh(xml->FirstChildElement("mesh"));
|
||||
}
|
||||
|
||||
+3
-42
@@ -1,10 +1,12 @@
|
||||
#ifndef __GEOMETRY_H__
|
||||
#define __GEOMETRY_H__
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include "data.h"
|
||||
|
||||
#define DEG2RAD M_PI/180
|
||||
|
||||
template<size_t DimCols,size_t DimRows,typename T> class mat;
|
||||
|
||||
@@ -234,46 +236,5 @@ typedef vec<3, float> Vec3f;
|
||||
typedef vec<3, int> Vec3i;
|
||||
typedef vec<4, float> Vec4f;
|
||||
typedef mat<4,4,float> Matrix;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Geometry
|
||||
{
|
||||
Mesh m_Mesh;
|
||||
public:
|
||||
Geometry() = default;
|
||||
Geometry(tinyxml2::XMLElement * xml);
|
||||
};
|
||||
|
||||
class Visualscene
|
||||
{
|
||||
node m_Mesh;
|
||||
public:
|
||||
Visualscene() = default;
|
||||
Visualscene(tinyxml2::XMLElement* xml);
|
||||
};
|
||||
#endif //__GEOMETRY_H__
|
||||
|
||||
|
||||
+51
-11
@@ -3,26 +3,29 @@
|
||||
#include "renderer.h"
|
||||
#include "ctime"
|
||||
|
||||
const int width = 800;
|
||||
const int height = 800;
|
||||
const int screen_width = 1000;
|
||||
const int screen_height = 1000;
|
||||
|
||||
#define TARGET_FRAMERATE 30
|
||||
|
||||
int prev_mouse_x = screen_width/2;
|
||||
int prev_mouse_y = screen_height/2;
|
||||
|
||||
float TIME = 0;
|
||||
|
||||
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
HWND hwnd;
|
||||
MSG Msg;
|
||||
|
||||
hwnd = create_window(width, height, hInstance);
|
||||
hwnd = create_window(hInstance);
|
||||
ShowCursor(false);
|
||||
ShowWindow(hwnd, nCmdShow);
|
||||
|
||||
char debug_str[100];
|
||||
init_camera();
|
||||
|
||||
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);
|
||||
SetTimer(hwnd, NULL, 1000 / TARGET_FRAMERATE, (TIMERPROC)FixedUpdate);
|
||||
|
||||
while (GetMessage(&Msg, NULL, 0, 0))
|
||||
{
|
||||
@@ -32,14 +35,51 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
return Msg.wParam;
|
||||
}
|
||||
|
||||
void HandleMouseMovement() {
|
||||
POINT point;
|
||||
GetCursorPos(&point);
|
||||
|
||||
camera.rotate_hor(point.x - prev_mouse_x);
|
||||
camera.rotate_ver(point.y - prev_mouse_y);
|
||||
|
||||
SetCursorPos(prev_mouse_x, prev_mouse_y);
|
||||
}
|
||||
|
||||
bool HandleButtonPressed() {
|
||||
if (GetAsyncKeyState(VK_UP) & 0x8000)
|
||||
camera.move_camera_forward();
|
||||
if (GetAsyncKeyState(VK_DOWN) & 0x8000)
|
||||
camera.move_camera_backward();
|
||||
if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
|
||||
camera.move_camera_right();
|
||||
if (GetAsyncKeyState(VK_LEFT) & 0x8000)
|
||||
camera.move_camera_left();
|
||||
if (GetAsyncKeyState(VK_SPACE) & 0x8000)
|
||||
camera.rise();
|
||||
if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
|
||||
camera.fall();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord)
|
||||
{
|
||||
TIME += 0.167;
|
||||
HandleButtonPressed();
|
||||
camera.ApplyChanges();
|
||||
render();
|
||||
Update();
|
||||
}
|
||||
|
||||
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message)
|
||||
{
|
||||
case WM_MOUSEMOVE:
|
||||
HandleMouseMovement();
|
||||
break;
|
||||
case WM_RBUTTONDOWN:
|
||||
break;
|
||||
case WM_LBUTTONDOWN:
|
||||
Update();
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
@@ -48,7 +48,7 @@ Model::Model(const char *filename) : verts_(), faces_(), norms_(), uv_(), diffus
|
||||
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_);
|
||||
load_texture(filename, "_spec.tga", specularmap_);
|
||||
}
|
||||
|
||||
Model::~Model() {}
|
||||
@@ -58,9 +58,9 @@ void Model::ApplyTransform() {
|
||||
}
|
||||
|
||||
void Model::translate(Vec3f tr) {
|
||||
Translation[0][3] += tr.x;
|
||||
Translation[1][3] += tr.y;
|
||||
Translation[2][3] += tr.z;
|
||||
Translation[0][3] = tr.x;
|
||||
Translation[1][3] = tr.y;
|
||||
Translation[2][3] = tr.z;
|
||||
}
|
||||
void Model::rotate(Vec3f rot) {
|
||||
rot = rot * DEG2RAD;
|
||||
|
||||
Binary file not shown.
+90
-199
@@ -1,225 +1,116 @@
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include "tgaimage.h"
|
||||
#include "model.h"
|
||||
#include "geometry.h"
|
||||
#include "model.h"
|
||||
#include "renderer.h"
|
||||
#include "util_window.h"
|
||||
#include <ctime>
|
||||
#include "ColladaModel.h"
|
||||
#include "COLLADA.h"
|
||||
#include "camera.h"
|
||||
#include "util_renderer.h"
|
||||
|
||||
#define HORIZONTAL_CAMERA_SPEED 0.1
|
||||
#define VERTICAL_CAMERA_SPEED 0.1
|
||||
#define VERTICAL_CAMERA_CLAMP_UP 90
|
||||
#define VERTICAL_CAMERA_CLAMP_DOWN -90
|
||||
#define NEAR_CLIP_PLANE 0
|
||||
#define FAR_CLIP_PLANE 10
|
||||
#define FOV 30
|
||||
#define CAMERA_MOVEMENT_SPEED 0.05f
|
||||
#define DEFAULT_CAMERA_POS Vec3f(0, 0, 5)
|
||||
#define DEFAULT_CAMERA_ROT Vec3f(0, 0, 0)
|
||||
#define LIGHT_INTENSITY 2.f
|
||||
|
||||
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;
|
||||
Matrix ViewPort = Matrix::identity();
|
||||
Matrix ModelView = Matrix::identity();
|
||||
Matrix Projection = Matrix::identity();
|
||||
|
||||
float* z_buffer;
|
||||
Vec3f light_dir = Vec3f(0, 0, 1).normalize();
|
||||
Vec3f eye(0, 0, 3);
|
||||
Vec3f center(0, 0, 0);
|
||||
Model* model = new Model("african_head.obj");
|
||||
Camera camera;
|
||||
|
||||
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;
|
||||
Vec3f light_dir = Vec3f(1, 1, 1).normalize();
|
||||
|
||||
m[0][0] = w / 2.f;
|
||||
m[1][1] = h / 2.f;
|
||||
m[2][2] = depth / 2.f;
|
||||
return m;
|
||||
void init_camera() {
|
||||
camera.SetPosition(DEFAULT_CAMERA_POS);
|
||||
camera.SetRotation(DEFAULT_CAMERA_ROT);
|
||||
camera.SetFOV(FOV);
|
||||
camera.SetNearPlane(NEAR_CLIP_PLANE);
|
||||
camera.SetFarPlane(FAR_CLIP_PLANE);
|
||||
camera.SetClampRotDown(VERTICAL_CAMERA_CLAMP_DOWN);
|
||||
camera.SetClampRotUp(VERTICAL_CAMERA_CLAMP_UP);
|
||||
camera.SetHorizontalRotSpeed(HORIZONTAL_CAMERA_SPEED);
|
||||
camera.SetVerticalRotSpeed(VERTICAL_CAMERA_SPEED);
|
||||
camera.SetMovementSpeed(CAMERA_MOVEMENT_SPEED);
|
||||
camera.ApplyChanges();
|
||||
}
|
||||
|
||||
void line(Vec2i p0, Vec2i p1, TGAImage &image, TGAColor color)
|
||||
void clear_zbuffer()
|
||||
{
|
||||
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
|
||||
ColladaModel* 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;
|
||||
z_buffer[i] = 0;
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
struct TextureShader : public IShader {
|
||||
mat<2, 3, float> varying_uv_coords;
|
||||
Matrix uniform_mit;
|
||||
Matrix uniform_m;
|
||||
|
||||
virtual Vec4f vertex(int iface, int nthvert) {
|
||||
varying_uv_coords.set_col(nthvert, model->uv(iface, nthvert));
|
||||
Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert));
|
||||
return ViewPort * Projection * ModelView * gl_Vertex; // transform it to screen coordinates
|
||||
}
|
||||
return Minv * Tr;
|
||||
}
|
||||
|
||||
virtual bool fragment(Vec3f bar, TGAColor &color) {
|
||||
Vec2f uv = varying_uv_coords * bar;
|
||||
Vec3f normal = Vec3f(uniform_mit * Vec4f(model->normal(uv))).normalize();
|
||||
Vec3f light = Vec3f(uniform_m * Vec4f(light_dir)).normalize();
|
||||
Vec3f reflection = (normal * (normal*light*2.f) - light).normalize();
|
||||
float spec_intensity = pow(std::fmax(reflection.z, 0.f), model->specular(uv));
|
||||
float diff_intensity = std::fmax(0.f, (normal*light));
|
||||
TGAColor c = model->diffuse(uv);
|
||||
color = c;
|
||||
for (int i = 0; i < 3; i++)
|
||||
color[i] = std::fmin(1 + c[i] * (diff_intensity + 0.8 * spec_intensity), 255) * LIGHT_INTENSITY;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void render()
|
||||
{
|
||||
COLLADA C("sssssssssssss.dae");
|
||||
ColladaModel* model = new ColladaModel("african_head.dae");
|
||||
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();
|
||||
|
||||
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->vertix(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;
|
||||
//light_dir = camera.GetForward().normalize() * -1;
|
||||
}
|
||||
|
||||
triangle(screen_coords, model, diffuse_coords, intensities, Vec3f(0, 0, 5));
|
||||
{
|
||||
viewport(0, 0, screen_width, screen_height, FAR_CLIP_PLANE, NEAR_CLIP_PLANE);
|
||||
Projection = camera.GetProjectionMatrix();
|
||||
ModelView = camera.GetModelViewMatrix();
|
||||
}
|
||||
|
||||
|
||||
//Matrix z = ViewPort * Projection * ModelView * model->Transform;
|
||||
|
||||
clear_zbuffer();
|
||||
TextureShader shader;
|
||||
shader.uniform_m = (Projection);
|
||||
shader.uniform_mit = (Projection).invert_transpose();
|
||||
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < model->nfaces(); i++) {
|
||||
Vec4f screen_coords[3];
|
||||
bool out = true;
|
||||
#pragma omp parallel for
|
||||
for (int j = 0; j < 3; j++) {
|
||||
screen_coords[j] = shader.vertex(i, j);
|
||||
Vec3f screen3(screen_coords[j]);
|
||||
|
||||
if (screen3.x > 0 && screen3.x < screen_width && screen3.y > 0 && screen3.y < screen_height) out = false;
|
||||
}
|
||||
if(!out)
|
||||
triangle(screen_coords, shader);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
#ifndef RENDERER_HEADER
|
||||
#define RENDERER_HEADER
|
||||
#include "tgaimage.h"
|
||||
#include "camera.h"
|
||||
|
||||
|
||||
extern float* z_buffer;
|
||||
extern Camera camera;
|
||||
extern float TIME;
|
||||
|
||||
void init_camera();
|
||||
void render();
|
||||
int color_to_int(TGAColor col);
|
||||
#endif
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,73 @@
|
||||
#include "util_renderer.h"
|
||||
#include "util_window.h"
|
||||
|
||||
IShader::~IShader() {}
|
||||
|
||||
float* z_buffer = new float[screen_width * screen_height];
|
||||
|
||||
void viewport(int x, int y, int w, int h, int far_plane, int near_plane) {
|
||||
ViewPort[0][3] = x + w / 2.f;
|
||||
ViewPort[1][3] = y + h / 2.f;
|
||||
ViewPort[2][3] = (far_plane-near_plane) / 2.f;
|
||||
|
||||
ViewPort[0][0] = w / 2.f;
|
||||
ViewPort[1][1] = h / 2.f;
|
||||
ViewPort[2][2] = (far_plane+near_plane) / 2.f;
|
||||
}
|
||||
|
||||
int color_to_int(TGAColor col) {
|
||||
return (col[2] << 16) | (col[1] << 8) | col[0];
|
||||
}
|
||||
|
||||
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( Vec4f* pts, IShader &shader)
|
||||
{
|
||||
Vec3f pts3[3];
|
||||
for (int i = 0; i < 3; i++)
|
||||
pts3[i] = Vec3f(pts[i]);
|
||||
|
||||
if (pts3[0].y == pts3[1].y && pts3[0].y == pts3[2].y) return; // i dont care about degenerate triangles
|
||||
//if (pts3[0].y > pts3[1].y) { std::swap(pts3[0], pts3[1]); }
|
||||
//if (pts3[0].y > pts3[2].y) { std::swap(pts3[0], pts3[2]); }
|
||||
//if (pts3[1].y > pts3[2].y) { std::swap(pts3[1], pts3[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);
|
||||
|
||||
#pragma omp parallel for
|
||||
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)pts3[i][j]));
|
||||
bounding_box_max[j] = std::fmin(clamp[j], std::fmax(bounding_box_max[j], (int)pts3[i][j]));
|
||||
}
|
||||
|
||||
|
||||
Vec3i P;
|
||||
#pragma omp parallel for
|
||||
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(pts3, P);
|
||||
float frag_depth = 0;
|
||||
for (int i = 0; i < 3; i++)
|
||||
frag_depth += pts3[i][2] * bc_coord[i];
|
||||
if (bc_coord.x < 0 || bc_coord.y < 0 || bc_coord.z < 0 || z_buffer[ P.x + P.y * screen_width ]>frag_depth) continue;
|
||||
TGAColor color;
|
||||
bool discard = shader.fragment(bc_coord, color);
|
||||
if (!discard) {
|
||||
z_buffer[P.x + P.y * screen_width] = frag_depth;
|
||||
set_pixel(P.x, P.y, color_to_int(color));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include "tgaimage.h"
|
||||
#include "model.h"
|
||||
#include "geometry.h"
|
||||
|
||||
extern Matrix ModelView;
|
||||
extern Matrix ViewPort;
|
||||
extern Matrix Projection;
|
||||
|
||||
void viewport(int x, int y, int w, int h, int far, int near);
|
||||
|
||||
struct IShader {
|
||||
virtual ~IShader();
|
||||
virtual Vec4f vertex(int iface, int nthvert) = 0;
|
||||
virtual bool fragment(Vec3f bar, TGAColor &color) = 0;
|
||||
};
|
||||
|
||||
//void triangle(Vec4f *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer);
|
||||
|
||||
//void triangle( Vec3f* pts, Vec2f* diff_pts, Model* model, float* intensities)
|
||||
|
||||
void triangle(Vec4f* pts, IShader &shader);
|
||||
@@ -8,8 +8,6 @@ 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;
|
||||
@@ -17,15 +15,13 @@ HDRAWDIB hdd;
|
||||
HDC bitmap_dc;
|
||||
HGDIOBJ old_obj;
|
||||
|
||||
HWND create_window(int width, int height, HINSTANCE &hInstance) {
|
||||
HWND create_window(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);
|
||||
|
||||
@@ -107,6 +103,16 @@ void set_pixel(unsigned int x, unsigned int y, unsigned int color) {
|
||||
screen_changed = true;
|
||||
}
|
||||
|
||||
void Update() {
|
||||
DrawDibDraw(hdd, hdc, 0, 0, screen_width, screen_height, &info.bmiHeader, pixels, 0, 0, screen_width, screen_height, 0);
|
||||
void clear_screen() {
|
||||
for (int x = 0; x < screen_width; x++)
|
||||
for (int y = 0; y < screen_height; y++)
|
||||
set_pixel(x, y, 0);
|
||||
}
|
||||
|
||||
void Update() {
|
||||
if (screen_changed) {
|
||||
DrawDibDraw(hdd, hdc, 0, 0, screen_width, screen_height, &info.bmiHeader, pixels, 0, 0, screen_width, screen_height, 0);
|
||||
clear_screen();
|
||||
screen_changed = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,18 +18,19 @@ extern HDC hdc;
|
||||
extern HDRAWDIB hdd;
|
||||
extern HDC bitmap_dc;
|
||||
extern HGDIOBJ old_obj;
|
||||
extern int screen_width;
|
||||
extern int screen_height;
|
||||
extern const int screen_width;
|
||||
extern const int screen_height;
|
||||
|
||||
|
||||
void init(HWND &hWnd);
|
||||
void destroy_window();
|
||||
HWND create_window(int width, int height, HINSTANCE &hInstance);
|
||||
HWND create_window(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);
|
||||
void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord);
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user