First commit
17
nbactions.xml
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<actions>
|
||||
<action>
|
||||
<actionName>run</actionName>
|
||||
<packagings>
|
||||
<packaging>jar</packaging>
|
||||
</packagings>
|
||||
<goals>
|
||||
<goal>process-classes</goal>
|
||||
<goal>org.codehaus.mojo:exec-maven-plugin:1.5.0:exec</goal>
|
||||
</goals>
|
||||
<properties>
|
||||
<exec.args>-classpath %classpath main.Main</exec.args>
|
||||
<exec.executable>java</exec.executable>
|
||||
</properties>
|
||||
</action>
|
||||
</actions>
|
||||
149
pom.xml
Normal file
@ -0,0 +1,149 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>orbitalstudio</groupId>
|
||||
<artifactId>InfiniteStratos</artifactId>
|
||||
<version>0.1</version>
|
||||
<packaging>jar</packaging>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>11</maven.compiler.source>
|
||||
<maven.compiler.target>11</maven.compiler.target>
|
||||
<lwjgl.version>3.2.3</lwjgl.version>
|
||||
<joml.version>1.9.19</joml.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<!-- https://mvnrepository.com/artifact/org.lwjgl/lwjgl -->
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-assimp</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-glfw</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-opengl</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-opengles</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-assimp</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-glfw</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-opengl</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lwjgl</groupId>
|
||||
<artifactId>lwjgl-opengles</artifactId>
|
||||
<version>${lwjgl.version}</version>
|
||||
<classifier>${lwjgl.natives}</classifier>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.joml</groupId>
|
||||
<artifactId>joml</artifactId>
|
||||
<version>${joml.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.6</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>lwjgl-natives-linux</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>unix</family>
|
||||
</os>
|
||||
</activation>
|
||||
<properties>
|
||||
<lwjgl.natives>natives-linux</lwjgl.natives>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>lwjgl-natives-macos</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>mac</family>
|
||||
</os>
|
||||
</activation>
|
||||
<properties>
|
||||
<lwjgl.natives>natives-macos</lwjgl.natives>
|
||||
</properties>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>lwjgl-natives-windows</id>
|
||||
<activation>
|
||||
<os>
|
||||
<family>windows</family>
|
||||
</os>
|
||||
</activation>
|
||||
<properties>
|
||||
<lwjgl.natives>natives-windows</lwjgl.natives>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
<build>
|
||||
<resources>
|
||||
<resource>
|
||||
<directory>${basedir}/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<mainClass>main.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
184
src/main/java/RendererObjects/AnimChannel.java
Normal file
@ -0,0 +1,184 @@
|
||||
package RendererObjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.ListIterator;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class AnimChannel {
|
||||
double timeCurrent;
|
||||
double timeTotal;
|
||||
public String nodeID;
|
||||
|
||||
|
||||
public Vector3f startingPosition;
|
||||
public ArrayList<Keyframe> positionFrame;
|
||||
public ListIterator<Keyframe> positionFrameIterator;
|
||||
Keyframe positionFrameCurrent;
|
||||
Keyframe positionFrameNext;
|
||||
double nextPositionTime;
|
||||
|
||||
|
||||
public Quaternionf startingRotation;
|
||||
public ArrayList<Keyframe> rotationFrame;
|
||||
public ListIterator<Keyframe> rotationFrameIterator;
|
||||
Keyframe rotationFrameCurrent;
|
||||
Keyframe rotationFrameNext;
|
||||
double nextRotationTime;
|
||||
|
||||
|
||||
public ArrayList<Keyframe> scaleFrame;
|
||||
public ListIterator<Keyframe> scaleFrameIterator;
|
||||
Keyframe scaleFrameCurrent;
|
||||
Keyframe scaleFrameNext;
|
||||
double nextScaleTime;
|
||||
|
||||
|
||||
public AnimChannel(double maxTime){
|
||||
timeTotal = maxTime;
|
||||
}
|
||||
|
||||
public Vector3f getCurrentPosition(){
|
||||
Vector3f rVal = new Vector3f();
|
||||
if(positionFrameCurrent != null){
|
||||
if(positionFrameNext != null){
|
||||
double percent_Next = ((timeCurrent - positionFrameCurrent.time) / (positionFrameNext.time - positionFrameCurrent.time));
|
||||
rVal = new Vector3f().add(new Vector3f().add(positionFrameCurrent.position).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(positionFrameNext.position).mul((float)(percent_Next)));
|
||||
} else {
|
||||
rVal = new Vector3f().add(positionFrameCurrent.position);
|
||||
}
|
||||
// rVal.add(new Vector3f().add(positionFrameCurrent.position).mul(()/(positionFrameNext.time - positionFrameCurrent.time)));
|
||||
}
|
||||
// rVal = rVal.sub(startingPosition);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public Quaternionf getCurrentRotation(){
|
||||
Quaternionf rVal = new Quaternionf();
|
||||
if(rotationFrameCurrent != null){
|
||||
if(rotationFrameNext != null){
|
||||
double percent_Next = ((timeCurrent - rotationFrameCurrent.time) / (rotationFrameNext.time - rotationFrameCurrent.time));
|
||||
// rVal = new Quaternionf(rotationFrameCurrent.rotation).normalize();//.add(rotationFrameCurrent.rotation);
|
||||
rVal = new Quaternionf(rotationFrameCurrent.rotation).slerp(rotationFrameNext.rotation, (float)percent_Next);
|
||||
// rVal = new Quaternionf(rotationFrameCurrent.rotation).normalize().slerp(new Quaternionf(rotationFrameNext.rotation).normalize(), (float)(percent_Next)).rotateAxis((float)(-Math.PI/2), new Vector3f(1,0,0));
|
||||
} else {
|
||||
rVal = new Quaternionf(rotationFrameCurrent.rotation);//.add(rotationFrameCurrent.rotation);
|
||||
}
|
||||
}
|
||||
// rVal = rVal.mul(new Quaternionf(startingRotation).invert());
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public Vector3f getCurrentScale(){
|
||||
Vector3f rVal = new Vector3f();
|
||||
if(scaleFrameCurrent != null){
|
||||
if(scaleFrameNext != null){
|
||||
double percent_Next = ((timeCurrent - scaleFrameCurrent.time) / (scaleFrameNext.time - scaleFrameCurrent.time));
|
||||
rVal = new Vector3f().add(new Vector3f().add(scaleFrameCurrent.scale).mul((float)(1.0 - percent_Next))).add(new Vector3f().add(scaleFrameNext.scale).mul((float)(percent_Next)));
|
||||
} else {
|
||||
rVal = new Vector3f().add(scaleFrameCurrent.scale);
|
||||
}
|
||||
// rVal.add(new Vector3f().add(positionFrameCurrent.position).mul(()/(positionFrameNext.time - positionFrameCurrent.time)));
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public void incrementTime(double incrementValue){
|
||||
timeCurrent = timeCurrent + incrementValue;
|
||||
while(positionFrameNext != null && timeCurrent > positionFrameNext.time){
|
||||
positionFrameCurrent = positionFrameNext;
|
||||
if(positionFrameIterator.hasNext()){
|
||||
positionFrameNext = positionFrameIterator.next();
|
||||
} else {
|
||||
positionFrameNext = null;
|
||||
}
|
||||
}
|
||||
while(rotationFrameNext != null && timeCurrent > rotationFrameNext.time){
|
||||
rotationFrameCurrent = rotationFrameNext;
|
||||
if(rotationFrameIterator.hasNext()){
|
||||
rotationFrameNext = rotationFrameIterator.next();
|
||||
} else {
|
||||
rotationFrameNext = null;
|
||||
}
|
||||
}
|
||||
while(scaleFrameNext != null && timeCurrent > scaleFrameNext.time){
|
||||
scaleFrameCurrent = scaleFrameNext;
|
||||
if(scaleFrameIterator.hasNext()){
|
||||
scaleFrameNext = scaleFrameIterator.next();
|
||||
} else {
|
||||
scaleFrameNext = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void rewind(){
|
||||
timeCurrent = 0;
|
||||
|
||||
//TODO: Make sure has at least two frames
|
||||
positionFrameIterator = positionFrame.listIterator();
|
||||
if(positionFrameIterator.hasNext()){
|
||||
positionFrameCurrent = positionFrameIterator.next();
|
||||
if(positionFrameIterator.hasNext()){
|
||||
positionFrameNext = positionFrameIterator.next();
|
||||
nextPositionTime = positionFrameNext.time;
|
||||
} else {
|
||||
positionFrameNext = null;
|
||||
}
|
||||
}
|
||||
|
||||
rotationFrameIterator = rotationFrame.listIterator();
|
||||
if(rotationFrameIterator.hasNext()){
|
||||
rotationFrameCurrent = rotationFrameIterator.next();
|
||||
if(rotationFrameIterator.hasNext()){
|
||||
rotationFrameNext = rotationFrameIterator.next();
|
||||
} else {
|
||||
rotationFrameNext = null;
|
||||
}
|
||||
}
|
||||
|
||||
scaleFrameIterator = scaleFrame.listIterator();
|
||||
if(scaleFrameIterator.hasNext()){
|
||||
scaleFrameCurrent = scaleFrameIterator.next();
|
||||
if(scaleFrameIterator.hasNext()){
|
||||
scaleFrameNext = scaleFrameIterator.next();
|
||||
} else {
|
||||
scaleFrameNext = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void describeChannel(){
|
||||
System.out.println("Target object: " + nodeID);
|
||||
System.out.println("Time: " + timeCurrent + "/" + timeTotal);
|
||||
System.out.println(positionFrame.size() + " position Frames");
|
||||
System.out.println(rotationFrame.size() + " rotation Frames");
|
||||
System.out.println(scaleFrame.size() + " scale Frames");
|
||||
}
|
||||
|
||||
public void fullDescribeChannel(){
|
||||
System.out.println("Target object: " + nodeID);
|
||||
System.out.println("Time: " + timeCurrent + "/" + timeTotal);
|
||||
System.out.println(positionFrame.size() + " position Frames");
|
||||
Iterator<Keyframe> frameIterator = positionFrame.iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
}
|
||||
System.out.println(rotationFrame.size() + " rotation Frames");
|
||||
frameIterator = rotationFrame.iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
}
|
||||
System.out.println(scaleFrame.size() + " scale Frames");
|
||||
frameIterator = scaleFrame.iterator();
|
||||
while(frameIterator.hasNext()){
|
||||
System.out.println(frameIterator.next());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
26
src/main/java/RendererObjects/AnimNode.java
Normal file
@ -0,0 +1,26 @@
|
||||
package RendererObjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.assimp.AINode;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class AnimNode {
|
||||
public String id;
|
||||
public Matrix4f transform;
|
||||
public AnimNode parent;
|
||||
public ArrayList<AnimNode> children;
|
||||
public boolean is_bone;
|
||||
public AINode raw_data;
|
||||
public AnimNode(String id, AnimNode parent, AINode raw_data){
|
||||
this.id = id;
|
||||
this.parent = parent;
|
||||
this.children = new ArrayList();
|
||||
this.transform = new Matrix4f();
|
||||
is_bone = false;
|
||||
this.raw_data = raw_data;
|
||||
}
|
||||
}
|
||||
249
src/main/java/RendererObjects/Animation.java
Normal file
@ -0,0 +1,249 @@
|
||||
package RendererObjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.PriorityQueue;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIAnimation;
|
||||
import org.lwjgl.assimp.AIMeshAnim;
|
||||
import org.lwjgl.assimp.AIMeshKey;
|
||||
import org.lwjgl.assimp.AINodeAnim;
|
||||
import org.lwjgl.assimp.AIQuatKey;
|
||||
import org.lwjgl.assimp.AIVectorKey;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class Animation {
|
||||
AIAnimation animData;
|
||||
public String name;
|
||||
public int ID;
|
||||
ArrayList<AINodeAnim> nodeChannelData;
|
||||
ArrayList<AIMeshAnim> meshChannelData;
|
||||
public ArrayList<AnimChannel> channels;
|
||||
public double duration = 0;
|
||||
public double timeCurrent = 0;
|
||||
public double ticksPerSecond;
|
||||
public Animation(AIAnimation animData, int ID){
|
||||
//
|
||||
//Read in metadata
|
||||
//
|
||||
this.animData = animData;
|
||||
name = animData.mName().dataString();
|
||||
this.duration = animData.mDuration();
|
||||
this.ticksPerSecond = animData.mTicksPerSecond();
|
||||
this.ID = ID;
|
||||
//
|
||||
//Print metadata
|
||||
//
|
||||
// System.out.println("Animation name: \"" + name + "\"");
|
||||
// System.out.println("ID:(" + ID + ")");
|
||||
// System.out.println("Ticks per second: " + ticksPerSecond);
|
||||
// System.out.println("Anim sizeof: " + animData.sizeof());
|
||||
// System.out.println("Duration: " + duration);
|
||||
//
|
||||
//Read in anim channels (bone modifications)
|
||||
//
|
||||
int channelCount = animData.mNumChannels();
|
||||
channels = new ArrayList();
|
||||
if(channelCount > 0){
|
||||
// System.out.println("Channel count: " + channelCount);
|
||||
for(int i = 0; i < channelCount; i++){
|
||||
AINodeAnim currentChannelData = AINodeAnim.create(animData.mChannels().get(i));
|
||||
// System.out.println("Channel[" + (i + 1) + "]: " + currentChannelData.mNodeName().dataString());
|
||||
|
||||
//Create channel
|
||||
AnimChannel currentChannel = new AnimChannel(duration);
|
||||
currentChannel.positionFrame = new ArrayList();
|
||||
currentChannel.rotationFrame = new ArrayList();
|
||||
currentChannel.scaleFrame = new ArrayList();
|
||||
currentChannel.nodeID = currentChannelData.mNodeName().dataString();
|
||||
channels.add(currentChannel);
|
||||
|
||||
|
||||
//get channel data
|
||||
|
||||
if(currentChannelData.mNumPositionKeys() > 0){
|
||||
org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mPositionKeys();
|
||||
// Iterator<AIVectorKey> keyIterator = buff.iterator();
|
||||
// while (keyIterator.hasNext()) {
|
||||
// AIVectorKey key = keyIterator.next();
|
||||
// Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
// currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
// currentChannel.positionFrame.add(currentFrame);
|
||||
// }
|
||||
if(buff != null && buff.hasRemaining()){
|
||||
// System.out.println("Position vectors: ");
|
||||
AIVectorKey key = buff.get();
|
||||
Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
currentChannel.positionFrame.add(currentFrame);
|
||||
// System.out.println(currentFrame.position);
|
||||
currentChannel.startingPosition = currentFrame.position;
|
||||
|
||||
Keyframe previousFrame;
|
||||
while(buff.hasRemaining()){
|
||||
previousFrame = currentFrame;
|
||||
key = buff.get();
|
||||
currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.position = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
// System.out.println(currentFrame.position);
|
||||
//check if duplicate
|
||||
// Keyframe previousFrame = currentChannel.positionFrame.get(currentChannel.positionFrame.size() - 1);
|
||||
if( previousFrame.position.x == currentFrame.position.x &&
|
||||
previousFrame.position.y == currentFrame.position.y &&
|
||||
previousFrame.position.z == currentFrame.position.z
|
||||
){
|
||||
} else {
|
||||
currentChannel.positionFrame.add(currentFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(currentChannelData.mNumRotationKeys() > 0){
|
||||
org.lwjgl.assimp.AIQuatKey.Buffer buff = currentChannelData.mRotationKeys();
|
||||
if(buff != null && buff.hasRemaining()){
|
||||
AIQuatKey key = buff.get();
|
||||
Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.rotation = new Quaternionf();
|
||||
currentFrame.rotation.set(key.mValue().x(), key.mValue().y(), key.mValue().z(), key.mValue().w());
|
||||
// currentFrame.rotation = new Quaternionf(key.mValue().x(),key.mValue().y(),key.mValue().z(),key.mValue().w());
|
||||
currentChannel.rotationFrame.add(currentFrame);
|
||||
|
||||
currentChannel.startingRotation = currentFrame.rotation;
|
||||
|
||||
Keyframe previousFrame;
|
||||
while(buff.hasRemaining()){
|
||||
previousFrame = currentFrame;
|
||||
key = buff.get();
|
||||
currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.rotation = new Quaternionf();
|
||||
currentFrame.rotation.set(key.mValue().x(), key.mValue().y(), key.mValue().z(), key.mValue().w());
|
||||
// currentFrame.rotation = new Quaternionf(key.mValue().x(),key.mValue().y(),key.mValue().z(),key.mValue().w());
|
||||
//check for duplicate
|
||||
// Keyframe previousFrame = currentChannel.rotationFrame.get(currentChannel.rotationFrame.size() - 1);
|
||||
if( previousFrame.rotation.w == currentFrame.rotation.w &&
|
||||
previousFrame.rotation.x == currentFrame.rotation.x &&
|
||||
previousFrame.rotation.y == currentFrame.rotation.y &&
|
||||
previousFrame.rotation.z == currentFrame.rotation.z
|
||||
){
|
||||
} else {
|
||||
currentChannel.rotationFrame.add(currentFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Iterator<AIQuatKey> keyIterator = buff.iterator();
|
||||
// while(keyIterator.hasNext()){
|
||||
// AIQuatKey key = keyIterator.next();
|
||||
// Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
// currentFrame.rotation = new Quaternionf(key.mValue().w(),key.mValue().x(),key.mValue().y(),key.mValue().z());
|
||||
// currentChannel.rotationFrame.add(currentFrame);
|
||||
// }
|
||||
}
|
||||
|
||||
if(currentChannelData.mNumScalingKeys() > 0){
|
||||
org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mScalingKeys();
|
||||
// Iterator<AIVectorKey> keyIterator = buff.iterator();
|
||||
// while (keyIterator.hasNext()) {
|
||||
// AIVectorKey key = keyIterator.next();
|
||||
// Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
// currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
// currentChannel.scaleFrame.add(currentFrame);
|
||||
// }
|
||||
if(buff != null && buff.hasRemaining()){
|
||||
AIVectorKey key = buff.get();
|
||||
Keyframe currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
currentChannel.scaleFrame.add(currentFrame);
|
||||
Keyframe previousFrame;
|
||||
while(buff.hasRemaining()){
|
||||
previousFrame = currentFrame;
|
||||
key = buff.get();
|
||||
currentFrame = new Keyframe(key.mTime());
|
||||
currentFrame.scale = new Vector3f(key.mValue().x(), key.mValue().y(), key.mValue().z());
|
||||
if( currentFrame.scale.x == previousFrame.scale.x &&
|
||||
currentFrame.scale.y == previousFrame.scale.y &&
|
||||
currentFrame.scale.z == previousFrame.scale.z
|
||||
){
|
||||
} else {
|
||||
currentChannel.scaleFrame.add(currentFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// System.out.println("end times");
|
||||
// for(int j = 0; j < currentChannelData.mNumPositionKeys(); j++){
|
||||
// org.lwjgl.assimp.AIVectorKey.Buffer buff = currentChannelData.mPositionKeys();
|
||||
// Iterator<AIVectorKey> keyIterator = buff.iterator();
|
||||
// AIVectorKey posKey = currentChannelData.mPositionKeys().get(i);
|
||||
// Keyframe currentFrame = new Keyframe(posKey.mTime());
|
||||
// currentFrame.position = new Vector3f(posKey.mValue().x(),posKey.mValue().y(),posKey.mValue().z());
|
||||
// }
|
||||
// for(int j = 0; j < currentChannelData.mNumRotationKeys(); j++){
|
||||
// AIQuatKey rotKey = currentChannelData.mRotationKeys().get(i);
|
||||
// HashMap test = new HashMap();
|
||||
// System.out.println(new Quaternionf(rotKey.mValue().w(),rotKey.mValue().x(),rotKey.mValue().y(),rotKey.mValue().z()));
|
||||
// }
|
||||
// for(int j = 0; j < currentChannelData.mNumScalingKeys(); j++){
|
||||
// AIVectorKey scaleKey = currentChannelData.mScalingKeys().get(i);
|
||||
//// scaleKey.mValue().
|
||||
// System.out.println(new Vector3f(scaleKey.mValue().x(),scaleKey.mValue().y(),scaleKey.mValue().z()));
|
||||
// }
|
||||
}
|
||||
}
|
||||
// int meshChannelCount = animData.mNumMeshChannels();
|
||||
// meshChannelData = new ArrayList();
|
||||
// if(meshChannelCount > 0){
|
||||
// for(int i = 0; i < meshChannelCount; i++){
|
||||
// AIMeshAnim test = AIMeshAnim.create(animData.mMeshChannels().get(i));
|
||||
// }
|
||||
// }
|
||||
//gotta free things
|
||||
nodeChannelData = null;
|
||||
meshChannelData = null;
|
||||
}
|
||||
public void describeAnimation(){
|
||||
System.out.println("=====================");
|
||||
System.out.println("Name: \"" + name + "\"");
|
||||
System.out.println("ID: " + ID);
|
||||
System.out.println("Duration: " + duration);
|
||||
System.out.println("Ticks per second: " + ticksPerSecond);
|
||||
Iterator<AnimChannel> channelIterator = channels.iterator();
|
||||
while(channelIterator.hasNext()){
|
||||
AnimChannel channelCurrent = channelIterator.next();
|
||||
System.out.println("=====================");
|
||||
channelCurrent.describeChannel();
|
||||
}
|
||||
System.out.println("=====================");
|
||||
}
|
||||
public void fullDescribeAnimation(){
|
||||
System.out.println("=====================");
|
||||
System.out.println("Name: " + name);
|
||||
System.out.println("ID: " + ID);
|
||||
System.out.println("Duration: " + duration);
|
||||
System.out.println("Ticks per second: " + ticksPerSecond);
|
||||
Iterator<AnimChannel> channelIterator = channels.iterator();
|
||||
while(channelIterator.hasNext()){
|
||||
AnimChannel channelCurrent = channelIterator.next();
|
||||
System.out.println("=====================");
|
||||
channelCurrent.fullDescribeChannel();
|
||||
}
|
||||
System.out.println("=====================");
|
||||
}
|
||||
|
||||
public boolean incrementTime(double time){
|
||||
timeCurrent += time;
|
||||
if(timeCurrent > duration){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
src/main/java/RendererObjects/Bone.java
Normal file
@ -0,0 +1,34 @@
|
||||
package RendererObjects;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import org.joml.Matrix4f;
|
||||
import org.lwjgl.assimp.AIBone;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class Bone {
|
||||
public String boneID;
|
||||
int numWeights;
|
||||
HashMap<Integer,Float> weights;
|
||||
public Matrix4f inverseBindPoseMatrix;
|
||||
public Matrix4f deform;
|
||||
public Matrix4f transform;
|
||||
public Matrix4f final_transform;
|
||||
public AIBone raw_data;
|
||||
public Bone(){
|
||||
transform = new Matrix4f();
|
||||
deform = new Matrix4f();
|
||||
final_transform = new Matrix4f();
|
||||
}
|
||||
public Bone(AIBone raw_data){
|
||||
transform = new Matrix4f();
|
||||
deform = new Matrix4f();
|
||||
final_transform = new Matrix4f();
|
||||
boneID = raw_data.mName().dataString();
|
||||
inverseBindPoseMatrix = util.util.convertAIMatrix(raw_data.mOffsetMatrix());
|
||||
this.raw_data = raw_data;
|
||||
}
|
||||
}
|
||||
39
src/main/java/RendererObjects/Camera.java
Normal file
@ -0,0 +1,39 @@
|
||||
package RendererObjects;
|
||||
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class Camera {
|
||||
public Vector3f pos_Center = new Vector3f(0,0,0);
|
||||
// public Vector3f pos_Front = new Vector3f(0,0,0);
|
||||
// public Vector3f pos_Top = new Vector3f(0,0,0);
|
||||
public Quaternionf rotation = new Quaternionf();
|
||||
public Camera(){
|
||||
|
||||
}
|
||||
|
||||
public void apply_camera(Camera c){
|
||||
pos_Center = new Vector3f(c.pos_Center);
|
||||
rotation = new Quaternionf(c.rotation);
|
||||
}
|
||||
|
||||
public Matrix4f get_view_matrix(){
|
||||
Matrix4f rVal = new Matrix4f();
|
||||
// rVal.setLookAt(pos_Center, pos_Front, pos_Top);
|
||||
Vector3f up = new Vector3f(pos_Center);
|
||||
//new Vector3f(pos_Center).add(new Quaternionf(rotation)..transform(new Vector3f(1,0,0)))
|
||||
Vector3f up_modifier = new Vector3f(1,0,0);
|
||||
Quaternionf up_transformation = new Quaternionf(rotation);
|
||||
up_transformation.rotateAxis((float)Math.PI/2.0f, new Vector3f(up).cross(new Vector3f(0,1,0))); // the hard part is getting the axis in this logic to correspond to the vertical
|
||||
up = up.add(up_transformation.transform(up_modifier));
|
||||
rVal.setLookAt(pos_Center, //where our camera is
|
||||
new Vector3f(pos_Center).add(rotation.transform(new Vector3f(1,0,0))), //where our camera wants to look
|
||||
up); //where "up" is relative to our camera
|
||||
return rVal;
|
||||
}
|
||||
}
|
||||
50
src/main/java/RendererObjects/Keyframe.java
Normal file
@ -0,0 +1,50 @@
|
||||
package RendererObjects;
|
||||
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class Keyframe implements Comparable{
|
||||
double time;
|
||||
Vector3f position;
|
||||
Quaternionf rotation;
|
||||
Vector3f scale;
|
||||
|
||||
public Keyframe(double time){
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Object t) {
|
||||
if(time > ((Keyframe)t).getTime()){
|
||||
return 1;
|
||||
} else if(time < ((Keyframe)t).getTime()){
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public double getTime(){
|
||||
return time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
String rVal = "";
|
||||
rVal = rVal + "[" + time + "]";
|
||||
if(position != null){
|
||||
rVal = rVal + " position:" + position.toString();
|
||||
}
|
||||
if(rotation != null){
|
||||
rVal = rVal + " rotation:" + rotation.toString();
|
||||
}
|
||||
if(scale != null){
|
||||
rVal = rVal + " scale:" + scale.toString();
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
}
|
||||
74
src/main/java/RendererObjects/Light/DirectionalLight.java
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package RendererObjects.Light;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class DirectionalLight {
|
||||
Vector3f direction;
|
||||
|
||||
Vector3f ambient;
|
||||
Vector3f diffuse;
|
||||
Vector3f specular;
|
||||
|
||||
public void setDirection(Vector3f direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public void setAmbient(Vector3f ambient) {
|
||||
this.ambient = ambient;
|
||||
}
|
||||
|
||||
public void setDiffuse(Vector3f diffuse) {
|
||||
this.diffuse = diffuse;
|
||||
}
|
||||
|
||||
public void setSpecular(Vector3f specular) {
|
||||
this.specular = specular;
|
||||
}
|
||||
|
||||
public Vector3f getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public Vector3f getAmbient() {
|
||||
return ambient;
|
||||
}
|
||||
|
||||
public Vector3f getDiffuse() {
|
||||
return diffuse;
|
||||
}
|
||||
|
||||
public Vector3f getSpecular() {
|
||||
return specular;
|
||||
}
|
||||
|
||||
public DirectionalLight(Vector3f direction){
|
||||
this.direction = direction;
|
||||
ambient = new Vector3f(0.05f, 0.05f, 0.05f);
|
||||
diffuse = new Vector3f(0.4f, 0.4f, 0.4f);
|
||||
specular = new Vector3f(0.5f, 0.5f, 0.5f);
|
||||
this.direction.normalize();
|
||||
ambient.normalize();
|
||||
diffuse.normalize();
|
||||
specular.normalize();
|
||||
}
|
||||
|
||||
public DirectionalLight(Vector3f direction, Vector3f color){
|
||||
this.direction = direction;
|
||||
ambient = new Vector3f( color.x * 0.05f, color.y * 0.05f, color.z * 0.05f);
|
||||
diffuse = new Vector3f( color.x * 0.4f, color.y * 0.4f, color.z * 0.4f);
|
||||
specular = new Vector3f(color.x * 0.5f, color.y * 0.5f, color.z * 0.5f);
|
||||
this.direction.normalize();
|
||||
ambient.normalize();
|
||||
diffuse.normalize();
|
||||
specular.normalize();
|
||||
}
|
||||
}
|
||||
23
src/main/java/RendererObjects/Light/LightBuffer.java
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package RendererObjects.Light;
|
||||
|
||||
import static org.lwjgl.opengl.GL15.*;
|
||||
import static org.lwjgl.opengl.GL31.GL_UNIFORM_BUFFER;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class LightBuffer {
|
||||
int light_uniform_buffer_address;
|
||||
|
||||
public LightBuffer(){
|
||||
light_uniform_buffer_address = glGenBuffers();
|
||||
glBindBuffer(GL_UNIFORM_BUFFER,light_uniform_buffer_address);
|
||||
//glBufferData(GL_UNIFORM_BUFFER, <my_data>, GL_STATIC_DRAW);
|
||||
}
|
||||
}
|
||||
106
src/main/java/RendererObjects/Light/PointLight.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package RendererObjects.Light;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class PointLight {
|
||||
Vector3f position;
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
Vector3f ambient;
|
||||
Vector3f diffuse;
|
||||
Vector3f specular;
|
||||
|
||||
public void setPosition(Vector3f position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public void setConstant(float constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
public void setLinear(float linear) {
|
||||
this.linear = linear;
|
||||
}
|
||||
|
||||
public void setQuadratic(float quadratic) {
|
||||
this.quadratic = quadratic;
|
||||
}
|
||||
|
||||
public void setAmbient(Vector3f ambient) {
|
||||
this.ambient = ambient;
|
||||
}
|
||||
|
||||
public void setDiffuse(Vector3f diffuse) {
|
||||
this.diffuse = diffuse;
|
||||
}
|
||||
|
||||
public void setSpecular(Vector3f specular) {
|
||||
this.specular = specular;
|
||||
}
|
||||
|
||||
public Vector3f getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public float getConstant() {
|
||||
return constant;
|
||||
}
|
||||
|
||||
public float getLinear() {
|
||||
return linear;
|
||||
}
|
||||
|
||||
public float getQuadratic() {
|
||||
return quadratic;
|
||||
}
|
||||
|
||||
public Vector3f getAmbient() {
|
||||
return ambient;
|
||||
}
|
||||
|
||||
public Vector3f getDiffuse() {
|
||||
return diffuse;
|
||||
}
|
||||
|
||||
public Vector3f getSpecular() {
|
||||
return specular;
|
||||
}
|
||||
|
||||
public PointLight(Vector3f position){
|
||||
this.position = position;
|
||||
constant = 1.0f;
|
||||
linear = 0.01f;
|
||||
quadratic = 0.01f;
|
||||
ambient = new Vector3f(0.05f, 0.05f, 0.05f);
|
||||
diffuse = new Vector3f(0.8f, 0.8f, 0.8f);
|
||||
specular = new Vector3f(1.0f, 1.0f, 1.0f);
|
||||
this.position.normalize();
|
||||
ambient.normalize();
|
||||
diffuse.normalize();
|
||||
specular.normalize();
|
||||
}
|
||||
|
||||
public PointLight(Vector3f position, Vector3f color){
|
||||
this.position = position;
|
||||
constant = 1.0f;
|
||||
linear = 0.01f;
|
||||
quadratic = 0.01f;
|
||||
ambient = new Vector3f(color.x * 0.05f, color.y * 0.05f, color.z * 0.05f);
|
||||
diffuse = new Vector3f(color.x * 0.8f, color.y * 0.8f, color.z * 0.8f);
|
||||
specular = new Vector3f(color.x, color.y, color.z);
|
||||
this.position.normalize();
|
||||
ambient.normalize();
|
||||
diffuse.normalize();
|
||||
specular.normalize();
|
||||
}
|
||||
}
|
||||
143
src/main/java/RendererObjects/Light/SpotLight.java
Normal file
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package RendererObjects.Light;
|
||||
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class SpotLight {
|
||||
Vector3f position;
|
||||
Vector3f direction;
|
||||
float cutOff;
|
||||
float outerCutOff;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
|
||||
Vector3f ambient;
|
||||
Vector3f diffuse;
|
||||
Vector3f specular;
|
||||
|
||||
public void setPosition(Vector3f position) {
|
||||
this.position = position;
|
||||
}
|
||||
|
||||
public void setDirection(Vector3f direction) {
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
public void setCutOff(float cutOff) {
|
||||
this.cutOff = cutOff;
|
||||
}
|
||||
|
||||
public void setOuterCutOff(float outerCutOff) {
|
||||
this.outerCutOff = outerCutOff;
|
||||
}
|
||||
|
||||
public void setConstant(float constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
public void setLinear(float linear) {
|
||||
this.linear = linear;
|
||||
}
|
||||
|
||||
public void setQuadratic(float quadratic) {
|
||||
this.quadratic = quadratic;
|
||||
}
|
||||
|
||||
public void setAmbient(Vector3f ambient) {
|
||||
this.ambient = ambient;
|
||||
}
|
||||
|
||||
public void setDiffuse(Vector3f diffuse) {
|
||||
this.diffuse = diffuse;
|
||||
}
|
||||
|
||||
public void setSpecular(Vector3f specular) {
|
||||
this.specular = specular;
|
||||
}
|
||||
|
||||
public Vector3f getPosition() {
|
||||
return position;
|
||||
}
|
||||
|
||||
public Vector3f getDirection() {
|
||||
return direction;
|
||||
}
|
||||
|
||||
public float getCutOff() {
|
||||
return cutOff;
|
||||
}
|
||||
|
||||
public float getOuterCutOff() {
|
||||
return outerCutOff;
|
||||
}
|
||||
|
||||
public float getConstant() {
|
||||
return constant;
|
||||
}
|
||||
|
||||
public float getLinear() {
|
||||
return linear;
|
||||
}
|
||||
|
||||
public float getQuadratic() {
|
||||
return quadratic;
|
||||
}
|
||||
|
||||
public Vector3f getAmbient() {
|
||||
return ambient;
|
||||
}
|
||||
|
||||
public Vector3f getDiffuse() {
|
||||
return diffuse;
|
||||
}
|
||||
|
||||
public Vector3f getSpecular() {
|
||||
return specular;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public SpotLight(Vector3f position, Vector3f direction){
|
||||
this.position = position;
|
||||
this.direction = direction;
|
||||
cutOff = (float)Math.toRadians(12.5f);
|
||||
outerCutOff = (float)Math.toRadians(15.0f);
|
||||
constant = 1.0f;
|
||||
linear = 0.01f;
|
||||
quadratic = 0.01f;
|
||||
ambient = new Vector3f(0.05f, 0.05f, 0.05f);
|
||||
diffuse = new Vector3f(0.8f, 0.8f, 0.8f);
|
||||
specular = new Vector3f(1.0f, 1.0f, 1.0f);
|
||||
this.position.normalize();
|
||||
this.direction.normalize();
|
||||
ambient.normalize();
|
||||
diffuse.normalize();
|
||||
specular.normalize();
|
||||
}
|
||||
|
||||
public SpotLight(Vector3f position, Vector3f direction, Vector3f color){
|
||||
this.position = position;
|
||||
this.direction = direction;
|
||||
constant = 1.0f;
|
||||
linear = 0.01f;
|
||||
quadratic = 0.01f;
|
||||
ambient = new Vector3f(color.x * 0.05f, color.y * 0.05f, color.z * 0.05f);
|
||||
diffuse = new Vector3f(color.x * 0.8f, color.y * 0.8f, color.z * 0.8f);
|
||||
specular = new Vector3f(color.x, color.y, color.z);
|
||||
this.position.normalize();
|
||||
this.direction.normalize();
|
||||
ambient.normalize();
|
||||
diffuse.normalize();
|
||||
specular.normalize();
|
||||
}
|
||||
}
|
||||
67
src/main/java/RendererObjects/Material.java
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package RendererObjects;
|
||||
|
||||
import RendererObjects.texture.Texture;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIMaterial;
|
||||
import org.lwjgl.assimp.AIMaterialProperty;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class Material {
|
||||
Texture diffuse;
|
||||
Texture specular;
|
||||
boolean hasTransparency = false;
|
||||
public Material(){
|
||||
|
||||
}
|
||||
//basically useless because blender doesn't support exporting mats with fbx
|
||||
public static Material load_material_from_aimaterial(AIMaterial input){
|
||||
Material rVal = new Material();
|
||||
if(input.mNumProperties() > 0){
|
||||
PointerBuffer property_buffer = input.mProperties();
|
||||
while(property_buffer.hasRemaining()){
|
||||
AIMaterialProperty new_property = AIMaterialProperty.create(property_buffer.get());
|
||||
// System.out.println("Property: " + new_property.mKey().dataString());
|
||||
}
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
public Texture get_diffuse(){
|
||||
return diffuse;
|
||||
}
|
||||
public Texture get_specular(){
|
||||
return specular;
|
||||
}
|
||||
public void set_diffuse(Texture t){
|
||||
diffuse = t;
|
||||
if(t.isTransparent()){
|
||||
hasTransparency = true;
|
||||
}
|
||||
}
|
||||
public void set_specular(Texture t){
|
||||
specular = t;
|
||||
if(t.isTransparent()){
|
||||
hasTransparency = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void apply_material(){
|
||||
diffuse.bind(0);
|
||||
specular.bind(1);
|
||||
}
|
||||
public void apply_material(int diffuse_channel, int specular_channel){
|
||||
diffuse.bind(diffuse_channel);
|
||||
specular.bind(specular_channel);
|
||||
}
|
||||
|
||||
public boolean isTransparent(){
|
||||
return hasTransparency;
|
||||
}
|
||||
}
|
||||
537
src/main/java/RendererObjects/Mesh.java
Normal file
@ -0,0 +1,537 @@
|
||||
package RendererObjects;
|
||||
|
||||
import main.Globals;
|
||||
import main.Main;
|
||||
import RendererObjects.Light.LightBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIBone;
|
||||
import org.lwjgl.assimp.AIFace;
|
||||
import org.lwjgl.assimp.AIMesh;
|
||||
import org.lwjgl.assimp.AIVector2D;
|
||||
import org.lwjgl.assimp.AIVector3D;
|
||||
import org.lwjgl.assimp.AIVertexWeight;
|
||||
import static org.lwjgl.opengl.ARBVertexBufferObject.*;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import static org.lwjgl.opengl.GL11.GL_FALSE;
|
||||
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
||||
import static org.lwjgl.opengl.GL11.GL_INT;
|
||||
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
|
||||
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
|
||||
import static org.lwjgl.opengl.GL15.GL_ELEMENT_ARRAY_BUFFER;
|
||||
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
|
||||
import static org.lwjgl.opengl.GL15.glBindBuffer;
|
||||
import static org.lwjgl.opengl.GL15.glGenBuffers;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||
import static org.lwjgl.opengl.GL20.glUniform3fv;
|
||||
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
||||
import static org.lwjgl.opengl.GL20.glUseProgram;
|
||||
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
||||
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class Mesh {
|
||||
public Model parent;
|
||||
public String nodeID;
|
||||
public AIMesh mesh;
|
||||
public int vertexBuffer;
|
||||
public int normalBuffer;
|
||||
public int elementArrayBuffer;
|
||||
public int elementCount;
|
||||
public int faceCount;
|
||||
public int vertexArrayObject;
|
||||
public int vertexCount;
|
||||
public int normalCount;
|
||||
public int boneWeightBuffer;
|
||||
public int boneIndexBuffer;
|
||||
public int boneCount;
|
||||
public int textureCoordBuffer;
|
||||
public int textureCoordCount;
|
||||
public ArrayList<Bone> bones = new ArrayList();
|
||||
public ArrayList<String> bone_id_list = new ArrayList();
|
||||
int bone_map_size = 0;
|
||||
boolean hasBones = true;
|
||||
public boolean hasTextureCoords = true;
|
||||
|
||||
|
||||
public ShaderProgram shader;
|
||||
|
||||
int shaderBoneArrayLocation;
|
||||
|
||||
Material material;
|
||||
|
||||
LightBuffer light_buffer;
|
||||
|
||||
public static Mesh create_mesh_from_aimesh(AIMesh mesh){
|
||||
boolean has_bones = false;
|
||||
boolean apply_lighting = true;
|
||||
|
||||
Mesh rVal = new Mesh();
|
||||
rVal.mesh = mesh;
|
||||
|
||||
//
|
||||
// VAO
|
||||
//
|
||||
rVal.vertexArrayObject = glGenVertexArrays();
|
||||
glBindVertexArray(rVal.vertexArrayObject);
|
||||
|
||||
|
||||
|
||||
//Basic checks
|
||||
//check num vertices
|
||||
int numVertices = 0;
|
||||
AIVector3D.Buffer vertexData = mesh.mVertices();
|
||||
while(vertexData.hasRemaining()){
|
||||
vertexData.get();
|
||||
numVertices++;
|
||||
}
|
||||
vertexData = vertexData.rewind();
|
||||
//check num normals
|
||||
int numNormals = 0;
|
||||
AIVector3D.Buffer normalData = mesh.mNormals();
|
||||
while(normalData.hasRemaining()){
|
||||
normalData.get();
|
||||
numNormals++;
|
||||
}
|
||||
normalData.rewind();
|
||||
if(numVertices != numNormals){
|
||||
System.out.println("Catastrophic failure: Number of vertices =/= Number of normals");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Buffer data to GPU
|
||||
//
|
||||
vertexData.rewind();
|
||||
|
||||
try {
|
||||
rVal.vertexCount = mesh.mNumVertices();
|
||||
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(rVal.vertexCount * 3);
|
||||
float[] temp = new float[3];
|
||||
for (int i = 0; i < rVal.vertexCount; i++) {
|
||||
AIVector3D vertex = vertexData.get();
|
||||
temp[0] = vertex.x();
|
||||
temp[1] = vertex.y();
|
||||
temp[2] = vertex.z();
|
||||
VertexArrayBufferData.put(temp);
|
||||
}
|
||||
VertexArrayBufferData.flip();
|
||||
rVal.buffer_vertices(VertexArrayBufferData);
|
||||
} catch (NullPointerException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
//
|
||||
// NORMALS
|
||||
//
|
||||
AIVector3D.Buffer normals = mesh.mNormals();
|
||||
try {
|
||||
rVal.normalCount = mesh.mNumVertices();
|
||||
FloatBuffer NormalArrayBufferData;
|
||||
if(rVal.normalCount > 0){
|
||||
NormalArrayBufferData = BufferUtils.createFloatBuffer(rVal.normalCount * 3);
|
||||
float[] temp = new float[3];
|
||||
for (int i = 0; i < rVal.normalCount; i++) {
|
||||
AIVector3D normal = normals.get(i);
|
||||
temp[0] = normal.x();
|
||||
temp[1] = normal.y();
|
||||
temp[2] = normal.z();
|
||||
NormalArrayBufferData.put(temp);
|
||||
}
|
||||
NormalArrayBufferData.flip();
|
||||
rVal.buffer_normals(NormalArrayBufferData);
|
||||
}
|
||||
} catch (NullPointerException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
//
|
||||
// FACES
|
||||
//
|
||||
rVal.faceCount = mesh.mNumFaces();
|
||||
rVal.elementCount = rVal.faceCount * 3;
|
||||
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(rVal.elementCount);
|
||||
AIFace.Buffer facesBuffer = mesh.mFaces();
|
||||
for(int i = 0; i < rVal.faceCount; i++){
|
||||
AIFace face = facesBuffer.get(i);
|
||||
if(face.mNumIndices() != 3){
|
||||
throw new IllegalStateException("AIFace.mNumIndices() != 3");
|
||||
}
|
||||
elementArrayBufferData.put(face.mIndices());
|
||||
}
|
||||
elementArrayBufferData.flip();
|
||||
rVal.buffer_faces(elementArrayBufferData);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// TEXTURE COORDINATES
|
||||
//
|
||||
if(mesh.mTextureCoords().capacity() > 0){
|
||||
AIVector3D.Buffer texturecoords = mesh.mTextureCoords(0);
|
||||
try {
|
||||
rVal.textureCoordCount = mesh.mTextureCoords(0).capacity();
|
||||
FloatBuffer TextureArrayBufferData;
|
||||
if(rVal.textureCoordCount > 0){
|
||||
TextureArrayBufferData = BufferUtils.createFloatBuffer(rVal.textureCoordCount * 2);
|
||||
float[] temp = new float[2];
|
||||
for (int i = 0; i < rVal.textureCoordCount; i++) {
|
||||
AIVector3D normal = texturecoords.get(i);
|
||||
temp[0] = normal.x();
|
||||
temp[1] = normal.y();
|
||||
// temp[2] = normal.z();
|
||||
TextureArrayBufferData.put(temp);
|
||||
}
|
||||
TextureArrayBufferData.flip();
|
||||
rVal.buffer_texture_coords(TextureArrayBufferData);
|
||||
}
|
||||
} catch (NullPointerException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
//System.out.println("Enabled texture coordinates");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Read in bones
|
||||
//AND buffer data (weights) to GPU
|
||||
//
|
||||
PointerBuffer boneBuffer = mesh.mBones();
|
||||
if(boneBuffer != null){
|
||||
has_bones = true;
|
||||
while(boneBuffer.hasRemaining()){
|
||||
long currentAddr = boneBuffer.get();
|
||||
AIBone currentBoneData = AIBone.createSafe(currentAddr);
|
||||
// System.out.println("Num weights: " + currentBoneData.mNumWeights());
|
||||
Bone currentBone = new Bone();
|
||||
currentBone.boneID = currentBoneData.mName().dataString();
|
||||
currentBone.inverseBindPoseMatrix = util.util.convertAIMatrix(currentBoneData.mOffsetMatrix());
|
||||
currentBone.numWeights = currentBoneData.mNumWeights();
|
||||
currentBone.weights = new HashMap();
|
||||
Iterator<AIVertexWeight> weightIterator = currentBoneData.mWeights().iterator();
|
||||
while(weightIterator.hasNext()){
|
||||
AIVertexWeight currentWeightData = weightIterator.next();
|
||||
currentBone.weights.put(currentWeightData.mVertexId(), currentWeightData.mWeight());
|
||||
}
|
||||
rVal.bones.add(currentBone);
|
||||
rVal.bone_id_list.add(currentBone.boneID);
|
||||
}
|
||||
rVal.boneCount = rVal.bones.size();
|
||||
FloatBuffer boneWeightDataBuffer = BufferUtils.createFloatBuffer(4 * rVal.vertexCount);//FloatBuffer.allocate(4 * vertexCount);
|
||||
FloatBuffer boneIndexDataBuffer = BufferUtils.createFloatBuffer(4 * rVal.vertexCount);//IntBuffer.allocate(4 * vertexCount);
|
||||
Iterator<Bone> boneIterator;
|
||||
for(int i = 0; i < rVal.vertexCount; i++){
|
||||
float[] weight = new float[4];
|
||||
float[] index = new float[4];
|
||||
int boneCounter = 0;
|
||||
boneIterator = rVal.bones.iterator();
|
||||
while(boneIterator.hasNext()){
|
||||
Bone currentBone = boneIterator.next();
|
||||
float boneVal = 0;
|
||||
if(currentBone.weights.get(i) != null){
|
||||
boneVal = currentBone.weights.get(i);
|
||||
}
|
||||
if(boneVal > 0){
|
||||
if(boneVal > weight[0]){
|
||||
weight[3] = weight[2];
|
||||
weight[2] = weight[1];
|
||||
weight[1] = weight[0];
|
||||
weight[0] = boneVal;
|
||||
index[3] = index[2];
|
||||
index[2] = index[1];
|
||||
index[1] = index[0];
|
||||
index[0] = boneCounter;
|
||||
} else if(boneVal > weight[1]){
|
||||
weight[3] = weight[2];
|
||||
weight[2] = weight[1];
|
||||
weight[1] = boneVal;
|
||||
index[3] = index[2];
|
||||
index[2] = index[1];
|
||||
index[1] = boneCounter;
|
||||
} else if(boneVal > weight[2]){
|
||||
weight[3] = weight[2];
|
||||
weight[2] = boneVal;
|
||||
index[3] = index[2];
|
||||
index[2] = boneCounter;
|
||||
} else if(boneVal > weight[3]){
|
||||
weight[3] = boneVal;
|
||||
index[3] = boneCounter;
|
||||
}
|
||||
}
|
||||
boneCounter++;
|
||||
}
|
||||
float total = weight[0] + weight[1] + weight[2] + weight[3];
|
||||
if(total != 1.0f){
|
||||
weight[0] = weight[0] * (1.0f / total);
|
||||
weight[1] = weight[1] * (1.0f / total);
|
||||
weight[2] = weight[2] * (1.0f / total);
|
||||
weight[3] = weight[3] * (1.0f / total);
|
||||
}
|
||||
boneIndexDataBuffer.put(index);
|
||||
boneWeightDataBuffer.put(weight);
|
||||
}
|
||||
boneIndexDataBuffer.flip();
|
||||
boneWeightDataBuffer.flip();
|
||||
|
||||
|
||||
rVal.boneWeightBuffer = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, rVal.boneWeightBuffer);
|
||||
GL15.glBufferData(GL_ARRAY_BUFFER, boneWeightDataBuffer, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(2, 4, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(2);
|
||||
|
||||
|
||||
rVal.boneIndexBuffer = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, rVal.boneIndexBuffer);
|
||||
GL15.glBufferData(GL_ARRAY_BUFFER, boneIndexDataBuffer, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(3, 4, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(3);
|
||||
} else {
|
||||
rVal.hasBones = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rVal.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
rVal.nodeID = mesh.mName().dataString();
|
||||
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
public Mesh(){
|
||||
|
||||
}
|
||||
|
||||
public void draw() {
|
||||
glUseProgram(shader.shaderProgram);
|
||||
|
||||
//Until we switch to uniform buffer objects we will have to buffer lighting data here manually each time we draw
|
||||
//side note: :(
|
||||
if(light_buffer == null){
|
||||
float temp[] = new float[3];
|
||||
temp[0] = 0.2f;
|
||||
temp[1] = -1.0f;
|
||||
temp[2] = 0.3f;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.direction"), temp);
|
||||
|
||||
temp[0] = 0.1f;
|
||||
temp[1] = 0.1f;
|
||||
temp[2] = 0.1f;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.ambient"), temp);
|
||||
|
||||
temp[0] = 0.8f;
|
||||
temp[1] = 0.8f;
|
||||
temp[2] = 0.8f;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.diffuse"), temp);
|
||||
|
||||
temp[0] = 0.1f;
|
||||
temp[1] = 0.1f;
|
||||
temp[2] = 0.1f;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.specular"), temp);
|
||||
|
||||
temp[0] = 32f;
|
||||
glUniform1fv(glGetUniformLocation(shader.shaderProgram, "material.shininess"), temp);
|
||||
|
||||
GL20.glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, "model"), false, parent.modelMatrix.get(new float[16]));
|
||||
|
||||
Vector3f cam_Loc = Globals.camera_visible.pos_Center;
|
||||
temp[0] = cam_Loc.x;
|
||||
temp[1] = cam_Loc.y;
|
||||
temp[2] = cam_Loc.z;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "viewPos"), temp);
|
||||
} else {
|
||||
GL20.glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, "model"), false, parent.modelMatrix.get(new float[16]));
|
||||
}
|
||||
|
||||
|
||||
if(material == null){
|
||||
Globals.material_default.apply_material(0,1);
|
||||
GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 0);
|
||||
} else {
|
||||
material.apply_material();
|
||||
if(material.hasTransparency){
|
||||
GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 1);
|
||||
} else {
|
||||
GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 1);
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(vertexArrayObject);
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Handle bones
|
||||
//
|
||||
if(bones != null && !bones.isEmpty()){
|
||||
glUniform1i(shader.shaderVertexHasBonesLoc, 1);
|
||||
glUniform1i(shader.shaderVertexNumBonesLoc, bones.size());
|
||||
Iterator<String> boneIterator = bone_id_list.iterator();
|
||||
float bufferarray[] = new float[16];
|
||||
int incrementer = 0;
|
||||
while (boneIterator.hasNext()){
|
||||
Bone currentBone = parent.boneMap.get(boneIterator.next());
|
||||
Matrix4f currentMat = new Matrix4f(currentBone.final_transform);
|
||||
currentMat.get(bufferarray);
|
||||
String currentUniform = "bones[" + incrementer + "]";
|
||||
GL20.glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, currentUniform), false, bufferarray);
|
||||
incrementer++;
|
||||
}
|
||||
} else {
|
||||
glUniform1i(shader.shaderVertexHasBonesLoc, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//buffer model/view/proj matrices
|
||||
glUniformMatrix4fv(shader.shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
|
||||
glUniformMatrix4fv(shader.shaderVertexViewLoc, false, Globals.viewMatrix.get(new float[16]));
|
||||
glUniformMatrix4fv(shader.shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16]));
|
||||
glUniform3fv(shader.shaderVertexViewPosLoc, Globals.camera_visible.pos_Center.get(BufferUtils.createFloatBuffer(3)));
|
||||
|
||||
//
|
||||
//
|
||||
//Testing Lights
|
||||
//
|
||||
//
|
||||
float test_Light_Data[] = new float[3];
|
||||
test_Light_Data[0] = 0.2f;
|
||||
test_Light_Data[1] = -1.0f;
|
||||
test_Light_Data[2] = 0.3f;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.direction"), test_Light_Data);
|
||||
|
||||
test_Light_Data = new float[3];
|
||||
test_Light_Data[0] = 0.3f;
|
||||
test_Light_Data[1] = 0.3f;
|
||||
test_Light_Data[2] = 0.3f;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.ambient"), test_Light_Data);
|
||||
|
||||
test_Light_Data = new float[3];
|
||||
test_Light_Data[0] = 0.5f;
|
||||
test_Light_Data[1] = 0.5f;
|
||||
test_Light_Data[2] = 0.5f;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.diffuse"), test_Light_Data);
|
||||
|
||||
Vector3f cam_Loc = Globals.camera_visible.pos_Center;
|
||||
test_Light_Data = new float[3];
|
||||
test_Light_Data[0] = cam_Loc.x;
|
||||
test_Light_Data[1] = cam_Loc.y;
|
||||
test_Light_Data[2] = cam_Loc.z;
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "viewPos"), test_Light_Data);
|
||||
|
||||
|
||||
GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
public void buffer_vertices(FloatBuffer verticies){
|
||||
vertexBuffer = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
GL15.glBufferData(GL_ARRAY_BUFFER, verticies, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(0);
|
||||
}
|
||||
|
||||
public void buffer_normals(FloatBuffer normals){
|
||||
normalBuffer = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
|
||||
GL15.glBufferData(GL_ARRAY_BUFFER, normals, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(1, 3, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(1);
|
||||
}
|
||||
|
||||
public void buffer_faces(IntBuffer faces){
|
||||
elementArrayBuffer = glGenBuffers();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
|
||||
GL15.glBufferData(GL_ELEMENT_ARRAY_BUFFER, faces, GL_STATIC_DRAW);
|
||||
elementCount = faces.capacity();
|
||||
}
|
||||
|
||||
public void buffer_texture_coords(FloatBuffer coords){
|
||||
textureCoordBuffer = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, textureCoordBuffer);
|
||||
GL15.glBufferData(GL_ARRAY_BUFFER, coords, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(4, 2, GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(4);
|
||||
}
|
||||
|
||||
public void set_material(Material input){
|
||||
this.material = input;
|
||||
}
|
||||
}
|
||||
335
src/main/java/RendererObjects/Model.java
Normal file
@ -0,0 +1,335 @@
|
||||
package RendererObjects;
|
||||
|
||||
import main.Globals;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.PointerBuffer;
|
||||
import org.lwjgl.assimp.AIMaterial;
|
||||
import org.lwjgl.assimp.AIMesh;
|
||||
import org.lwjgl.assimp.AIScene;
|
||||
import static org.lwjgl.assimp.Assimp.*;
|
||||
import static org.lwjgl.opengl.ARBVertexBufferObject.*;
|
||||
import static org.lwjgl.opengl.ARBVertexProgram.*;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL13.*;
|
||||
import static org.lwjgl.opengl.GL15.*;
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
import RendererObjects.texture.TextureMap;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Stack;
|
||||
import org.joml.Quaternionf;
|
||||
import org.lwjgl.assimp.AIAnimation;
|
||||
import org.lwjgl.assimp.AIBone;
|
||||
import org.lwjgl.assimp.AINode;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author satellite
|
||||
*/
|
||||
public class Model {
|
||||
public boolean is_Ready_To_Display = false;
|
||||
public AIScene scene;
|
||||
public ArrayList<Mesh> meshes;
|
||||
public ArrayList<Animation> animations;
|
||||
public ArrayList<Bone> bones;
|
||||
public HashMap<String,Bone> boneMap;
|
||||
public HashMap<String,AnimNode> node_map;
|
||||
public ArrayList<Material> materials;
|
||||
public Matrix4f modelMatrix = new Matrix4f();
|
||||
ShaderProgram program;
|
||||
public Animation currentAnimation;
|
||||
public Matrix4f globalInverseTransform;
|
||||
|
||||
AnimNode root_anim_node;
|
||||
|
||||
public static Model create_model_from_aiscene(AIScene s){
|
||||
Model rVal = new Model();
|
||||
//
|
||||
//set the scene
|
||||
//
|
||||
rVal.scene = s;
|
||||
|
||||
//
|
||||
//load meshes
|
||||
//
|
||||
int meshCount = s.mNumMeshes();
|
||||
PointerBuffer meshesBuffer = s.mMeshes();
|
||||
rVal.meshes = new ArrayList();
|
||||
while(meshesBuffer.hasRemaining()){
|
||||
Mesh currentMesh = Mesh.create_mesh_from_aimesh(AIMesh.create(meshesBuffer.get()));
|
||||
rVal.meshes.add(currentMesh);
|
||||
currentMesh.parent = rVal;
|
||||
}
|
||||
//
|
||||
//register bones
|
||||
//
|
||||
rVal.bones = new ArrayList();
|
||||
rVal.boneMap = new HashMap();
|
||||
meshesBuffer.rewind();
|
||||
while(meshesBuffer.hasRemaining()){
|
||||
AIMesh currentMeshData = AIMesh.createSafe(meshesBuffer.get());
|
||||
PointerBuffer boneBuffer = currentMeshData.mBones();
|
||||
for(int j = 0; j < currentMeshData.mNumBones(); j++){
|
||||
AIBone currentBone = AIBone.createSafe(boneBuffer.get());
|
||||
String currentBoneName = currentBone.mName().dataString();
|
||||
if(!rVal.boneMap.containsKey(currentBoneName)){
|
||||
Bone boneObject = new Bone(currentBone);
|
||||
rVal.boneMap.put(currentBoneName, boneObject);
|
||||
rVal.bones.add(boneObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
Iterator<Mesh> meshIterator = rVal.meshes.iterator();
|
||||
rVal.bones = new ArrayList();
|
||||
rVal.boneMap = new HashMap();
|
||||
rVal.node_map = new HashMap();
|
||||
while(meshIterator.hasNext()){
|
||||
Mesh currentMesh = meshIterator.next();
|
||||
Iterator<Bone> boneIterator = currentMesh.bones.iterator();
|
||||
ArrayList<Bone> to_remove_queue = new ArrayList();
|
||||
ArrayList<Bone> to_add_queue = new ArrayList();
|
||||
while(boneIterator.hasNext()){
|
||||
Bone currentBone = boneIterator.next();
|
||||
if(!rVal.boneMap.containsKey(currentBone.boneID)){
|
||||
rVal.bones.add(currentBone);
|
||||
rVal.boneMap.put(currentBone.boneID, currentBone);
|
||||
}
|
||||
}
|
||||
boneIterator = to_remove_queue.iterator();
|
||||
while(boneIterator.hasNext()){
|
||||
currentMesh.bones.remove(boneIterator.next());
|
||||
}
|
||||
boneIterator = to_add_queue.iterator();
|
||||
while(boneIterator.hasNext()){
|
||||
currentMesh.bones.add(boneIterator.next());
|
||||
}
|
||||
}
|
||||
//
|
||||
//parse animation nodes and form hierarchy
|
||||
//
|
||||
AINode rootNode = s.mRootNode();
|
||||
rVal.globalInverseTransform = util.util.convertAIMatrix(rootNode.mTransformation());
|
||||
// System.out.println("Global inverse transform");
|
||||
// System.out.println(globalInverseTransform);
|
||||
rVal.root_anim_node = rVal.build_anim_node_map(s.mRootNode(),null);
|
||||
//
|
||||
//load animations
|
||||
//
|
||||
int animCount = s.mNumAnimations();
|
||||
PointerBuffer animBuffer = s.mAnimations();
|
||||
rVal.animations = new ArrayList();
|
||||
for(int i = 0; i < animCount; i++){
|
||||
rVal.animations.add(new Animation(AIAnimation.create(animBuffer.get(i)), i));
|
||||
}
|
||||
//
|
||||
//Load materials
|
||||
//
|
||||
if(s.mNumMaterials() > 0){
|
||||
rVal.materials = new ArrayList();
|
||||
PointerBuffer material_buffer = s.mMaterials();
|
||||
while(material_buffer.hasRemaining()){
|
||||
rVal.materials.add(Material.load_material_from_aimaterial(AIMaterial.create(material_buffer.get())));
|
||||
}
|
||||
}
|
||||
//garbage collect
|
||||
System.gc();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public Model(){
|
||||
/*
|
||||
public boolean is_Ready_To_Display = false;
|
||||
public AIScene scene;
|
||||
public ArrayList<Mesh> meshes;
|
||||
public ArrayList<Animation> animations;
|
||||
public ArrayList<Bone> bones;
|
||||
public HashMap<String,Bone> boneMap;
|
||||
public HashMap<String,AnimNode> node_map = new HashMap();
|
||||
public ArrayList<Material> materials;
|
||||
public Matrix4f modelMatrix = new Matrix4f().translation(new Vector3f(0,0,0));
|
||||
ShaderProgram program;
|
||||
public Animation currentAnimation;
|
||||
public Matrix4f globalInverseTransform;
|
||||
*/
|
||||
scene = null;
|
||||
meshes = null;
|
||||
animations = null;
|
||||
bones = null;
|
||||
boneMap = null;
|
||||
node_map = null;
|
||||
materials = null;
|
||||
modelMatrix = new Matrix4f();
|
||||
program = null;
|
||||
currentAnimation = null;
|
||||
globalInverseTransform = null;
|
||||
}
|
||||
|
||||
public void free() {
|
||||
aiReleaseImport(scene);
|
||||
scene = null;
|
||||
meshes = null;
|
||||
}
|
||||
|
||||
public void draw(){
|
||||
if(node_map != null && !node_map.isEmpty()){
|
||||
update_node_transform(root_anim_node);
|
||||
}
|
||||
Iterator<Mesh> mesh_Iterator = meshes.iterator();
|
||||
while(mesh_Iterator.hasNext()){
|
||||
Mesh currentMesh = mesh_Iterator.next();
|
||||
currentMesh.draw();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void playAnimation(String s){
|
||||
this.currentAnimation = null;
|
||||
Iterator<Animation> animationIterator = animations.iterator();
|
||||
while(animationIterator.hasNext()){
|
||||
Animation current_iterator_item = animationIterator.next();
|
||||
if(current_iterator_item.name.equals(s)){
|
||||
this.currentAnimation = current_iterator_item;
|
||||
}
|
||||
}
|
||||
if(currentAnimation != null){
|
||||
currentAnimation.timeCurrent = 0;
|
||||
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
while(channelIterator.hasNext()){
|
||||
AnimChannel currentChannel = channelIterator.next();
|
||||
currentChannel.rewind();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void incrementTime(double time){
|
||||
boolean isDone = currentAnimation.incrementTime(time);
|
||||
if(isDone){
|
||||
currentAnimation.timeCurrent = 0;
|
||||
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
while(channelIterator.hasNext()){
|
||||
AnimChannel currentChannel = channelIterator.next();
|
||||
currentChannel.rewind();
|
||||
}
|
||||
Iterator<Bone> boneIterator = bones.iterator();
|
||||
while(boneIterator.hasNext()){
|
||||
Bone currentBone = boneIterator.next();
|
||||
currentBone.transform = new Matrix4f();
|
||||
}
|
||||
currentAnimation = null;
|
||||
} else {
|
||||
//First we push transformFromParent into deform so that later in the pipeline bones without a current animation take on transformFromParent as their transformation to the hierarchy
|
||||
//I BELIEVE this is so that control bones still apply their offset to the hierarchy even when they're not animated :tm:
|
||||
//4/5/20
|
||||
Iterator<Bone> boneIterator = bones.iterator();
|
||||
while(boneIterator.hasNext()){
|
||||
Bone currentBone = boneIterator.next();
|
||||
// currentBone.deform = currentBone.transformFromParent;
|
||||
}
|
||||
//Once that's done, for every channel we set the corresponding bone's deform to the channels TRS
|
||||
Iterator<AnimChannel> channelIterator = currentAnimation.channels.iterator();
|
||||
while(channelIterator.hasNext()){
|
||||
AnimChannel currentChannel = channelIterator.next();
|
||||
currentChannel.incrementTime(time);
|
||||
Bone currentBone = boneMap.get(currentChannel.nodeID);
|
||||
if(currentBone != null){
|
||||
//T * S * R
|
||||
currentBone.deform = new Matrix4f();
|
||||
currentBone.deform.translate(currentChannel.getCurrentPosition());
|
||||
currentBone.deform.rotate(currentChannel.getCurrentRotation());
|
||||
currentBone.deform.scale(currentChannel.getCurrentScale());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void describeAllAnimations(){
|
||||
if(animations.size() > 0){
|
||||
System.out.println("=====================");
|
||||
System.out.println(animations.size() + " animations available in model!");
|
||||
Iterator<Animation> animIterator = animations.iterator();
|
||||
while(animIterator.hasNext()){
|
||||
Animation currentAnim = animIterator.next();
|
||||
currentAnim.describeAnimation();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final AnimNode build_anim_node_map(AINode node, AnimNode parent){
|
||||
AnimNode node_object = new AnimNode(node.mName().dataString(), parent, node);
|
||||
node_map.put(node_object.id, node_object);
|
||||
if(boneMap.containsKey(node_object.id)){
|
||||
node_object.is_bone = true;
|
||||
}
|
||||
int num_children = node.mNumChildren();
|
||||
for(int i = 0; i < num_children; i++){
|
||||
AnimNode temp_child = build_anim_node_map(AINode.create(node.mChildren().get(i)),node_object);
|
||||
// if(boneMap.containsKey(node_object.id)){
|
||||
// Bone parent_bone = boneMap.get(node_object.id);
|
||||
// node_object.children.add(temp_child);
|
||||
// if(boneMap.containsKey(temp_child.id)){
|
||||
// Bone child_bone = boneMap.get(temp_child.id);
|
||||
// parent_bone.children.add(child_bone);
|
||||
// child_bone.parent = parent_bone;
|
||||
// }
|
||||
// }
|
||||
node_object.children.add(temp_child);
|
||||
}
|
||||
return node_object;
|
||||
}
|
||||
|
||||
public void update_node_transform(AnimNode n){
|
||||
if(n.parent != null){
|
||||
n.transform = new Matrix4f(n.parent.transform);
|
||||
} else {
|
||||
n.transform = new Matrix4f();
|
||||
}
|
||||
if(n.is_bone){
|
||||
/*
|
||||
Bone bone = boneList.get(j);
|
||||
Node node = rootNode.findByName(bone.getBoneName());
|
||||
Matrix4f boneMatrix = Node.getParentTransforms(node, i);
|
||||
boneMatrix.mul(bone.getOffsetMatrix());
|
||||
boneMatrix = new Matrix4f(rootTransformation).mul(boneMatrix);
|
||||
frame.setMatrix(j, boneMatrix);
|
||||
*/
|
||||
Bone target_bone = boneMap.get(n.id);
|
||||
n.transform = n.transform.mul(target_bone.deform);
|
||||
Matrix4f bone_matrix = new Matrix4f(n.transform).mul(target_bone.inverseBindPoseMatrix);
|
||||
bone_matrix = new Matrix4f(globalInverseTransform).mul(bone_matrix);
|
||||
target_bone.final_transform = bone_matrix;
|
||||
// if(!toggled){
|
||||
// System.out.println(n.id);
|
||||
// System.out.println("Transform:");
|
||||
// System.out.println(n.parent.transform);
|
||||
// System.out.println(target_bone.deform);
|
||||
// System.out.println(n.transform);
|
||||
// System.out.println("Final transform:");
|
||||
// System.out.println(globalInverseTransform);
|
||||
// System.out.println(n.transform);
|
||||
// System.out.println(target_bone.inverseBindPoseMatrix);
|
||||
// System.out.println(target_bone.final_transform);
|
||||
// System.out.println("\n\n\n\n");
|
||||
// }
|
||||
} else {
|
||||
n.transform = n.transform.mul(util.util.convertAIMatrix(n.raw_data.mTransformation()));
|
||||
}
|
||||
Iterator<AnimNode> node_iterator = n.children.iterator();
|
||||
while(node_iterator.hasNext()){
|
||||
AnimNode current_node = node_iterator.next();
|
||||
update_node_transform(current_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
279
src/main/java/RendererObjects/RenderUtils.java
Normal file
@ -0,0 +1,279 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package RendererObjects;
|
||||
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import main.Globals;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
||||
import static org.lwjgl.opengl.GL11.GL_INT;
|
||||
import static org.lwjgl.opengl.GL11.GL_LEQUAL;
|
||||
import static org.lwjgl.opengl.GL11.GL_LESS;
|
||||
import static org.lwjgl.opengl.GL11.GL_SHORT;
|
||||
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
|
||||
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
|
||||
import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
|
||||
import static org.lwjgl.opengl.GL15.glBindBuffer;
|
||||
import static org.lwjgl.opengl.GL15.glGenBuffers;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray;
|
||||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1fv;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||
import static org.lwjgl.opengl.GL20.glUniform3fv;
|
||||
import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
||||
import static org.lwjgl.opengl.GL20.glUseProgram;
|
||||
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
||||
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class RenderUtils {
|
||||
public static Model createSkyboxModel(Material optionalMaterial){
|
||||
Model skybox_model = new Model();
|
||||
skybox_model.meshes = new ArrayList();
|
||||
|
||||
skybox_model.modelMatrix = new Matrix4f();
|
||||
|
||||
|
||||
|
||||
boolean apply_lighting = false;
|
||||
boolean has_bones = false;
|
||||
|
||||
Mesh skyboxmesh = new Mesh(){
|
||||
@Override
|
||||
public void draw(){
|
||||
GL11.glDepthFunc(GL_LEQUAL);
|
||||
glUseProgram(shader.shaderProgram);
|
||||
|
||||
if(material == null){
|
||||
Globals.material_default.apply_material(0,1);
|
||||
Iterator<Vector3f> colorIterator = Globals.skybox_colors.iterator();
|
||||
int counter = 0;
|
||||
float[] temp = new float[3];
|
||||
while(colorIterator.hasNext()){
|
||||
Vector3f colorCurrent = colorIterator.next();
|
||||
temp[0] = colorCurrent.x / 255.0f;
|
||||
temp[1] = colorCurrent.y / 255.0f;
|
||||
temp[2] = colorCurrent.z / 255.0f;
|
||||
// System.out.println("colors[" + counter + "] " + temp[0] + " " + temp[1] + " " + temp[2]);
|
||||
glUniform3fv(glGetUniformLocation(shader.shaderProgram, "colors[" + counter + "]"), temp);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
|
||||
glBindVertexArray(vertexArrayObject);
|
||||
|
||||
|
||||
|
||||
|
||||
//buffer model/view/proj matrices
|
||||
glUniformMatrix4fv(shader.shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
|
||||
glUniformMatrix4fv(shader.shaderVertexViewLoc, false, new Matrix4f(Globals.viewMatrix).scale(100).get(new float[16]));
|
||||
glUniformMatrix4fv(shader.shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16]));
|
||||
glUniform3fv(shader.shaderVertexViewPosLoc, Globals.camera_visible.pos_Center.get(BufferUtils.createFloatBuffer(3)));
|
||||
|
||||
|
||||
GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
GL11.glDepthFunc(GL_LESS);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
skyboxmesh.mesh = null;
|
||||
|
||||
//
|
||||
// VAO
|
||||
//
|
||||
skyboxmesh.vertexArrayObject = glGenVertexArrays();
|
||||
glBindVertexArray(skyboxmesh.vertexArrayObject);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
float[] vertexcoords = {
|
||||
1.0f,1.0f,1.0f,
|
||||
1.0f,1.0f,-1.0f,
|
||||
1.0f,-1.0f,1.0f,
|
||||
1.0f,-1.0f,-1.0f,
|
||||
-1.0f,1.0f,1.0f,
|
||||
-1.0f,1.0f,-1.0f,
|
||||
-1.0f,-1.0f,1.0f,
|
||||
-1.0f,-1.0f,-1.0f,
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
//Buffer data to GPU
|
||||
//
|
||||
|
||||
try {
|
||||
skyboxmesh.vertexCount = vertexcoords.length / 3;
|
||||
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.vertexCount * 3);
|
||||
float[] temp = new float[3];
|
||||
for (int i = 0; i < skyboxmesh.vertexCount; i++) {
|
||||
temp[0] = vertexcoords[i * 3 + 0];
|
||||
temp[1] = vertexcoords[i * 3 + 1];
|
||||
temp[2] = vertexcoords[i * 3 + 2];
|
||||
VertexArrayBufferData.put(temp);
|
||||
}
|
||||
VertexArrayBufferData.flip();
|
||||
skyboxmesh.buffer_vertices(VertexArrayBufferData);
|
||||
} catch (NullPointerException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
int[] facedata = {
|
||||
0,1,4,
|
||||
1,4,5,
|
||||
1,3,5,
|
||||
3,5,7,
|
||||
4,5,7,
|
||||
4,6,7,
|
||||
|
||||
0,2,4,
|
||||
2,4,6,
|
||||
0,1,2,
|
||||
1,2,3,
|
||||
|
||||
2,3,6,
|
||||
3,6,7,
|
||||
|
||||
};
|
||||
|
||||
//
|
||||
// FACES
|
||||
//
|
||||
skyboxmesh.faceCount = facedata.length / 3;
|
||||
skyboxmesh.elementCount = facedata.length;
|
||||
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(skyboxmesh.elementCount);
|
||||
for(int i = 0; i < skyboxmesh.faceCount; i++){
|
||||
int[] temp = new int[3];
|
||||
temp[0] = facedata[i * 3 + 0];
|
||||
temp[1] = facedata[i * 3 + 1];
|
||||
temp[2] = facedata[i * 3 + 2];
|
||||
elementArrayBufferData.put(temp);
|
||||
}
|
||||
elementArrayBufferData.flip();
|
||||
skyboxmesh.buffer_faces(elementArrayBufferData);
|
||||
|
||||
|
||||
|
||||
|
||||
if(optionalMaterial != null){
|
||||
//
|
||||
// NORMALS
|
||||
//
|
||||
try {
|
||||
skyboxmesh.normalCount = vertexcoords.length / 3;
|
||||
FloatBuffer NormalArrayBufferData;
|
||||
if(skyboxmesh.normalCount > 0){
|
||||
NormalArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.normalCount * 3);
|
||||
float[] temp = new float[3];
|
||||
for (int i = 0; i < skyboxmesh.normalCount; i++) {
|
||||
temp[0] = vertexcoords[i * 3 + 0];
|
||||
temp[1] = vertexcoords[i * 3 + 1];
|
||||
temp[2] = vertexcoords[i * 3 + 2];
|
||||
NormalArrayBufferData.put(temp);
|
||||
}
|
||||
NormalArrayBufferData.flip();
|
||||
skyboxmesh.buffer_normals(NormalArrayBufferData);
|
||||
}
|
||||
} catch (NullPointerException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
//
|
||||
// TEXTURE COORDINATES
|
||||
//
|
||||
/*try {
|
||||
skyboxmesh.textureCoordCount = mesh.mTextureCoords(0).capacity();
|
||||
FloatBuffer TextureArrayBufferData;
|
||||
if(skyboxmesh.textureCoordCount > 0){
|
||||
TextureArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.textureCoordCount * 2);
|
||||
float[] temp = new float[2];
|
||||
for (int i = 0; i < skyboxmesh.textureCoordCount; i++) {
|
||||
AIVector3D normal = texturecoords.get(i);
|
||||
temp[0] = normal.x();
|
||||
temp[1] = normal.y();
|
||||
// temp[2] = normal.z();
|
||||
TextureArrayBufferData.put(temp);
|
||||
}
|
||||
TextureArrayBufferData.flip();
|
||||
skyboxmesh.buffer_texture_coords(TextureArrayBufferData);
|
||||
}
|
||||
} catch (NullPointerException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
skyboxmesh.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting);
|
||||
|
||||
skybox_model.materials.add(optionalMaterial);
|
||||
*/
|
||||
} else {
|
||||
skyboxmesh.shader = ShaderProgram.loadSpecificShader("/Shaders/skybox/VertexShaderNoTexture.vs", "/Shaders/skybox/FragmentShaderNoTexture.fs");
|
||||
try {
|
||||
FloatBuffer ColorArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.vertexCount);
|
||||
for (int i = 0; i < skyboxmesh.vertexCount; i++) {
|
||||
ColorArrayBufferData.put(i);
|
||||
}
|
||||
ColorArrayBufferData.flip();
|
||||
int idBuffer = glGenBuffers();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, idBuffer);
|
||||
GL15.glBufferData(GL_ARRAY_BUFFER, ColorArrayBufferData, GL_STATIC_DRAW);
|
||||
glVertexAttribPointer(1, 1, GL11.GL_FLOAT, false, 0, 0);
|
||||
glEnableVertexAttribArray(1);
|
||||
} catch (NullPointerException ex){
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
skyboxmesh.hasBones = false;
|
||||
|
||||
|
||||
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
skyboxmesh.nodeID = "skybox";
|
||||
|
||||
skyboxmesh.parent = skybox_model;
|
||||
|
||||
|
||||
skybox_model.meshes.add(skyboxmesh);
|
||||
|
||||
|
||||
return skybox_model;
|
||||
}
|
||||
}
|
||||
374
src/main/java/RendererObjects/ShaderProgram.java
Normal file
@ -0,0 +1,374 @@
|
||||
package RendererObjects;
|
||||
|
||||
import main.Main;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class ShaderProgram {
|
||||
//
|
||||
//Program stuff
|
||||
//
|
||||
int vertexShader;
|
||||
int fragmentShader;
|
||||
int shaderProgram;
|
||||
|
||||
|
||||
//
|
||||
//Uniform locations
|
||||
//
|
||||
public int shaderVertexModelLoc;
|
||||
public int shaderVertexViewLoc;
|
||||
public int shaderVertexProjectionLoc;
|
||||
public int shaderVertexViewPosLoc;
|
||||
public int shaderVertexBonesLoc;
|
||||
public int shaderVertexHasBonesLoc;
|
||||
public int shaderVertexNumBonesLoc;
|
||||
|
||||
|
||||
//Uniforms
|
||||
//list of names of all uniforms in the shader
|
||||
public ArrayList<String> uniformList;
|
||||
//map
|
||||
//string -> tuple
|
||||
//tuple: a string describing the type of the data,the current value,location
|
||||
//ie arrayVec3,[<1,0,0>,<2,0,0>],colors
|
||||
// Mat4,[Matrix4f],modelMatrix
|
||||
public HashMap<String,ArrayList> uniformMap;
|
||||
|
||||
public static ShaderProgram smart_assemble_shader(boolean ContainsBones, boolean apply_lighting){
|
||||
|
||||
String vertex_shader_path = "";
|
||||
if(ContainsBones){
|
||||
vertex_shader_path = "/Shaders/VertexShader.vs";
|
||||
} else {
|
||||
vertex_shader_path = "/Shaders/VertexShaderNoBones.vs";
|
||||
}
|
||||
|
||||
String fragment_shader_path = "/Shaders/FragmentShader.fs";
|
||||
//
|
||||
//Create ShaderProgram object
|
||||
//
|
||||
ShaderProgram rVal = new ShaderProgram();
|
||||
//
|
||||
//Read in shader programs
|
||||
//
|
||||
String tempForReadingShaders = "";
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource(vertex_shader_path).getFile()));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = br.readLine();
|
||||
|
||||
while (line != null) {
|
||||
sb.append(line);
|
||||
sb.append(System.lineSeparator());
|
||||
line = br.readLine();
|
||||
}
|
||||
tempForReadingShaders = sb.toString();
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String vertexShaderSource = tempForReadingShaders;
|
||||
//This try-catch block reads the FragmentShader source into memory
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource(fragment_shader_path).getFile()));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = br.readLine();
|
||||
while (line != null) {
|
||||
sb.append(line);
|
||||
sb.append(System.lineSeparator());
|
||||
line = br.readLine();
|
||||
}
|
||||
tempForReadingShaders = sb.toString();
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String fragmentShaderSource = tempForReadingShaders;
|
||||
//Creates a new shader object and assigns its 'pointer' to the integer "vertexShader"
|
||||
rVal.vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
//This alerts openGL to the presence of a vertex shader and points the shader at its source
|
||||
glShaderSource(rVal.vertexShader, vertexShaderSource);
|
||||
//Compiles the source for the vertex shader object
|
||||
glCompileShader(rVal.vertexShader);
|
||||
//The following tests if the vertex shader compiles successfully
|
||||
int success;
|
||||
success = glGetShaderi(rVal.vertexShader, GL_COMPILE_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
System.out.println("Vertex Shader failed to compile!");
|
||||
throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.vertexShader));
|
||||
}
|
||||
//Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader
|
||||
rVal.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
//This points the opengl shadder object to its proper source
|
||||
glShaderSource(rVal.fragmentShader, fragmentShaderSource);
|
||||
//This compiles the shader object
|
||||
glCompileShader(rVal.fragmentShader);
|
||||
//This tests for the success of the compile attempt
|
||||
success = glGetShaderi(rVal.fragmentShader, GL_COMPILE_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
System.out.println("Fragment Shader failed to compile!");
|
||||
throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader));
|
||||
}
|
||||
//This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram
|
||||
rVal.shaderProgram = glCreateProgram();
|
||||
//This attaches the vertex and fragment shaders to the program
|
||||
glAttachShader(rVal.shaderProgram, rVal.vertexShader);
|
||||
glAttachShader(rVal.shaderProgram, rVal.fragmentShader);
|
||||
//This links the program to the GPU (I think its to the GPU anyway)
|
||||
glLinkProgram(rVal.shaderProgram);
|
||||
//Tests for the success of the shader program creation
|
||||
success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram));
|
||||
}
|
||||
|
||||
//Deletes the individual shader objects to free up memory
|
||||
glDeleteShader(rVal.vertexShader);
|
||||
glDeleteShader(rVal.fragmentShader);
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Set locations
|
||||
//
|
||||
rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model");
|
||||
rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view");
|
||||
rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection");
|
||||
rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos");
|
||||
if(ContainsBones){
|
||||
rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderProgram, "bones");
|
||||
rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderProgram, "numBones");
|
||||
}
|
||||
rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderProgram, "hasBones");
|
||||
|
||||
|
||||
|
||||
|
||||
return rVal;
|
||||
}
|
||||
public static ShaderProgram load_default_shader_program(){
|
||||
|
||||
|
||||
//
|
||||
//Create ShaderProgram object
|
||||
//
|
||||
ShaderProgram rVal = new ShaderProgram();
|
||||
//
|
||||
//Read in shader programs
|
||||
//
|
||||
String tempForReadingShaders = "";
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource("/Shaders/VertexShader.vs").getFile()));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = br.readLine();
|
||||
|
||||
while (line != null) {
|
||||
sb.append(line);
|
||||
sb.append(System.lineSeparator());
|
||||
line = br.readLine();
|
||||
}
|
||||
tempForReadingShaders = sb.toString();
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String vertexShaderSource = tempForReadingShaders;
|
||||
//This try-catch block reads the FragmentShader source into memory
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource("/Shaders/FragmentShader.fs").getFile()));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = br.readLine();
|
||||
while (line != null) {
|
||||
sb.append(line);
|
||||
sb.append(System.lineSeparator());
|
||||
line = br.readLine();
|
||||
}
|
||||
tempForReadingShaders = sb.toString();
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String fragmentShaderSource = tempForReadingShaders;
|
||||
//Creates a new shader object and assigns its 'pointer' to the integer "vertexShader"
|
||||
rVal.vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
//This alerts openGL to the presence of a vertex shader and points the shader at its source
|
||||
glShaderSource(rVal.vertexShader, vertexShaderSource);
|
||||
//Compiles the source for the vertex shader object
|
||||
glCompileShader(rVal.vertexShader);
|
||||
//The following tests if the vertex shader compiles successfully
|
||||
int success;
|
||||
success = glGetShaderi(rVal.vertexShader, GL_COMPILE_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
System.out.println("Vertex Shader failed to compile!");
|
||||
throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.vertexShader));
|
||||
}
|
||||
//Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader
|
||||
rVal.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
//This points the opengl shadder object to its proper source
|
||||
glShaderSource(rVal.fragmentShader, fragmentShaderSource);
|
||||
//This compiles the shader object
|
||||
glCompileShader(rVal.fragmentShader);
|
||||
//This tests for the success of the compile attempt
|
||||
success = glGetShaderi(rVal.fragmentShader, GL_COMPILE_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
System.out.println("Fragment Shader failed to compile!");
|
||||
throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader));
|
||||
}
|
||||
//This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram
|
||||
rVal.shaderProgram = glCreateProgram();
|
||||
//This attaches the vertex and fragment shaders to the program
|
||||
glAttachShader(rVal.shaderProgram, rVal.vertexShader);
|
||||
glAttachShader(rVal.shaderProgram, rVal.fragmentShader);
|
||||
//This links the program to the GPU (I think its to the GPU anyway)
|
||||
glLinkProgram(rVal.shaderProgram);
|
||||
//Tests for the success of the shader program creation
|
||||
success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram));
|
||||
}
|
||||
|
||||
//Deletes the individual shader objects to free up memory
|
||||
glDeleteShader(rVal.vertexShader);
|
||||
glDeleteShader(rVal.fragmentShader);
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Set locations
|
||||
//
|
||||
rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model");
|
||||
rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view");
|
||||
rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection");
|
||||
rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos");
|
||||
rVal.shaderVertexBonesLoc = glGetUniformLocation(rVal.shaderProgram, "bones");
|
||||
rVal.shaderVertexNumBonesLoc = glGetUniformLocation(rVal.shaderProgram, "numBones");
|
||||
rVal.shaderVertexHasBonesLoc = glGetUniformLocation(rVal.shaderProgram, "hasBones");
|
||||
|
||||
|
||||
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static ShaderProgram loadSpecificShader(String vertexPath, String fragmentPath){
|
||||
ShaderProgram rVal = new ShaderProgram();
|
||||
|
||||
String vertex_shader_path = vertexPath;
|
||||
String fragment_shader_path = fragmentPath;
|
||||
//
|
||||
//Read in shader programs
|
||||
//
|
||||
String tempForReadingShaders = "";
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource(vertex_shader_path).getFile()));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = br.readLine();
|
||||
|
||||
while (line != null) {
|
||||
sb.append(line);
|
||||
sb.append(System.lineSeparator());
|
||||
line = br.readLine();
|
||||
}
|
||||
tempForReadingShaders = sb.toString();
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String vertexShaderSource = tempForReadingShaders;
|
||||
//This try-catch block reads the FragmentShader source into memory
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(Main.class.getResource(fragment_shader_path).getFile()));
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String line = br.readLine();
|
||||
while (line != null) {
|
||||
sb.append(line);
|
||||
sb.append(System.lineSeparator());
|
||||
line = br.readLine();
|
||||
}
|
||||
tempForReadingShaders = sb.toString();
|
||||
} finally {
|
||||
br.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
String fragmentShaderSource = tempForReadingShaders;
|
||||
//Creates a new shader object and assigns its 'pointer' to the integer "vertexShader"
|
||||
rVal.vertexShader = glCreateShader(GL_VERTEX_SHADER);
|
||||
//This alerts openGL to the presence of a vertex shader and points the shader at its source
|
||||
glShaderSource(rVal.vertexShader, vertexShaderSource);
|
||||
//Compiles the source for the vertex shader object
|
||||
glCompileShader(rVal.vertexShader);
|
||||
//The following tests if the vertex shader compiles successfully
|
||||
int success;
|
||||
success = glGetShaderi(rVal.vertexShader, GL_COMPILE_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
System.out.println("Vertex Shader failed to compile!");
|
||||
throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.vertexShader));
|
||||
}
|
||||
//Creates and opengl object for a fragment shader and assigns its 'pointer' to the integer fragmentShader
|
||||
rVal.fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
//This points the opengl shadder object to its proper source
|
||||
glShaderSource(rVal.fragmentShader, fragmentShaderSource);
|
||||
//This compiles the shader object
|
||||
glCompileShader(rVal.fragmentShader);
|
||||
//This tests for the success of the compile attempt
|
||||
success = glGetShaderi(rVal.fragmentShader, GL_COMPILE_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
System.out.println("Fragment Shader failed to compile!");
|
||||
throw new RuntimeException(GL20.glGetShaderInfoLog(rVal.fragmentShader));
|
||||
}
|
||||
//This creates a shader program opengl object and assigns its 'pointer' to the integer shaderProgram
|
||||
rVal.shaderProgram = glCreateProgram();
|
||||
//This attaches the vertex and fragment shaders to the program
|
||||
glAttachShader(rVal.shaderProgram, rVal.vertexShader);
|
||||
glAttachShader(rVal.shaderProgram, rVal.fragmentShader);
|
||||
//This links the program to the GPU (I think its to the GPU anyway)
|
||||
glLinkProgram(rVal.shaderProgram);
|
||||
//Tests for the success of the shader program creation
|
||||
success = glGetProgrami(rVal.shaderProgram, GL_LINK_STATUS);
|
||||
if (success != GL_TRUE) {
|
||||
throw new RuntimeException(glGetProgramInfoLog(rVal.shaderProgram));
|
||||
}
|
||||
|
||||
//Deletes the individual shader objects to free up memory
|
||||
glDeleteShader(rVal.vertexShader);
|
||||
glDeleteShader(rVal.fragmentShader);
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Set locations
|
||||
//
|
||||
rVal.shaderVertexModelLoc = glGetUniformLocation(rVal.shaderProgram, "model");
|
||||
rVal.shaderVertexViewLoc = glGetUniformLocation(rVal.shaderProgram, "view");
|
||||
rVal.shaderVertexProjectionLoc = glGetUniformLocation(rVal.shaderProgram, "projection");
|
||||
rVal.shaderVertexViewPosLoc = glGetUniformLocation(rVal.shaderProgram, "viewPos");
|
||||
|
||||
|
||||
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
}
|
||||
136
src/main/java/RendererObjects/texture/Texture.java
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package RendererObjects.texture;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.imageio.ImageIO;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL14.*;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class Texture {
|
||||
int texture_pointer;
|
||||
int width;
|
||||
int height;
|
||||
boolean hasTransparency;
|
||||
public Texture(){
|
||||
|
||||
}
|
||||
public Texture(String path){
|
||||
//generate the texture object on gpu
|
||||
texture_pointer = glGenTextures();
|
||||
//bind the new texture
|
||||
glBindTexture(GL_TEXTURE_2D, texture_pointer);
|
||||
//how are we gonna wrap the texture??
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT);
|
||||
//set the border color to black
|
||||
float borderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||
//set magnification and minification operation sampling strategies
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
//load the image here
|
||||
ByteBuffer data;
|
||||
width = 1;
|
||||
height = 1;
|
||||
try {
|
||||
BufferedImage image_data = ImageIO.read(new File(Thread.currentThread().getContextClassLoader().getResource(path).getFile()));
|
||||
if (
|
||||
image_data.getType() == BufferedImage.TYPE_3BYTE_BGR ||
|
||||
image_data.getType() == BufferedImage.TYPE_INT_RGB
|
||||
){
|
||||
hasTransparency = false;
|
||||
} else if(
|
||||
image_data.getType() == BufferedImage.TYPE_4BYTE_ABGR ||
|
||||
image_data.getType() == BufferedImage.TYPE_INT_ARGB
|
||||
){
|
||||
hasTransparency = true;
|
||||
}
|
||||
width = image_data.getWidth();
|
||||
height = image_data.getHeight();
|
||||
if(hasTransparency){
|
||||
data = BufferUtils.createByteBuffer(width * height * 4);
|
||||
} else {
|
||||
data = BufferUtils.createByteBuffer(width * height * 3);
|
||||
}
|
||||
/*
|
||||
imgBuffer = BufferUtils.createByteBuffer(4 * dimX * dimY);
|
||||
for(int x = 0; x < dimX; x++){
|
||||
for(int y = 0; y < dimY; y++){
|
||||
Color temp = new Color(image_data.getRGB(x, y));
|
||||
data.put((byte)(temp.getRed());
|
||||
data.put((byte)(temp.getGreen());
|
||||
data.put((byte)(temp.getBlue());
|
||||
data.put((byte)(temp.getAlpha());
|
||||
}
|
||||
}
|
||||
imgBuffer.flip();
|
||||
*/
|
||||
for(int y = height - 1; y > -1; y--){
|
||||
for(int x = 0; x < width; x++){
|
||||
Color temp = new Color(image_data.getRGB(x, y), true);
|
||||
|
||||
data.put((byte)temp.getRed());
|
||||
data.put((byte)temp.getGreen());
|
||||
data.put((byte)temp.getBlue());
|
||||
if(hasTransparency){
|
||||
data.put((byte)temp.getAlpha());
|
||||
}
|
||||
// data[x * y * 3 + 0] = temp.getRed();
|
||||
// data[x * y * 3 + 1] = temp.getGreen();
|
||||
// data[x * y * 3 + 2] = temp.getBlue();
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
hasTransparency = false;
|
||||
data = BufferUtils.createByteBuffer(3);
|
||||
data.put((byte)0);
|
||||
data.put((byte)0);
|
||||
data.put((byte)0);
|
||||
}
|
||||
data.flip();
|
||||
//call if width != height so opengl figures out how to unpack it properly
|
||||
if(width != height){
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
}
|
||||
//buffer the texture information
|
||||
if(hasTransparency){
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
//OPTIONAL free the original image data now that it's on the gpu
|
||||
System.gc();
|
||||
}
|
||||
|
||||
public void bind(){
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_pointer);
|
||||
}
|
||||
|
||||
public void bind(int attrib_val){
|
||||
glActiveTexture(GL_TEXTURE0 + attrib_val);
|
||||
glBindTexture(GL_TEXTURE_2D, texture_pointer);
|
||||
}
|
||||
|
||||
public boolean isTransparent(){
|
||||
return hasTransparency;
|
||||
}
|
||||
}
|
||||
64
src/main/java/RendererObjects/texture/TextureMap.java
Normal file
@ -0,0 +1,64 @@
|
||||
package RendererObjects.texture;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class TextureMap {
|
||||
//The convention is
|
||||
//Map of strings (the name of a model) to a model
|
||||
//each model is a map of a string (the name of a mesh) to a list which contains
|
||||
//First the model's diffuse, then the model's specular
|
||||
//always in that order
|
||||
//if either the diffuse or the specular isn't included then it should
|
||||
//instead contain and empty string - ""
|
||||
//this convention must be followed
|
||||
Map<String,Map<String,ArrayList<String>>> texture_map = new HashMap();
|
||||
|
||||
public Map<String,ArrayList<String>> get_mesh_map(String name){
|
||||
return texture_map.get(name);
|
||||
}
|
||||
|
||||
public static ArrayList<String> get_mesh_textures(Map<String,ArrayList<String>> input, String name){
|
||||
if(input == null){
|
||||
//TODO: Add big fuckin' error here
|
||||
return null;
|
||||
}
|
||||
return input.get(name);
|
||||
}
|
||||
|
||||
//for the lazy
|
||||
public static String get_diffuse_path(ArrayList<String> input){
|
||||
if(input == null || input.size() < 2){
|
||||
//TODO: Add big fuckin' error here
|
||||
return null;
|
||||
}
|
||||
return input.get(0);
|
||||
}
|
||||
|
||||
//for the lazy
|
||||
public static String get_specular_path(ArrayList<String> input){
|
||||
if(input == null || input.size() < 2){
|
||||
//TODO: Add big fuckin' error here
|
||||
return null;
|
||||
}
|
||||
return input.get(1);
|
||||
}
|
||||
|
||||
public TextureMap(){
|
||||
texture_map = new HashMap();
|
||||
}
|
||||
public void add_model(String model_name){
|
||||
texture_map.put(model_name, new HashMap());
|
||||
}
|
||||
public void add_mesh_to_model(String model_name, String mesh_name){
|
||||
ArrayList temp = new ArrayList();
|
||||
temp.add("");
|
||||
temp.add("");
|
||||
texture_map.get(model_name).put(mesh_name, temp);
|
||||
}
|
||||
}
|
||||
14
src/main/java/audio/AudioEngine.java
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package audio;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class AudioEngine {
|
||||
|
||||
}
|
||||
37
src/main/java/entity/Entity.java
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package entity;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class Entity {
|
||||
|
||||
static int entity_id_iterator = 0;
|
||||
|
||||
int id;
|
||||
|
||||
HashMap<String,Object> data;
|
||||
|
||||
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public HashMap<String, Object> getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public Entity(){
|
||||
data = new HashMap();
|
||||
id = entity_id_iterator;
|
||||
entity_id_iterator++;
|
||||
}
|
||||
}
|
||||
45
src/main/java/entity/EntityUtil.java
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package entity;
|
||||
|
||||
import RendererObjects.Model;
|
||||
import main.Globals;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class EntityUtil {
|
||||
|
||||
public static Vector3f getEntityPosition(Entity e){
|
||||
return (Vector3f)e.getData().get("position");
|
||||
}
|
||||
|
||||
public static Quaternionf getEntityRotation(Entity e){
|
||||
return (Quaternionf)e.getData().get("rotation");
|
||||
}
|
||||
|
||||
public static Vector3f getEntityScale(Entity e){
|
||||
return (Vector3f)e.getData().get("scale");
|
||||
}
|
||||
|
||||
public static Model getEntityModel(Entity e){
|
||||
return (Model)e.getData().get("model");
|
||||
}
|
||||
|
||||
public static Entity spawnDrawableEntity(Model m){
|
||||
Entity rVal = new Entity();
|
||||
rVal.getData().put("model", m);
|
||||
rVal.getData().put("position", new Vector3f(0,0,0));
|
||||
rVal.getData().put("rotation", new Quaternionf().rotateAxis((float)0, new Vector3f(1,0,0)));
|
||||
rVal.getData().put("scale", new Vector3f(1,1,1));
|
||||
Globals.entity_list.add(rVal);
|
||||
Globals.drawable_list.add(rVal);
|
||||
return rVal;
|
||||
}
|
||||
}
|
||||
93
src/main/java/main/Globals.java
Normal file
@ -0,0 +1,93 @@
|
||||
package main;
|
||||
|
||||
import RendererObjects.Camera;
|
||||
import RendererObjects.Light.DirectionalLight;
|
||||
import RendererObjects.Light.PointLight;
|
||||
import RendererObjects.Light.SpotLight;
|
||||
import RendererObjects.Material;
|
||||
import RendererObjects.Model;
|
||||
import RendererObjects.texture.Texture;
|
||||
import RendererObjects.texture.TextureMap;
|
||||
import com.google.gson.Gson;
|
||||
import entity.Entity;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import util.ModelLoader;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class Globals {
|
||||
|
||||
//
|
||||
//OpenGL - Other
|
||||
//
|
||||
//Array that holds all models that need to be shoved to the gpu
|
||||
public static Matrix4f viewMatrix = new Matrix4f();
|
||||
public static Matrix4f projectionMatrix;
|
||||
|
||||
|
||||
|
||||
public static Texture texture_diffuse_default;
|
||||
public static Texture texture_specular_default;
|
||||
public static Material material_default;
|
||||
|
||||
public static DirectionalLight light_directional_default;
|
||||
public static ArrayList<PointLight> light_point_list_default;
|
||||
public static SpotLight light_spot_default;
|
||||
|
||||
public static TextureMap texture_map_default;
|
||||
|
||||
public static ArrayList<Entity> entity_list;
|
||||
public static ArrayList<Entity> drawable_list;
|
||||
|
||||
public static Camera camera_visible;
|
||||
|
||||
//
|
||||
//Game specific models
|
||||
//
|
||||
|
||||
//famous fuckin last words, but temporary solution
|
||||
//global arraylist of values for the skybox colors
|
||||
public static ArrayList<Vector3f> skybox_colors;
|
||||
|
||||
|
||||
|
||||
public static void init_globals(){
|
||||
//create default textures
|
||||
texture_diffuse_default = new Texture("Textures/default_diffuse.png");
|
||||
texture_specular_default = new Texture("Textures/default_specular.png");
|
||||
//create default material
|
||||
material_default = new Material();
|
||||
material_default.set_diffuse(texture_diffuse_default);
|
||||
material_default.set_specular(texture_specular_default);
|
||||
//create default lights
|
||||
light_directional_default = new DirectionalLight(new Vector3f(0,-1f,0));
|
||||
//load in default texture map
|
||||
Gson gson = new Gson();
|
||||
try {
|
||||
//deserializes the texture map from its default path using gson
|
||||
//also done in one line
|
||||
texture_map_default = gson.fromJson(Files.newBufferedReader(new File(Thread.currentThread().getContextClassLoader().getResource("Textures/default_texture_map.json").getFile()).toPath()), TextureMap.class); //only the best of coding practices :)
|
||||
} catch (IOException ex) { ex.printStackTrace(); } //TODO: handle better :tm:
|
||||
//create entity list
|
||||
entity_list = new ArrayList();
|
||||
drawable_list = new ArrayList();
|
||||
//create the camera object that generates view matrix
|
||||
camera_visible = new Camera();
|
||||
//init game specific variables
|
||||
init_game_specifics();
|
||||
//temporary hold for skybox colors
|
||||
skybox_colors = new ArrayList();
|
||||
}
|
||||
|
||||
public static void init_game_specifics(){
|
||||
}
|
||||
}
|
||||
564
src/main/java/main/Main.java
Normal file
@ -0,0 +1,564 @@
|
||||
package main;
|
||||
|
||||
import RendererObjects.Camera;
|
||||
import RendererObjects.Material;
|
||||
import RendererObjects.Model;
|
||||
import RendererObjects.RenderUtils;
|
||||
import RendererObjects.ShaderProgram;
|
||||
import RendererObjects.texture.Texture;
|
||||
import entity.Entity;
|
||||
import entity.EntityUtil;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Quaternionf;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.glfw.*;
|
||||
import static org.lwjgl.glfw.GLFW.*;
|
||||
import org.lwjgl.opengl.*;
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL13.*;
|
||||
import static org.lwjgl.opengl.GL14.*;
|
||||
import static org.lwjgl.opengl.GL15.*;
|
||||
import static org.lwjgl.opengl.GL20.*;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
import util.ModelLoader;
|
||||
import util.util;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class Main {
|
||||
//
|
||||
//Generic OpenGL Statements
|
||||
//
|
||||
//Callback function for opengl errors
|
||||
private final static GLFWErrorCallback ERROR_CALLBACK = GLFWErrorCallback.createPrint(System.err);
|
||||
private static long window;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Visualization Controls
|
||||
//
|
||||
//These are used in calculating the time between frames for visualization (camera) control and such
|
||||
public static float deltaTime = 0.0f;
|
||||
public static float lastFrame = 0.0f;
|
||||
//View Controls
|
||||
public static float view_Range = 2000.0f;
|
||||
public static Camera camera_Current = new Camera();
|
||||
/*
|
||||
Mouse Controls
|
||||
*/
|
||||
static float mouse_lastX = 400;
|
||||
static float mouse_lastY = 300;
|
||||
static double xpos = 400;
|
||||
static double ypos = 300;
|
||||
static float mouseSensitivity = .1f;
|
||||
static double mouse_X_Buffer[] = new double[1];
|
||||
static double mouse_Y_Buffer[] = new double[1];
|
||||
static float cameraSpeed;
|
||||
static float yaw = 150;
|
||||
static float pitch = 50;
|
||||
|
||||
|
||||
|
||||
//
|
||||
//Player Object Variables
|
||||
//
|
||||
public static boolean CAMERA_UNDER_USER_CONTROL = false;
|
||||
public static boolean CAMERA_UNDER_FREE_CONTROL = false;
|
||||
public static boolean PLAYER_UNDER_USER_CONTROL = true;
|
||||
public static boolean CAMERA_IS_ORBIT = true;
|
||||
public static float camera_Orbit_Length = 1.0f;
|
||||
// public static Camera cam_Player_Orbit;
|
||||
//Camera angles using theta-phi system
|
||||
//Euler angles where theta is applied, then phi
|
||||
//There is no bank applied to the camera
|
||||
|
||||
public static Model model;
|
||||
|
||||
|
||||
|
||||
|
||||
public static void main(String args[]){
|
||||
|
||||
//
|
||||
//
|
||||
// I N I T I A L I Z A T I O N
|
||||
//
|
||||
//
|
||||
|
||||
//run initialization stuff
|
||||
|
||||
//Create opengl
|
||||
create_opengl_context();
|
||||
|
||||
//init global variables
|
||||
Globals.init_globals();
|
||||
|
||||
|
||||
|
||||
|
||||
initWorld();
|
||||
|
||||
init_skybox();
|
||||
|
||||
|
||||
|
||||
Entity player = new Entity();
|
||||
player.getData().put("position", new Vector3f(0f,6f,0f));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// C A M E R A C R E A T I O N
|
||||
///
|
||||
Camera camera_player_chase = new Camera();
|
||||
Camera cam_Player_Orbit = new Camera();
|
||||
|
||||
|
||||
|
||||
//main loop
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
|
||||
/*
|
||||
Frame calculation
|
||||
*/
|
||||
float currentFrame = (float) glfwGetTime();
|
||||
deltaTime = currentFrame - lastFrame;
|
||||
lastFrame = currentFrame;
|
||||
|
||||
//poll mouse variables and update camera variables
|
||||
update_mouse_variables();
|
||||
|
||||
|
||||
float cam_Player_Orbit_Magnitude = 1f;
|
||||
float cam_Player_Orbit_Offset_Height = 1f;
|
||||
cam_Player_Orbit.pos_Center = new Vector3f(0, 0, 0);
|
||||
cam_Player_Orbit.pos_Center.x = 0 + (float) Math.cos(yaw / 180.0f * Math.PI) * cam_Player_Orbit_Magnitude;
|
||||
cam_Player_Orbit.pos_Center.y = 0 + (float) Math.sin(pitch / 180.0f * Math.PI) * cam_Player_Orbit_Magnitude;
|
||||
cam_Player_Orbit.pos_Center.z = 0 + (float) Math.sin(yaw / 180.0f * Math.PI) * cam_Player_Orbit_Magnitude;
|
||||
cam_Player_Orbit.pos_Center.normalize();
|
||||
// System.out.println(cam_Player_Orbit.pos_Center);
|
||||
|
||||
|
||||
|
||||
if(CAMERA_IS_ORBIT){
|
||||
camera_Current = cam_Player_Orbit;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
///
|
||||
/// I N P U T C O N T R O L S
|
||||
///
|
||||
cameraSpeed = 2.5f * deltaTime;
|
||||
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
|
||||
break;
|
||||
}
|
||||
if (glfwGetKey(window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) {
|
||||
if(CAMERA_UNDER_FREE_CONTROL) {
|
||||
//cameraSpeed = cameraSpeed * 100;
|
||||
} else if(PLAYER_UNDER_USER_CONTROL) {
|
||||
|
||||
}
|
||||
}
|
||||
if(glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS){
|
||||
EntityUtil.getEntityPosition(player).add(new Vector3f(-camera_Current.pos_Center.x,0,-camera_Current.pos_Center.z));
|
||||
}
|
||||
if(glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS){
|
||||
EntityUtil.getEntityPosition(player).add(new Vector3f(camera_Current.pos_Center.x,0,camera_Current.pos_Center.z));
|
||||
}
|
||||
if(glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS){
|
||||
EntityUtil.getEntityPosition(player).add(new Vector3f(-camera_Current.pos_Center.x,0,-camera_Current.pos_Center.z).rotateY((float)(-90 * Math.PI / 180)));
|
||||
}
|
||||
if(glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS){
|
||||
EntityUtil.getEntityPosition(player).add(new Vector3f(-camera_Current.pos_Center.x,0,-camera_Current.pos_Center.z).rotateY((float)(90 * Math.PI / 180)));
|
||||
}
|
||||
if(glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS){
|
||||
EntityUtil.getEntityPosition(player).add(new Vector3f(0,0.6f,0));
|
||||
}
|
||||
if(glfwGetKey(window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS){
|
||||
EntityUtil.getEntityPosition(player).add(new Vector3f(0,-0.6f,0));
|
||||
}
|
||||
|
||||
|
||||
// camera_player_chase.pos_Center = new Vector3f(EntityUtil.getEntityPosition(player)).sub(EntityUtil.getEntityRotation(player).transform(new Vector3f(-1,1,0)));
|
||||
|
||||
Globals.camera_visible.apply_camera(camera_player_chase);
|
||||
|
||||
Globals.viewMatrix = Globals.camera_visible.get_view_matrix();
|
||||
Globals.viewMatrix = new Matrix4f().setLookAt(camera_Current.pos_Center, new Vector3f(0,0,0), new Vector3f(camera_Current.pos_Center).add(new Vector3f(0,1.0f,0))).scale(1.0f, 1.5f, 1.0f);
|
||||
|
||||
//Sets the background color.
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
|
||||
//
|
||||
// Draw all entities
|
||||
//
|
||||
Iterator<Entity> entity_iterator = Globals.drawable_list.iterator();
|
||||
while(entity_iterator.hasNext()){
|
||||
Entity currentEntity = entity_iterator.next();
|
||||
Model currentModel = EntityUtil.getEntityModel(currentEntity);
|
||||
currentModel.modelMatrix = new Matrix4f();
|
||||
currentModel.modelMatrix.translate(new Vector3f(EntityUtil.getEntityPosition(currentEntity)).sub(EntityUtil.getEntityPosition(player)));
|
||||
currentModel.modelMatrix.rotate(EntityUtil.getEntityRotation(currentEntity));
|
||||
currentModel.modelMatrix.scale(EntityUtil.getEntityScale(currentEntity));
|
||||
currentModel.draw();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//check and call events and swap the buffers
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
//Terminate the program.
|
||||
glfwTerminate();
|
||||
}
|
||||
|
||||
static void sleep(int i) {
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(i);
|
||||
} catch (InterruptedException ex) {
|
||||
System.out.println("Sleep somehow interrupted?!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public static void create_opengl_context(){
|
||||
//Sets the variables that control the window sizing
|
||||
int screenWidth = 1920;
|
||||
int screenHeight = 1080;
|
||||
//Initializes opengl
|
||||
glfwInit();
|
||||
//Gives hints to glfw to control how opengl will be used
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
//Creates the window reference object
|
||||
window = glfwCreateWindow(screenWidth, screenHeight, "LearnOpenGL", NULL, NULL);
|
||||
//Errors for failure to create window (IE: No GUI mode on linux ?)
|
||||
if (window == NULL) {
|
||||
System.out.println("Failed to make window.");
|
||||
glfwTerminate();
|
||||
}
|
||||
//Makes the window that was just created the current OS-level window context
|
||||
glfwMakeContextCurrent(window);
|
||||
//Maximize it
|
||||
glfwMaximizeWindow(window);
|
||||
//Creates the OpenGL capabilities for the program.
|
||||
GL.createCapabilities();
|
||||
|
||||
//This enables Z-buffering so that farther-back polygons are not drawn over nearer ones
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Support for transparency
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
//Hide the cursor and capture it
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Points the texture uniforms in the shader programs at the correct variables
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Projection and View matrix creation
|
||||
//
|
||||
Globals.projectionMatrix = new Matrix4f();
|
||||
Globals.viewMatrix = new Matrix4f();
|
||||
float FOV = (float)(120.0f * Math.PI /180.0f);
|
||||
Globals.projectionMatrix.setPerspective(FOV, 1.0f, 0.1f, view_Range);
|
||||
Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f));
|
||||
}
|
||||
|
||||
|
||||
public static void update_mouse_variables(){
|
||||
glfwGetCursorPos(window, mouse_X_Buffer, mouse_Y_Buffer);
|
||||
xpos = mouse_X_Buffer[0];
|
||||
ypos = mouse_Y_Buffer[0];
|
||||
float xoffset = (float) (xpos - mouse_lastX) * mouseSensitivity;
|
||||
float yoffset = (float) (mouse_lastY - ypos) * mouseSensitivity;
|
||||
mouse_lastX = (float) xpos;
|
||||
mouse_lastY = (float) ypos;
|
||||
|
||||
yaw = yaw + xoffset;
|
||||
pitch = pitch - yoffset;
|
||||
|
||||
if (pitch > 100.0f) {
|
||||
pitch = 100.0f;
|
||||
}
|
||||
if (pitch < -99.0f) {
|
||||
pitch = -99.0f;
|
||||
}
|
||||
}
|
||||
|
||||
static void init_skybox(){
|
||||
Model skyboxModel = RenderUtils.createSkyboxModel(null);
|
||||
Entity skyboxEntity = EntityUtil.spawnDrawableEntity(skyboxModel);
|
||||
EntityUtil.getEntityScale(skyboxEntity).mul(100);
|
||||
|
||||
|
||||
Globals.skybox_colors.add(new Vector3f(200,200,160));
|
||||
Globals.skybox_colors.add(new Vector3f(200,200,160));
|
||||
Globals.skybox_colors.add(new Vector3f(200,100,50));
|
||||
Globals.skybox_colors.add(new Vector3f(200,100,50));
|
||||
Globals.skybox_colors.add(new Vector3f(50,100,150));
|
||||
Globals.skybox_colors.add(new Vector3f(50,100,150));
|
||||
Globals.skybox_colors.add(new Vector3f(10,10,10));
|
||||
Globals.skybox_colors.add(new Vector3f(10,10,10));
|
||||
}
|
||||
|
||||
|
||||
//I swear it's a temporary function
|
||||
/*
|
||||
for(int angle = 0; angle < 45; angle=angle+2){
|
||||
for(int radius = 115; radius < 130; radius=radius+2){
|
||||
*/
|
||||
// static float[] getTreePos(){
|
||||
// return new float[]{
|
||||
// 115.0f,7.0f,0.0f,
|
||||
// 110.0f,7.0f,10.0f,
|
||||
//
|
||||
// 82.0f,7.0f,82.0f,
|
||||
// };
|
||||
// }
|
||||
|
||||
static void initWorld(){
|
||||
Model building_model = ModelLoader.load_Model_From_File("Models/arcdock5deg1Try2.fbx");
|
||||
Texture whiteTexture = new Texture("Textures/w1.png");
|
||||
Material whiteMaterial = new Material();
|
||||
whiteMaterial.set_diffuse(whiteTexture);
|
||||
whiteMaterial.set_specular(whiteTexture);
|
||||
building_model.meshes.get(0).set_material(whiteMaterial);
|
||||
for(int i = 0; i < 36; i++){
|
||||
Entity arcCurrent = EntityUtil.spawnDrawableEntity(building_model);
|
||||
float angleRad = i * 10;
|
||||
float angleDeg = (float)(angleRad * Math.PI / 180);
|
||||
float posX = (float)(Math.cos(angleDeg) * 100);
|
||||
float posY = (float)(Math.sin(angleDeg) * 100);
|
||||
EntityUtil.getEntityPosition(arcCurrent).set(posX, 0.01f, posY);
|
||||
EntityUtil.getEntityScale(arcCurrent).set(1f);
|
||||
EntityUtil.getEntityRotation(arcCurrent)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)((180-angleRad) * Math.PI / 180))
|
||||
;
|
||||
arcCurrent = EntityUtil.spawnDrawableEntity(building_model);
|
||||
angleRad = i * 10 + 5;
|
||||
angleDeg = (float)(angleRad * Math.PI / 180);
|
||||
posX = (float)(Math.cos(angleDeg) * 100);
|
||||
posY = (float)(Math.sin(angleDeg) * 100);
|
||||
EntityUtil.getEntityPosition(arcCurrent).set(posX, 5.01f, posY);
|
||||
EntityUtil.getEntityScale(arcCurrent).set(1f);
|
||||
EntityUtil.getEntityRotation(arcCurrent)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)((180-angleRad) * Math.PI / 180))
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
Model dirtPlane = ModelLoader.load_Model_From_File("Models/groundplanemassiveuv.fbx");
|
||||
Texture dirtTexture = new Texture("Textures/Ground/Dirt1.png");
|
||||
Material dirtMaterial = new Material();
|
||||
dirtMaterial.set_diffuse(dirtTexture);
|
||||
dirtMaterial.set_specular(dirtTexture);
|
||||
dirtPlane.meshes.get(0).set_material(dirtMaterial);
|
||||
for(int x = -120; x < 120; x=x+20){
|
||||
for(int y = -120; y < 120; y=y+20){
|
||||
Entity dirtPlaneEntity = EntityUtil.spawnDrawableEntity(dirtPlane);
|
||||
EntityUtil.getEntityPosition(dirtPlaneEntity).set(x, -1.0f, y);
|
||||
EntityUtil.getEntityScale(dirtPlaneEntity).set(10f);
|
||||
EntityUtil.getEntityRotation(dirtPlaneEntity)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
Model tree2 = ModelLoader.load_Model_From_File("Models/tree2.fbx");
|
||||
Texture leavesTexture = new Texture("Textures/leaves.png");
|
||||
Material leavesMaterial = new Material();
|
||||
leavesMaterial.set_diffuse(leavesTexture);
|
||||
leavesMaterial.set_specular(leavesTexture);
|
||||
Texture trunkTexture = new Texture("Textures/trunk.png");
|
||||
Material trunkMaterial = new Material();
|
||||
trunkMaterial.set_diffuse(trunkTexture);
|
||||
trunkMaterial.set_specular(trunkTexture);
|
||||
tree2.meshes.get(0).set_material(trunkMaterial);
|
||||
tree2.meshes.get(1).set_material(leavesMaterial);
|
||||
tree2.meshes.get(2).set_material(leavesMaterial);
|
||||
Random treeRand = new Random();
|
||||
|
||||
ArrayList<Entity> treeList = new ArrayList();
|
||||
for(int angle = -105; angle < 45; angle=angle+2){
|
||||
for(int radius = 115; radius < 140; radius=radius+2){
|
||||
Entity treeEntity = EntityUtil.spawnDrawableEntity(tree2);
|
||||
EntityUtil.getEntityPosition(treeEntity).set(
|
||||
(float)Math.cos(angle * Math.PI / 180) * radius + (treeRand.nextFloat() - 0.5f) * 2,
|
||||
radius - 113 + treeRand.nextFloat(),
|
||||
(float)Math.sin(angle * Math.PI / 180) * radius + (treeRand.nextFloat() - 0.5f) * 2
|
||||
);
|
||||
EntityUtil.getEntityScale(treeEntity).set(1f);
|
||||
EntityUtil.getEntityRotation(treeEntity)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)((treeRand.nextFloat() * 359) * Math.PI / 180))
|
||||
;
|
||||
treeList.add(treeEntity);
|
||||
}
|
||||
}
|
||||
// float[] treepos = getTreePos();
|
||||
// for(int i = 0; i < treepos.length/3; i++){
|
||||
// float posX = treepos[i*3];
|
||||
// float posY = treepos[i*3+1];
|
||||
// float posZ = treepos[i*3+2];
|
||||
// Entity treeEntity = EntityUtil.spawnDrawableEntity(tree2);
|
||||
// EntityUtil.getEntityPosition(treeEntity).set(posX,posY,posZ);
|
||||
// EntityUtil.getEntityScale(treeEntity).set(1f);
|
||||
// EntityUtil.getEntityRotation(treeEntity)
|
||||
// .identity()
|
||||
// .rotateLocalX((float)(-Math.PI / 2))
|
||||
// .rotateLocalY((float)((treeRand.nextFloat() * 359) * Math.PI / 180))
|
||||
// ;
|
||||
// treeList.add(treeEntity);
|
||||
// }
|
||||
|
||||
Model arenaSpire = ModelLoader.load_Model_From_File("Models/ArenaSpire1.fbx");
|
||||
arenaSpire.meshes.get(0).set_material(whiteMaterial);
|
||||
Entity spireEntity = EntityUtil.spawnDrawableEntity(arenaSpire);
|
||||
EntityUtil.getEntityRotation(spireEntity)
|
||||
.identity()
|
||||
.rotateLocalZ((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(220) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(spireEntity).set(-105, 0, 0);
|
||||
|
||||
Model railTrackModel = ModelLoader.load_Model_From_File("Models/RailTrack1Part1.fbx");
|
||||
Texture railTrackTexture = new Texture("Textures/RailTrack1Part1.png");
|
||||
Material railTrackMaterial = new Material();
|
||||
railTrackMaterial.set_diffuse(railTrackTexture);
|
||||
railTrackMaterial.set_specular(railTrackTexture);
|
||||
railTrackModel.meshes.get(0).set_material(railTrackMaterial);
|
||||
Entity railTrackEntity = EntityUtil.spawnDrawableEntity(railTrackModel);
|
||||
EntityUtil.getEntityRotation(railTrackEntity)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(0) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(railTrackEntity).set(-15, 10, -20);
|
||||
|
||||
Model railSupportModel = ModelLoader.load_Model_From_File("Models/MonorailSupport.fbx");
|
||||
Texture railSupportTexture = new Texture("Textures/MonorailSupport.png");
|
||||
Material railSupportMaterial = new Material();
|
||||
railSupportMaterial.set_diffuse(railSupportTexture);
|
||||
railSupportMaterial.set_specular(railSupportTexture);
|
||||
railSupportModel.meshes.get(0).set_material(railSupportMaterial);
|
||||
|
||||
//support 1
|
||||
Entity railSupport1 = EntityUtil.spawnDrawableEntity(railSupportModel);
|
||||
EntityUtil.getEntityRotation(railSupport1)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(180) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(railSupport1).set(0, -71.5f, -125);
|
||||
|
||||
//support 2
|
||||
Entity railSupport2 = EntityUtil.spawnDrawableEntity(railSupportModel);
|
||||
EntityUtil.getEntityRotation(railSupport2)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(200) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(railSupport2).set(30, -69.5f, -115);
|
||||
|
||||
//support 3
|
||||
Entity railSupport3 = EntityUtil.spawnDrawableEntity(railSupportModel);
|
||||
EntityUtil.getEntityRotation(railSupport3)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(217) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(railSupport3).set(62, -65.5f, -95);
|
||||
|
||||
//support 4
|
||||
Entity railSupport4 = EntityUtil.spawnDrawableEntity(railSupportModel);
|
||||
EntityUtil.getEntityRotation(railSupport4)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(222) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(railSupport4).set(90, -61f, -70);
|
||||
|
||||
//support 5
|
||||
Entity railSupport5 = EntityUtil.spawnDrawableEntity(railSupportModel);
|
||||
EntityUtil.getEntityRotation(railSupport5)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(235) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(railSupport5).set(121, -57.5f, -25);
|
||||
|
||||
//support 6
|
||||
Entity railSupport6 = EntityUtil.spawnDrawableEntity(railSupportModel);
|
||||
EntityUtil.getEntityRotation(railSupport6)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(265) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(railSupport6).set(135, -58.5f, 30);
|
||||
|
||||
|
||||
Model tallBuildingModel = ModelLoader.load_Model_From_File("Models/tallbuilding1.fbx");
|
||||
tallBuildingModel.meshes.get(0).set_material(whiteMaterial);
|
||||
Entity tallBuildingEntity1 = EntityUtil.spawnDrawableEntity(tallBuildingModel);
|
||||
EntityUtil.getEntityRotation(tallBuildingEntity1)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(0) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(tallBuildingEntity1).set(200, 0.0f, -80);
|
||||
EntityUtil.getEntityScale(tallBuildingEntity1).set(0.6f, 0.6f, 1f);
|
||||
|
||||
Entity tallBuildingEntity2 = EntityUtil.spawnDrawableEntity(tallBuildingModel);
|
||||
EntityUtil.getEntityRotation(tallBuildingEntity2)
|
||||
.identity()
|
||||
.rotateLocalX((float)(-Math.PI / 2))
|
||||
.rotateLocalY((float)(-(35) * Math.PI / 180))
|
||||
;
|
||||
EntityUtil.getEntityPosition(tallBuildingEntity2).set(190, 10.0f, 10.0f);
|
||||
EntityUtil.getEntityScale(tallBuildingEntity2).set(0.5f, 0.5f, 1f);
|
||||
}
|
||||
|
||||
}
|
||||
14
src/main/java/net/Client.java
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package net;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class Client {
|
||||
|
||||
}
|
||||
14
src/main/java/net/Server.java
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* To change this license header, choose License Headers in Project Properties.
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package net;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
*/
|
||||
public class Server {
|
||||
|
||||
}
|
||||
85
src/main/java/util/ModelLoader.java
Normal file
@ -0,0 +1,85 @@
|
||||
package util;
|
||||
|
||||
import main.Globals;
|
||||
import RendererObjects.Material;
|
||||
import RendererObjects.Mesh;
|
||||
import RendererObjects.Model;
|
||||
import RendererObjects.texture.Texture;
|
||||
import RendererObjects.texture.TextureMap;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.lwjgl.assimp.AIScene;
|
||||
import static org.lwjgl.assimp.Assimp.*;
|
||||
import static org.lwjgl.assimp.Assimp.aiImportFile;
|
||||
|
||||
public class ModelLoader {
|
||||
public static Model load_Model_From_File(String fileName){
|
||||
Model rVal;
|
||||
AIScene scene;
|
||||
File file = new File(Thread.currentThread().getContextClassLoader().getResource(fileName).getFile());
|
||||
scene = aiImportFile(file.getAbsolutePath(),
|
||||
aiProcess_GenSmoothNormals |
|
||||
aiProcess_JoinIdenticalVertices |
|
||||
aiProcess_Triangulate |
|
||||
aiProcess_FixInfacingNormals |
|
||||
aiProcess_LimitBoneWeights);
|
||||
if(scene == null){
|
||||
throw new IllegalStateException(aiGetErrorString());
|
||||
}
|
||||
rVal = Model.create_model_from_aiscene(scene);
|
||||
attempt_add_textures_from_pathname(fileName, rVal);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
//TODO: this logic should exclusively use functions provided in the TextureMap class
|
||||
//this way if we change the underlying structure of the TextureMap it doesn't fuck over this logic
|
||||
static void attempt_add_textures_from_pathname(String path, Model m){
|
||||
//first we get the default texture map that's global
|
||||
TextureMap global_map = Globals.texture_map_default;
|
||||
//then we try to get the path of our model from the map
|
||||
Map<String,ArrayList<String>> mesh_map = global_map.get_mesh_map(path);
|
||||
//if it exists..
|
||||
if(mesh_map != null){
|
||||
//iterate through each mesh in the model that was provided as input
|
||||
Iterator<Mesh> mesh_iterator = m.meshes.iterator();
|
||||
while(mesh_iterator.hasNext()){
|
||||
Mesh current_mesh = mesh_iterator.next();
|
||||
//if the current iteration is contained within the mesh map we procured from above
|
||||
if(mesh_map.containsKey(current_mesh.nodeID)){
|
||||
//we create a new material, check if the diffuse or specular is not null,
|
||||
//and if they aren't we add that path as a new texture of respective type to the material
|
||||
Material final_material = new Material();
|
||||
ArrayList<String> texture_path_list = mesh_map.get(current_mesh.nodeID);
|
||||
String diffuse_path = TextureMap.get_diffuse_path(texture_path_list);
|
||||
if(diffuse_path != null){
|
||||
System.out.println(diffuse_path);
|
||||
Texture diffuse = new Texture(diffuse_path);
|
||||
final_material.set_diffuse(diffuse);
|
||||
System.out.println(diffuse);
|
||||
} else {
|
||||
final_material.set_diffuse(Globals.texture_diffuse_default);
|
||||
}
|
||||
String specular_path = TextureMap.get_specular_path(texture_path_list);
|
||||
if(specular_path != null){
|
||||
Texture specular = new Texture(specular_path);
|
||||
final_material.set_specular(specular);
|
||||
System.out.println(specular);
|
||||
} else {
|
||||
final_material.set_specular(Globals.texture_specular_default);
|
||||
}
|
||||
//once we've either added default textures or actual textures,
|
||||
//set the current mesh's material to this new one
|
||||
current_mesh.set_material(final_material);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
234
src/main/java/util/util.java
Normal file
@ -0,0 +1,234 @@
|
||||
package util;
|
||||
|
||||
import RendererObjects.Material;
|
||||
import RendererObjects.Mesh;
|
||||
import RendererObjects.Model;
|
||||
import RendererObjects.ShaderProgram;
|
||||
import RendererObjects.texture.Texture;
|
||||
import RendererObjects.texture.TextureMap;
|
||||
import com.google.gson.Gson;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.FloatBuffer;
|
||||
import java.nio.IntBuffer;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import org.joml.Matrix4f;
|
||||
import org.joml.Vector3f;
|
||||
import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.assimp.AIMatrix4x4;
|
||||
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||
/**
|
||||
*
|
||||
* @author awhoove
|
||||
*/
|
||||
public class util {
|
||||
|
||||
|
||||
|
||||
public static Matrix4f convertAIMatrix(AIMatrix4x4 mat){
|
||||
Matrix4f rVal = new Matrix4f();
|
||||
//Old, wrong approach:
|
||||
// mat.set(
|
||||
// mat.a1(),
|
||||
// mat.b1(),
|
||||
// mat.c1(),
|
||||
// mat.d1(),
|
||||
// mat.a2(),
|
||||
// mat.b2(),
|
||||
// mat.c2(),
|
||||
// mat.d2(),
|
||||
// mat.a3(),
|
||||
// mat.b3(),
|
||||
// mat.c3(),
|
||||
// mat.d3(),
|
||||
// mat.a4(),
|
||||
// mat.b4(),
|
||||
// mat.c4(),
|
||||
// mat.d4()
|
||||
// );
|
||||
//as demo'd in https://github.com/lwjglgamedev/lwjglbook/blob/master/chapter27/c27-p2/src/main/java/org/lwjglb/engine/loaders/assimp/AnimMeshesLoader.java
|
||||
rVal.m00(mat.a1());
|
||||
rVal.m10(mat.a2());
|
||||
rVal.m20(mat.a3());
|
||||
rVal.m30(mat.a4());
|
||||
rVal.m01(mat.b1());
|
||||
rVal.m11(mat.b2());
|
||||
rVal.m21(mat.b3());
|
||||
rVal.m31(mat.b4());
|
||||
rVal.m02(mat.c1());
|
||||
rVal.m12(mat.c2());
|
||||
rVal.m22(mat.c3());
|
||||
rVal.m32(mat.c4());
|
||||
rVal.m03(mat.d1());
|
||||
rVal.m13(mat.d2());
|
||||
rVal.m23(mat.d3());
|
||||
rVal.m33(mat.d4());
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static Model create_terrain_model(float[][] heightfield){
|
||||
Model rVal = new Model();
|
||||
rVal.meshes = new ArrayList();
|
||||
Mesh m = new Mesh();
|
||||
int width = heightfield.length;
|
||||
int height = heightfield[0].length;
|
||||
FloatBuffer vertices = BufferUtils.createFloatBuffer(width * height * 3);
|
||||
FloatBuffer normals = BufferUtils.createFloatBuffer(width * height * 3);
|
||||
IntBuffer faces = BufferUtils.createIntBuffer((width - 1) * (height - 1) * 2 * 3);
|
||||
FloatBuffer texture_coords = BufferUtils.createFloatBuffer(width * height * 2);
|
||||
for(int x = 0; x < width; x++){
|
||||
for(int y = 0; y < height; y++){
|
||||
//deal with vertex
|
||||
vertices.put(x);
|
||||
vertices.put(heightfield[x][y]);
|
||||
vertices.put(y);
|
||||
//deal with normal
|
||||
if(x < width - 1){
|
||||
if(y < height - 1){
|
||||
float hL;
|
||||
if(x > 0){
|
||||
hL = heightfield[x-1][y];
|
||||
} else {
|
||||
hL = heightfield[x][y];
|
||||
}
|
||||
float hR = heightfield[x+1][y];
|
||||
float hD = heightfield[x][y+1];
|
||||
float hU;
|
||||
if(y > 0){
|
||||
hU = heightfield[x][y-1];
|
||||
} else {
|
||||
hU = heightfield[x][y];
|
||||
}
|
||||
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
|
||||
Normal.normalize();
|
||||
normals.put(Normal.x);
|
||||
normals.put(Normal.y);
|
||||
normals.put(Normal.z);
|
||||
} else {
|
||||
float hL;
|
||||
if(x > 0){
|
||||
hL = heightfield[x-1][y];
|
||||
} else {
|
||||
hL = heightfield[x][y];
|
||||
}
|
||||
float hR = heightfield[x+1][y];
|
||||
float hD = heightfield[x][y];
|
||||
float hU = heightfield[x][y-1];
|
||||
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
|
||||
Normal.normalize();
|
||||
normals.put(Normal.x);
|
||||
normals.put(Normal.y);
|
||||
normals.put(Normal.z);
|
||||
}
|
||||
} else {
|
||||
if(y < height - 1){
|
||||
float hL = heightfield[x-1][y];
|
||||
float hR = heightfield[x][y];
|
||||
float hD = heightfield[x][y+1];
|
||||
float hU;
|
||||
if(y > 0){
|
||||
hU = heightfield[x][y-1];
|
||||
} else {
|
||||
hU = heightfield[x][y];
|
||||
}
|
||||
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
|
||||
Normal.normalize();
|
||||
normals.put(Normal.x);
|
||||
normals.put(Normal.y);
|
||||
normals.put(Normal.z);
|
||||
} else {
|
||||
float hL = heightfield[x-1][y];
|
||||
float hR = heightfield[x][y];
|
||||
float hD = heightfield[x][y];
|
||||
float hU = heightfield[x][y-1];
|
||||
Vector3f Normal = new Vector3f(hL - hR, 2.0f, hD - hU);
|
||||
Normal.normalize();
|
||||
normals.put(Normal.x);
|
||||
normals.put(Normal.y);
|
||||
normals.put(Normal.z);
|
||||
}
|
||||
}
|
||||
//deal with texture coordinates
|
||||
if(x % 2 == 0){
|
||||
if(y % 2 == 0){
|
||||
texture_coords.put(0);
|
||||
texture_coords.put(0);
|
||||
} else {
|
||||
texture_coords.put(0);
|
||||
texture_coords.put(1);
|
||||
}
|
||||
} else {
|
||||
if(y % 2 == 0){
|
||||
texture_coords.put(1);
|
||||
texture_coords.put(0);
|
||||
} else {
|
||||
texture_coords.put(1);
|
||||
texture_coords.put(1);
|
||||
}
|
||||
}
|
||||
//deal with faces
|
||||
if(x < width - 1 && y < height - 1){
|
||||
faces.put((x + 0) * height + (y + 0));
|
||||
faces.put((x + 0) * height + (y + 1));
|
||||
faces.put((x + 1) * height + (y + 0));
|
||||
faces.put((x + 1) * height + (y + 0));
|
||||
faces.put((x + 0) * height + (y + 1));
|
||||
faces.put((x + 1) * height + (y + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
vertices.flip();
|
||||
normals.flip();
|
||||
faces.flip();
|
||||
texture_coords.flip();
|
||||
|
||||
m.vertexArrayObject = glGenVertexArrays();
|
||||
glBindVertexArray(m.vertexArrayObject);
|
||||
//buffer vertices
|
||||
m.buffer_vertices(vertices);
|
||||
//buffer normals
|
||||
m.buffer_normals(normals);
|
||||
//buffer faces
|
||||
m.buffer_faces(faces);
|
||||
//buffer texture coords
|
||||
m.buffer_texture_coords(texture_coords);
|
||||
m.shader = ShaderProgram.smart_assemble_shader(false,true);
|
||||
glBindVertexArray(0);
|
||||
m.parent = rVal;
|
||||
|
||||
Material grass_mat = new Material();
|
||||
Texture grass_texture = new Texture("Textures/grass_texture.jpg");
|
||||
grass_mat.set_diffuse(grass_texture);
|
||||
grass_mat.set_specular(grass_texture);
|
||||
m.set_material(grass_mat);
|
||||
|
||||
rVal.meshes.add(m);
|
||||
return rVal;
|
||||
}
|
||||
|
||||
public static void save_test_texture_map_to_location(String s){
|
||||
TextureMap t = new TextureMap();
|
||||
t.add_model("model1");
|
||||
t.add_mesh_to_model("model1", "mesh1");
|
||||
t.add_mesh_to_model("model1", "mesh2");
|
||||
t.add_mesh_to_model("model1", "mesh3");
|
||||
t.add_model("model2");
|
||||
t.add_mesh_to_model("model2", "mesh1");
|
||||
t.add_mesh_to_model("model2", "mesh2");
|
||||
t.add_model("model3");
|
||||
t.add_mesh_to_model("model3", "mesh1");
|
||||
t.add_mesh_to_model("model3", "mesh2");
|
||||
t.add_mesh_to_model("model3", "mesh3");
|
||||
t.add_mesh_to_model("model3", "mesh4");
|
||||
Gson gson = new Gson();
|
||||
try {
|
||||
Files.write(new File(s).toPath(), gson.toJson(t).getBytes());
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace(); // just for testing :thinking:
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/Models/ArenaSpire1.fbx
Normal file
BIN
src/main/resources/Models/MonorailSupport.fbx
Normal file
BIN
src/main/resources/Models/RailTrack1Part1.fbx
Normal file
BIN
src/main/resources/Models/Wheat1.fbx
Normal file
BIN
src/main/resources/Models/arcdock5deg1Try2.fbx
Normal file
BIN
src/main/resources/Models/arcdock5deg1notex.fbx
Normal file
BIN
src/main/resources/Models/groundplanemassiveuv.fbx
Normal file
BIN
src/main/resources/Models/plane.fbx
Normal file
BIN
src/main/resources/Models/skyscraper1.fbx
Normal file
BIN
src/main/resources/Models/tallbuilding1.fbx
Normal file
BIN
src/main/resources/Models/test3.fbx
Normal file
BIN
src/main/resources/Models/test5.fbx
Normal file
BIN
src/main/resources/Models/tree2.fbx
Normal file
148
src/main/resources/Shaders/FragmentShader.fs
Normal file
@ -0,0 +1,148 @@
|
||||
|
||||
|
||||
#version 430 core
|
||||
out vec4 FragColor;
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
sampler2D specular;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
struct DirLight {
|
||||
vec3 direction;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
struct PointLight {
|
||||
vec3 position;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
struct SpotLight {
|
||||
vec3 position;
|
||||
vec3 direction;
|
||||
float cutOff;
|
||||
float outerCutOff;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
#define NR_POINT_LIGHTS 10
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoord;
|
||||
|
||||
uniform vec3 viewPos;
|
||||
uniform DirLight dirLight;
|
||||
uniform PointLight pointLights[NR_POINT_LIGHTS];
|
||||
uniform SpotLight spotLight;
|
||||
uniform Material material;
|
||||
|
||||
//texture stuff
|
||||
uniform sampler2D ourTexture;
|
||||
uniform int hasTransparency;
|
||||
|
||||
|
||||
// function prototypes
|
||||
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
|
||||
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||
|
||||
void main(){
|
||||
if(hasTransparency == 1){
|
||||
if(texture(material.diffuse, TexCoord).a < 0.1){
|
||||
discard;
|
||||
}
|
||||
}
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
|
||||
vec3 result = CalcDirLight(dirLight, norm, viewDir);
|
||||
//for(int i = 0; i < NR_POINT_LIGHTS; i++){
|
||||
// result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
|
||||
//}
|
||||
//result += CalcSpotLight(spotLight, norm, FragPos, viewDir);
|
||||
FragColor = vec4(result, texture(material.diffuse, TexCoord).a);//texture(ourTexture, TexCoord);//vec4(result, 1.0);
|
||||
}
|
||||
|
||||
// calculates the color when using a directional light.
|
||||
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir){
|
||||
vec3 lightDir = normalize(-light.direction);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
// combine results
|
||||
vec3 texColor = texture(material.diffuse, TexCoord).rgb;
|
||||
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoord).rgb);
|
||||
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoord).rgb);
|
||||
//vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoord).rgb);
|
||||
return (ambient + diffuse);// + specular);
|
||||
}
|
||||
|
||||
|
||||
// calculates the color when using a point light.
|
||||
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir){
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
// attenuation
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||
// combine results
|
||||
vec3 ambient = light.ambient * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||
vec3 diffuse = light.diffuse * diff * vec4(texture(material.diffuse, TexCoord)).xyz;
|
||||
vec3 specular = light.specular * spec * vec4(texture(material.specular, TexCoord)).xyz;
|
||||
ambient *= attenuation;
|
||||
diffuse *= attenuation;
|
||||
specular *= attenuation;
|
||||
return (ambient + diffuse + specular);
|
||||
}
|
||||
|
||||
// calculates the color when using a spot light.
|
||||
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
|
||||
{
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
// attenuation
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||
// spotlight intensity
|
||||
float theta = dot(lightDir, normalize(-light.direction));
|
||||
float epsilon = light.cutOff - light.outerCutOff;
|
||||
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
|
||||
// combine results
|
||||
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoord));
|
||||
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoord));
|
||||
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoord));
|
||||
ambient *= attenuation * intensity;
|
||||
diffuse *= attenuation * intensity;
|
||||
specular *= attenuation * intensity;
|
||||
return (ambient + diffuse + specular);
|
||||
}
|
||||
56
src/main/resources/Shaders/VertexShader.vs
Normal file
@ -0,0 +1,56 @@
|
||||
//Vertex Shader
|
||||
#version 430 core
|
||||
|
||||
|
||||
|
||||
//input buffers
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec4 aWeights;
|
||||
layout (location = 3) in vec4 aIndex;
|
||||
layout (location = 4) in vec2 aTex;
|
||||
|
||||
|
||||
//coordinate space transformation matrices
|
||||
uniform mat4 transform;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
//bone related variables
|
||||
const int MAX_WEIGHTS = 4;
|
||||
const int MAX_BONES = 100;
|
||||
uniform mat4 bones[MAX_BONES];
|
||||
uniform int hasBones;
|
||||
uniform int numBones;
|
||||
|
||||
|
||||
|
||||
//output buffers
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec2 TexCoord;
|
||||
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
//calculate bone transform
|
||||
mat4 BoneTransform = (bones[int(aIndex[0])] * aWeights[0]);
|
||||
BoneTransform = BoneTransform + (bones[int(aIndex[1])] * aWeights[1]);
|
||||
BoneTransform = BoneTransform + (bones[int(aIndex[2])] * aWeights[2]);
|
||||
BoneTransform = BoneTransform + (bones[int(aIndex[3])] * aWeights[3]);
|
||||
//apply bone transform to position vectors
|
||||
vec4 FinalVertex = BoneTransform * vec4(aPos, 1.0);
|
||||
vec4 FinalNormal = BoneTransform * vec4(aNormal, 1.0);
|
||||
//make sure the W component is 1.0
|
||||
FinalVertex = vec4(FinalVertex.xyz, 1.0);
|
||||
FinalNormal = vec4(FinalNormal.xyz, 1.0);
|
||||
//push frag, normal, and texture positions to fragment shader
|
||||
FragPos = vec3(model * FinalVertex);
|
||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
TexCoord = aTex;
|
||||
//set final position with opengl space
|
||||
gl_Position = projection * view * model * FinalVertex;
|
||||
}
|
||||
39
src/main/resources/Shaders/VertexShaderNoBones.vs
Normal file
@ -0,0 +1,39 @@
|
||||
//Vertex Shader
|
||||
#version 430 core
|
||||
|
||||
|
||||
|
||||
//input buffers
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 4) in vec2 aTex;
|
||||
|
||||
|
||||
//coordinate space transformation matrices
|
||||
uniform mat4 transform;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
|
||||
|
||||
//output buffers
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec2 TexCoord;
|
||||
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
//normalize posiiton and normal
|
||||
vec4 FinalVertex = vec4(aPos, 1.0);
|
||||
vec4 FinalNormal = vec4(aNormal, 1.0);
|
||||
//push frag, normal, and texture positions to fragment shader
|
||||
FragPos = vec3(model * FinalVertex);
|
||||
Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
TexCoord = aTex;
|
||||
//set final position with opengl space
|
||||
gl_Position = projection * view * model * FinalVertex;
|
||||
}
|
||||
165
src/main/resources/Shaders/backup/FragmentShader.fs
Normal file
@ -0,0 +1,165 @@
|
||||
|
||||
|
||||
#version 430 core
|
||||
out vec4 FragColor;
|
||||
|
||||
struct Material {
|
||||
sampler2D diffuse;
|
||||
sampler2D specular;
|
||||
float shininess;
|
||||
};
|
||||
|
||||
struct DirLight {
|
||||
vec3 direction;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
struct PointLight {
|
||||
vec3 position;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
struct SpotLight {
|
||||
vec3 position;
|
||||
vec3 direction;
|
||||
float cutOff;
|
||||
float outerCutOff;
|
||||
|
||||
float constant;
|
||||
float linear;
|
||||
float quadratic;
|
||||
|
||||
vec3 ambient;
|
||||
vec3 diffuse;
|
||||
vec3 specular;
|
||||
};
|
||||
|
||||
#define NR_POINT_LIGHTS 4
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec2 TexCoords;
|
||||
|
||||
|
||||
uniform int fragHasTexture;
|
||||
|
||||
uniform vec3 viewPos;
|
||||
uniform DirLight dirLight;
|
||||
uniform PointLight pointLights[NR_POINT_LIGHTS];
|
||||
uniform SpotLight spotLight;
|
||||
uniform Material material;
|
||||
|
||||
// function prototypes
|
||||
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir);
|
||||
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir);
|
||||
|
||||
void main()
|
||||
{
|
||||
// properties
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
|
||||
// == =====================================================
|
||||
// Our lighting is set up in 3 phases: directional, point lights and an optional flashlight
|
||||
// For each phase, a calculate function is defined that calculates the corresponding color
|
||||
// per lamp. In the main() function we take all the calculated colors and sum them up for
|
||||
// this fragment's final color.
|
||||
// == =====================================================
|
||||
// phase 1: directional lighting
|
||||
vec3 result = CalcDirLight(dirLight, norm, viewDir);
|
||||
// phase 2: point lights
|
||||
//for(int i = 0; i < NR_POINT_LIGHTS; i++)
|
||||
// result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
|
||||
// phase 3: spot light
|
||||
//result += CalcSpotLight(spotLight, norm, FragPos, viewDir);
|
||||
|
||||
FragColor = vec4(result, 1.0);
|
||||
}
|
||||
|
||||
// calculates the color when using a directional light.
|
||||
vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir)
|
||||
{
|
||||
vec3 lightDir = normalize(-light.direction);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
// combine results
|
||||
vec3 ambient = vec3(1.0,1.0,1.0);
|
||||
vec3 diffuse = vec3(1.0,1.0,1.0);
|
||||
vec3 specular = vec3(1.0,1.0,1.0);
|
||||
if(fragHasTexture == 1){
|
||||
ambient = light.ambient;// * vec3(texture(material.diffuse, TexCoords));
|
||||
diffuse = light.diffuse * diff;// * vec3(texture(material.diffuse, TexCoords));
|
||||
specular = light.specular * spec;// * vec3(texture(material.specular, TexCoords));
|
||||
} else {
|
||||
ambient = light.ambient;// * vec3(texture(material.diffuse, TexCoords));
|
||||
diffuse = light.diffuse * diff;// * vec3(texture(material.diffuse, TexCoords));
|
||||
specular = light.specular * spec;// * vec3(texture(material.specular, TexCoords));
|
||||
}
|
||||
//vec3 ambient = light.ambient;// * vec3(texture(material.diffuse, TexCoords));
|
||||
//vec3 diffuse = light.diffuse * diff;// * vec3(texture(material.diffuse, TexCoords));
|
||||
//vec3 specular = light.specular * spec;// * vec3(texture(material.specular, TexCoords));
|
||||
return (ambient + diffuse);// + specular);
|
||||
}
|
||||
|
||||
// calculates the color when using a point light.
|
||||
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
|
||||
{
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
// attenuation
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||
// combine results
|
||||
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
|
||||
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
|
||||
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
|
||||
ambient *= attenuation;
|
||||
diffuse *= attenuation;
|
||||
specular *= attenuation;
|
||||
return (ambient + diffuse + specular);
|
||||
}
|
||||
|
||||
// calculates the color when using a spot light.
|
||||
vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir)
|
||||
{
|
||||
vec3 lightDir = normalize(light.position - fragPos);
|
||||
// diffuse shading
|
||||
float diff = max(dot(normal, lightDir), 0.0);
|
||||
// specular shading
|
||||
vec3 reflectDir = reflect(-lightDir, normal);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
|
||||
// attenuation
|
||||
float distance = length(light.position - fragPos);
|
||||
float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
|
||||
// spotlight intensity
|
||||
float theta = dot(lightDir, normalize(-light.direction));
|
||||
float epsilon = light.cutOff - light.outerCutOff;
|
||||
float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0);
|
||||
// combine results
|
||||
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
|
||||
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
|
||||
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
|
||||
ambient *= attenuation * intensity;
|
||||
diffuse *= attenuation * intensity;
|
||||
specular *= attenuation * intensity;
|
||||
return (ambient + diffuse + specular);
|
||||
}
|
||||
|
||||
97
src/main/resources/Shaders/backup/NewVertexShader.vs
Normal file
@ -0,0 +1,97 @@
|
||||
//Vertex Shader
|
||||
#version 430 core
|
||||
|
||||
|
||||
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec4 aWeights;
|
||||
layout (location = 3) in vec4 aIndex;
|
||||
layout (location = 4) in vec2 aText;
|
||||
|
||||
|
||||
|
||||
uniform mat4 transform;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
|
||||
const int MAX_BONES = 100;
|
||||
uniform mat4 bones[MAX_BONES];
|
||||
uniform int hasBones;
|
||||
uniform int numBones;
|
||||
|
||||
uniform int hasTexture;
|
||||
|
||||
|
||||
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec2 TexCoords;
|
||||
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 FinalVertex = vec4(aPos, 1.0);
|
||||
vec4 FinalNormal = vec4(aNormal, 0.0);
|
||||
if(hasBones == 1){
|
||||
//mat4 BoneTransform;
|
||||
//for(int i = 0; i < MAX_BONES; i++){
|
||||
// if(i < numBones){
|
||||
// BoneTransform += bones[i] * aWeights[i];
|
||||
// }
|
||||
//}
|
||||
//vec4 FinalVertex = vec4(aPos, 1.0);
|
||||
//vec4 FinalNormal = vec4(aNormal, 1.0);
|
||||
//mat4 BoneTransform;
|
||||
//BoneTransform = mat4(
|
||||
// 1.0,0.0,0.0,0.0,
|
||||
// 0.0,1.0,0.0,0.0,
|
||||
// 0.0,0.0,1.0,0.0,
|
||||
// 0.0,0.0,0.0,1.0);
|
||||
//BoneTransform = BoneTransform * mat4(
|
||||
// 1.0,0.0,0.0,0.0,
|
||||
// 0.0,1.0,0.0,0.0,
|
||||
// 0.0,0.0,2.0,0.0,
|
||||
// 0.0,0.0,0.0,1.0);
|
||||
//BoneTransform = BoneTransform * bones[aIndex[0]] * aWeights[0];
|
||||
//BoneTransform += bones[aIndex[0]] * 1.0;
|
||||
//BoneTransform += bones[aIndex[1]] * aWeights[1];
|
||||
//BoneTransform += bones[aIndex[2]] * aWeights[2];
|
||||
//BoneTransform += bones[aIndex[3]] * aWeights[3];
|
||||
//FinalVertex = BoneTransform * FinalVertex;
|
||||
vec4 inputVertex = FinalVertex;
|
||||
vec4 inputNormal = FinalNormal;
|
||||
//mat4 BoneTransform;
|
||||
//BoneTransform = bones[int(aIndex[0])] * aWeights[0];
|
||||
//BoneTransform += bones[int(aIndex[1])] * aWeights[1];
|
||||
//BoneTransform += bones[int(aIndex[2])] * aWeights[2];
|
||||
//BoneTransform += bones[int(aIndex[3])] * aWeights[3];
|
||||
//FinalVertex = BoneTransform * inputVertex;
|
||||
//FinalNormal = BoneTransform * inputNormal;
|
||||
FinalVertex = (bones[int(aIndex[0])] * inputVertex) * aWeights[0];
|
||||
FinalVertex = (bones[int(aIndex[1])] * inputVertex) * aWeights[1] + FinalVertex;
|
||||
FinalVertex = (bones[int(aIndex[2])] * inputVertex) * aWeights[2] + FinalVertex;
|
||||
FinalVertex = (bones[int(aIndex[3])] * inputVertex) * aWeights[3] + FinalVertex;
|
||||
FinalNormal = (bones[int(aIndex[0])] * inputNormal) * aWeights[0];
|
||||
FinalNormal = (bones[int(aIndex[1])] * inputNormal) * aWeights[1] + FinalNormal;
|
||||
FinalNormal = (bones[int(aIndex[2])] * inputNormal) * aWeights[2] + FinalNormal;
|
||||
FinalNormal = (bones[int(aIndex[3])] * inputNormal) * aWeights[3] + FinalNormal;
|
||||
} else {
|
||||
//gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
}
|
||||
|
||||
vec2 FinalTexture = vec2(1.0,1.0);
|
||||
if(hasTexture == 1){
|
||||
FinalTexture = aText;
|
||||
}
|
||||
TexCoords = FinalTexture;
|
||||
|
||||
FragPos = vec3(model * FinalVertex);
|
||||
Normal = vec3(transpose(inverse(model)) * FinalNormal);
|
||||
gl_Position = projection * view * model * FinalVertex;
|
||||
}
|
||||
13
src/main/resources/Shaders/old/LampShader.fs
Normal file
@ -0,0 +1,13 @@
|
||||
//Fragment Shader
|
||||
#version 330 core
|
||||
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform vec3 objectColor;
|
||||
uniform vec3 lightColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(1.0);
|
||||
}
|
||||
68
src/main/resources/Shaders/old/VertexShader.vs
Normal file
@ -0,0 +1,68 @@
|
||||
//Vertex Shader
|
||||
#version 430 core
|
||||
|
||||
|
||||
|
||||
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
layout (location = 2) in vec4 aWeights;
|
||||
layout (location = 3) in ivec4 aIndex;
|
||||
|
||||
|
||||
|
||||
uniform mat4 transform;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
|
||||
const int MAX_BONES = 100;
|
||||
uniform mat4 bones[MAX_BONES];
|
||||
uniform int hasBones;
|
||||
uniform int numBones;
|
||||
|
||||
|
||||
|
||||
out vec3 Normal;
|
||||
out vec3 FragPos;
|
||||
out vec2 TexCoords;
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
if(hasBones == 1){
|
||||
//mat4 BoneTransform;
|
||||
//for(int i = 0; i < MAX_BONES; i++){
|
||||
// if(i < numBones){
|
||||
// BoneTransform += bones[i] * aWeights[i];
|
||||
// }
|
||||
//}
|
||||
mat4 BoneTransform;
|
||||
BoneTransform = mat4(
|
||||
1.0,0.0,0.0,0.0,
|
||||
0.0,1.0,0.0,0.0,
|
||||
0.0,0.0,1.0,0.0,
|
||||
0.0,0.0,0.0,1.0);
|
||||
//BoneTransform = BoneTransform * mat4(
|
||||
// 1.0,0.0,0.0,0.0,
|
||||
// 0.0,1.0,0.0,0.0,
|
||||
// 0.0,0.0,2.0,0.0,
|
||||
// 0.0,0.0,0.0,1.0);
|
||||
BoneTransform = BoneTransform * bones[aIndex[0]] * aWeights[0];
|
||||
BoneTransform += BoneTransform * bones[aIndex[1]] * aWeights[1];
|
||||
BoneTransform += BoneTransform * bones[aIndex[2]] * aWeights[2];
|
||||
BoneTransform += BoneTransform * bones[aIndex[3]] * aWeights[3];
|
||||
//BoneTransform += bones[aIndex[0]] * 1.0;
|
||||
//BoneTransform += bones[aIndex[1]] * aWeights[1];
|
||||
//BoneTransform += bones[aIndex[2]] * aWeights[2];
|
||||
//BoneTransform += bones[aIndex[3]] * aWeights[3];
|
||||
gl_Position = projection * view * model * BoneTransform * vec4(aPos, 1.0);
|
||||
} else {
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
}
|
||||
FragPos = vec3(model * vec4(aPos, 1.0));
|
||||
Normal = vec3(vec4(aNormal, 1.0));
|
||||
TexCoords = vec2(0.5, 0.5);
|
||||
}
|
||||
61
src/main/resources/Shaders/old/old shader code
Normal file
@ -0,0 +1,61 @@
|
||||
//Vertex Shader
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
//layout (location = 1) in vec3 aColor;
|
||||
//layout (location = 1) in vec2 aTexCoord;
|
||||
//layout (location = 2) in vec3 aNormal;
|
||||
|
||||
//out vec3 ourColor;
|
||||
|
||||
//uniform vec3 offset;
|
||||
|
||||
uniform mat4 transform;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
//out vec3 ourPos;
|
||||
//out vec2 TexCoord;
|
||||
//out vec3 FragPos;
|
||||
//out vec3 Normal;
|
||||
void main()
|
||||
{
|
||||
//gl_Position = vec4(aPos, 1.0);
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
//ourColor = aColor;
|
||||
//FragPos = vec3(model * vec4(aPos, 1.0));
|
||||
//TexCoord = aTexCoord;
|
||||
//Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//Fragment Shader
|
||||
#version 330 core
|
||||
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
//in vec3 ourColor;
|
||||
|
||||
//in vec2 TexCoord;
|
||||
//uniform sampler2D ourTexture1;
|
||||
//uniform sampler2D ourTexture2;
|
||||
//in vec3 Normal;
|
||||
//uniform vec3 lightPos;
|
||||
//in vec3 FragPos;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
//vec3 lightColor = vec3(1.0, 1.0, 1.0);
|
||||
//vec3 norm = normalize(Normal);
|
||||
//vec3 lightDir = normalize(lightPos - FragPos);
|
||||
//float diff = max(dot(Normal, lightDir), 0.0);
|
||||
//vec3 diffuse = diff * lightColor;
|
||||
//vec3 result = diffuse * objectColor;
|
||||
//FragColor = mix(texture(ourTexture1, TexCoord), texture(ourTexture2, TexCoord), 0.2);// - (vec4(diffuse, 1.0)*0.2);// * vec4(ourColor, 1.0);
|
||||
FragColor = vec4(0.5, 0.5, 0.5, 1.0);
|
||||
}
|
||||
34
src/main/resources/Shaders/old/oldFragShader.fs
Normal file
@ -0,0 +1,34 @@
|
||||
//Fragment Shader
|
||||
#version 330 core
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
|
||||
uniform vec3 objectColor;
|
||||
uniform vec3 lightColor;
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 viewPos;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
//Diffuse calculations..
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 lightDir = normalize(lightPos - FragPos);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = diff * lightColor;
|
||||
//Ambient Light
|
||||
float ambientStrength = 0.5;
|
||||
vec3 ambient = ambientStrength * lightColor;
|
||||
//Specular calculations..
|
||||
float specularStrength = 0.5;
|
||||
vec3 viewDir = normalize(viewPos - FragPos);
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
|
||||
vec3 specular = specularStrength * spec * lightColor;
|
||||
//result color
|
||||
vec3 result = (ambient + diffuse + specular) * objectColor;
|
||||
//push output color
|
||||
FragColor = vec4(result, 1.0);
|
||||
}
|
||||
13
src/main/resources/Shaders/skybox/FragmentShaderNoTexture.fs
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
#version 430 core
|
||||
out vec4 FragColor;
|
||||
|
||||
|
||||
in vec3 color;
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
34
src/main/resources/Shaders/skybox/VertexShaderNoTexture.vs
Normal file
@ -0,0 +1,34 @@
|
||||
//Vertex Shader
|
||||
#version 430 core
|
||||
|
||||
|
||||
|
||||
//input buffers
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in float id;
|
||||
|
||||
|
||||
//coordinate space transformation matrices
|
||||
uniform mat4 transform;
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
|
||||
|
||||
uniform vec3 colors[8];
|
||||
|
||||
out vec3 color;
|
||||
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
//normalize posiiton and normal
|
||||
vec4 FinalVertex = vec4(aPos, 1.0);
|
||||
//send color to the frag shader
|
||||
color = colors[int(id)];
|
||||
//set final position with opengl space
|
||||
vec4 pos = projection * view * FinalVertex;
|
||||
gl_Position = pos.xyww;
|
||||
}
|
||||
BIN
src/main/resources/Textures/Fonts/OpenSansBitmap.bmp
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
src/main/resources/Textures/Ground/Dirt1.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
src/main/resources/Textures/Ground/Road1.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/main/resources/Textures/Ground/RoadIntersection1.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/main/resources/Textures/MonorailSupport.png
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
src/main/resources/Textures/RailTrack1Part1.png
Normal file
|
After Width: | Height: | Size: 5.8 KiB |
BIN
src/main/resources/Textures/Spaceplane.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
src/main/resources/Textures/SpaceplaneSpecular.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/main/resources/Textures/Wheat1stretch.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/main/resources/Textures/default_diffuse.png
Normal file
|
After Width: | Height: | Size: 967 B |
BIN
src/main/resources/Textures/default_specular.png
Normal file
|
After Width: | Height: | Size: 967 B |
22
src/main/resources/Textures/default_texture_map.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"texture_map": {
|
||||
"Models/plane.fbx": {
|
||||
"Cube": [
|
||||
"Textures/Ground/Dirt1.png",
|
||||
"Textures/Ground/Dirt1.png"
|
||||
]
|
||||
},
|
||||
"Models/arcdock5deg1notex.fbx": {
|
||||
"Cube": [
|
||||
"Textures/w1.png",
|
||||
"Textures/w1.png"
|
||||
]
|
||||
},
|
||||
"Models/Wheat1.fbx": {
|
||||
"Stalk": [
|
||||
"Textures/Wheat1stretch.png",
|
||||
"Textures/Wheat1stretch.png"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
src/main/resources/Textures/leaves.png
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
src/main/resources/Textures/skyscraper1_diffuse.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
src/main/resources/Textures/trunk.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/main/resources/Textures/w1.png
Normal file
|
After Width: | Height: | Size: 165 B |