Skip to content

Commit

Permalink
projection logic bugfix
Browse files Browse the repository at this point in the history
  • Loading branch information
ssloy committed Jan 28, 2015
1 parent a4537e0 commit af1861a
Show file tree
Hide file tree
Showing 8 changed files with 41 additions and 37 deletions.
1 change: 1 addition & 0 deletions geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ template <> template <> vec<3,int> ::vec(const vec<3,float> &v) : x(int(v.x+.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) {}

3 changes: 1 addition & 2 deletions geometry.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#ifndef __GEOMETRY_H__
#define __GEOMETRY_H__

#include <cmath>
#include <vector>
#include <cassert>
Expand Down Expand Up @@ -208,5 +207,5 @@ typedef vec<3, float> Vec3f;
typedef vec<3, int> Vec3i;
typedef vec<4, float> Vec4f;
typedef mat<4,4,float> Matrix;

#endif //__GEOMETRY_H__

8 changes: 4 additions & 4 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,18 @@ const int width = 800;
const int height = 800;

Vec3f light_dir(1,1,1);
Vec3f eye(1,1,3);
Vec3f eye(0,-1,3);
Vec3f center(0,0,0);
Vec3f up(0,1,0);

struct GouraudShader : public IShader {
Vec3f varying_intensity; // written by vertex shader, read by fragment shader

virtual Vec3i vertex(int iface, int nthvert) {
virtual Vec4f vertex(int iface, int nthvert) {
Vec4f gl_Vertex = embed<4>(model->vert(iface, nthvert)); // read the vertex from .obj file
gl_Vertex = Viewport*Projection*ModelView*gl_Vertex; // transform it to screen coordinates
varying_intensity[nthvert] = std::max(0.f, model->normal(iface, nthvert)*light_dir); // get diffuse lighting intensity
return proj<3>(gl_Vertex/gl_Vertex[3]); // project homogenious coordinates to 3d
return gl_Vertex;
}

virtual bool fragment(Vec3f bar, TGAColor &color) {
Expand All @@ -49,7 +49,7 @@ int main(int argc, char** argv) {

GouraudShader shader;
for (int i=0; i<model->nfaces(); i++) {
Vec3i screen_coords[3];
Vec4f screen_coords[3];
for (int j=0; j<3; j++) {
screen_coords[j] = shader.vertex(i, j);
}
Expand Down
17 changes: 10 additions & 7 deletions model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,28 +78,31 @@ void Model::load_texture(std::string filename, const char *suffix, TGAImage &img
}
}

TGAColor Model::diffuse(Vec2i uv) {
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(Vec2i uv) {
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;
}

Vec2i Model::uv(int iface, int nthvert) {
int idx = faces_[iface][nthvert][1];
return Vec2i(uv_[idx][0]*diffusemap_.get_width(), uv_[idx][1]*diffusemap_.get_height());
Vec2f Model::uv(int iface, int nthvert) {
return uv_[faces_[iface][nthvert][1]];
}

float Model::specular(Vec2i uv) {
return specularmap_.get(uv.x, uv.y)[0]/1.f;
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();
}

11 changes: 5 additions & 6 deletions model.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#ifndef __MODEL_H__
#define __MODEL_H__

#include <vector>
#include <string>
#include "geometry.h"
Expand All @@ -22,13 +21,13 @@ class Model {
int nverts();
int nfaces();
Vec3f normal(int iface, int nthvert);
Vec3f normal(Vec2i uv);
Vec3f normal(Vec2f uv);
Vec3f vert(int i);
Vec3f vert(int iface, int nthvert);
Vec2i uv(int iface, int nthvert);
TGAColor diffuse(Vec2i uv);
float specular(Vec2i uv);
Vec2f uv(int iface, int nthvert);
TGAColor diffuse(Vec2f uv);
float specular(Vec2f uv);
std::vector<int> face(int idx);
};

#endif //__MODEL_H__

27 changes: 15 additions & 12 deletions our_gl.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <cmath>
#include <limits>
#include <cstdlib>
#include "our_gl.h"

Matrix ModelView;
Expand Down Expand Up @@ -36,8 +37,8 @@ void lookat(Vec3f eye, Vec3f center, Vec3f up) {
}
}

Vec3f barycentric(Vec3i A, Vec3i B, Vec3i C, Vec3i P) {
Vec3i s[2];
Vec3f barycentric(Vec2f A, Vec2f B, Vec2f C, Vec2f P) {
Vec3f s[2];
for (int i=2; i--; ) {
s[i][0] = C[i]-A[i];
s[i][1] = B[i]-A[i];
Expand All @@ -49,25 +50,27 @@ Vec3f barycentric(Vec3i A, Vec3i B, Vec3i C, Vec3i P) {
return Vec3f(-1,1,1); // in this case generate negative coordinates, it will be thrown away by the rasterizator
}

void triangle(Vec3i *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer) {
Vec2i bboxmin( std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
Vec2i bboxmax(-std::numeric_limits<int>::max(), -std::numeric_limits<int>::max());
void triangle(Vec4f *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer) {
Vec2f bboxmin( std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
Vec2f bboxmax(-std::numeric_limits<float>::max(), -std::numeric_limits<float>::max());
for (int i=0; i<3; i++) {
for (int j=0; j<2; j++) {
bboxmin[j] = std::min(bboxmin[j], pts[i][j]);
bboxmax[j] = std::max(bboxmax[j], pts[i][j]);
bboxmin[j] = std::min(bboxmin[j], pts[i][j]/pts[i][3]);
bboxmax[j] = std::max(bboxmax[j], pts[i][j]/pts[i][3]);
}
}
Vec3i P;
Vec2i P;
TGAColor color;
for (P.x=bboxmin.x; P.x<=bboxmax.x; P.x++) {
for (P.y=bboxmin.y; P.y<=bboxmax.y; P.y++) {
Vec3f c = barycentric(pts[0], pts[1], pts[2], P);
P.z = std::max(0, std::min(255, int(pts[0].z*c.x + pts[1].z*c.y + pts[2].z*c.z + .5))); // clamping to 0-255 since it is stored in unsigned char
if (c.x<0 || c.y<0 || c.z<0 || zbuffer.get(P.x, P.y)[0]>P.z) continue;
Vec3f c = barycentric(proj<2>(pts[0]/pts[0][3]), proj<2>(pts[1]/pts[1][3]), proj<2>(pts[2]/pts[2][3]), proj<2>(P));
float z = pts[0][2]*c.x + pts[1][2]*c.y + pts[2][2]*c.z;
float w = pts[0][3]*c.x + pts[1][3]*c.y + pts[2][3]*c.z;
int frag_depth = std::max(0, std::min(255, int(z/w+.5)));
if (c.x<0 || c.y<0 || c.z<0 || zbuffer.get(P.x, P.y)[0]>frag_depth) continue;
bool discard = shader.fragment(c, color);
if (!discard) {
zbuffer.set(P.x, P.y, TGAColor(P.z));
zbuffer.set(P.x, P.y, TGAColor(frag_depth));
image.set(P.x, P.y, color);
}
}
Expand Down
10 changes: 4 additions & 6 deletions our_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ void projection(float coeff=0.f); // coeff = -1/c
void lookat(Vec3f eye, Vec3f center, Vec3f up);

struct IShader {
virtual ~IShader() = 0;
virtual Vec3i vertex(int iface, int nthvert) = 0;
virtual ~IShader();
virtual Vec4f vertex(int iface, int nthvert) = 0;
virtual bool fragment(Vec3f bar, TGAColor &color) = 0;
};

void triangle(Vec3i *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer);
template <typename T> T CLAMP(const T& value, const T& low, const T& high) {
return value < low ? low : (value > high ? high : value);
}
void triangle(Vec4f *pts, IShader &shader, TGAImage &image, TGAImage &zbuffer);

#endif //__OUR_GL_H__

1 change: 1 addition & 0 deletions tgaimage.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,4 @@ class TGAImage {
};

#endif //__IMAGE_H__

0 comments on commit af1861a

Please sign in to comment.