Skip to content

Commit 2822490

Browse files
mansen4200x0TestMe
andauthored
MVC into master (#7)
* restructured: mvc * mvc * mvc-no-errors * added controller * random-test * fix-folder-name * Merge changes from master to M.V.C (#6) * Implement Texture class, normal mapping, and diffuse mapping * Reorganize files * Update README.md * Change directory structure to MVC --------- Co-authored-by: bannads <bannaziad990@gmail.com>
1 parent 1880f26 commit 2822490

11 files changed

Lines changed: 320 additions & 21 deletions

File tree

Main.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import java.awt.*;
22
import java.io.IOException;
33

4+
import model.pipeline.programmable.*;
5+
import model.renderer.*;
6+
import view.Window;
47

58
import model.pipeline.programmable.*;
69
import model.renderer.*;
@@ -11,41 +14,41 @@ public class Main
1114
{
1215
public static void main(String[]args) throws IOException
1316
{
14-
//init model.renderer
17+
// init renderer
1518
Renderer myRenderer = new Renderer(pix_width, pix_height);
1619
PhongShader myShader = new PhongShader();
1720
myRenderer.setShader(myShader);
1821

1922
Window myWindow = new Window("Java Rasterizer", myRenderer);
2023

2124
int i = 0;
22-
//TODO structure : make breaking of while loop dependent on user input
23-
//render loop
24-
while (true)
25-
{
25+
// TODO structure : make breaking of while loop dependent on user input
26+
// render loop
27+
while (true) {
2628
long start = System.nanoTime();
27-
//clear buffers at the beginning of the frame. 10-15ms
29+
// clear buffers at the beginning of the frame. 10-15ms
2830
myRenderer.myRasterizer.clearDepthBuffer();
29-
myRenderer.myRasterizer.clearPixelBuffer(new Color(50,50,50));
31+
myRenderer.myRasterizer.clearPixelBuffer(new Color(50, 50, 50));
3032

31-
//specify rotation angle of object around y-axis in radians
32-
rotationAngle = (float)i/5;
33+
// specify rotation angle of object around y-axis in radians
34+
rotationAngle = (float) i / 5;
3335

3436
//do the magic
3537
myShader.rotationAngle = rotationAngle;
3638
myShader.updateMatrices();
3739
myRenderer.renderModel();
3840

39-
//write to the buffer after doing all processing.
40-
//avoid writing multiple times per frame as tearing happens.
41+
// write to the buffer after doing all processing.
42+
// avoid writing multiple times per frame as tearing happens.
4143
myRenderer.printBuffer();
4244
myWindow.update();
4345
i++;
4446

4547
long time = System.nanoTime() - start;
46-
System.out.println("processing time : " + (((double) time/1_000_000) + " ms/frame"));
48+
System.out.println("processing time : " + (((double) time / 1_000_000) + " ms/frame"));
4749
}
4850
}
51+
4952
public static final int pix_height = 300;
5053
public static final int pix_width = 300;
5154
}

model/Model.java

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package model;
2+
3+
import java.io.BufferedReader;
4+
import java.io.FileReader;
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class Model {
9+
private final ArrayList<float[]> vertexCoords;
10+
private final ArrayList<float[]> normalCoords;
11+
private final ArrayList<float[]> texCoords;
12+
private final List<Integer> vertexIndices;
13+
private final List<Integer> textureIndices;
14+
private final List<Integer> normalIndices;
15+
private final ArrayList<int[]> Vindices;
16+
private final ArrayList<int[]> Nindices;
17+
private final ArrayList<int[]> Tindices;
18+
private final String filePath;
19+
public float minCoord = Float.MAX_VALUE;
20+
public float maxCoord = -Float.MAX_VALUE;
21+
22+
public Model(String filePath) {
23+
this.filePath = filePath;
24+
normalIndices = new ArrayList<>();
25+
textureIndices = new ArrayList<>();
26+
vertexIndices = new ArrayList<>();
27+
texCoords = new ArrayList<>();
28+
normalCoords = new ArrayList<>();
29+
vertexCoords = new ArrayList<>();
30+
// load data AFTER instantiating the fields
31+
loadData();
32+
Vindices = new ArrayList<>();
33+
Nindices = new ArrayList<>();
34+
Tindices = new ArrayList<>();
35+
organizeIndices();
36+
}
37+
38+
public void printFaces() {
39+
for (int i = 0; i < Vindices.size(); i++) {
40+
for (int j = 0; j < 3; j++) {
41+
System.out.print(Vindices.get(i)[j]);
42+
if (!Tindices.isEmpty())
43+
System.out.print("/" + Tindices.get(i)[j]);
44+
if (!Nindices.isEmpty())
45+
System.out.print("/" + Nindices.get(i)[j]);
46+
System.out.print(" ");
47+
}
48+
System.out.println();
49+
}
50+
}
51+
52+
private void organizeIndices() { // inserting data into arrays of 3 rather than having everything in one array
53+
if (vertexIndices.size() % 3 == 0) {
54+
for (int i = 0; i < vertexIndices.size(); i++) {
55+
Vindices.add(new int[] { vertexIndices.get(i++), vertexIndices.get(i++), vertexIndices.get(i) });
56+
if (!normalIndices.isEmpty())
57+
Nindices.add(
58+
new int[] { normalIndices.get(i - 2), normalIndices.get(i - 1), normalIndices.get(i) });
59+
if (!textureIndices.isEmpty())
60+
Tindices.add(
61+
new int[] { textureIndices.get(i - 2), textureIndices.get(i - 1), textureIndices.get(i) });
62+
}
63+
} else {
64+
System.out.println("Critical error : faces not divisible by 3");
65+
}
66+
}
67+
68+
public boolean hasTextureCoords() {
69+
return !Tindices.isEmpty();
70+
}
71+
72+
public boolean hasNormalCoords() {
73+
return !Nindices.isEmpty();
74+
}
75+
76+
public float[] getVertexCoords(int idx) {
77+
return vertexCoords.get(idx);
78+
}
79+
80+
public float[] getTexCoords(int idx) {
81+
return texCoords.get(idx);
82+
}
83+
84+
public float[] getNormalCoords(int idx) {
85+
return normalCoords.get(idx);
86+
}
87+
88+
public int[] getVertexIndices(int idx) {
89+
return Vindices.get(idx);
90+
}
91+
92+
public int[] getNormalIndices(int idx) {
93+
return Nindices.get(idx);
94+
}
95+
96+
public int[] getTextureIndices(int idx) {
97+
return Tindices.get(idx);
98+
}
99+
100+
public int nVerts() {
101+
return vertexCoords.size();
102+
}
103+
104+
public int nNormals() {
105+
return normalCoords.size();
106+
}
107+
108+
public int nTextures() {
109+
return texCoords.size();
110+
}
111+
112+
public int nFaces() {
113+
return Vindices.size();
114+
}
115+
116+
private void loadData() {
117+
try {
118+
FileReader f = new FileReader(filePath);
119+
BufferedReader reader = new BufferedReader(f);
120+
String Line;
121+
String[] P;
122+
while ((Line = reader.readLine()) != null) {
123+
P = Line.split("\\s+");
124+
125+
if (P.length == 0) {
126+
continue;
127+
}
128+
129+
if (P[0].equals("v")) {
130+
float x = Float.parseFloat(P[1]);
131+
float y = Float.parseFloat(P[2]);
132+
float z = Float.parseFloat(P[3]);
133+
float minCandidate = Math.min(x, Math.min(y, z));
134+
minCoord = Math.min(minCoord, minCandidate);
135+
float maxCandidate = Math.max(x, Math.max(y, z));
136+
maxCoord = Math.max(maxCoord, maxCandidate);
137+
vertexCoords.add(new float[] { x, y, z });
138+
}
139+
if (P[0].equals("vn")) {
140+
float x = Float.parseFloat(P[1]);
141+
float y = Float.parseFloat(P[2]);
142+
float z = Float.parseFloat(P[3]);
143+
float[] Vs = { x, y, z };
144+
normalCoords.add(Vs);
145+
}
146+
if (P[0].equals("vt")) {
147+
float x = Float.parseFloat(P[1]);
148+
float y = Float.parseFloat(P[2]);
149+
float z = Float.parseFloat(P[3]);
150+
float[] Vs = { x, y, z };
151+
texCoords.add(Vs);
152+
}
153+
String[] parts;
154+
155+
if (P[0].equals("f")) {
156+
// TODO bug fixing : as far as I'm aware this condition is unnecessary,
157+
// and can miss faces in some formats. Check with team.
158+
if (true) // previous condition : P[1].contains("/")
159+
{
160+
for (int i = 1; i < P.length; i++) {
161+
int coordCounter = 0;
162+
parts = P[i].split("/"); // '1 1 1'
163+
// -1 because indices in .obj format start from 1
164+
vertexIndices.add(Integer.parseInt(parts[coordCounter++]) - 1);
165+
if (!texCoords.isEmpty())
166+
textureIndices.add(Integer.parseInt(parts[coordCounter++]) - 1);
167+
if (!normalCoords.isEmpty())
168+
normalIndices.add(Integer.parseInt(parts[coordCounter++]) - 1);
169+
}
170+
}
171+
}
172+
173+
}
174+
reader.close();
175+
} catch (Exception e) {
176+
System.out.println(e);
177+
}
178+
179+
}
180+
}

model/math/Vec3f.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ public Vec3f (Matrix m)
3535
raw[2]=raw[2].floatValue();
3636
}
3737
@Override
38-
public Vec3f getNormalized() {
38+
public Vec3f getNormalized()
39+
{
3940
return new Vec3f(getNormalizedCoords()[0], getNormalizedCoords()[1], getNormalizedCoords()[2]);
4041
}
4142
@Override

model/pipeline/fixed/Rasterizer.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ public Rasterizer(int viewportWidth, int viewportHeight)
1919
initDepthBuffer();
2020
initPixelBuffer();
2121
}
22-
2322
public Shader activeShader;
2423
private int viewportWidth, viewportHeight;
2524
private int[] pixelBuffer;
@@ -34,7 +33,8 @@ public void clearPixelBuffer(Color clearColor)
3433
Arrays.fill(pixelBuffer, clearColor.getRGB());
3534
}
3635

37-
private void initDepthBuffer() {
36+
private void initDepthBuffer()
37+
{
3838
depthBuffer = new float[viewportWidth*viewportHeight];
3939
clearDepthBuffer();
4040
}

model/pipeline/fixed/Shader.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package model.pipeline.fixed;
22

33
import model.math.Vec3f;
4-
54
import java.awt.*;
65

76
public abstract class Shader
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package model.pipeline.fixed;
2+
3+
import model.math.Matrix;
4+
import model.math.Vec3f;
5+
6+
import java.util.ArrayList;
7+
import java.util.Stack;
8+
9+
import static model.math.VecOperator.mul;
10+
11+
public class Transform { // this class is responsible for combining multiple transformations into a
12+
// single transform
13+
public Transform() {
14+
}
15+
16+
public void clear() {
17+
matrices.clear();
18+
}
19+
20+
private ArrayList<Matrix> matrices = new ArrayList<>();
21+
22+
public void addTransform(Matrix transformMatrix) {
23+
matrices.add(transformMatrix);
24+
}
25+
26+
public Vec3f transform(Vec3f rawVertex) {
27+
Matrix transformMatrix = new Matrix(rawVertex, true);
28+
for (int i = 0; i < matrices.size(); i++) {
29+
transformMatrix = mul(matrices.get(i), transformMatrix);
30+
}
31+
return new Vec3f(transformMatrix);
32+
}
33+
34+
public Vec3f transformNormals(Vec3f normals) {
35+
Matrix transformMatrix = new Matrix(normals, true);
36+
for (int i = 0; i < matrices.size(); i++) {
37+
transformMatrix = mul(matrices.get(i).inverse().transpose(), transformMatrix);
38+
}
39+
return new Vec3f(transformMatrix);
40+
}
41+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package model.pipeline.programmable;
2+
3+
import model.math.Vec3f;
4+
5+
import java.awt.*;
6+
7+
public class Light {
8+
public Vec3f direction;
9+
public Color lightColor;
10+
11+
public Light() {
12+
direction = new Vec3f(0, 0, 0);
13+
lightColor = new Color(0, 0, 0);
14+
}
15+
16+
public Light(Vec3f direction, Color color) {
17+
this.direction = direction;
18+
lightColor = color;
19+
}
20+
}

0 commit comments

Comments
 (0)