Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 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,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
|
||||
@@ -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,22 +115,20 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ColladaModel.cpp" />
|
||||
<ClCompile Include="camera.cpp" />
|
||||
<ClCompile Include="geometry.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="model.cpp" />
|
||||
<ClCompile Include="renderer.cpp" />
|
||||
<ClCompile Include="tgaimage.cpp" />
|
||||
<ClCompile Include="tinyxml2.cpp" />
|
||||
<ClCompile Include="util_window.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="ColladaModel.h" />
|
||||
<ClInclude Include="geometry.h" />
|
||||
<ClInclude Include="camera.h" />
|
||||
<ClInclude Include="model.h" />
|
||||
<ClInclude Include="renderer.h" />
|
||||
<ClInclude Include="tgaimage.h" />
|
||||
<ClInclude Include="tinyxml2.h" />
|
||||
<ClInclude Include="util_window.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -33,10 +33,7 @@
|
||||
<ClCompile Include="renderer.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ColladaModel.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="tinyxml2.cpp">
|
||||
<ClCompile Include="camera.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
@@ -56,10 +53,7 @@
|
||||
<ClInclude Include="renderer.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ColladaModel.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="tinyxml2.h">
|
||||
<ClInclude Include="camera.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,117 @@
|
||||
#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::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));
|
||||
right = Vec3f(cos(rotation.y*DEG2RAD), 0, sin(rotation.y * DEG2RAD));
|
||||
up = cross(right, forward);
|
||||
}
|
||||
|
||||
Matrix Camera::GetModelViewMatrix() {
|
||||
Vec3f center = position + forward;
|
||||
Vec3f z = (position - 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;
|
||||
}
|
||||
|
||||
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,48 @@
|
||||
#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 ApplyChanges();
|
||||
Matrix GetModelViewMatrix();
|
||||
Matrix GetProjectionMatrix();
|
||||
};
|
||||
#endif
|
||||
@@ -1,10 +1,13 @@
|
||||
#ifndef __GEOMETRY_H__
|
||||
#define __GEOMETRY_H__
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
#define DEG2RAD M_PI/180
|
||||
|
||||
template<size_t DimCols,size_t DimRows,typename T> class mat;
|
||||
|
||||
template <size_t DIM, typename T> struct vec {
|
||||
|
||||
+44
-11
@@ -3,26 +3,27 @@
|
||||
#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;
|
||||
|
||||
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 +33,46 @@ 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();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CALLBACK FixedUpdate(HWND hwnd, UINT message, UINT uInt, DWORD dWord)
|
||||
{
|
||||
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);
|
||||
|
||||
@@ -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.
+88
-48
@@ -1,5 +1,4 @@
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include "tgaimage.h"
|
||||
@@ -8,33 +7,46 @@
|
||||
#include "renderer.h"
|
||||
#include "util_window.h"
|
||||
#include <ctime>
|
||||
#include "ColladaModel.h"
|
||||
#include "camera.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 15
|
||||
#define FOV 30
|
||||
#define DEFAULT_CAMERA_POS Vec3f(0, 0, 5)
|
||||
#define DEFAULT_CAMERA_ROT Vec3f(0, 0, 0)
|
||||
#define CAMERA_MOVEMENT_SPEED 1.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;
|
||||
bool wireframe = false;
|
||||
|
||||
float* z_buffer;
|
||||
|
||||
Model* model = new Model("african_head.obj");
|
||||
Camera camera;
|
||||
|
||||
float* z_buffer = new float[screen_width * screen_height];
|
||||
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[2][3] = (FAR_CLIP_PLANE-NEAR_CLIP_PLANE) / 2.f;
|
||||
|
||||
m[0][0] = w / 2.f;
|
||||
m[1][1] = h / 2.f;
|
||||
m[2][2] = depth / 2.f;
|
||||
m[2][2] = (FAR_CLIP_PLANE+NEAR_CLIP_PLANE) / 2.f;
|
||||
return m;
|
||||
}
|
||||
|
||||
void line(Vec2i p0, Vec2i p1, TGAImage &image, TGAColor color)
|
||||
void line(Vec3f p0, Vec3f p1, TGAColor color)
|
||||
{
|
||||
bool steep = false;
|
||||
|
||||
@@ -60,10 +72,10 @@ void line(Vec2i p0, Vec2i p1, TGAImage &image, TGAColor color)
|
||||
|
||||
for (int x = p0[0]; x <= p1[0]; x++) {
|
||||
if (steep) {
|
||||
image.set(y, x, color);
|
||||
set_pixel(y, x, color_to_int(color));
|
||||
}
|
||||
else {
|
||||
image.set(x, y, color);
|
||||
set_pixel(x, y, color_to_int(color));
|
||||
}
|
||||
error2 += derror2;
|
||||
if (error2 > dx) {
|
||||
@@ -87,45 +99,61 @@ Vec3f barycentric(Vec3f* pts, Vec3f P)
|
||||
|
||||
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
|
||||
Model* model,
|
||||
float* intensities)
|
||||
{
|
||||
|
||||
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]);
|
||||
if(diff_pts)
|
||||
std::swap(diff_pts[0], diff_pts[1]);
|
||||
if(intensities)
|
||||
std::swap(intensities[0], intensities[1]);
|
||||
}
|
||||
if (pts[0].y > pts[2].y) {
|
||||
std::swap(pts[0], pts[2]);
|
||||
if(diff_pts)
|
||||
std::swap(diff_pts[0], diff_pts[2]);
|
||||
if(intensities)
|
||||
std::swap(intensities[0], intensities[2]);
|
||||
}
|
||||
if (pts[1].y > pts[2].y) {
|
||||
std::swap(pts[1], pts[2]);
|
||||
if(diff_pts)
|
||||
std::swap(diff_pts[1], diff_pts[2]);
|
||||
if(intensities)
|
||||
std::swap(intensities[1], intensities[2]);
|
||||
}
|
||||
|
||||
if (wireframe)
|
||||
{
|
||||
line(pts[0], pts[1], white);
|
||||
line(pts[1], pts[2], white);
|
||||
line(pts[2], pts[0], white);
|
||||
return;
|
||||
}
|
||||
|
||||
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++) {
|
||||
#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)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++) {
|
||||
#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(pts, P);
|
||||
if(bc_coord.x < 0 || bc_coord.y < 0 || bc_coord.z < 0) continue;
|
||||
if (bc_coord.x < 0 || bc_coord.y < 0 || bc_coord.z < 0) continue;
|
||||
|
||||
|
||||
float intensity =
|
||||
@@ -136,16 +164,16 @@ void triangle(
|
||||
|
||||
// Interpolating Z using the barycentric coordinates
|
||||
P.z = 0;
|
||||
for(int i = 0; i < 3; i++) P.z += pts[i][2] * bc_coord[i];
|
||||
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)])
|
||||
if (P.z > z_buffer[(int)(P.x + P.y * screen_width)] && P.z > 0)
|
||||
{
|
||||
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) {
|
||||
if (diff_pts) {
|
||||
Vec2f diff_pt =
|
||||
diff_pts[0]
|
||||
+ (diff_pts[1] - diff_pts[0]) * bc_coord[1]
|
||||
@@ -155,6 +183,9 @@ void triangle(
|
||||
}
|
||||
color = color * intensity;
|
||||
set_pixel(P.x, P.y, color_to_int(color));
|
||||
//char debugStr[200];
|
||||
//sprintf_s(debugStr, "%f\n", P.z);
|
||||
//OutputDebugString(debugStr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -164,40 +195,41 @@ int color_to_int(TGAColor col) {
|
||||
return (col[2] << 16) | (col[1] << 8) | col[0];
|
||||
}
|
||||
|
||||
void init_zbuffer()
|
||||
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 clear_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;
|
||||
}
|
||||
Matrix ViewPort = Matrix::identity();
|
||||
Matrix Projection = Matrix::identity();
|
||||
Matrix ModelView = Matrix::identity();
|
||||
|
||||
void render()
|
||||
{
|
||||
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();
|
||||
light_dir = camera.GetForward() * -1;
|
||||
ViewPort = viewport(0, 0, screen_width, screen_height);
|
||||
Projection = camera.GetProjectionMatrix();
|
||||
ModelView = camera.GetModelViewMatrix();
|
||||
|
||||
Matrix z = ViewPort * Projection * ModelView * model->Transform;
|
||||
|
||||
init_zbuffer();
|
||||
clear_zbuffer();
|
||||
#pragma omp parallel for
|
||||
for (int i = 0; i < model->nfaces(); i++)
|
||||
{
|
||||
std::vector<int> face = model->face(i);
|
||||
@@ -205,19 +237,27 @@ void render()
|
||||
Vec3f world_coords[3];
|
||||
Vec2f diffuse_coords[3];
|
||||
float intensities[3];
|
||||
bool out = true;
|
||||
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
Vec3f v = model->vertix(face[j]);
|
||||
Vec3f v = model->vert(face[j]);
|
||||
Vec4f v4(v);
|
||||
Vec3f coord(z * v4);
|
||||
|
||||
if (coord.x > 0 && coord.x < screen_width
|
||||
&& coord.y > 0 && coord.y < screen_height)
|
||||
out = false;
|
||||
|
||||
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));
|
||||
if (out) continue;
|
||||
|
||||
triangle(screen_coords, diffuse_coords, model, intensities);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
#ifndef RENDERER_HEADER
|
||||
#define RENDERER_HEADER
|
||||
#include "tgaimage.h"
|
||||
#include "camera.h"
|
||||
|
||||
|
||||
extern float* z_buffer;
|
||||
extern Camera camera;
|
||||
|
||||
void init_camera();
|
||||
void render();
|
||||
int color_to_int(TGAColor col);
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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