Skip to content

Commit

Permalink
Added Shaders !!!
Browse files Browse the repository at this point in the history
-Added PixelShader class! (is called to shade when a pixel in the Camera
is set)
-Added Shader class! (is called to shade the vertexes and polygons by
the SceneRenderer)
  • Loading branch information
John committed Sep 5, 2018
1 parent 7ccd8de commit a85dc46
Show file tree
Hide file tree
Showing 15 changed files with 255 additions and 94 deletions.
4 changes: 3 additions & 1 deletion ProjectHistory
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ v0.1 - 24/08/2018
-Now the SceneRenderer does the transformations and the SceneRasterizer draws the Scene
-Performance improved with this new graphics pipeline!!!
-Updated SceneRenderer comments and added comments to the SceneRasterizer class

05/09/2018
-Added PixelShader class! (is called to shade when a pixel in the Camera is set)
-Added Shader class! (is called to shade the vertexes and polygons by the SceneRenderer)



Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/johnsproject/jpge/GameManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public static GameManager getInstance() {
return instance;
}

private int targetFPS = 60;
private int targetFPS = 50;
private int renderUpdateRate = 60;
private int inputUpdateRate = 30;
private int physicsUpdateRate = 30;
Expand Down
33 changes: 27 additions & 6 deletions src/main/java/com/johnsproject/jpge/graphics/Camera.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ public class Camera extends Canvas{
private boolean changed = false;
private ProjectionType projectionType = ProjectionType.perspective;
private RenderingType renderingType = RenderingType.textured;
private PixelShader shader;

/**
* Creates a new instance of the Camera class filled with the given values.
Expand All @@ -48,16 +49,17 @@ public Camera(String name, Transform transform, int screenPosition, int screenSi
this.screenSize = screenSize;
int px = Vector2Utils.getX(screenPosition), py = Vector2Utils.getY(screenPosition);
int sx = Vector2Utils.getX(screenSize), sy = Vector2Utils.getY(screenSize);
halfscreenSize = Vector2Utils.setX(halfscreenSize, sx/2);
halfscreenSize = Vector2Utils.setY(halfscreenSize, sy/2);
this.halfscreenSize = Vector2Utils.setX(halfscreenSize, sx/2);
this.halfscreenSize = Vector2Utils.setY(halfscreenSize, sy/2);
this.scaleFactor = Math.abs((sx+sy)>>7)+1;
this.setSize(sx, sy);
this.screenPosition = screenPosition;
this.setLocation(px, py);
viewBuffer = new BufferedImage(sx, sy, BufferedImage.TYPE_INT_ARGB_PRE);
viewBuffer.setAccelerationPriority(1);
viewBufferData = ((DataBufferInt)viewBuffer.getRaster().getDataBuffer()).getData();
this.viewBuffer = new BufferedImage(sx, sy, BufferedImage.TYPE_INT_ARGB_PRE);
this.viewBuffer.setAccelerationPriority(1);
this.viewBufferData = ((DataBufferInt)viewBuffer.getRaster().getDataBuffer()).getData();
this.changed = true;
this.shader = new PixelShader();
}

/**
Expand All @@ -82,7 +84,8 @@ public void drawBuffer() {
*/
public void setPixel(int x, int y, int color){
//if((x > 0 && y > 0) && (x < rect[0] && y < rect[1])) {
viewBufferData[x + (y * Vector2Utils.getX(screenSize))] = color;
//viewBufferData[x + (y * Vector2Utils.getX(screenSize))] = color;
shader.shadePixel(x, y, color, Vector2Utils.getX(screenSize), viewBufferData);
//}
}

Expand Down Expand Up @@ -279,6 +282,24 @@ boolean changed() {
void changed(boolean changed) {
this.changed = changed;
}

/**
* Returns the {@link PixelShader} used by this camera.
*
* @return {@link PixelShader} used by this camera.
*/
public PixelShader getShader() {
return shader;
}

/**
* Sets the {@link PixelShader} of this camera.
*
* @param shader {@link PixelShader} to set.
*/
public void setShader(PixelShader shader) {
this.shader = shader;
}

@Override
public String toString() {
Expand Down
54 changes: 54 additions & 0 deletions src/main/java/com/johnsproject/jpge/graphics/PixelShader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.johnsproject.jpge.graphics;

import com.johnsproject.jpge.utils.Vector2Utils;

/**
* The PixelShader class is used to used shade the pixels that are set to the {@link Camera}.
*
* @author John´s Project - John Konrad Ferraz Salomon
*/
public class PixelShader {

/**
* This method is called by the {@link Camera} when a pixel is set.
*
* @param x position of pixel in the x axis.
* @param y position of pixel in the y axis.
* @param color color of pixel.
* @param cameraWidth the width of the camera at the screen, used when to calculate pixel position in the viewBuffer.
* @param viewBuffer buffer containing pixels of the {@link Camera}.
*/
public void shadePixel (int x, int y, int color, int cameraWidth, int[] viewBuffer) {
setPixel(x, y, color, cameraWidth, viewBuffer);
}

/**
* Sets the color of the pixel at the given position in the viewBuffer equals to the given color.
*
* @param x position of pixel in the x axis.
* @param y position of pixel in the y axis.
* @param color color of pixel.
* @param cameraWidth the width of the camera at the screen, used when to calculate pixel position in the viewBuffer.
* @param viewBuffer buffer containing pixels of the {@link Camera}.
*/
public void setPixel(int x, int y, int color, int cameraWidth, int[] viewBuffer) {
int pos = x + (y * Vector2Utils.getX(cameraWidth));
if (pos >= 0 && pos < viewBuffer.length) viewBuffer[pos] = color;
}

/**
* Returns the color of the pixel at the given position in the viewBuffer.
*
* @param x position of pixel in the x axis.
* @param y position of pixel in the y axis.
* @param cameraWidth the width of the camera at the screen, used when to calculate pixel position in the viewBuffer.
* @param viewBuffer buffer containing pixels of the {@link Camera}.
* @return color of a pixel of the viewBuffer at the given position.
*/
public int getPixel(int x, int y, int cameraWidth, int[] viewBuffer) {
int pos = x + (y * Vector2Utils.getX(cameraWidth));
if (pos >= 0 && pos < viewBuffer.length) return viewBuffer[pos];
return 0;
}

}
2 changes: 2 additions & 0 deletions src/main/java/com/johnsproject/jpge/graphics/SceneFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* its like a window or portal that shows another world.
* It contains a {@link SceneRenderer} that is called to render the {@link Scene} when
* it receives an {@link UpdateEvent} from the {@link GameManager}.
* It contains a {@link SceneRasterizer} that is called to rasterize the {@link Scene} when
* it receives an {@link UpdateEvent} from the {@link GameManager}.
* It contains a {@link SceneAnimator} that is called to animate the {@link Scene} when
* it receives an {@link UpdateEvent} from the {@link GameManager}.
*
Expand Down
22 changes: 21 additions & 1 deletion src/main/java/com/johnsproject/jpge/graphics/SceneObject.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ public class SceneObject {
private String name;
private Transform transform;
private Mesh mesh;
private Shader shader;
private boolean changed = false;

/**
Expand All @@ -23,7 +24,8 @@ public SceneObject(String name, Transform transform, Mesh mesh){
this.name = name;
this.transform = transform;
this.mesh = mesh;
changed = true;
this.changed = true;
this.shader = new Shader();
}

/**
Expand Down Expand Up @@ -84,6 +86,24 @@ void changed(boolean changed) {
this.changed = changed;
}

/**
* Returns the {@link Shader} used by this scene object.
*
* @return {@link Shader} used by this scene object.
*/
public Shader getShader() {
return shader;
}

/**
* Sets the {@link Shader} used by this scene object equals to the given {@link Shader}.
*
* @param shader {@link Shader} to set.
*/
public void setShader(Shader shader) {
this.shader = shader;
}

@Override
public String toString() {
return "SceneObject [name=" + name + ", transform=" + transform.toString() + ", mesh=" + mesh.toString() + "]";
Expand Down
42 changes: 13 additions & 29 deletions src/main/java/com/johnsproject/jpge/graphics/SceneRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@

import java.util.List;
import com.johnsproject.jpge.utils.Vector2Utils;
import com.johnsproject.jpge.utils.VectorMathUtils;
import com.johnsproject.jpge.utils.Vector3Utils;
import com.johnsproject.jpge.utils.VertexUtils;

/**
* The SceneRenderer class renders the {@link Scene} assigned to the {@link SceneFrame}.
Expand Down Expand Up @@ -39,53 +37,39 @@ public void render(Scene scene) {
void render(SceneObject sceneObject, Camera camera, List<Light> lights) {
Mesh mesh = sceneObject.getMesh();
// Animation animation = mesh.getCurrentAnimation();
Transform objt = sceneObject.getTransform();
Shader shader = sceneObject.getShader();
mesh.resetBuffer();
for (int i = 0; i < mesh.getVertexes().length; i++) {
long vertex = mesh.getVertex(i);
long vector = VertexUtils.getVector(vertex);
vector = VectorMathUtils.movePointByScale(vector, objt.getScale());
// for (int j = 0; j <= VertexUtils.getBoneIndex(vertex); j++) {
// Transform bone = animation.getBone(j, animation.getCurrentFrame());
// vector = VectorMathUtils.movePointByScale(vector, bone.getScale());
// vector = VectorMathUtils.movePointByAnglesXYZ(vector, bone.getRotation());
// //vector = VectorMathUtils.add(vector, bone.getPosition());
// }
vector = VectorMathUtils.movePointByAnglesXYZ(vector, objt.getRotation());
vector = projectVertex(vector, objt.getPosition(), camera);
vertex = VertexUtils.setVector(vertex, vector);
vertex = shader.shadeVertex(vertex, sceneObject.getTransform(), camera, lights);
mesh.setBufferedVertex(i, vertex);
}
for (int[] polygon : mesh.getPolygons()) {
polygon[Mesh.CULLED] = 1;
if (!cullViewFrustum(polygon, mesh, camera)) {
if (!cullBackface(polygon, mesh)) {
polygon[Mesh.CULLED] = 0;
}
}
polygon = shader.shadePolygon(polygon, mesh, camera);
}
}

long projectVertex(long vertex, long objectPosition, Camera camera) {
public static long projectVertex(long vector, long objectPosition, Camera camera) {
long px = 0, py = 0, pz = 0;
int fov = camera.getFieldOfView(), rescalef = camera.getScaleFactor();
long camRot = camera.getTransform().getRotation(),
camPos = camera.getTransform().getPosition();
long pos = VectorMathUtils.add(vertex, objectPosition);
pos = VectorMathUtils.subtract(pos, camPos);
pos = VectorMathUtils.movePointByAnglesXYZ(pos, camRot);
switch (camera.getProjectionType()) {
case perspective: // this projectionType uses depth
long z = (Vector3Utils.getZ(pos) + fov);
long z = (Vector3Utils.getZ(vector) + fov);
if (z <= 0) z = 1;
px = ((Vector3Utils.getX(pos)) * rescalef * fov) / z;
py = ((Vector3Utils.getY(pos)) * rescalef * fov) / z;
pz = z + (Vector3Utils.getZ(pos)<<1);
px = ((Vector3Utils.getX(vector)) * rescalef * fov) / z;
py = ((Vector3Utils.getY(vector)) * rescalef * fov) / z;
pz = z + (Vector3Utils.getZ(vector)<<1);
break;
case orthographic: // this projectionType ignores depth
px = (Vector3Utils.getX(pos) * rescalef)>>5;
py = (Vector3Utils.getY(pos) * rescalef)>>5;
pz = Vector3Utils.getZ(pos) + Vector3Utils.getZ(objectPosition);
px = (Vector3Utils.getX(vector) * rescalef)>>5;
py = (Vector3Utils.getY(vector) * rescalef)>>5;
pz = Vector3Utils.getZ(vector) + Vector3Utils.getZ(objectPosition);
break;
}
long x = (px) + Vector2Utils.getX(camera.getHalfScreenSize()) + Vector3Utils.getX(objectPosition);
Expand All @@ -94,7 +78,7 @@ long projectVertex(long vertex, long objectPosition, Camera camera) {
return Vector3Utils.convert(x, y, z);
}

boolean cullViewFrustum(int[] polygon, Mesh mesh, Camera camera) {
public static boolean cullViewFrustum(int[] polygon, Mesh mesh, Camera camera) {
long v1 = mesh.getBufferedVertex(polygon[Mesh.VERTEX_1]);
int ncp = camera.getNearClippingPlane();
int fcp = camera.getFarClippingPlane();
Expand All @@ -106,7 +90,7 @@ boolean cullViewFrustum(int[] polygon, Mesh mesh, Camera camera) {
}

//backface culling with sholeance algorithm
boolean cullBackface(int[] polygon, Mesh mesh) {
public static boolean cullBackface(int[] polygon, Mesh mesh) {
long v1 = mesh.getBufferedVertex(polygon[Mesh.VERTEX_1]),
v2 = mesh.getBufferedVertex(polygon[Mesh.VERTEX_2]),
v3 = mesh.getBufferedVertex(polygon[Mesh.VERTEX_3]);
Expand Down
59 changes: 59 additions & 0 deletions src/main/java/com/johnsproject/jpge/graphics/Shader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.johnsproject.jpge.graphics;

import java.util.List;

import com.johnsproject.jpge.utils.VectorMathUtils;
import com.johnsproject.jpge.utils.VertexUtils;

/**
* The Shader class is used to used shade the vertexes and the polygons that are being rendered by the {@link SceneRenderer}.
*
* @author John´s Project - John Konrad Ferraz Salomon
*/
public class Shader {

/**
* This method by the {@link SceneRenderer} at the rendering process.
*
* @param vertex vertex to shade.
* @param sceneObjectTransform {@link Transform} of the {@link SceneObject} this vertex belongs to.
* @param camera {@link Camera} being rendered to.
* @param lights All {@link Light Lights} of the {@link Scene} being rendered.
* @return shaded vertex.
*/
public long shadeVertex(long vertex, Transform sceneObjectTransform, Camera camera, List<Light> lights) {
Transform objt = sceneObjectTransform;
Transform camt = camera.getTransform();
long vector = VertexUtils.getVector(vertex);
//transforming vertex in object space
vector = VectorMathUtils.movePointByScale(vector, objt.getScale());
vector = VectorMathUtils.movePointByAnglesXYZ(vector, objt.getRotation());
vector = VectorMathUtils.add(vector, objt.getPosition());
//transforming vertex in camera space
vector = VectorMathUtils.subtract(vector, camt.getPosition());
vector = VectorMathUtils.movePointByAnglesXYZ(vector, camt.getRotation());
//projecting vector to screen coordinates
vector = SceneRenderer.projectVertex(vector, objt.getPosition(), camera);
vertex = VertexUtils.setVector(vertex, vector);
return vertex;
}

/**
* This method by the {@link SceneRenderer} at the rendering process.
*
* @param polygon polygon to shade.
* @param mesh {@link Mesh} this polygon belongs to.
* @param camera {@link Camera} being rendered to.
* @return shaded polygon.
*/
public int[] shadePolygon(int[] polygon, Mesh mesh, Camera camera) {
polygon[Mesh.CULLED] = 1;
if (!SceneRenderer.cullViewFrustum(polygon, mesh, camera)) {
if (!SceneRenderer.cullBackface(polygon, mesh)) {
polygon[Mesh.CULLED] = 0;
}
}
return polygon;
}

}
6 changes: 4 additions & 2 deletions src/main/java/com/johnsproject/jpge/graphics/Transform.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ public void translate(int x, int y, int z) {
* @param z how much to move in the z axis.
*/
public void translateLocal(int x, int y, int z) {
//long dist = Vector3Utils.convert(x, y, z);
position = VectorMathUtils.add(position, Vector3Utils.convert(x, y, z));
long vector = Vector3Utils.convert(x, y, z);
long rot = Vector3Utils.convert(-Vector3Utils.getX(rotation), -Vector3Utils.getY(rotation), -Vector3Utils.getZ(rotation));
vector = VectorMathUtils.movePointByAnglesXYZ(vector, rot);
position = VectorMathUtils.add(position, vector);
}

/**
Expand Down
Loading

0 comments on commit a85dc46

Please sign in to comment.