Skip to content

Commit c3ec378

Browse files
committed
Improve UI
Improves UI, adds some interfaces, and updates some old code
1 parent 8470d3f commit c3ec378

5 files changed

Lines changed: 147 additions & 77 deletions

File tree

Main.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,34 @@ public static void main(String[]args) throws IOException
2020

2121
Window myWindow = new Window("Java Rasterizer", myRenderer);
2222

23-
//configure light settings
23+
// default global light settings
2424
Light wlight = new Light();
2525
wlight.lightColor = new Color(255,255,0);
2626
wlight.position = new Vec3f(1.0f, 1.45f, 0.f);
2727
LightShader.addLight(wlight);
2828

2929
// TODO structure : make breaking of while loop dependent on user input
3030
// render loop
31-
int i = 0;
3231
while (true) {
3332
long start = System.nanoTime();
3433
// clear buffers at the beginning of the frame
35-
myRenderer.myRasterizer.clearDepthBuffer();
36-
myRenderer.myRasterizer.clearPixelBuffer(new Color(50, 50, 50));
34+
myRenderer.clearDepthBuffer();
35+
myRenderer.clearColorBuffer(new Color(50, 50, 50));
3736

38-
// specify rotation angle of object around y-axis in radians
37+
// upate global geometric variables
3938
updateMatrices();
4039

4140
//do the magic
4241
myRenderer.renderModel();
4342

4443
// write to the buffer after doing all processing.
4544
// avoid writing multiple times per frame as tearing happens.
46-
myRenderer.printBufferOutput();
45+
myRenderer.writePixelBuffer();
4746
myWindow.update();
48-
i++;
49-
long time = System.nanoTime() - start;
47+
long time = System.nanoTime() - start;
5048
// System.out.println("processing time : " + (((double) time / 1_000_000) + "ms/frame"));
5149
}
5250
}
53-
public static final int pix_height = 300;
54-
public static final int pix_width = 300;
51+
public static final int pix_height = 350;
52+
public static final int pix_width = 350;
5553
}

controller/renderer/Renderer.java

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,49 @@
11
package controller.renderer;
22

3+
import java.awt.Color;
34
import java.awt.image.BufferedImage;
45

56
import model.object3D.Object3D;
67
import model.math.*;
78
import model.pipeline.fixed.Rasterizer;
89
import model.pipeline.fixed.Shader;
10+
//TODO structure : accommodate loading of multiple models
11+
//TODO error handling : null handling
912

1013
public class Renderer {
1114
BufferedImage pixelBuffer;
15+
// model data. stored such that index 0 corresponds to the 3 coordinates specified by the first face.
1216
Object3D modelObject;
13-
//model data. stored such that index 0 corresponds to the 3 3D coordinates specified by face 0.
14-
//TODO structure : accommodate loading of multiple models
15-
//TODO error handling : null handling
16-
//TODO structure : implement a way to handle objects that have no texture coords, or false texture coords. Also implement a texture loading function
17-
Vec3f[][] vertexCoords;
18-
Vec3f[][] textureCoords;
19-
Vec3f[][] normalCoords;
17+
private Vec3f[][] vertexCoords;
18+
private Vec3f[][] textureCoords;
19+
private Vec3f[][] normalCoords;
20+
// render data
2021
public int width, height;
21-
public int[] colorBuffer; //pixel buffer
2222
public boolean buttonFlag = false;
23-
public boolean modelLoaded = false;
24-
public Rasterizer myRasterizer;
25-
public Shader myShader;
23+
private boolean modelLoaded = false;
24+
private Rasterizer myRasterizer;
25+
private Shader myShader;
2626

27-
//TODO structure : probably better to use an entire array of lights. Improve the general structure.
2827
public Renderer(int screenWidth, int screenHeight)
2928
{
3029
width=screenWidth;
3130
height=screenHeight;
3231
pixelBuffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
3332
myRasterizer= new Rasterizer(width, height);
3433
}
34+
public void setShader(Shader yourShader)
35+
{
36+
myShader=yourShader;
37+
myRasterizer.setActiveShader(myShader);
38+
}
39+
public void clearDepthBuffer()
40+
{
41+
myRasterizer.clearDepthBuffer();
42+
}
43+
public void clearColorBuffer(Color clearColor)
44+
{
45+
myRasterizer.clearPixelBuffer(clearColor);
46+
}
3547
public void loadModelData(Object3D modelObject)
3648
{
3749
System.out.println("FUNCTION CALL : model.renderer.loadModelData ");
@@ -62,35 +74,31 @@ public void loadModelData(Object3D modelObject)
6274
}
6375
modelLoaded=true;
6476
}
65-
public void setShader(Shader yourShader)
66-
{
67-
myShader=yourShader;
68-
myRasterizer.setActiveShader(myShader);
69-
}
7077
public void renderModel()
7178
{
72-
//calls drawTriangle function on loaded model data
7379
//TODO error handling : this function assumes nFaces() always matches coords size
7480
if (buttonFlag || !modelLoaded)
7581
return;
7682
System.out.println("FUNCTION CALL : model.renderer.rendererModel");
7783
for (int i = 0; i<modelObject.nFaces(); i++)
7884
{
7985
//future tip, don't change the coordinates values, only copy them, especially if you're updating every frame :)
80-
//deliver data
81-
//TODO structure : implement this as an optional?
86+
//TODO structure : implement these as optionals ?
8287
if (vertexCoords[i][0]==null||vertexCoords[i][1]==null||vertexCoords[i][2]==null)
8388
{
8489
return;
8590
}
8691
//deliver data.
87-
myRasterizer.rasterize(new Vec3f[]{vertexCoords[i][0], vertexCoords[i][1], vertexCoords[i][2],
92+
myRasterizer.rasterize(
93+
new Vec3f[]{
94+
vertexCoords[i][0], vertexCoords[i][1], vertexCoords[i][2],
8895
normalCoords[i][0], normalCoords[i][1], normalCoords[i][2],
89-
textureCoords[i][0], textureCoords[i][1], textureCoords[i][2]});
96+
textureCoords[i][0], textureCoords[i][1], textureCoords[i][2]}
97+
);
9098
}
9199
}
92-
public void printBufferOutput()
93-
{
100+
public void writePixelBuffer()
101+
{ //writes content of the virtual buffer inside the rasterizer to the buffered image.
94102
pixelBuffer.setRGB(0,0, width, height, myRasterizer.getPixelBuffer(),0, width);
95103
}
96104
public BufferedImage getPixelBuffer(){return pixelBuffer;}

model/pipeline/programmable/PhongShader.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public void vertex(Vec3f[] objectData)
3232
texCoords[i] = objectData[i+6];
3333
}
3434
}
35+
3536
Texture diffuseMap = new Texture("assets/african_head_diffuse.png");
3637
Texture normalMap = new Texture("assets/african_head_nm.png");
3738
Texture specMap = new Texture("assets/african_head_spec.png");
@@ -73,8 +74,6 @@ public Color fragment(Vec3f fragment, Vec3f bar)
7374

7475
return LightShader.shade(normal, interpolatedPosition, fragmentSpecColor.getRed(), fragmentTextureColor);
7576
}
76-
77-
7877
private Color fragmentNoTex (Vec3f fragment, Vec3f bar, Vec3f interpolatedPosition)
7978
{
8079
//We have normal coordinates?

model/pipeline/programmable/shaderUtilities/lighting/LightShader.java

Lines changed: 77 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,42 +15,66 @@ public class LightShader {
1515
{
1616
ambient.direction = null;
1717
}
18-
1918
public static void addLight(Light yourLight)
2019
{
2120
diffuseLights.add(yourLight);
2221
}
2322
private static boolean currentlyRendering = false;
24-
public static void clearLights()
23+
24+
private static boolean hideDiffuse = false;
25+
private static boolean hideAmbient = false;
26+
private static boolean hideSpecular = false;
27+
private static boolean hideTexture = false;
28+
private static boolean shadeChunky = false;
29+
public static boolean specRdotZ = true;
30+
private static int numberOfChunks = 3;
31+
32+
//public interface for settings
33+
34+
public static void setDefaults()
2535
{
26-
if (!currentlyRendering)
27-
diffuseLights.clear();
36+
hideDiffuse = false;
37+
hideAmbient = false;
38+
hideSpecular = false;
39+
hideTexture = false;
40+
shadeChunky = false;
41+
specRdotZ = true;
2842
}
29-
public static Color shadeChunky(Vec3f surfaceNormal, int numberOfChunks)
43+
public static void toggleChunky()
3044
{
31-
currentlyRendering = true;
32-
33-
Color result = Color.black;
34-
for (int i = 0; i < diffuseLights.size(); i++)
35-
{
36-
float intensity = Math.max(dot(surfaceNormal.getNormalized(), diffuseLights.get(i).direction.getNormalized().neg()), 0.0f);
37-
intensity = map(0,1,0,numberOfChunks,intensity).floatValue();
38-
for (int j = 0; j < numberOfChunks; j++)
39-
{
40-
if(Math.abs(j-intensity)<0.5)
41-
intensity= j;
42-
}
43-
intensity = map(0,numberOfChunks, 0,1, intensity).floatValue();
44-
result = sumColor(result, scaleColor(diffuseLights.get(i).lightColor, intensity));
45-
}
46-
currentlyRendering = false;
47-
return sumColor(result, ambient.lightColor);
45+
shadeChunky = !shadeChunky;
46+
if (shadeChunky == true)
47+
hideTexture = true;
48+
}
49+
public static void toggleDiffuse()
50+
{
51+
hideDiffuse = !hideDiffuse;
52+
}
53+
public static void toggleSpec()
54+
{
55+
hideSpecular = !hideSpecular;
56+
}
57+
public static void toggleAmbient()
58+
{
59+
hideAmbient = !hideAmbient;
60+
}
61+
public static void toggleTex()
62+
{
63+
hideTexture = !hideTexture;
64+
}
65+
public static void toggleSpecMode()
66+
{
67+
specRdotZ = !specRdotZ;
4868
}
4969

70+
public static void clearLights()
71+
{
72+
if (!currentlyRendering)
73+
diffuseLights.clear();
74+
}
5075
public static Color shade(Vec3f normal, Vec3f interpolatedPosition, float fragSpecStregnth, Color fragDiffuseColor)
5176
{
5277
currentlyRendering = true;
53-
5478
surfaceNormal = normal;
5579
Color result = Color.black;
5680
for (int i = 0; i < diffuseLights.size(); i++)
@@ -59,23 +83,45 @@ public static Color shade(Vec3f normal, Vec3f interpolatedPosition, float fragSp
5983
{
6084
diffuseLights.get(i).direction = minus(interpolatedPosition, diffuseLights.get(i).position);
6185
}
62-
result = sumColor(result, shadeDiffuseLight(diffuseLights.get(i)));
63-
result = mulColor(result, 0.75f); //scale down diffuse
64-
result = sumColor(result, mulColor(diffuseLights.get(i).lightColor,
65-
shadeSpecLight(diffuseLights.get(i), fragSpecStregnth, interpolatedPosition)));
86+
if (shadeChunky)
87+
{ //TODO : this is repeating code
88+
89+
float intensity = Math.max(dot(surfaceNormal.getNormalized(), diffuseLights.get(i).direction.getNormalized().neg()), 0.0f);
90+
float specIntensity = shadeSpecLight(diffuseLights.get(i), fragSpecStregnth, interpolatedPosition);
91+
intensity = map(0,1,0,numberOfChunks,intensity).floatValue();
92+
specIntensity = map(0,1, 0, numberOfChunks, specIntensity).floatValue();
93+
for (int j = 0; j < numberOfChunks; j++)
94+
{
95+
if(Math.abs(j - intensity)<0.5)
96+
intensity = j;
97+
if(Math.abs(j - specIntensity)<0.5)
98+
specIntensity = j;
99+
}
100+
intensity = map(0, numberOfChunks, 0, 1, intensity).floatValue();
101+
specIntensity = map(0, numberOfChunks, 0, 1, specIntensity).floatValue();
102+
result = hideDiffuse ? result : sumColor(result, scaleColor(diffuseLights.get(i).lightColor, intensity));
103+
result = hideSpecular ? result : sumColor(result, mulColor(diffuseLights.get(i).lightColor, specIntensity));
104+
}
105+
else
106+
{
107+
result = hideDiffuse ? result : sumColor(result, shadeDiffuseLight(diffuseLights.get(i)));
108+
result = hideDiffuse ? result : mulColor(result, 0.75f); //scale down diffuse
109+
result = hideSpecular ? result : sumColor(result, mulColor(diffuseLights.get(i).lightColor,
110+
shadeSpecLight(diffuseLights.get(i), fragSpecStregnth, interpolatedPosition)));
111+
}
66112
}
67-
//multiply texture once and only once. Order matters ?
68-
result = mulColor(fragDiffuseColor, result);
113+
//multiply texture once and only once. Order probably matters here.
114+
result = hideTexture ? result : mulColor(fragDiffuseColor, result);
69115
currentlyRendering = false;
70-
return sumColor(result, ambient.lightColor);
116+
return hideAmbient ? result : sumColor(result, ambient.lightColor);
71117
}
72118
private static float shadeSpecLight (Light specular, float specStrength, Vec3f interpolatedPos)
73119
{
74120
Vec3f n = surfaceNormal.getNormalized();
75121
Vec3f l = specular.direction.getNormalized();
76122
Vec3f r = minus(l, n.scale(2.f*dot(l, n))).getNormalized();
77123
Vec3f v = minus(CommonTransformations.camPos, interpolatedPos).getNormalized();
78-
float spec = max (r.z(), 0.f);
124+
float spec = max (specRdotZ ? r.z() : dot(r, v), 0.f);
79125
spec = (float)pow(spec, specStrength);
80126
return spec;
81127
}

view/buttone.java

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@ public class buttone extends JPanel implements ActionListener {
3232
cameraIncYLabel,
3333
cameraZlabel, rotationLabel;
3434
JComboBox menulist;
35-
String[] menuItems = { "Flat Shader", "Phong + Normal Mapping" };
35+
String[] menuItems = { "Default", "Toggle Chunky", "Toggle Texture", "Toggle Diffuse", "Toggle Specular",
36+
"Toggle Ambient", "Toggle Spec Mode"};
3637
Object[] optionButton = { "Point Light", "Directional Light" };
3738
Object[] optionNextButton = { "Next", "Cancel" };
3839
static float posX, posY, posZ;
@@ -168,15 +169,33 @@ public void actionPerformed(ActionEvent e) {
168169
clearLight();
169170
}
170171
if (src == menulist) {
171-
if (menulist.getSelectedIndex() == 0)
172-
renderer.setShader(new FlatShader());
173-
if (menulist.getSelectedIndex() == 1) {
174-
try {
175-
renderer.setShader(new PhongShader());
176-
} catch (IOException ex) {
177-
throw new RuntimeException(ex);
178-
}
179-
}
172+
// { "Default", "Toggle Chunky", "Toggle Texture",
173+
// "Toggle Diffuse", "Toggle Specular",
174+
// "Toggle Ambient", "Toggle Spec Mode"}
175+
switch (menulist.getSelectedIndex()) {
176+
case 0:
177+
LightShader.setDefaults();
178+
break;
179+
case 1:
180+
LightShader.toggleChunky();
181+
break;
182+
case 2:
183+
LightShader.toggleTex();
184+
break;
185+
case 3:
186+
LightShader.toggleDiffuse();
187+
break;
188+
case 4:
189+
LightShader.toggleSpec();
190+
break;
191+
case 5:
192+
LightShader.toggleAmbient();
193+
break;
194+
case 6:
195+
LightShader.toggleSpecMode();
196+
default:
197+
break;
198+
}
180199
}
181200
if (src == OKbutton)
182201
updateInput();

0 commit comments

Comments
 (0)