277 lines
9.1 KiB
Java
277 lines
9.1 KiB
Java
package engine.object;
|
|
|
|
import engine.graphics.*;
|
|
import engine.math.*;
|
|
|
|
import static org.lwjgl.glfw.GLFW.glfwGetTime;
|
|
|
|
/**
|
|
*
|
|
*/
|
|
public class ObjectGl {
|
|
|
|
/**
|
|
* STATE CONST DECLARATION
|
|
*/
|
|
public static final int DEFAULT = 0, STICK_BOTTOM = 1, STICK_TOP = 2;
|
|
|
|
private int stick_state;
|
|
|
|
protected VertexArray vertexArray;
|
|
protected Shader shader;
|
|
protected Matrix4f transform;
|
|
|
|
/**
|
|
* Projection and view matrix are set by the engine do not modify
|
|
*/
|
|
public static Matrix4f projection;
|
|
public static Matrix4f view;
|
|
|
|
/**
|
|
* xPos and yPos will stop to be relevant if you use rotate function
|
|
*/
|
|
private float xPos;
|
|
private float yPos;
|
|
private float zPos;
|
|
private float xAngle;
|
|
private float yAngle;
|
|
private float zAngle;
|
|
private float width; // To be used in setTextureWrap
|
|
private float height;
|
|
private float scalingFactor;
|
|
|
|
public boolean useTime;
|
|
|
|
private Texture texture;
|
|
private float[] textureWrap;
|
|
|
|
/**
|
|
* Create a rectangle shape, use setTextureWrap to correctly align the texture with the model
|
|
* @param z depth of your model the larger it is the more it will be "close" to the camera
|
|
* @param w height of the rectangle
|
|
* @param h width of the rectangle
|
|
* @param size scaling factor of the rectangle, the model could not show up because this value is too small or too large, a good compromise is between 2 and 15
|
|
* @param tex set to null if you don't want a tex on your model
|
|
* @param color set to null if you don't want a Color on your model
|
|
*/
|
|
public ObjectGl(float z, float w, float h, float size, String tex, Vector3f color){
|
|
float[] colorBuffer = null;
|
|
// Check des options
|
|
if (color != null){
|
|
colorBuffer = new float[] {
|
|
color.x, color.y, color.z,
|
|
color.x, color.y, color.z,
|
|
color.x, color.y, color.z,
|
|
color.x, color.y, color.z
|
|
};
|
|
}
|
|
|
|
if (tex != null){
|
|
this.texture = new Texture(tex, 0);
|
|
}
|
|
|
|
this.xPos = 0.0f;
|
|
this.yPos = 0.0f;
|
|
this.zPos = z;
|
|
this.height = h;
|
|
this.width = w;
|
|
|
|
this.textureWrap = Primitive.stdTexWrap;
|
|
this.vertexArray = new VertexArray(Primitive.createRectangle(this.zPos, this.width, this.height), Primitive.rectangle_indices, colorBuffer, Primitive.stdTexWrap);
|
|
|
|
this.scalingFactor = 1;
|
|
this.transform = Matrix4f.identity();
|
|
this.scale(new Vector3f(size, size,1.0f));
|
|
this.stick_state = DEFAULT;
|
|
this.useTime = false;
|
|
|
|
// use different shader for each set of option
|
|
if (tex == null && color == null){
|
|
this.shader = new Shader("shaders/ObjectGl/vert.glsl","shaders/ObjectGl/frag.glsl");
|
|
} else if (tex == null){
|
|
this.shader = new Shader("shaders/ObjectGlColor/vert.glsl","shaders/ObjectGlColor/frag.glsl");
|
|
} else if (color == null){
|
|
this.shader = new Shader("shaders/ObjectGlTex/vert.glsl","shaders/ObjectGlTex/frag.glsl");
|
|
} else {
|
|
this.shader = new Shader("shaders/ObjectGlTexColor/vert.glsl","shaders/ObjectGlTexColor/frag.glsl");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Reset the transform matrix, the model will appear at the 0.0.0 coordinate, his scaleFactor will be set to zero
|
|
* Because the model is at position 0 on the z axis he will not show up on screen
|
|
*/
|
|
public void resetTransform(){
|
|
this.transform = Matrix4f.identity();
|
|
this.scalingFactor = 1;
|
|
this.xPos = 0.0f;
|
|
this.yPos = 0.0f;
|
|
this.zPos = 0.0f;
|
|
}
|
|
|
|
/**
|
|
* Move the object according to vec, direction can change if rotation method have been used
|
|
* @param vec Vector3f
|
|
*/
|
|
public void translate(Vector3f vec){
|
|
this.xPos += vec.x;
|
|
this.yPos += vec.y;
|
|
this.zPos += vec.z;
|
|
vec.divXY(this.scalingFactor);
|
|
this.transform = this.transform.multiply(Matrix4f.translate(vec));
|
|
}
|
|
|
|
/**
|
|
* Scale the model with the vec vector, the x component is used to mitigate size modification in the behavior of other transformation method
|
|
* @param vec Vector3f
|
|
*/
|
|
public void scale(Vector3f vec){
|
|
this.scalingFactor *= vec.x;
|
|
this.transform = this.transform.multiply(Matrix4f.scale(vec));
|
|
}
|
|
|
|
/**
|
|
* rotate the model by angle degree on the local x axis, beware this will change the behavior of the translate method
|
|
* @param angle in degree
|
|
*/
|
|
public void rotateX(float angle){
|
|
this.transform = this.transform.multiply(Matrix4f.rotateX(angle));
|
|
}
|
|
|
|
/**
|
|
* rotate the model by angle degree on the local y axis, beware this will change the behavior of the translate method
|
|
* @param angle in degree
|
|
*/
|
|
public void rotateY(float angle){
|
|
this.transform = this.transform.multiply(Matrix4f.rotateY(angle));
|
|
}
|
|
|
|
/**
|
|
* rotate the model by angle degree on the local z axis, beware this will change the behavior of the translate method
|
|
* @param angle in degree
|
|
*/
|
|
public void rotateZ(float angle){
|
|
this.transform = this.transform.multiply(Matrix4f.rotateZ(angle));
|
|
}
|
|
|
|
/**
|
|
* Set a new texture to be used on the model. You may need to use setTextureWrap tp get the correct wrap
|
|
* @param texPath path to the new texture
|
|
*/
|
|
public void setTexture(String texPath){
|
|
this.texture = new Texture(texPath, 0);
|
|
}
|
|
|
|
/**
|
|
* Change the wrapping coordinate
|
|
* @param x starting wrapping on the horizontal axis
|
|
* @param y starting wrapping on the vertical axis
|
|
* @param w the length of the wrapping on the horizontal axis
|
|
* @param h the length of the wrapping on the vertical axis
|
|
*/
|
|
public void setTextureWrap(float x, float y, float w, float h, int sticky){
|
|
// TODO set sticky property + precision issue
|
|
if (this.stick_state != sticky){ // Check if we're using a new dimension
|
|
if (sticky == STICK_BOTTOM){
|
|
this.stick_state = STICK_BOTTOM;
|
|
this.translate(new Vector3f(0.0f, (h - this.height)*this.scalingFactor, 0.0f));
|
|
} else if (sticky == STICK_TOP){
|
|
this.stick_state = STICK_TOP;
|
|
this.translate(new Vector3f(0.0f, (h - this.height)*this.scalingFactor, 0.0f));
|
|
} else {
|
|
this.stick_state = DEFAULT;
|
|
}
|
|
}
|
|
this.height = h;
|
|
this.width = w;
|
|
this.vertexArray.swapVertexBufferObject(Primitive.createRectangle(this.zPos, w, h));
|
|
int texWidth = this.texture.getWidth();
|
|
int texHeight = this.texture.getHeight();
|
|
x /= texWidth;
|
|
w /= texWidth;
|
|
y /= texHeight;
|
|
h /= texHeight;
|
|
float[] result = {
|
|
x , y ,
|
|
x + w , y ,
|
|
x + w , y + h ,
|
|
x , y + h ,
|
|
};
|
|
this.setTextureWrap(result);
|
|
}
|
|
|
|
/**
|
|
* Reverse the textureWrap left to right
|
|
*/
|
|
public void flipTextureWrapH(){
|
|
float[] textureWrapTemp = new float[] {
|
|
this.textureWrap[2], this.textureWrap[3],
|
|
this.textureWrap[0], this.textureWrap[1],
|
|
this.textureWrap[6], this.textureWrap[7],
|
|
this.textureWrap[4], this.textureWrap[5]
|
|
};
|
|
setTextureWrap(textureWrapTemp);
|
|
}
|
|
|
|
/**
|
|
* Set a new shader to be used by this object
|
|
* @param vert path to glsl Vertex Shader
|
|
* @param frag path to glsl Fragment Shader
|
|
*/
|
|
public void setShader(String vert, String frag){
|
|
this.shader = new Shader(vert, frag);
|
|
}
|
|
|
|
/**
|
|
* Set a new Color for the object if the shader do not use the color attrib this will make no change.
|
|
* @param color Vector3f r,g,b format
|
|
*/
|
|
public void setColor(Vector3f color){
|
|
float[] colorBuffer = new float[] {
|
|
color.x, color.y, color.z,
|
|
color.x, color.y, color.z,
|
|
color.x, color.y, color.z,
|
|
color.x, color.y, color.z
|
|
};
|
|
this.vertexArray = new VertexArray(Primitive.createRectangle(this.zPos, this.width, this.height), Primitive.rectangle_indices, colorBuffer, Primitive.stdTexWrap);
|
|
}
|
|
|
|
private void setTextureWrap(float[] texture){
|
|
this.textureWrap = texture;
|
|
this.vertexArray.swapTextureBufferObject(texture);
|
|
}
|
|
|
|
public float getXPos(){
|
|
return xPos;
|
|
}
|
|
|
|
public float getYPos(){
|
|
return yPos;
|
|
}
|
|
|
|
public float getZPos(){
|
|
return zPos;
|
|
}
|
|
|
|
/**
|
|
* Do shader binding, texture binding and vertexArray drawing
|
|
*/
|
|
public void render(){
|
|
|
|
this.shader.enable();
|
|
if (this.texture != null) this.texture.bind();
|
|
|
|
if (this.useTime) this.shader.setUniform1f("time", (float) glfwGetTime());
|
|
|
|
this.shader.setUniformMat4f("projection", projection);
|
|
this.shader.setUniformMat4f("view", view);
|
|
this.shader.setUniformMat4f("transform", this.transform);
|
|
|
|
this.vertexArray.render();
|
|
|
|
if (this.texture != null) this.texture.unbind();
|
|
this.shader.disable();
|
|
}
|
|
|
|
}
|