Compare commits
6 Commits
bc66523cde
...
f7887fc875
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7887fc875 | ||
|
|
0db8734f44 | ||
|
|
29299a7781 | ||
|
|
14d423d533 | ||
|
|
e5a187ce19 | ||
|
|
df4fe45dd5 |
6
.gitignore
vendored
6
.gitignore
vendored
@ -33,6 +33,9 @@
|
||||
/saves/random_sp_world
|
||||
/saves/defaultLevel*
|
||||
|
||||
#screenshots
|
||||
/assets/Screenshots
|
||||
|
||||
#debug
|
||||
/netmonitor
|
||||
|
||||
@ -45,3 +48,6 @@
|
||||
|
||||
#imgui local layout
|
||||
/imgui.ini
|
||||
|
||||
#script engine related
|
||||
/assets/Scripts/compiler/typescript.js
|
||||
|
||||
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
@ -4,5 +4,7 @@
|
||||
"**/.git/objects/**": true,
|
||||
"**/node_modules/**": true
|
||||
},
|
||||
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable"
|
||||
"java.jdt.ls.vmargs": "-XX:+UseParallelGC -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -Dsun.zip.disableMemoryMapping=true -Xmx2G -Xms100m -Xlog:disable",
|
||||
"javascript.preferences.importModuleSpecifier": "non-relative",
|
||||
"typescript.preferences.importModuleSpecifier": "non-relative"
|
||||
}
|
||||
@ -16,6 +16,11 @@
|
||||
"Green Grass"
|
||||
],
|
||||
"texture" : "/Textures/Ground/GrassTileable256.png"
|
||||
},
|
||||
{
|
||||
"id" : 3,
|
||||
"name" : "baguette",
|
||||
"texture" : "/Textures/Ground/baguette256.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
119
assets/Scripts/compiler/compiler.js
Normal file
119
assets/Scripts/compiler/compiler.js
Normal file
@ -0,0 +1,119 @@
|
||||
|
||||
/**
|
||||
* The map of all source files to their content and compiled value
|
||||
*/
|
||||
let COMPILER_fileMap = { }
|
||||
|
||||
/**
|
||||
* The compiled program
|
||||
*/
|
||||
let COMPILER_emitted_value = ''
|
||||
|
||||
|
||||
/**
|
||||
* Registers a file with the compiler
|
||||
* @param {*} fileName The file's name
|
||||
* @param {*} content The content of the file
|
||||
*/
|
||||
const COMPILER_registerFile = (fileName, content) => {
|
||||
let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName,false)
|
||||
loggerScripts.INFO('REGISTER FILE ' + normalizedFilePath)
|
||||
COMPILER_fileMap[normalizedFilePath] = {
|
||||
content: content,
|
||||
compiled: ts.createSourceFile(
|
||||
normalizedFilePath, content, ts.ScriptTarget.Latest
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The callback invoked when the compiler host tries to read a file
|
||||
* @param {*} fileName The name of the file
|
||||
* @param {*} languageVersion The language version
|
||||
* @returns The file if it exists, null otherwise
|
||||
*/
|
||||
const COMPILER_getSourceFile = (fileName, languageVersion) => {
|
||||
if(!!COMPILER_fileMap[fileName]){
|
||||
return COMPILER_fileMap[fileName].compiled
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructs the compiler host
|
||||
* https://www.typescriptlang.org/tsconfig/#compilerOptions
|
||||
*/
|
||||
const COMPILER_customCompilerHost = {
|
||||
getSourceFile: COMPILER_getSourceFile,
|
||||
writeFile: (fileName, data) => {
|
||||
let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName)
|
||||
loggerScripts.INFO("EMIT FILE " + normalizedFilePath)
|
||||
let finalData =
|
||||
"let exports = { }\n" +
|
||||
data + "\n" +
|
||||
"return exports"
|
||||
// COMPILER_emitted_value = data
|
||||
COMPILER_fileMap[normalizedFilePath] = {
|
||||
content: data, //to be eval'd from top level
|
||||
moduleContent: finalData, //to be eval'd from require()
|
||||
}
|
||||
},
|
||||
getDefaultLibFileName: () => "lib.d.ts",
|
||||
useCaseSensitiveFileNames: () => false,
|
||||
getCanonicalFileName: filename => filename,
|
||||
getCurrentDirectory: () => "",
|
||||
getNewLine: () => "\n",
|
||||
getDirectories: () => [],
|
||||
fileExists: () => true,
|
||||
readFile: () => ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Instructs Typescript to emit the final compiled value
|
||||
*/
|
||||
const COMPILER_run = () => {
|
||||
loggerScripts.INFO('COMPILE ALL REGISTERED FILES')
|
||||
|
||||
const compilerOptions = { }
|
||||
|
||||
const COMPILER_program = ts.createProgram(
|
||||
Object.keys(COMPILER_fileMap), compilerOptions, COMPILER_customCompilerHost
|
||||
)
|
||||
COMPILER_program.emit()
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a file
|
||||
* @param {*} fileName The name of the file to load (preferably already has .ts at the end)
|
||||
*/
|
||||
const COMPILER_runFile = (fileName) => {
|
||||
let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName)
|
||||
if(!!COMPILER_fileMap[normalizedFilePath]){
|
||||
loggerScripts.INFO('RUN FILE ' + normalizedFilePath)
|
||||
eval(COMPILER_fileMap[normalizedFilePath].content)
|
||||
} else {
|
||||
const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath
|
||||
loggerScripts.WARNING(message)
|
||||
throw new Error(message)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a file
|
||||
* @param {*} fileName The name of the file to load (preferably already has .ts at the end)
|
||||
*/
|
||||
const COMPILER_printSource = (fileName) => {
|
||||
let normalizedFilePath = FILE_RESOLUTION_getFilePath(fileName)
|
||||
if(!!COMPILER_fileMap[normalizedFilePath]){
|
||||
loggerScripts.INFO('FILE CONTENT ' + normalizedFilePath)
|
||||
} else {
|
||||
const message = 'FAILED TO RESOLVE FILE ' + normalizedFilePath
|
||||
loggerScripts.WARNING(message)
|
||||
loggerScripts.WARNING('file map content:')
|
||||
loggerScripts.WARNING(OBject.keys(COMPILER_fileMap) + "")
|
||||
throw new Error(message)
|
||||
}
|
||||
}
|
||||
23
assets/Scripts/compiler/file_resolution.js
Normal file
23
assets/Scripts/compiler/file_resolution.js
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
/**
|
||||
* Normalizes a file path
|
||||
* @param {*} rawFilePath The raw file path
|
||||
* @returns The normalized file path
|
||||
*/
|
||||
const FILE_RESOLUTION_getFilePath = (rawFilePath, isJavascript = true) => {
|
||||
let fileName = rawFilePath
|
||||
if(isJavascript && fileName.includes('.ts')){
|
||||
fileName = fileName.replace('.ts','.js')
|
||||
}
|
||||
if(fileName.startsWith('/Scripts')){
|
||||
fileName = fileName.replace('/Scripts','')
|
||||
}
|
||||
if(fileName.startsWith('Scripts/')){
|
||||
fileName = fileName.replace('Scripts/','/')
|
||||
}
|
||||
if(isJavascript && !fileName.endsWith(".js")){
|
||||
fileName = fileName + ".js"
|
||||
}
|
||||
return fileName
|
||||
}
|
||||
|
||||
1
assets/Scripts/compiler/get_typescript.sh
Normal file
1
assets/Scripts/compiler/get_typescript.sh
Normal file
@ -0,0 +1 @@
|
||||
wget -O typescript.js https://unpkg.com/typescript@latest/lib/typescript.js
|
||||
21
assets/Scripts/compiler/host_access.js
Normal file
21
assets/Scripts/compiler/host_access.js
Normal file
@ -0,0 +1,21 @@
|
||||
|
||||
/**
|
||||
* The host context that contains the core engine functions
|
||||
*/
|
||||
let HOST_ACCESS = {
|
||||
classes: { }, //the classes available to the script engine
|
||||
singletons: { }, //the singletons available to the script engine
|
||||
}
|
||||
|
||||
//fake require
|
||||
REQUIRE_CACHE["/compiler/host_access.js"] = {
|
||||
exports: {
|
||||
'HOST_ACCESS': HOST_ACCESS,
|
||||
'loggerScripts': loggerScripts,
|
||||
},
|
||||
exportedValues: [
|
||||
'HOST_ACCESS',
|
||||
'loggerScripts'
|
||||
],
|
||||
}
|
||||
|
||||
43
assets/Scripts/compiler/require_polyfill.js
Normal file
43
assets/Scripts/compiler/require_polyfill.js
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
/**
|
||||
* Caches loaded modules
|
||||
*/
|
||||
let REQUIRE_CACHE = { }
|
||||
|
||||
/**
|
||||
* Used if the module is directly executed instead of being require'd for some reason
|
||||
*/
|
||||
let exports = { }
|
||||
|
||||
/**
|
||||
* Imports a module
|
||||
* @param {*} path The path of the module
|
||||
* @param {*} cwd The current working directory
|
||||
*/
|
||||
const require = (path) => {
|
||||
loggerScripts.DEBUG('Require path ' + path)
|
||||
let normalizedFilePath = FILE_RESOLUTION_getFilePath(path)
|
||||
if(!!REQUIRE_CACHE[normalizedFilePath]){
|
||||
return REQUIRE_CACHE[normalizedFilePath].exports
|
||||
} else if(!!COMPILER_fileMap[normalizedFilePath]?.content) {
|
||||
const code = COMPILER_fileMap[normalizedFilePath].moduleContent
|
||||
let exports = new Function(code)()
|
||||
//create module object
|
||||
const module = {
|
||||
exports: exports,
|
||||
exportedValues: Object.keys(exports),
|
||||
}
|
||||
REQUIRE_CACHE[normalizedFilePath] = module
|
||||
loggerScripts.INFO("[require] CREATE MODULE " + normalizedFilePath)
|
||||
return module.exports
|
||||
} else {
|
||||
const errorMsg = "FAILED TO REQUIRE FILE " + normalizedFilePath
|
||||
loggerScripts.WARNING(errorMsg)
|
||||
loggerScripts.WARNING('Module value:')
|
||||
loggerScripts.WARNING(Object.keys(REQUIRE_CACHE?.[normalizedFilePath]) + '')
|
||||
loggerScripts.WARNING('Require cache contents:')
|
||||
loggerScripts.WARNING(Object.keys(REQUIRE_CACHE) + '')
|
||||
throw new Error(errorMsg)
|
||||
}
|
||||
}
|
||||
11
assets/Scripts/engine/engine-init.ts
Normal file
11
assets/Scripts/engine/engine-init.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Host } from '/engine/engine-interface'
|
||||
import { loggerScripts } from '/compiler/host_access'
|
||||
|
||||
let host: Host
|
||||
|
||||
/**
|
||||
* Called when the script engine first initializes
|
||||
*/
|
||||
export const ENGINE_onInit = () => {
|
||||
loggerScripts.INFO('Script Engine Init')
|
||||
}
|
||||
9
assets/Scripts/engine/engine-interface.ts
Normal file
9
assets/Scripts/engine/engine-interface.ts
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
|
||||
/**
|
||||
* The host context that contains all core engine functions
|
||||
*/
|
||||
export interface Host {
|
||||
classes: any, //the host's view of the scripting engine
|
||||
singletons: any, //the singletons available to the script engine
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
console.log("test")
|
||||
@ -1,3 +1,3 @@
|
||||
#maven.buildNumber.plugin properties file
|
||||
#Wed Jun 19 19:19:09 EDT 2024
|
||||
buildNumber=138
|
||||
#Wed Jul 03 15:06:42 EDT 2024
|
||||
buildNumber=149
|
||||
|
||||
@ -5,3 +5,4 @@
|
||||
- @subpage largelocationideas
|
||||
- @subpage macrolocationideas
|
||||
- @subpage smalllocations
|
||||
- @subpage minidungeons
|
||||
4
docs/src/highlevel-design/locations/minidungeons.md
Normal file
4
docs/src/highlevel-design/locations/minidungeons.md
Normal file
@ -0,0 +1,4 @@
|
||||
@page minidungeons Mini Dungeons
|
||||
|
||||
In certain levels, you can find premade characters that can join your party.
|
||||
|
||||
@ -17,11 +17,11 @@ Audio FX for everything
|
||||
= Coding =
|
||||
Sub menu on title screen that allows changing control mappings
|
||||
- Automatically generate based on the controls arrays in controls handler
|
||||
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||
- Introduce block hitbox (blockbox) type
|
||||
- Sour spot, sweet spot for damage hitboxes and hurtboxes
|
||||
Review combat code
|
||||
- Damage calculation
|
||||
- Particle generation
|
||||
- Revive tree
|
||||
Enemy AI
|
||||
better scaffolding for scriptig engine with hooks for equipping items, spawning entities, pausing/resuming play, etc
|
||||
Ability for private realms to have time start/stop based on the player's feedback <-- sync this up to tutorial ui via script
|
||||
Scene Message Service
|
||||
- Can send arbitrary events and messages
|
||||
|
||||
@ -406,6 +406,21 @@ Audio
|
||||
- Sword Hit Metal
|
||||
- Sword Hit Flesh
|
||||
|
||||
(07/02/2024)
|
||||
better scaffolding for scripting engine with hooks for equipping items, spawning entities, pausing/resuming play, etc
|
||||
Redo hitboxes to have capsules and also chaining between frames (but not between swinging the camera around)
|
||||
- Introduce block hitbox (blockbox) type
|
||||
- Sour spot, sweet spot for damage hitboxes and hurtboxes
|
||||
|
||||
(07/03/2024)
|
||||
Clean up framebuffer class
|
||||
- Comment everything
|
||||
- Error checking
|
||||
Overhaul opengl error checking generally (as in, actually use it)
|
||||
- Add all over the place to help debugging graphics issues
|
||||
- Handle uniforms being sent to shaders that don't have the uniform defined
|
||||
Extracting pixels from framebuffers
|
||||
|
||||
|
||||
# TODO
|
||||
|
||||
@ -413,8 +428,10 @@ Audio
|
||||
BIG BIG BIG BIG IMMEDIATE TO DO:
|
||||
always enforce opengl interface across all opengl calls jesus christ the bone uniform bug was impossible
|
||||
|
||||
|
||||
|
||||
Unit Testing
|
||||
- Capture image from opengl to pixel-check
|
||||
- Ability to click through the ui via scripts
|
||||
- Add ui tests
|
||||
|
||||
|
||||
Goof off today requirements:
|
||||
@ -429,6 +446,9 @@ Transvoxel implementation
|
||||
- Ability to get terrain at point for interactions with game world eg placing grass/water collision
|
||||
|
||||
|
||||
Fix not all grass tiles update when updating a nearby voxel (ie it doesn't go into negative coordinates to scan for foliage updates)
|
||||
|
||||
Refactor menu clases under electrosphere.client package
|
||||
|
||||
Allow texture map to bind multiple model paths to a single set of mesh->textures
|
||||
|
||||
@ -460,9 +480,6 @@ Data Cleanup
|
||||
Clean up Material class
|
||||
- fix storing textures in the mat class ( pain :c )
|
||||
|
||||
Clean up framebuffer class
|
||||
- Comment everything
|
||||
|
||||
Overhaul of 'attach' semantics
|
||||
- Having different types of attach tree propagation
|
||||
- Ability to turn on/off combinations of models at will (already exists, but needs review)
|
||||
|
||||
20
pom.xml
20
pom.xml
@ -13,6 +13,7 @@
|
||||
<joml.version>1.9.19</joml.version>
|
||||
<recast.version>1.5.7</recast.version>
|
||||
<imgui.version>1.86.11</imgui.version>
|
||||
<graalvm.version>23.1.3</graalvm.version>
|
||||
</properties>
|
||||
|
||||
<!-- Used for build number plugin because it LITERALLY WONT LET YOU NOT HAVE SCM-->
|
||||
@ -173,18 +174,21 @@
|
||||
<!--GraalVM-->
|
||||
<!--License: GPLv2 w/ classpath exception-->
|
||||
<!--apparently maybe classpath exception allows use in eg game engine??-->
|
||||
<!-- https://mvnrepository.com/artifact/org.graalvm.js/js -->
|
||||
<dependency>
|
||||
<groupId>org.graalvm.js</groupId>
|
||||
<artifactId>js</artifactId>
|
||||
<version>22.1.0.1</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.graalvm.js/js-scriptengine -->
|
||||
<dependency>
|
||||
<groupId>org.graalvm.js</groupId>
|
||||
<artifactId>js-scriptengine</artifactId>
|
||||
<version>22.1.0.1</version>
|
||||
<version>${graalvm.version}</version>
|
||||
</dependency>
|
||||
<!-- https://mvnrepository.com/artifact/org.graalvm.polyglot/js-community -->
|
||||
<dependency>
|
||||
<groupId>org.graalvm.polyglot</groupId>
|
||||
<artifactId>js-community</artifactId>
|
||||
<version>${graalvm.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
<!--steamworks4j-->
|
||||
<!--License: MIT-->
|
||||
@ -326,6 +330,8 @@
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
|
||||
<mainClass>electrosphere.engine.Main</mainClass>
|
||||
</transformer>
|
||||
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer">
|
||||
</transformer>
|
||||
</transformers>
|
||||
</configuration>
|
||||
</execution>
|
||||
|
||||
@ -491,6 +491,182 @@ public class DrawCellManager {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
transvoxel algorithm spacing management
|
||||
|
||||
want to specify a radius and have it be a circle so we're not wasting resolution on far off corners
|
||||
To benefit from the LOD, should have a series of for loops
|
||||
First loop iterates over (-largest radius) -> (largest radius) at an interval of the width of the lowest level of detail chunk
|
||||
We check all 8 corners of the chunk to see if they all fall within the largest lod concentric circle
|
||||
There are a few cases to consider
|
||||
- All fall outside the largest LOD radius (ignore)
|
||||
- All but one fall outside thel argest LOD radius (ignore)
|
||||
- All fall within the largest LOD circle (make LOD chunk)
|
||||
- One is within the next LOD radius, others are within the current LOD radius (ignore for this pass)
|
||||
- All are within a lower LOD radius (ignore)
|
||||
|
||||
Once we're done with the largest LOD radius, we go to a higher resolution radius and iterate for smaller bounds
|
||||
|
||||
In a middle LOD level, if all corners are outside, but the lower resolution didn't
|
||||
already pick it up, still need to generate a chunk at the current resolution
|
||||
|
||||
Detection of this case is tricky
|
||||
We could snap the currently considered position to the nearest low-resolution chunk and then bounds check that low resolution chunk for every
|
||||
higher resolution position we're considering
|
||||
This is probably a bad idea
|
||||
|
||||
We could recurse every time a chunk doesn't work for the current level of detail, then evaluate it for a higher level of detail at this closer value
|
||||
|
||||
*/
|
||||
|
||||
//the number of corners to consider for a valid chunk
|
||||
static final int NUM_CORNERS_TO_CONSIDER = 8;
|
||||
|
||||
//offsets to get from current position to the actual corner to consider
|
||||
int[] cornerOffsetsX = new int[]{0,1,0,1,0,1,0,1,};
|
||||
int[] cornerOffsetsY = new int[]{0,0,0,0,1,1,1,1,};
|
||||
int[] cornerOffsetsZ = new int[]{0,0,1,1,0,0,1,1,};
|
||||
|
||||
/**
|
||||
* Recursive function that does chunk validity checking
|
||||
* @param playerChunkPos
|
||||
* @param minPoint
|
||||
* @param maxPoint
|
||||
* @param currentLOD
|
||||
*/
|
||||
public void assesChunkPositionsAtLOD(
|
||||
Vector3i playerChunkPos,
|
||||
Vector3i minPoint,
|
||||
Vector3i maxPoint,
|
||||
int currentLOD
|
||||
){
|
||||
Vector3i currentChunkPositionConsidered = new Vector3i(playerChunkPos); // The chunk position we're currently considering
|
||||
double currentRadius = lodLevelRadiusTable[currentLOD];
|
||||
double nextRadius = 0;
|
||||
int increment = 1;
|
||||
if(currentLOD > 0){
|
||||
//only works when the LOD is greater than 0. When it's 0, there is no lower bound on chunk positions to generate
|
||||
nextRadius = lodLevelRadiusTable[currentLOD-1];
|
||||
increment = (int)Math.pow(2,currentLOD);
|
||||
}
|
||||
|
||||
//iterate
|
||||
for(int x = minPoint.x; x < maxPoint.x; x = x + increment){
|
||||
for(int y = minPoint.y; y < maxPoint.x; y = y + increment){
|
||||
for(int z = minPoint.z; z < maxPoint.x; z = z + increment){
|
||||
//we have 8 corners to consider
|
||||
//need to identify which case the current position is
|
||||
int positionCase = 0;
|
||||
for(int j = 0; j < NUM_CORNERS_TO_CONSIDER; j++){
|
||||
currentChunkPositionConsidered.set(
|
||||
x + cornerOffsetsX[j] * increment,
|
||||
y + cornerOffsetsY[j] * increment,
|
||||
z + cornerOffsetsZ[j] * increment
|
||||
);
|
||||
//figure out the case of this corner
|
||||
double distance = currentChunkPositionConsidered.distance(playerChunkPos);
|
||||
if(distance > currentRadius){
|
||||
positionCase = 1;
|
||||
break;
|
||||
} else if(distance <= nextRadius){
|
||||
positionCase = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch(positionCase){
|
||||
case 0: {
|
||||
//fully within current band, generate chunk
|
||||
} break;
|
||||
case 1: {
|
||||
//partially outside bound, ignore
|
||||
} break;
|
||||
case 2: {
|
||||
//partially inside higher resolution bound, recurse
|
||||
assesChunkPositionsAtLOD(
|
||||
playerChunkPos,
|
||||
new Vector3i(x,y,z),
|
||||
new Vector3i(x+increment,y+increment,z+increment),
|
||||
currentLOD
|
||||
);
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assess all LOD chunk levels
|
||||
*/
|
||||
public void assesLODChunks(){
|
||||
|
||||
//pre-existing values
|
||||
Vector3d playerPosition = EntityUtils.getPosition(Globals.playerEntity);
|
||||
Vector3i playerChunkPosition = Globals.clientWorldData.convertRealToChunkSpace(playerPosition);
|
||||
|
||||
//variables used while iterating across chunk positions
|
||||
double currentRadius = 0; //the current radius is in units of chunks, even though it's a double (it's discrete, not real)
|
||||
double nextRadius = 0; //the next radius is in units of chunks, even though it's a double (it's discrete, not real)
|
||||
int increment = 1; //the increment is in units of chunks, not real
|
||||
//the offsets from the player's position to
|
||||
//the nearest possible spot we could place a chunk of the current LOD at (in units of chunks)
|
||||
Vector3i lowerOffsets = new Vector3i(0,0,0);
|
||||
Vector3i currentChunkPositionConsidered = new Vector3i(playerChunkPosition); // The chunk position we're currently considering
|
||||
|
||||
//actual logic to search for valid chunks
|
||||
for(int i = NUMBER_OF_LOD_LEVELS - 1; i >= 0; i--){
|
||||
currentRadius = lodLevelRadiusTable[i];
|
||||
nextRadius = 0;
|
||||
increment = 1;
|
||||
if(i > 0){
|
||||
//only works when the LOD is greater than 0. When it's 0, there is no lower bound on chunk positions to generate
|
||||
nextRadius = lodLevelRadiusTable[i-1];
|
||||
increment = (int)Math.pow(2,i);
|
||||
}
|
||||
//calculate offsets to get from player's current chunk position to the lower resolution grid for the current LOD
|
||||
lowerOffsets.x = playerChunkPosition.x % ((int)increment);
|
||||
lowerOffsets.y = playerChunkPosition.y % ((int)increment);
|
||||
lowerOffsets.z = playerChunkPosition.z % ((int)increment);
|
||||
|
||||
//iterate
|
||||
for(int x = -(int)currentRadius - lowerOffsets.x; x < currentRadius; x = x + increment){
|
||||
for(int y = -(int)currentRadius - lowerOffsets.y; y < currentRadius; y = y + increment){
|
||||
for(int z = -(int)currentRadius - lowerOffsets.z; z < currentRadius; z = z + increment){
|
||||
//we have 8 corners to consider
|
||||
//need to identify which case the current position is
|
||||
int positionCase = 0;
|
||||
for(int j = 0; j < NUM_CORNERS_TO_CONSIDER; j++){
|
||||
currentChunkPositionConsidered.set(
|
||||
x + cornerOffsetsX[j] * increment,
|
||||
y + cornerOffsetsY[j] * increment,
|
||||
z + cornerOffsetsZ[j] * increment
|
||||
);
|
||||
//figure out the case of this corner
|
||||
double distance = currentChunkPositionConsidered.distance(playerChunkPosition);
|
||||
if(distance > currentRadius){
|
||||
positionCase = 1;
|
||||
break;
|
||||
} else if(distance <= nextRadius){
|
||||
positionCase = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch(positionCase){
|
||||
case 0: {
|
||||
//fully within current band, generate chunk
|
||||
} break;
|
||||
case 1: {
|
||||
//partially outside bound, ignore
|
||||
} break;
|
||||
case 2: {
|
||||
//partially inside higher resolution bound, recurse
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -18,6 +18,9 @@ public class Control {
|
||||
ControlType type;
|
||||
boolean state;
|
||||
int keyValue;
|
||||
String name;
|
||||
String description;
|
||||
boolean rebindable;
|
||||
ControlMethod onPress;
|
||||
ControlMethod onRelease;
|
||||
ControlMethod onRepeat;
|
||||
@ -52,10 +55,13 @@ public class Control {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
public Control(ControlType type, int keyValue) {
|
||||
public Control(ControlType type, int keyValue, boolean rebindable, String name, String description) {
|
||||
this.type = type;
|
||||
this.keyValue = keyValue;
|
||||
this.state = false;
|
||||
this.rebindable = rebindable;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public void setOnPress(ControlMethod method){
|
||||
@ -134,6 +140,18 @@ public class Control {
|
||||
repeatTimeout = timeout;
|
||||
}
|
||||
|
||||
public boolean isRebindable(){
|
||||
return rebindable;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription(){
|
||||
return description;
|
||||
}
|
||||
|
||||
|
||||
public interface ControlMethod {
|
||||
public void execute();
|
||||
|
||||
@ -26,6 +26,7 @@ import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F2;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F24;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_F4;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_G;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_H;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_KEY_I;
|
||||
@ -99,6 +100,7 @@ import electrosphere.menu.WindowUtils;
|
||||
import electrosphere.menu.debug.ImGuiWindowMacros;
|
||||
import electrosphere.menu.ingame.MenuGeneratorsInGame;
|
||||
import electrosphere.menu.ingame.MenuGeneratorsInventory;
|
||||
import electrosphere.renderer.RenderingEngine;
|
||||
import electrosphere.renderer.ui.elements.Window;
|
||||
import electrosphere.renderer.ui.events.ClickEvent;
|
||||
import electrosphere.renderer.ui.events.KeyboardEvent;
|
||||
@ -112,6 +114,7 @@ import electrosphere.renderer.ui.events.ScrollEvent;
|
||||
*/
|
||||
public class ControlHandler {
|
||||
|
||||
//main game
|
||||
public static final String INPUT_CODE_CAMERA_ROTATION = "cameraRotation";
|
||||
public static final String DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD = "moveForward";
|
||||
public static final String DATA_STRING_INPUT_CODE_MOVEMENT_BACKWARD = "moveBackward";
|
||||
@ -134,6 +137,8 @@ public class ControlHandler {
|
||||
public static final String INPUT_CODE_PLACE_TERRAIN = "placeTerrain";
|
||||
public static final String INPUT_CODE_REMOVE_TERRAIN = "removeTerrain";
|
||||
|
||||
|
||||
//menu navigation
|
||||
public static final String DATA_STRING_INPUT_CODE_MENU_NAVIGATE_FORWARD = "menuNavigateForward";
|
||||
public static final String DATA_STRING_INPUT_CODE_MENU_NAVIGATE_BACKWARDS = "menuNavigateBackwards";
|
||||
public static final String DATA_STRING_INPUT_CODE_MENU_INCREMENT = "menuIncrement";
|
||||
@ -145,9 +150,11 @@ public class ControlHandler {
|
||||
public static final String MENU_SCROLL = "menuScroll";
|
||||
public static final String MENU_DRAG_MANIPULATE = "menuDragManipulate";
|
||||
public static final String MENU_DRAG_START = "menuDragStart";
|
||||
public static final String MENU_CAPTURE_SCREEN = "menuCaptureScreen";
|
||||
|
||||
|
||||
|
||||
//typing
|
||||
public static final String DATA_STRING_INPUT_CODE_MENU_TYPE_BACKSPACE = "menuTypeBackspace";
|
||||
public static final String DATA_STRING_INPUT_CODE_MENU_TYPE_0 = "menuType0";
|
||||
public static final String DATA_STRING_INPUT_CODE_MENU_TYPE_1 = "menuType1";
|
||||
@ -188,14 +195,16 @@ public class ControlHandler {
|
||||
public static final String DATA_STRING_INPUT_CODE_MENU_TYPE_Z = "menuTypeZ";
|
||||
public static final String INPUT_CODE_MENU_TYPE_FORWARD_SLASH = "menuTypeForwardSlash";
|
||||
|
||||
//inventory
|
||||
public static final String INPUT_CODE_INVENTORY_CLOSE = "inventoryClose";
|
||||
public static final String INPUT_CODE_INVENTORY_ITEM_MANIPULATE = "inventoryItemManipulate";
|
||||
public static final String INPUT_CODE_INVENTORY_ITEM_DRAG = "inventoryDrag";
|
||||
|
||||
//debug
|
||||
public static final String DEBUG_FRAMESTEP = "framestep";
|
||||
public static final String DEBUG_OPEN_DEBUG_MENU = "openDebugMenu";
|
||||
|
||||
|
||||
//freecam
|
||||
public static final String FREECAM_UP = "freecamUp";
|
||||
public static final String FREECAM_DOWN = "freecamDown";
|
||||
public static final String FREECAM_FORWARD = "freecamForward";
|
||||
@ -295,111 +304,112 @@ public class ControlHandler {
|
||||
/*
|
||||
Map the controls
|
||||
*/
|
||||
handler.addControl(INPUT_CODE_CAMERA_ROTATION, new Control(ControlType.MOUSE_MOVEMENT,0));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD, new Control(ControlType.KEY,GLFW_KEY_W));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_BACKWARD, new Control(ControlType.KEY,GLFW_KEY_S));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT, new Control(ControlType.KEY,GLFW_KEY_F24));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT, new Control(ControlType.KEY,GLFW_KEY_F24));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_STRAFE_LEFT, new Control(ControlType.KEY,GLFW_KEY_A));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_STRAFE_RIGHT, new Control(ControlType.KEY,GLFW_KEY_D));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_JUMP, new Control(ControlType.KEY,GLFW_KEY_SPACE));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_FALL, new Control(ControlType.KEY,GLFW_KEY_LEFT_CONTROL));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_LEFT));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU, new Control(ControlType.KEY,GLFW_KEY_ESCAPE));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_LOCK_CROSSHAIR, new Control(ControlType.KEY,GLFW_KEY_CAPS_LOCK));
|
||||
handler.addControl(INPUT_CODE_SPRINT, new Control(ControlType.KEY,GLFW_KEY_LEFT_SHIFT));
|
||||
handler.addControl(INPUT_CODE_INTERACT, new Control(ControlType.KEY,GLFW_KEY_E));
|
||||
handler.addControl(INPUT_CODE_DROP, new Control(ControlType.KEY,GLFW_KEY_Y));
|
||||
handler.addControl(INPUT_CODE_INVENTORY_OPEN, new Control(ControlType.KEY,GLFW_KEY_I));
|
||||
handler.addControl(INPUT_CODE_CHARACTER_OPEN, new Control(ControlType.KEY,GLFW_KEY_C));
|
||||
handler.addControl(ITEM_SECONDARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_RIGHT));
|
||||
handler.addControl(INPUT_CODE_CAMERA_ROTATION, new Control(ControlType.MOUSE_MOVEMENT,0,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_FORWARD, new Control(ControlType.KEY,GLFW_KEY_W,false,"Move Foward","Moves the player forward"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_BACKWARD, new Control(ControlType.KEY,GLFW_KEY_S,false,"Move Backward","Moves the player backward"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_LEFT, new Control(ControlType.KEY,GLFW_KEY_F24,false,"Move Left","Moves the player left"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_RIGHT, new Control(ControlType.KEY,GLFW_KEY_F24,false,"Move Right","Moves the player right"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_STRAFE_LEFT, new Control(ControlType.KEY,GLFW_KEY_A,false,"Strafe Left","Strafes the player left"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_STRAFE_RIGHT, new Control(ControlType.KEY,GLFW_KEY_D,false,"Strafe Right","Strafes the player right"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_JUMP, new Control(ControlType.KEY,GLFW_KEY_SPACE,false,"Jump","Jumps"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MOVEMENT_FALL, new Control(ControlType.KEY,GLFW_KEY_LEFT_CONTROL,false,"Fall","Lowers the camera"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_ATTACK_PRIMARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_LEFT,false,"Attack","Attacks"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU, new Control(ControlType.KEY,GLFW_KEY_ESCAPE,false,"Main Menu","Opens the main menu while in game"));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_LOCK_CROSSHAIR, new Control(ControlType.KEY,GLFW_KEY_CAPS_LOCK,false,"Lock On","Locks the camera onto the target"));
|
||||
handler.addControl(INPUT_CODE_SPRINT, new Control(ControlType.KEY,GLFW_KEY_LEFT_SHIFT,false,"Sprint (hold)","Causes the player to sprint"));
|
||||
handler.addControl(INPUT_CODE_INTERACT, new Control(ControlType.KEY,GLFW_KEY_E,false,"Interact","Interacts with whatever is targeted currently"));
|
||||
handler.addControl(INPUT_CODE_DROP, new Control(ControlType.KEY,GLFW_KEY_Y,false,"Drop","Drops the currently equipped item"));
|
||||
handler.addControl(INPUT_CODE_INVENTORY_OPEN, new Control(ControlType.KEY,GLFW_KEY_I,false,"Inventory","Opens the player's inventory"));
|
||||
handler.addControl(INPUT_CODE_CHARACTER_OPEN, new Control(ControlType.KEY,GLFW_KEY_C,false,"Equip Menu","Opens the player's equipment menu"));
|
||||
handler.addControl(ITEM_SECONDARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_RIGHT,false,"Secondary","Uses the secondary equipped item"));
|
||||
|
||||
/*
|
||||
Map the menu navigation controls
|
||||
*/
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_NAVIGATE_FORWARD, new Control(ControlType.KEY,GLFW_KEY_DOWN));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_NAVIGATE_BACKWARDS, new Control(ControlType.KEY,GLFW_KEY_UP));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_INCREMENT, new Control(ControlType.KEY,GLFW_KEY_RIGHT));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_DECREMENT, new Control(ControlType.KEY,GLFW_KEY_LEFT));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_SELECT, new Control(ControlType.KEY,GLFW_KEY_ENTER));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_BACKOUT, new Control(ControlType.KEY,GLFW_KEY_ESCAPE));
|
||||
handler.addControl(MENU_MOUSE_MOVE, new Control(ControlType.MOUSE_MOVEMENT,0));
|
||||
handler.addControl(INPUT_CODE_MENU_MOUSE_PRIMARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_LEFT));
|
||||
handler.addControl(MENU_SCROLL, new Control(ControlType.MOUSE_SCROLL,0));
|
||||
handler.addControl(MENU_DRAG_START, new Control(ControlType.MOUSE_MOVEMENT,0));
|
||||
handler.addControl(MENU_DRAG_MANIPULATE, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_1));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_NAVIGATE_FORWARD, new Control(ControlType.KEY,GLFW_KEY_DOWN,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_NAVIGATE_BACKWARDS, new Control(ControlType.KEY,GLFW_KEY_UP,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_INCREMENT, new Control(ControlType.KEY,GLFW_KEY_RIGHT,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_DECREMENT, new Control(ControlType.KEY,GLFW_KEY_LEFT,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_SELECT, new Control(ControlType.KEY,GLFW_KEY_ENTER,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_BACKOUT, new Control(ControlType.KEY,GLFW_KEY_ESCAPE,false,"",""));
|
||||
handler.addControl(MENU_MOUSE_MOVE, new Control(ControlType.MOUSE_MOVEMENT,0,false,"",""));
|
||||
handler.addControl(INPUT_CODE_MENU_MOUSE_PRIMARY, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_LEFT,false,"",""));
|
||||
handler.addControl(MENU_SCROLL, new Control(ControlType.MOUSE_SCROLL,0,false,"",""));
|
||||
handler.addControl(MENU_DRAG_START, new Control(ControlType.MOUSE_MOVEMENT,0,false,"",""));
|
||||
handler.addControl(MENU_CAPTURE_SCREEN, new Control(ControlType.KEY,GLFW_KEY_F4,true,"Screenshot","Takes a screenshot of the engine"));
|
||||
handler.addControl(MENU_DRAG_MANIPULATE, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_1,false,"",""));
|
||||
|
||||
/*
|
||||
Map the typing controls
|
||||
*/
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_BACKSPACE, new Control(ControlType.KEY,GLFW_KEY_BACKSPACE));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_0, new Control(ControlType.KEY,GLFW_KEY_0));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_1, new Control(ControlType.KEY,GLFW_KEY_1));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_2, new Control(ControlType.KEY,GLFW_KEY_2));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_3, new Control(ControlType.KEY,GLFW_KEY_3));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_4, new Control(ControlType.KEY,GLFW_KEY_4));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_5, new Control(ControlType.KEY,GLFW_KEY_5));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_6, new Control(ControlType.KEY,GLFW_KEY_6));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_7, new Control(ControlType.KEY,GLFW_KEY_7));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_8, new Control(ControlType.KEY,GLFW_KEY_8));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_9, new Control(ControlType.KEY,GLFW_KEY_9));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_PERIOD, new Control(ControlType.KEY,GLFW_KEY_PERIOD));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_A, new Control(ControlType.KEY,GLFW_KEY_A));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_B, new Control(ControlType.KEY,GLFW_KEY_B));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_C, new Control(ControlType.KEY,GLFW_KEY_C));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_D, new Control(ControlType.KEY,GLFW_KEY_D));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_E, new Control(ControlType.KEY,GLFW_KEY_E));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_F, new Control(ControlType.KEY,GLFW_KEY_F));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_G, new Control(ControlType.KEY,GLFW_KEY_G));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_H, new Control(ControlType.KEY,GLFW_KEY_H));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_I, new Control(ControlType.KEY,GLFW_KEY_I));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_J, new Control(ControlType.KEY,GLFW_KEY_J));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_K, new Control(ControlType.KEY,GLFW_KEY_K));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_L, new Control(ControlType.KEY,GLFW_KEY_L));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_M, new Control(ControlType.KEY,GLFW_KEY_M));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_N, new Control(ControlType.KEY,GLFW_KEY_N));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_O, new Control(ControlType.KEY,GLFW_KEY_O));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_P, new Control(ControlType.KEY,GLFW_KEY_P));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_Q, new Control(ControlType.KEY,GLFW_KEY_Q));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_R, new Control(ControlType.KEY,GLFW_KEY_R));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_S, new Control(ControlType.KEY,GLFW_KEY_S));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_T, new Control(ControlType.KEY,GLFW_KEY_T));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_U, new Control(ControlType.KEY,GLFW_KEY_U));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_V, new Control(ControlType.KEY,GLFW_KEY_V));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_W, new Control(ControlType.KEY,GLFW_KEY_W));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_X, new Control(ControlType.KEY,GLFW_KEY_X));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_Y, new Control(ControlType.KEY,GLFW_KEY_Y));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_Z, new Control(ControlType.KEY,GLFW_KEY_Z));
|
||||
handler.addControl(INPUT_CODE_MENU_TYPE_FORWARD_SLASH, new Control(ControlType.KEY,GLFW_KEY_SLASH));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_BACKSPACE, new Control(ControlType.KEY,GLFW_KEY_BACKSPACE,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_0, new Control(ControlType.KEY,GLFW_KEY_0,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_1, new Control(ControlType.KEY,GLFW_KEY_1,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_2, new Control(ControlType.KEY,GLFW_KEY_2,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_3, new Control(ControlType.KEY,GLFW_KEY_3,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_4, new Control(ControlType.KEY,GLFW_KEY_4,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_5, new Control(ControlType.KEY,GLFW_KEY_5,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_6, new Control(ControlType.KEY,GLFW_KEY_6,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_7, new Control(ControlType.KEY,GLFW_KEY_7,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_8, new Control(ControlType.KEY,GLFW_KEY_8,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_9, new Control(ControlType.KEY,GLFW_KEY_9,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_PERIOD, new Control(ControlType.KEY,GLFW_KEY_PERIOD,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_A, new Control(ControlType.KEY,GLFW_KEY_A,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_B, new Control(ControlType.KEY,GLFW_KEY_B,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_C, new Control(ControlType.KEY,GLFW_KEY_C,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_D, new Control(ControlType.KEY,GLFW_KEY_D,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_E, new Control(ControlType.KEY,GLFW_KEY_E,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_F, new Control(ControlType.KEY,GLFW_KEY_F,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_G, new Control(ControlType.KEY,GLFW_KEY_G,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_H, new Control(ControlType.KEY,GLFW_KEY_H,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_I, new Control(ControlType.KEY,GLFW_KEY_I,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_J, new Control(ControlType.KEY,GLFW_KEY_J,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_K, new Control(ControlType.KEY,GLFW_KEY_K,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_L, new Control(ControlType.KEY,GLFW_KEY_L,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_M, new Control(ControlType.KEY,GLFW_KEY_M,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_N, new Control(ControlType.KEY,GLFW_KEY_N,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_O, new Control(ControlType.KEY,GLFW_KEY_O,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_P, new Control(ControlType.KEY,GLFW_KEY_P,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_Q, new Control(ControlType.KEY,GLFW_KEY_Q,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_R, new Control(ControlType.KEY,GLFW_KEY_R,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_S, new Control(ControlType.KEY,GLFW_KEY_S,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_T, new Control(ControlType.KEY,GLFW_KEY_T,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_U, new Control(ControlType.KEY,GLFW_KEY_U,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_V, new Control(ControlType.KEY,GLFW_KEY_V,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_W, new Control(ControlType.KEY,GLFW_KEY_W,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_X, new Control(ControlType.KEY,GLFW_KEY_X,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_Y, new Control(ControlType.KEY,GLFW_KEY_Y,false,"",""));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_MENU_TYPE_Z, new Control(ControlType.KEY,GLFW_KEY_Z,false,"",""));
|
||||
handler.addControl(INPUT_CODE_MENU_TYPE_FORWARD_SLASH, new Control(ControlType.KEY,GLFW_KEY_SLASH,false,"",""));
|
||||
|
||||
/*
|
||||
Inventory controls
|
||||
*/
|
||||
handler.addControl(INPUT_CODE_INVENTORY_CLOSE, new Control(ControlType.KEY,GLFW_KEY_I));
|
||||
handler.addControl(INPUT_CODE_INVENTORY_ITEM_MANIPULATE, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_1));
|
||||
handler.addControl(INPUT_CODE_INVENTORY_ITEM_DRAG, new Control(ControlType.MOUSE_MOVEMENT,0));
|
||||
handler.addControl(INPUT_CODE_INVENTORY_CLOSE, new Control(ControlType.KEY,GLFW_KEY_I,false,"",""));
|
||||
handler.addControl(INPUT_CODE_INVENTORY_ITEM_MANIPULATE, new Control(ControlType.MOUSE_BUTTON,GLFW_MOUSE_BUTTON_1,false,"",""));
|
||||
handler.addControl(INPUT_CODE_INVENTORY_ITEM_DRAG, new Control(ControlType.MOUSE_MOVEMENT,0,false,"",""));
|
||||
|
||||
/**
|
||||
Terrain controls
|
||||
*/
|
||||
handler.addControl(INPUT_CODE_PLACE_TERRAIN, new Control(ControlType.KEY,GLFW_KEY_T));
|
||||
handler.addControl(INPUT_CODE_REMOVE_TERRAIN, new Control(ControlType.KEY,GLFW_KEY_Y));
|
||||
handler.addControl(INPUT_CODE_PLACE_TERRAIN, new Control(ControlType.KEY,GLFW_KEY_T,false,"Place Terrain","Places terrain"));
|
||||
handler.addControl(INPUT_CODE_REMOVE_TERRAIN, new Control(ControlType.KEY,GLFW_KEY_Y,false,"Remove Terrain","Removes terrain"));
|
||||
|
||||
/*
|
||||
framestep controls
|
||||
*/
|
||||
handler.addControl(DEBUG_FRAMESTEP, new Control(ControlType.KEY, GLFW_KEY_P));
|
||||
handler.addControl(DEBUG_FRAMESTEP, new Control(ControlType.KEY, GLFW_KEY_P,false,"Framesetp","Steps the engine forward one frame"));
|
||||
|
||||
/*
|
||||
* Free camera
|
||||
*/
|
||||
handler.addControl(FREECAM_UP, new Control(ControlType.KEY,GLFW_KEY_SPACE));
|
||||
handler.addControl(FREECAM_DOWN, new Control(ControlType.KEY,GLFW_KEY_LEFT_CONTROL));
|
||||
handler.addControl(FREECAM_FORWARD, new Control(ControlType.KEY,GLFW_KEY_W));
|
||||
handler.addControl(FREECAM_BACKWARD, new Control(ControlType.KEY,GLFW_KEY_S));
|
||||
handler.addControl(FREECAM_LEFT, new Control(ControlType.KEY,GLFW_KEY_A));
|
||||
handler.addControl(FREECAM_RIGHT, new Control(ControlType.KEY,GLFW_KEY_D));
|
||||
handler.addControl(FREECAM_MOUSE, new Control(ControlType.MOUSE_MOVEMENT,0));
|
||||
handler.addControl(FREECAM_UP, new Control(ControlType.KEY,GLFW_KEY_SPACE,false,"Up","Moves the camera up"));
|
||||
handler.addControl(FREECAM_DOWN, new Control(ControlType.KEY,GLFW_KEY_LEFT_CONTROL,false,"Down","Moves the camera down"));
|
||||
handler.addControl(FREECAM_FORWARD, new Control(ControlType.KEY,GLFW_KEY_W,false,"Forward","Moves the camera forward"));
|
||||
handler.addControl(FREECAM_BACKWARD, new Control(ControlType.KEY,GLFW_KEY_S,false,"Backward","Moves the camera backward"));
|
||||
handler.addControl(FREECAM_LEFT, new Control(ControlType.KEY,GLFW_KEY_A,false,"Left","Moves the camera left"));
|
||||
handler.addControl(FREECAM_RIGHT, new Control(ControlType.KEY,GLFW_KEY_D,false,"Right","Moves the camera right"));
|
||||
handler.addControl(FREECAM_MOUSE, new Control(ControlType.MOUSE_MOVEMENT,0,false,"",""));
|
||||
|
||||
|
||||
/*
|
||||
@ -410,8 +420,8 @@ public class ControlHandler {
|
||||
/*
|
||||
Debug controls
|
||||
*/
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM, new Control(ControlType.KEY,GLFW_KEY_Q));
|
||||
handler.addControl(DEBUG_OPEN_DEBUG_MENU, new Control(ControlType.KEY, GLFW_KEY_F2));
|
||||
handler.addControl(DATA_STRING_INPUT_CODE_DEBUG_SPAWN_ITEM, new Control(ControlType.KEY,GLFW_KEY_Q,false,"",""));
|
||||
handler.addControl(DEBUG_OPEN_DEBUG_MENU, new Control(ControlType.KEY, GLFW_KEY_F2,false,"Debug Menu","Opens the debug menu"));
|
||||
|
||||
/*
|
||||
return
|
||||
@ -946,7 +956,9 @@ public class ControlHandler {
|
||||
Globals.elementManager.focusFirstElement();
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.IN_GAME_MAIN_MENU);
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
}});
|
||||
controls.get(DATA_STRING_INPUT_CODE_IN_GAME_MAIN_MENU).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
||||
|
||||
@ -967,7 +979,9 @@ public class ControlHandler {
|
||||
//controls
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.INVENTORY);
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
//
|
||||
Globals.openInventoriesCount++;
|
||||
} else if(InventoryUtils.hasNaturalInventory(Globals.playerEntity) && Globals.elementManager.getWindow(WindowUtils.getInventoryWindowID(InventoryUtils.getNaturalInventory(Globals.playerEntity).getId())) != null){
|
||||
@ -992,7 +1006,9 @@ public class ControlHandler {
|
||||
//controls
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.INVENTORY);
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
//
|
||||
Globals.openInventoriesCount++;
|
||||
} else if(InventoryUtils.hasEquipInventory(Globals.playerEntity) && Globals.elementManager.getWindow(WindowStrings.WINDOW_CHARACTER) != null){
|
||||
@ -1095,7 +1111,9 @@ public class ControlHandler {
|
||||
LoggerInterface.loggerEngine.INFO("open debug menu");
|
||||
ImGuiWindowMacros.toggleMainDebugMenu();
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/openMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
}});
|
||||
controls.get(DEBUG_OPEN_DEBUG_MENU).setRepeatTimeout(0.5f * Main.targetFrameRate);
|
||||
}
|
||||
@ -1172,6 +1190,14 @@ public class ControlHandler {
|
||||
}
|
||||
}});
|
||||
|
||||
/**
|
||||
Screenshots
|
||||
*/
|
||||
menuNavigationControlList.add(controls.get(MENU_CAPTURE_SCREEN));
|
||||
controls.get(MENU_CAPTURE_SCREEN).setOnPress(new Control.ControlMethod() {public void execute(){
|
||||
RenderingEngine.screenFramebuffer.getPixels(Globals.renderingEngine.getOpenGLState());
|
||||
}});
|
||||
|
||||
|
||||
|
||||
|
||||
@ -1424,6 +1450,14 @@ public class ControlHandler {
|
||||
}});
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the main controls list
|
||||
* @return The main controls
|
||||
*/
|
||||
public List<Control> getMainControlsList(){
|
||||
return mainGameControlList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks a list of controls to see if the corresponding key/mouse event is firing this frame
|
||||
|
||||
@ -140,6 +140,8 @@ public class Globals {
|
||||
public static ClientNetworking clientConnection;
|
||||
public static boolean RUN_DEMO = false;
|
||||
public static boolean RUN_CLIENT = true;
|
||||
public static boolean RUN_HIDDEN = false; //glfw session will be created with hidden window
|
||||
public static boolean RUN_AUDIO = false;
|
||||
public static int clientCharacterID;
|
||||
|
||||
//
|
||||
@ -444,7 +446,6 @@ public class Globals {
|
||||
elementManager = new ElementManager();
|
||||
//script engine
|
||||
scriptEngine = new ScriptEngine();
|
||||
scriptEngine.init();
|
||||
//ai manager
|
||||
aiManager = new AIManager();
|
||||
//realm & data cell manager
|
||||
|
||||
@ -76,6 +76,9 @@ public class Main {
|
||||
//init global variables
|
||||
Globals.initGlobals();
|
||||
|
||||
//init scripting engine
|
||||
Globals.scriptEngine.init();
|
||||
|
||||
//controls
|
||||
if(Globals.RUN_CLIENT){
|
||||
initControlHandler();
|
||||
@ -179,7 +182,7 @@ public class Main {
|
||||
// }
|
||||
|
||||
//create the audio context
|
||||
if(Globals.RUN_CLIENT && !Globals.HEADLESS){
|
||||
if(Globals.RUN_CLIENT && !Globals.HEADLESS && Globals.RUN_AUDIO){
|
||||
Globals.virtualAudioSourceManager = new VirtualAudioSourceManager();
|
||||
Globals.audioEngine = new AudioEngine();
|
||||
Globals.audioEngine.init();
|
||||
@ -425,7 +428,7 @@ public class Main {
|
||||
}
|
||||
}
|
||||
//shut down audio engine
|
||||
if(!Globals.HEADLESS && Globals.RUN_CLIENT){
|
||||
if(!Globals.HEADLESS && Globals.RUN_CLIENT && Globals.RUN_AUDIO){
|
||||
Globals.audioEngine.shutdown();
|
||||
}
|
||||
//if netmonitor is running, close
|
||||
|
||||
@ -62,7 +62,9 @@ public class InitialAssetLoading implements Runnable {
|
||||
int offY = iterator / VoxelTextureAtlas.ELEMENTS_PER_ROW;
|
||||
try {
|
||||
BufferedImage newType = ImageIO.read(FileUtils.getAssetFile(type.getTexture()));
|
||||
graphics.drawImage(newType, iterator * VoxelTextureAtlas.ATLAS_ELEMENT_DIM * offX, VoxelTextureAtlas.ATLAS_DIM - VoxelTextureAtlas.ATLAS_ELEMENT_DIM - iterator * VoxelTextureAtlas.ATLAS_ELEMENT_DIM * offY, null);
|
||||
int drawX = VoxelTextureAtlas.ATLAS_ELEMENT_DIM * offX;
|
||||
int drawY = VoxelTextureAtlas.ATLAS_DIM - VoxelTextureAtlas.ATLAS_ELEMENT_DIM - VoxelTextureAtlas.ATLAS_ELEMENT_DIM * offY;
|
||||
graphics.drawImage(newType, drawX, drawY, null);
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerRenderer.ERROR("Texture atlas failed to find texture " + type.getTexture(), e);
|
||||
}
|
||||
|
||||
@ -56,10 +56,11 @@ public class SceneLoader {
|
||||
}
|
||||
}
|
||||
//load scripts
|
||||
for(String scriptPath : file.getScriptPaths()){
|
||||
Globals.scriptEngine.loadScript(scriptPath);
|
||||
}
|
||||
Globals.scriptEngine.runScript(file.getInitScriptPath());
|
||||
//TODO: integrate scripts for client side of scenes
|
||||
// for(String scriptPath : file.getScriptPaths()){
|
||||
// Globals.scriptEngine.loadScript(scriptPath);
|
||||
// }
|
||||
// Globals.scriptEngine.runScript(file.getInitScriptPath());
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
@ -41,6 +41,15 @@ public class HitboxCollectionState {
|
||||
BLOCK, // blocks a hit from another entity
|
||||
}
|
||||
|
||||
/**
|
||||
* The subtype of hitbox
|
||||
*/
|
||||
public enum HitboxSubtype {
|
||||
SWEET, //extra damage
|
||||
REGULAR, //regular damage
|
||||
SOUR, //less damage
|
||||
}
|
||||
|
||||
//the parent entity of the hitbox state
|
||||
Entity parent;
|
||||
|
||||
@ -86,6 +95,9 @@ public class HitboxCollectionState {
|
||||
DGeom geom = null;
|
||||
HitboxType type = HitboxType.HIT;
|
||||
HitboxShapeType shapeType = HitboxShapeType.SPHERE;
|
||||
//
|
||||
//Get the type as an enum
|
||||
//
|
||||
switch(hitboxDataRaw.getType()){
|
||||
case HitboxData.HITBOX_TYPE_HIT: {
|
||||
type = HitboxType.HIT;
|
||||
@ -113,11 +125,34 @@ public class HitboxCollectionState {
|
||||
geom = CollisionBodyCreation.createCapsuleShape(manager.getCollisionEngine(), hitboxDataRaw.getRadius(), hitboxDataRaw.getLength(), Collidable.TYPE_OBJECT_BIT);
|
||||
} break;
|
||||
}
|
||||
//
|
||||
//Get the subtype as an enum
|
||||
//
|
||||
HitboxSubtype subType;
|
||||
String subTypeRaw = hitboxDataRaw.getSubType();
|
||||
if(subTypeRaw == null){
|
||||
subTypeRaw = HitboxData.HITBOX_SUBTYPE_REUGLAR;
|
||||
}
|
||||
switch(subTypeRaw){
|
||||
case HitboxData.HITBOX_SUBTYPE_SWEET: {
|
||||
subType = HitboxSubtype.SWEET;
|
||||
} break;
|
||||
case HitboxData.HITBOX_SUBTYPE_REUGLAR: {
|
||||
subType = HitboxSubtype.REGULAR;
|
||||
} break;
|
||||
case HitboxData.HITBOX_SUBTYPE_SOUR: {
|
||||
subType = HitboxSubtype.SOUR;
|
||||
} break;
|
||||
default: {
|
||||
subType = HitboxSubtype.REGULAR;
|
||||
} break;
|
||||
}
|
||||
|
||||
if(hitboxDataRaw.getBone() != null){
|
||||
rVal.hitboxGeomMap.put(hitboxDataRaw.getBone(),geom);
|
||||
}
|
||||
rVal.geoms.add(geom);
|
||||
rVal.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, shapeType, true));
|
||||
rVal.geomStateMap.put(geom,new HitboxState(hitboxDataRaw.getBone(), hitboxDataRaw, type, subType, shapeType, true));
|
||||
}
|
||||
|
||||
//create body with all the shapes
|
||||
@ -310,7 +345,7 @@ public class HitboxCollectionState {
|
||||
worldPosition = worldPosition.rotate(rotation);
|
||||
worldPosition.add(new Vector3f((float)parentPos.x,(float)parentPos.y,(float)parentPos.z));
|
||||
double length = shapeStatus.getHitboxData().getRadius();
|
||||
double radius = shapeStatus.getHitboxData().getRadius();
|
||||
// double radius = shapeStatus.getHitboxData().getRadius();
|
||||
|
||||
if(previousWorldPos != null){
|
||||
//called all subsequent updates to hitbox position
|
||||
@ -461,6 +496,9 @@ public class HitboxCollectionState {
|
||||
//the type of hitbox
|
||||
HitboxType type;
|
||||
|
||||
//the subtype
|
||||
HitboxSubtype subType;
|
||||
|
||||
//the type of geometry
|
||||
HitboxShapeType shapeType;
|
||||
|
||||
@ -481,13 +519,15 @@ public class HitboxCollectionState {
|
||||
* @param boneName The name of the bone the hitbox is attached to, if any
|
||||
* @param data the hitbox data object
|
||||
* @param type The type of hitbox
|
||||
* @param subType The subtype of hitbox
|
||||
* @param shapeType The type of shape the hitbox is
|
||||
* @param isActive if the hitbox is active or not
|
||||
*/
|
||||
public HitboxState(String boneName, HitboxData data, HitboxType type, HitboxShapeType shapeType, boolean isActive){
|
||||
public HitboxState(String boneName, HitboxData data, HitboxType type, HitboxSubtype subType, HitboxShapeType shapeType, boolean isActive){
|
||||
this.boneName = boneName;
|
||||
this.data = data;
|
||||
this.type = type;
|
||||
this.subType = subType;
|
||||
this.shapeType = shapeType;
|
||||
this.isActive = isActive;
|
||||
}
|
||||
@ -540,6 +580,22 @@ public class HitboxCollectionState {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subtype of the hitbox
|
||||
* @return The subtype
|
||||
*/
|
||||
public HitboxSubtype getSubType(){
|
||||
return subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subtype of the hitbox
|
||||
* @param subType The subtype
|
||||
*/
|
||||
public void setSubType(HitboxSubtype subType){
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets whether the hitbox is active or not
|
||||
* @return true if active, false otherwise
|
||||
|
||||
@ -21,12 +21,23 @@ public class HitboxData {
|
||||
//a block sphere that is connected to its previous position by a capsule. The capsule is used for collision checks
|
||||
public static final String HITBOX_TYPE_BLOCK_CONNECTED = "block_connected";
|
||||
|
||||
//a hitbox with extra effect (ie more damage)
|
||||
public static final String HITBOX_SUBTYPE_SWEET = "sweet";
|
||||
//a hitbox with normal effect
|
||||
public static final String HITBOX_SUBTYPE_REUGLAR = "regular";
|
||||
//a hitbox with less effect (ie reduced damange)
|
||||
public static final String HITBOX_SUBTYPE_SOUR = "sour";
|
||||
|
||||
|
||||
//used for debugging -- to show whether a hitbox is colliding with it or not
|
||||
public static final String HITBOX_TYPE_STATIC_CAPSULE = "static_capsule";
|
||||
|
||||
//the type of hitbox
|
||||
String type;
|
||||
|
||||
//the subtype of hitbox (ie, sweetspot, sour spot, critical spot, armor spot, etc)
|
||||
String subType;
|
||||
|
||||
//the bone it is attached to
|
||||
String bone;
|
||||
|
||||
@ -53,6 +64,14 @@ public class HitboxData {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the subtype of the hitbox
|
||||
* @return the subtype of hitbox
|
||||
*/
|
||||
public String getSubType() {
|
||||
return subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type of bone
|
||||
* @return the type of bone
|
||||
@ -101,10 +120,26 @@ public class HitboxData {
|
||||
this.bone = bone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of the hitbox
|
||||
* @param type the type
|
||||
*/
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the subtype of the hitbox
|
||||
* @param subType the subtype
|
||||
*/
|
||||
public void setSubType(String subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the radius of the hitbox
|
||||
* @param radius The radius
|
||||
*/
|
||||
public void setRadius(float radius) {
|
||||
this.radius = radius;
|
||||
}
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
package electrosphere.logger;
|
||||
|
||||
import org.graalvm.polyglot.HostAccess.Export;
|
||||
|
||||
/**
|
||||
* A channel for logging messages
|
||||
*/
|
||||
@ -44,6 +46,7 @@ public class Logger {
|
||||
* This should be used for debugging messages that are executed on a given condition that won't necessarily be every loop (ie all network messages)
|
||||
* @param message The message to report
|
||||
*/
|
||||
@Export
|
||||
public void DEBUG(String message){
|
||||
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG){
|
||||
System.out.println(message);
|
||||
@ -56,6 +59,7 @@ public class Logger {
|
||||
* This should be used for messages that would have interest to someone running a server (ie specific network messages, account creation, etc)
|
||||
* @param message The message to report
|
||||
*/
|
||||
@Export
|
||||
public void INFO(String message){
|
||||
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO){
|
||||
System.out.println(message);
|
||||
@ -68,6 +72,7 @@ public class Logger {
|
||||
* This should be used for reporting events that happen in the engine that are concerning but don't mean the engine has failed to execute (ie a texture failed to load)
|
||||
* @param message The message to report
|
||||
*/
|
||||
@Export
|
||||
public void WARNING(String message){
|
||||
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING){
|
||||
System.out.println(message);
|
||||
@ -83,6 +88,17 @@ public class Logger {
|
||||
public void ERROR(String message, Exception e){
|
||||
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING || level == LogLevel.ERROR){
|
||||
System.err.println(message);
|
||||
ERROR(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an error message.
|
||||
* This should be used every time we throw any kind of error in the engine
|
||||
* @param e The exception to report
|
||||
*/
|
||||
public void ERROR(Exception e){
|
||||
if(level == LogLevel.LOOP_DEBUG || level == LogLevel.DEBUG || level == LogLevel.INFO || level == LogLevel.WARNING || level == LogLevel.ERROR){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,7 @@ public class LoggerInterface {
|
||||
public static Logger loggerDB;
|
||||
public static Logger loggerAudio;
|
||||
public static Logger loggerUI;
|
||||
public static Logger loggerScripts;
|
||||
|
||||
/**
|
||||
* Initializes all logic objects
|
||||
@ -35,6 +36,7 @@ public class LoggerInterface {
|
||||
loggerDB = new Logger(LogLevel.WARNING);
|
||||
loggerAudio = new Logger(LogLevel.WARNING);
|
||||
loggerUI = new Logger(LogLevel.WARNING);
|
||||
loggerScripts = new Logger(LogLevel.WARNING);
|
||||
loggerStartup.INFO("Initialized loggers");
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||
import electrosphere.entity.types.creature.CreatureUtils;
|
||||
import electrosphere.game.data.creature.type.CreatureType;
|
||||
import electrosphere.game.data.creature.type.visualattribute.VisualAttribute;
|
||||
import electrosphere.menu.mainmenu.MenuGeneratorsKeybind;
|
||||
import electrosphere.menu.mainmenu.MenuGeneratorsTitleMenu;
|
||||
import electrosphere.net.NetUtils;
|
||||
import electrosphere.renderer.RenderingEngine;
|
||||
@ -34,6 +35,7 @@ import electrosphere.renderer.ui.elements.Slider;
|
||||
import electrosphere.renderer.ui.elements.TextInput;
|
||||
import electrosphere.renderer.ui.elements.Window;
|
||||
import electrosphere.renderer.ui.elementtypes.ClickableElement;
|
||||
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
|
||||
import electrosphere.renderer.ui.elementtypes.Element;
|
||||
import electrosphere.renderer.ui.elementtypes.NavigableElement.NavigationEventCallback;
|
||||
import electrosphere.renderer.ui.elementtypes.ValueElement.ValueChangeEventCallback;
|
||||
@ -353,6 +355,13 @@ public class MenuGenerators {
|
||||
return false;
|
||||
}});
|
||||
|
||||
//button to open rebind controls window
|
||||
Button rebindControlsButton = Button.createButton("Controls", new ClickEventCallback() {public boolean execute(ClickEvent event) {
|
||||
WindowUtils.replaceMainMenuContents(MenuGeneratorsKeybind.createControlsRebindMenu());
|
||||
return false;
|
||||
}});
|
||||
rVal.addChild(rebindControlsButton);
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@ public class WindowUtils {
|
||||
}
|
||||
|
||||
static void initLoadingWindow(){
|
||||
Window loadingWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT,false);
|
||||
Window loadingWindow = new Window(Globals.renderingEngine.getOpenGLState(), 0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT,false);
|
||||
Label loadingLabel = new Label(1.0f);
|
||||
loadingLabel.setText("LOADING");
|
||||
loadingWindow.addChild(loadingLabel);
|
||||
@ -166,7 +166,7 @@ public class WindowUtils {
|
||||
}
|
||||
|
||||
static void initMainMenuWindow(){
|
||||
Window mainMenuWindow = new Window(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT,false);
|
||||
Window mainMenuWindow = new Window(Globals.renderingEngine.getOpenGLState(), 0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT,false);
|
||||
Globals.elementManager.registerWindow(WindowStrings.WINDOW_MENU_MAIN, mainMenuWindow);
|
||||
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
|
||||
}
|
||||
@ -176,7 +176,7 @@ public class WindowUtils {
|
||||
}
|
||||
|
||||
static void initItemDragContainerWindow(){
|
||||
Window itemDragContainerWindow = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,false);
|
||||
Window itemDragContainerWindow = new Window(Globals.renderingEngine.getOpenGLState(), 0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,false);
|
||||
Globals.elementManager.registerWindow(WindowStrings.WINDOW_ITEM_DRAG_CONTAINER, itemDragContainerWindow);
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,7 @@ public class MenuGeneratorsInGame {
|
||||
// int screenTop = Globals.WINDOW_HEIGHT - 150;
|
||||
int width = 500;
|
||||
int height = 500;
|
||||
Window rVal = new Window(0,0,width,height,true);
|
||||
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
|
||||
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
|
||||
Div div = new Div();
|
||||
rVal.addChild(div);
|
||||
@ -143,7 +143,7 @@ public class MenuGeneratorsInGame {
|
||||
int width = 500;
|
||||
int height = 500;
|
||||
float fontSize = 1.0f;
|
||||
Window rVal = new Window(0,0,width,height,true);
|
||||
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
|
||||
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
|
||||
// Div div = new Div();
|
||||
// div.setPositionX(0);
|
||||
@ -340,14 +340,14 @@ public class MenuGeneratorsInGame {
|
||||
int width = 500;
|
||||
int height = 500;
|
||||
float fontSize = 0.4f;
|
||||
Window rVal = new Window(0,0,width,height,true);
|
||||
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
|
||||
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
|
||||
// Div div = new Div();
|
||||
// div.setPositionX(0);
|
||||
// div.setPositionY(0);
|
||||
// div.setWidth(500);
|
||||
// div.setHeight(500);
|
||||
ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height);
|
||||
ScrollableContainer scrollable = new ScrollableContainer(Globals.renderingEngine.getOpenGLState(), 0, 0, width, height);
|
||||
rVal.addChild(scrollable);
|
||||
// scrollable.addChild(div);
|
||||
rVal.setOnNavigationCallback(new NavigationEventCallback() {public boolean execute(NavigationEvent event){
|
||||
|
||||
@ -34,7 +34,7 @@ public class MenuGeneratorsInventory {
|
||||
int width = 500;
|
||||
int height = 500;
|
||||
|
||||
Window rVal = new Window(0,0,width,height,true);
|
||||
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
|
||||
rVal.setParentAlignItem(Yoga.YGAlignCenter);
|
||||
rVal.setParentJustifyContent(Yoga.YGJustifyCenter);
|
||||
|
||||
@ -53,7 +53,9 @@ public class MenuGeneratorsInventory {
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||
}
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/closeMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/closeMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
return false;
|
||||
}});
|
||||
|
||||
@ -136,7 +138,9 @@ public class MenuGeneratorsInventory {
|
||||
container.removeChild(panel);
|
||||
WindowUtils.pushItemIconToItemWindow(panel);
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
return false;
|
||||
}});
|
||||
panel.setOnDrag(new DragEventCallback() {public boolean execute(DragEvent event){
|
||||
@ -179,7 +183,9 @@ public class MenuGeneratorsInventory {
|
||||
//re-render inventory
|
||||
WindowUtils.replaceWindow(WindowUtils.getInventoryWindowID(inventory.getId()), MenuGeneratorsInventory.createNaturalInventoryMenu(inventory));
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
}
|
||||
//now the fun begins :)
|
||||
//if transfer item
|
||||
@ -211,7 +217,7 @@ public class MenuGeneratorsInventory {
|
||||
int width = 500;
|
||||
int height = 500;
|
||||
// int screenLeft = (Globals.WINDOW_WIDTH - width)/2;
|
||||
Window rVal = new Window(0,0,width,height,true);
|
||||
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,width,height,true);
|
||||
|
||||
Div div = new Div();
|
||||
rVal.addChild(div);
|
||||
@ -225,7 +231,9 @@ public class MenuGeneratorsInventory {
|
||||
Globals.controlHandler.hintUpdateControlState(ControlsState.MAIN_GAME);
|
||||
}
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/closeMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/closeMenu.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
return false;
|
||||
}});
|
||||
|
||||
@ -304,7 +312,9 @@ public class MenuGeneratorsInventory {
|
||||
container.removeChild(panel);
|
||||
WindowUtils.pushItemIconToItemWindow(panel);
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventoryGrabItem.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
return false;
|
||||
}});
|
||||
panel.setOnDrag(new DragEventCallback() {public boolean execute(DragEvent event){
|
||||
@ -340,7 +350,9 @@ public class MenuGeneratorsInventory {
|
||||
ClientEquipState equipState = ClientEquipState.getEquipState(Globals.playerEntity);
|
||||
equipState.commandAttemptEquip(item,inventory.getEquipPointFromSlot(slots.get(itemId)));
|
||||
//play sound effect
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false);
|
||||
if(Globals.virtualAudioSourceManager != null){
|
||||
Globals.virtualAudioSourceManager.createVirtualAudioSource("/Audio/inventorySlotItem.ogg", VirtualAudioSourceType.UI, false);
|
||||
}
|
||||
}
|
||||
//update ui
|
||||
Globals.dragSourceInventory = null;
|
||||
@ -391,7 +403,7 @@ public class MenuGeneratorsInventory {
|
||||
}
|
||||
|
||||
public static Element worldItemDropCaptureWindow(){
|
||||
Window rVal = new Window(0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true);
|
||||
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,Globals.WINDOW_WIDTH,Globals.WINDOW_HEIGHT,true);
|
||||
Div div = new Div();
|
||||
div.setOnDragRelease(new DragEventCallback() {public boolean execute(DragEvent event){
|
||||
if(Globals.draggedItem != null){
|
||||
|
||||
@ -62,7 +62,7 @@ public class MenuGeneratorsLevelEditor {
|
||||
*/
|
||||
public static Window createLevelEditorSidePanel(){
|
||||
//setup window
|
||||
mainSidePanel = new Window(0,0,SIDE_PANEL_WIDTH,Globals.WINDOW_HEIGHT,true);
|
||||
mainSidePanel = new Window(Globals.renderingEngine.getOpenGLState(),0,0,SIDE_PANEL_WIDTH,Globals.WINDOW_HEIGHT,true);
|
||||
mainSidePanel.setParentAlignContent(Yoga.YGAlignFlexEnd);
|
||||
mainSidePanel.setParentJustifyContent(Yoga.YGJustifyFlexEnd);
|
||||
mainSidePanel.setParentAlignItem(Yoga.YGAlignFlexEnd);
|
||||
|
||||
@ -54,7 +54,7 @@ public class MenuGeneratorsTerrainEditing {
|
||||
*/
|
||||
public static Window createVoxelTypeSelectionPanel(){
|
||||
//setup window
|
||||
rVal = new Window(0,0,WINDOW_WIDTH,WINDOW_HEIGHT,true);
|
||||
rVal = new Window(Globals.renderingEngine.getOpenGLState(),0,0,WINDOW_WIDTH,WINDOW_HEIGHT,true);
|
||||
rVal.setParentAlignContent(Yoga.YGAlignCenter);
|
||||
rVal.setParentJustifyContent(Yoga.YGJustifyCenter);
|
||||
rVal.setParentAlignItem(Yoga.YGAlignCenter);
|
||||
|
||||
@ -25,7 +25,7 @@ public class MenuGeneratorsDebug {
|
||||
static final int X_OFFSET = 1000;
|
||||
|
||||
public static Window createTopLevelDebugMenu(){
|
||||
Window rVal = new Window(X_OFFSET,100,800,800,true);
|
||||
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),X_OFFSET,100,800,800,true);
|
||||
|
||||
//label (title)
|
||||
Label titleLabel = new Label(1.0f);
|
||||
@ -50,7 +50,7 @@ public class MenuGeneratorsDebug {
|
||||
}
|
||||
|
||||
public static Element createDebugUIMenu(){
|
||||
ScrollableContainer rVal = new ScrollableContainer(0, 0, 800, 800);
|
||||
ScrollableContainer rVal = new ScrollableContainer(Globals.renderingEngine.getOpenGLState(), 0, 0, 800, 800);
|
||||
rVal.addChild(WidgetUtils.createLabelButton("Toggle UI Outline",100,150,1.0f,new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||
DebugRendering.toggleOutlineMask();
|
||||
return false;
|
||||
@ -59,7 +59,7 @@ public class MenuGeneratorsDebug {
|
||||
}
|
||||
|
||||
public static Element createListUIElements(){
|
||||
ScrollableContainer rVal = new ScrollableContainer(0, 0, 800, 800);
|
||||
ScrollableContainer rVal = new ScrollableContainer(Globals.renderingEngine.getOpenGLState(), 0, 0, 800, 800);
|
||||
int verticalOffset = 0;
|
||||
int horizontalOffset = 0;
|
||||
List<Element> elementsToAdd = new LinkedList<Element>();
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
package electrosphere.menu.mainmenu;
|
||||
|
||||
import org.lwjgl.util.yoga.Yoga;
|
||||
|
||||
import electrosphere.controls.Control;
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.menu.WindowUtils;
|
||||
import electrosphere.renderer.ui.elements.Button;
|
||||
import electrosphere.renderer.ui.elements.Div;
|
||||
import electrosphere.renderer.ui.elements.FormElement;
|
||||
import electrosphere.renderer.ui.elements.Label;
|
||||
import electrosphere.renderer.ui.elements.VirtualScrollable;
|
||||
import electrosphere.renderer.ui.elementtypes.ClickableElement;
|
||||
import electrosphere.renderer.ui.elementtypes.ClickableElement.ClickEventCallback;
|
||||
import electrosphere.renderer.ui.elementtypes.Element;
|
||||
import electrosphere.renderer.ui.events.ClickEvent;
|
||||
|
||||
/**
|
||||
* A menu for rebinding controls
|
||||
*/
|
||||
public class MenuGeneratorsKeybind {
|
||||
|
||||
//tracks whether the menu has been used to rebind a control or not
|
||||
static boolean modifiedControls = false;
|
||||
|
||||
/**
|
||||
* The controls rebind window
|
||||
* @return the window element
|
||||
*/
|
||||
public static Element createControlsRebindMenu(){
|
||||
FormElement rVal = new FormElement();
|
||||
rVal.setAlignItems(Yoga.YGAlignCenter);
|
||||
|
||||
//header buttons
|
||||
Div headerButtons = new Div();
|
||||
headerButtons.setFlexDirection(Yoga.YGFlexDirectionRow);
|
||||
Button backButton = Button.createButton("Back", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
|
||||
return false;
|
||||
}});
|
||||
headerButtons.addChild(backButton);
|
||||
|
||||
Button saveButton = Button.createButton("Save", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
|
||||
return false;
|
||||
}});
|
||||
saveButton.setVisible(false);
|
||||
headerButtons.addChild(saveButton);
|
||||
|
||||
Button cancelButton = Button.createButton("Cancel", new ClickableElement.ClickEventCallback(){public boolean execute(ClickEvent event){
|
||||
WindowUtils.replaceMainMenuContents(MenuGeneratorsTitleMenu.createTitleMenu());
|
||||
return false;
|
||||
}});
|
||||
cancelButton.setVisible(false);
|
||||
headerButtons.addChild(cancelButton);
|
||||
|
||||
rVal.addChild(headerButtons);
|
||||
|
||||
|
||||
//
|
||||
//Generate keybind controls
|
||||
VirtualScrollable virtualScrollable = new VirtualScrollable(300, 700);
|
||||
virtualScrollable.setAlignItems(Yoga.YGAlignFlexStart);
|
||||
//add a ton of children
|
||||
for(Control control : Globals.controlHandler.getMainControlsList()){
|
||||
if(control.isRebindable()){
|
||||
Div rebindItem = new Div();
|
||||
rebindItem.setFlexDirection(Yoga.YGFlexDirectionRow);
|
||||
|
||||
Label controlNameLabel = Label.createLabel(control.getName());
|
||||
rebindItem.addChild(controlNameLabel);
|
||||
|
||||
Button testButton = Button.createButton(control.getKeyValue() + "", new ClickEventCallback() {public boolean execute(ClickEvent event) {
|
||||
System.out.println("Start rebind");
|
||||
return false;
|
||||
}});
|
||||
rebindItem.addChild(testButton);
|
||||
|
||||
virtualScrollable.addChild(rebindItem);
|
||||
}
|
||||
}
|
||||
|
||||
rVal.addChild(virtualScrollable);
|
||||
|
||||
return rVal;
|
||||
}
|
||||
|
||||
}
|
||||
@ -97,7 +97,7 @@ public class MenuGeneratorsMultiplayer {
|
||||
|
||||
//create actor panel
|
||||
Actor characterActor = ActorUtils.createActorFromModelPath(selectedRaceType.getModelPath());
|
||||
ActorPanel actorPanel = new ActorPanel(1200, 100, 500, 500, characterActor);
|
||||
ActorPanel actorPanel = new ActorPanel(Globals.renderingEngine.getOpenGLState(), 1200, 100, 500, 500, characterActor);
|
||||
actorPanel.setAnimation(Animation.ANIMATION_IDLE_1);
|
||||
actorPanel.setPosition(new Vector3f(0,-0.5f,-0.6f));
|
||||
// actorPanel.setRotation(new Quaternionf().rotateLocalY(0));
|
||||
@ -206,7 +206,7 @@ public class MenuGeneratorsMultiplayer {
|
||||
Div rVal = new Div();
|
||||
rVal.setFlexDirection(Yoga.YGFlexDirectionRow);
|
||||
|
||||
ScrollableContainer scrollable = new ScrollableContainer(0, 0, width, height);
|
||||
ScrollableContainer scrollable = new ScrollableContainer(Globals.renderingEngine.getOpenGLState(), 0, 0, width, height);
|
||||
for(Element newControl : controlsToAdd){
|
||||
scrollable.addChild(newControl);
|
||||
}
|
||||
|
||||
@ -37,7 +37,7 @@ public class MenuGeneratorsUITesting {
|
||||
}});
|
||||
rVal.addChild(backButton);
|
||||
|
||||
ActorPanel actorPanel = new ActorPanel(500, 100, 500, 500, ActorUtils.createActorFromModelPath("Models/deer1.fbx"));
|
||||
ActorPanel actorPanel = new ActorPanel(Globals.renderingEngine.getOpenGLState(), 500, 100, 500, 500, ActorUtils.createActorFromModelPath("Models/deer1.fbx"));
|
||||
if(Globals.playerCamera == null){
|
||||
Globals.playerCamera = CameraEntityUtils.spawnBasicCameraEntity(new Vector3f(0,0,0), new Vector3f(-1,0,0));
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ public class TutorialMenus {
|
||||
windowEl = (Window)Globals.elementManager.getWindow(WindowStrings.TUTORIAL_POPUP);
|
||||
} else {
|
||||
//create the window
|
||||
windowEl = new Window(50,50,500,500,true);
|
||||
windowEl = new Window(Globals.renderingEngine.getOpenGLState(),50,50,500,500,true);
|
||||
windowEl.setParentAlignContent(Yoga.YGAlignCenter);
|
||||
windowEl.setParentJustifyContent(Yoga.YGJustifyCenter);
|
||||
windowEl.setFlexDirection(Yoga.YGFlexDirectionColumn);
|
||||
|
||||
@ -15,6 +15,9 @@ import electrosphere.renderer.shader.ShaderProgram;
|
||||
*/
|
||||
public class OpenGLState {
|
||||
|
||||
//the max texture allowed by the current environment
|
||||
int MAX_TEXTURE_WIDTH = 0;
|
||||
|
||||
//the current viewport dimensions
|
||||
private Vector2i viewport = new Vector2i(0,0);
|
||||
|
||||
@ -41,6 +44,22 @@ public class OpenGLState {
|
||||
//map of texture units and their corresponding texture pointers
|
||||
Map<Integer,Integer> unitToPointerMap = new HashMap<Integer,Integer>();
|
||||
|
||||
|
||||
/**
|
||||
* Gets the constraints of the current environment (ie how large can the max texture be)
|
||||
*/
|
||||
public void storeCurrentEnvironmentContraints(){
|
||||
|
||||
//the array used to store values fetched from opengl
|
||||
int[] intFetchArray = new int[1];
|
||||
|
||||
//get max texture size
|
||||
GL40.glGetIntegerv(GL40.GL_MAX_TEXTURE_SIZE, intFetchArray);
|
||||
MAX_TEXTURE_WIDTH = intFetchArray[0];
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the viewport
|
||||
* @param x the width
|
||||
@ -54,6 +73,14 @@ public class OpenGLState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the viewport's dimensions
|
||||
* @return The viewport's dimensions
|
||||
*/
|
||||
public Vector2i getViewport(){
|
||||
return viewport;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the depth test
|
||||
* @param depthTest the depth test state
|
||||
@ -131,6 +158,14 @@ public class OpenGLState {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the currently bound framebuffer's pointer
|
||||
* @return The pointer
|
||||
*/
|
||||
public int getBoundFramebuffer(){
|
||||
return this.framebufferPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the currently active shader program for the renderer
|
||||
* @param renderPipelineState The render pipeline state object
|
||||
@ -161,4 +196,12 @@ public class OpenGLState {
|
||||
return this.activeShader == program;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets MAX_TEXTURE_WIDTH
|
||||
* @return MAX_TEXTURE_WIDTH
|
||||
*/
|
||||
public int getMAX_TEXTURE_WIDTH(){
|
||||
return MAX_TEXTURE_WIDTH;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -229,6 +229,10 @@ public class RenderingEngine {
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glslVersion = "#version 410";
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
//headless option
|
||||
if(Globals.RUN_HIDDEN){
|
||||
glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
|
||||
}
|
||||
// glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); Allows you to make the background transparent
|
||||
// glfwWindowHint(GLFW_OPACITY, 23);
|
||||
//Creates the window reference object
|
||||
@ -286,6 +290,9 @@ public class RenderingEngine {
|
||||
//Creates the OpenGL capabilities for the program.
|
||||
GL.createCapabilities();
|
||||
|
||||
//get environment constraints
|
||||
openGLState.storeCurrentEnvironmentContraints();
|
||||
|
||||
//init imgui pipeline
|
||||
imGuiPipeline = new ImGuiPipeline(Globals.window, glslVersion);
|
||||
|
||||
@ -314,10 +321,10 @@ public class RenderingEngine {
|
||||
// screenTextureShaders = ShaderProgram.loadSpecificShader("/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.vs", "/Shaders/screentexture/drawDepthBuffer/drawDepthBuffer.fs");
|
||||
|
||||
//generate framebuffers
|
||||
screenTextureColor = FramebufferUtils.generateScreenTextureColor(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
screenFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), screenTextureColor, screenTextureDepth);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, GL_DEFAULT_FRAMEBUFFER);
|
||||
screenTextureColor = FramebufferUtils.generateScreenTextureColor(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
screenTextureDepth = FramebufferUtils.generateScreenTextureDepth(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
screenFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), screenTextureColor, screenTextureDepth);
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, GL_DEFAULT_FRAMEBUFFER);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, GL_DEFAULT_RENDERBUFFER);
|
||||
|
||||
//
|
||||
@ -330,7 +337,7 @@ public class RenderingEngine {
|
||||
//
|
||||
lightDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/lightDepth/lightDepth.vs", "/Shaders/lightDepth/lightDepth.fs");
|
||||
Globals.depthMapShaderProgramLoc = lightDepthShaderProgram.getShaderId();
|
||||
lightDepthBuffer = FramebufferUtils.generateDepthBuffer();
|
||||
lightDepthBuffer = FramebufferUtils.generateDepthBuffer(openGLState);
|
||||
Globals.shadowMapTextureLoc = lightDepthBuffer.getTexturePointer();
|
||||
// glEnable(GL_CULL_FACE); // enabled for shadow mapping
|
||||
|
||||
@ -338,10 +345,10 @@ public class RenderingEngine {
|
||||
//create volume depth framebuffer/shader for volumetric rendering
|
||||
//
|
||||
volumeDepthShaderProgram = ShaderProgram.loadSpecificShader("/Shaders/volumeBuffer/volumetric.vs", "/Shaders/volumeBuffer/volumetric.fs");
|
||||
volumeDepthBackfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
volumeDepthBackfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthBackfaceTexture);
|
||||
volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthFrontfaceTexture);
|
||||
volumeDepthBackfaceTexture = FramebufferUtils.generateDepthBufferTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
volumeDepthBackfaceFramebuffer = FramebufferUtils.generateDepthBuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthBackfaceTexture);
|
||||
volumeDepthFrontfaceTexture = FramebufferUtils.generateDepthBufferTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
volumeDepthFrontfaceFramebuffer = FramebufferUtils.generateDepthBuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), volumeDepthFrontfaceTexture);
|
||||
|
||||
//
|
||||
//Game normals
|
||||
@ -351,19 +358,19 @@ public class RenderingEngine {
|
||||
static Framebuffer gameImageNormalsFramebuffer;
|
||||
static ShaderProgram renderNormalsShader;
|
||||
*/
|
||||
gameImageNormalsTexture = FramebufferUtils.generateScreenTextureColor(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
Texture gameImageNormalsDepthTexture = FramebufferUtils.generateScreenTextureDepth(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
gameImageNormalsFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), gameImageNormalsTexture, gameImageNormalsDepthTexture);
|
||||
gameImageNormalsTexture = FramebufferUtils.generateScreenTextureColor(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
Texture gameImageNormalsDepthTexture = FramebufferUtils.generateScreenTextureDepth(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
gameImageNormalsFramebuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), gameImageNormalsTexture, gameImageNormalsDepthTexture);
|
||||
renderNormalsShader = ShaderProgram.loadSpecificShader("Shaders/anime/renderNormals.vs", "Shaders/anime/renderNormals.fs");
|
||||
|
||||
//
|
||||
//Transparency framebuffers
|
||||
//
|
||||
transparencyAccumulatorClear = new float[]{0.0f, 0.0f, 0.0f, 0.0f};
|
||||
transparencyAccumulatorTexture = FramebufferUtils.generateOITAccumulatorTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
transparencyAccumulatorTexture = FramebufferUtils.generateOITAccumulatorTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
transparencyRevealageClear = new float[]{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
transparencyRevealageTexture = FramebufferUtils.generateOITRevealageTexture(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
transparencyBuffer = FramebufferUtils.generateOITFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), transparencyAccumulatorTexture, transparencyRevealageTexture, screenTextureDepth);
|
||||
transparencyRevealageTexture = FramebufferUtils.generateOITRevealageTexture(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
transparencyBuffer = FramebufferUtils.generateOITFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), transparencyAccumulatorTexture, transparencyRevealageTexture, screenTextureDepth);
|
||||
oitCompositeProgram = ShaderProgram.loadSpecificShader("Shaders/oit/composite.vs", "Shaders/oit/composite.fs");
|
||||
|
||||
//projection matrices
|
||||
@ -377,8 +384,8 @@ public class RenderingEngine {
|
||||
static Framebuffer normalsOutlineFrambuffer;
|
||||
static ShaderProgram normalsOutlineShader;
|
||||
*/
|
||||
normalsOutlineTexture = FramebufferUtils.generateScreenTextureColorAlpha(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
normalsOutlineFrambuffer = FramebufferUtils.generateScreenTextureFramebuffer(Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), normalsOutlineTexture);
|
||||
normalsOutlineTexture = FramebufferUtils.generateScreenTextureColorAlpha(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY());
|
||||
normalsOutlineFrambuffer = FramebufferUtils.generateScreenTextureFramebuffer(openGLState, Globals.userSettings.getRenderResolutionX(), Globals.userSettings.getRenderResolutionY(), normalsOutlineTexture);
|
||||
// normalsOutlineShader = ShaderProgram.loadSpecificShader("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs");
|
||||
Globals.assetManager.addShaderToQueue("Shaders/anime/outlineNormals.vs", "Shaders/anime/outlineNormals.fs");
|
||||
|
||||
@ -416,7 +423,7 @@ public class RenderingEngine {
|
||||
//
|
||||
//Init pipelines
|
||||
//
|
||||
firstPersonItemsPipeline.init();
|
||||
firstPersonItemsPipeline.init(Globals.renderingEngine.getOpenGLState());
|
||||
compositePipeline.setFirstPersonPipeline(firstPersonItemsPipeline);
|
||||
|
||||
//
|
||||
@ -455,6 +462,7 @@ public class RenderingEngine {
|
||||
|
||||
//Update light buffer
|
||||
lightManager.updateData();
|
||||
checkError();
|
||||
|
||||
|
||||
//Render content to the game framebuffer
|
||||
@ -464,18 +472,24 @@ public class RenderingEngine {
|
||||
} else {
|
||||
mainContentNoOITPipeline.render(openGLState, renderPipelineState);
|
||||
}
|
||||
checkError();
|
||||
debugContentPipeline.render(openGLState, renderPipelineState);
|
||||
checkError();
|
||||
normalsForOutlinePipeline.render(openGLState, renderPipelineState);
|
||||
checkError();
|
||||
firstPersonItemsPipeline.render(openGLState, renderPipelineState);
|
||||
checkError();
|
||||
postProcessingPipeline.render(openGLState, renderPipelineState);
|
||||
checkError();
|
||||
compositePipeline.render(openGLState, renderPipelineState);
|
||||
checkError();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//bind default FBO
|
||||
glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER,0);
|
||||
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
@ -483,10 +497,12 @@ public class RenderingEngine {
|
||||
//Render the game framebuffer texture to a quad
|
||||
if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER){
|
||||
renderScreenPipeline.render(openGLState, renderPipelineState);
|
||||
checkError();
|
||||
}
|
||||
|
||||
//render ui
|
||||
uiPipeline.render(openGLState, renderPipelineState);
|
||||
checkError();
|
||||
|
||||
//Render boundaries of ui elements
|
||||
if(Globals.RENDER_FLAG_RENDER_UI_BOUNDS){
|
||||
@ -497,6 +513,7 @@ public class RenderingEngine {
|
||||
* Render imgui
|
||||
*/
|
||||
imGuiPipeline.render(openGLState, renderPipelineState);
|
||||
checkError();
|
||||
|
||||
|
||||
//check for errors
|
||||
@ -506,6 +523,7 @@ public class RenderingEngine {
|
||||
LoggerInterface.loggerRenderer.DEBUG_LOOP("Swap buffers");
|
||||
glfwSwapBuffers(Globals.window);
|
||||
glfwPollEvents();
|
||||
checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -516,7 +534,7 @@ public class RenderingEngine {
|
||||
}
|
||||
|
||||
public void bindFramebuffer(int framebufferPointer){
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebufferPointer);
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, framebufferPointer);
|
||||
}
|
||||
|
||||
public void setTitleBarDimensions(){
|
||||
@ -615,40 +633,61 @@ public class RenderingEngine {
|
||||
* Checks for any errors currently caught by OpenGL.
|
||||
* Refer: https://docs.gl/gl4/glGetError
|
||||
*/
|
||||
private static void checkError(){
|
||||
int error = GL11.glGetError();
|
||||
String errorInEnglish = "";
|
||||
switch(error){
|
||||
case GL11.GL_NO_ERROR: {
|
||||
errorInEnglish = "";
|
||||
} break;
|
||||
case GL11.GL_INVALID_ENUM: {
|
||||
errorInEnglish = "An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
} break;
|
||||
case GL11.GL_INVALID_VALUE: {
|
||||
errorInEnglish = "A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
} break;
|
||||
case GL11.GL_INVALID_OPERATION: {
|
||||
errorInEnglish = "The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
} break;
|
||||
case GL30.GL_INVALID_FRAMEBUFFER_OPERATION: {
|
||||
errorInEnglish = "The framebuffer object is not complete. The offending command is ignored and has no other side effect than to set the error flag. ";
|
||||
} break;
|
||||
case GL11.GL_OUT_OF_MEMORY: {
|
||||
errorInEnglish = "There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded. ";
|
||||
} break;
|
||||
case GL11.GL_STACK_UNDERFLOW: {
|
||||
errorInEnglish = "An attempt has been made to perform an operation that would cause an internal stack to underflow. ";
|
||||
} break;
|
||||
case GL11.GL_STACK_OVERFLOW: {
|
||||
errorInEnglish = "An attempt has been made to perform an operation that would cause an internal stack to overflow. ";
|
||||
} break;
|
||||
default: {
|
||||
errorInEnglish = "Un-enum'd error " + error;
|
||||
} break;
|
||||
public void checkError(){
|
||||
int error = this.getError();
|
||||
if(error != GL11.GL_NO_ERROR){
|
||||
LoggerInterface.loggerRenderer.ERROR("checkError - " + getErrorInEnglish(error), new IllegalStateException("OpenGL Error"));
|
||||
}
|
||||
if(!errorInEnglish.equals("")){
|
||||
LoggerInterface.loggerRenderer.ERROR(errorInEnglish, new Exception(errorInEnglish));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current error code
|
||||
* @return The error code
|
||||
*/
|
||||
public int getError(){
|
||||
int lastCode = GL11.glGetError();
|
||||
int currentCode = lastCode;
|
||||
while((currentCode = GL11.glGetError()) != GL11.GL_NO_ERROR){
|
||||
lastCode = currentCode;
|
||||
}
|
||||
return lastCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks for any errors currently caught by OpenGL.
|
||||
* Refer: https://docs.gl/gl4/glGetError
|
||||
* @param errorCode The error code
|
||||
* @return The message
|
||||
*/
|
||||
public static String getErrorInEnglish(int errorCode){
|
||||
switch(errorCode){
|
||||
case GL11.GL_NO_ERROR: {
|
||||
return null;
|
||||
}
|
||||
case GL11.GL_INVALID_ENUM: {
|
||||
return "An unacceptable value is specified for an enumerated argument. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
}
|
||||
case GL11.GL_INVALID_VALUE: {
|
||||
return "A numeric argument is out of range. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
}
|
||||
case GL11.GL_INVALID_OPERATION: {
|
||||
return "The specified operation is not allowed in the current state. The offending command is ignored and has no other side effect than to set the error flag.";
|
||||
}
|
||||
case GL30.GL_INVALID_FRAMEBUFFER_OPERATION: {
|
||||
return "The framebuffer object is not complete. The offending command is ignored and has no other side effect than to set the error flag. ";
|
||||
}
|
||||
case GL11.GL_OUT_OF_MEMORY: {
|
||||
return "There is not enough memory left to execute the command. The state of the GL is undefined, except for the state of the error flags, after this error is recorded. ";
|
||||
}
|
||||
case GL11.GL_STACK_UNDERFLOW: {
|
||||
return "An attempt has been made to perform an operation that would cause an internal stack to underflow. ";
|
||||
}
|
||||
case GL11.GL_STACK_OVERFLOW: {
|
||||
return "An attempt has been made to perform an operation that would cause an internal stack to overflow. ";
|
||||
}
|
||||
default: {
|
||||
return "Un-enum'd error or no error. Code: " + errorCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,57 +1,128 @@
|
||||
package electrosphere.renderer.framebuffer;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderingEngine;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import electrosphere.util.FileUtils;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import org.lwjgl.opengl.GL30;
|
||||
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
|
||||
import static org.lwjgl.opengl.GL30.GL_DRAW_FRAMEBUFFER;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.lwjgl.opengl.GL40;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
|
||||
import static org.lwjgl.opengl.GL30.glCheckFramebufferStatus;
|
||||
import static org.lwjgl.opengl.GL30.glDeleteFramebuffers;
|
||||
import static org.lwjgl.opengl.GL30.glGenFramebuffers;
|
||||
import static org.lwjgl.opengl.GL45.glCheckNamedFramebufferStatus;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
* Framebuffer object
|
||||
*/
|
||||
public class Framebuffer {
|
||||
|
||||
//the pointer to the framebuffer
|
||||
int framebufferPointer;
|
||||
//gets the texture pointer to the framebuffer's content
|
||||
int texturePointer;
|
||||
//the mipmap level
|
||||
int mipMap = -1;
|
||||
//the map of attachment point to texture object
|
||||
Map<Integer,Texture> attachTextureMap = new HashMap<Integer,Texture>();
|
||||
|
||||
/**
|
||||
* Creates a framebuffer
|
||||
*/
|
||||
public Framebuffer(){
|
||||
framebufferPointer = glGenFramebuffers();
|
||||
}
|
||||
|
||||
public void setTexturePointer(int texturePointer){
|
||||
/**
|
||||
* Sets the texture attached to the framebuffer
|
||||
* @param texture The texture attached to the framebuffer
|
||||
*/
|
||||
public void setTexture(Texture texture){
|
||||
setTexture(texture.getTexturePointer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the texture attached to the framebuffer
|
||||
* @param texturePointer The texture attached to the framebuffer
|
||||
*/
|
||||
public void setTexture(int texturePointer){
|
||||
this.texturePointer = texturePointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the texture associated with the framebuffer
|
||||
* @return The texture's pointer
|
||||
*/
|
||||
public int getTexturePointer(){
|
||||
return texturePointer;
|
||||
}
|
||||
|
||||
public void bind(){
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, framebufferPointer);
|
||||
/**
|
||||
* Binds the framebuffer
|
||||
*/
|
||||
public void bind(OpenGLState openGLState){
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, framebufferPointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the framebuffer compiled correctly
|
||||
* @return true if compiled correctly, false otherwise
|
||||
*/
|
||||
public boolean isComplete(){
|
||||
bind();
|
||||
return glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
|
||||
return glCheckNamedFramebufferStatus(framebufferPointer,GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the framebuffer has an error
|
||||
* @return true if error, false otherwise
|
||||
*/
|
||||
public boolean isError(){
|
||||
return glCheckNamedFramebufferStatus(framebufferPointer,GL_FRAMEBUFFER) == 0;
|
||||
}
|
||||
|
||||
public void checkStatus(){
|
||||
if(isError()){
|
||||
LoggerInterface.loggerRenderer.WARNING("Framebuffer [error] - " + RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError()));
|
||||
} else if(!isComplete()){
|
||||
LoggerInterface.loggerRenderer.WARNING("Framebuffer [glError] - " + RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError()));
|
||||
LoggerInterface.loggerRenderer.WARNING("Framebuffer [status] - " + getStatus());
|
||||
LoggerInterface.loggerRenderer.ERROR("Failed to build framebuffer", new IllegalStateException("Framebuffer failed to build."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the framebuffer's pointer
|
||||
* @return The framebuffer's pointer
|
||||
*/
|
||||
public int getFramebufferPointer(){
|
||||
return framebufferPointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees the framebuffer
|
||||
*/
|
||||
public void free(){
|
||||
glDeleteFramebuffers(framebufferPointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Blocks the thread until the framebuffer has compiled
|
||||
*/
|
||||
public void blockUntilCompiled(){
|
||||
int status = -1;
|
||||
while((status = glCheckFramebufferStatus(framebufferPointer)) != GL_FRAMEBUFFER_UNDEFINED){
|
||||
while(glCheckNamedFramebufferStatus(framebufferPointer,GL_FRAMEBUFFER) != GL_FRAMEBUFFER_UNDEFINED){
|
||||
try {
|
||||
TimeUnit.MILLISECONDS.sleep(1);
|
||||
} catch (InterruptedException ex) {
|
||||
@ -59,4 +130,202 @@ public class Framebuffer {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the status of the framebuffer
|
||||
* @return The status
|
||||
*/
|
||||
public String getStatus(){
|
||||
switch(glCheckNamedFramebufferStatus(framebufferPointer,GL_FRAMEBUFFER)){
|
||||
case GL_FRAMEBUFFER_UNDEFINED: {
|
||||
return "The specified framebuffer is the default read or draw framebuffer, but the default framebuffer does not exist.";
|
||||
}
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: {
|
||||
return "Any of the framebuffer attachment points are framebuffer incomplete.";
|
||||
}
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: {
|
||||
return "The framebuffer does not have at least one image attached to it.";
|
||||
}
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: {
|
||||
return "The value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for any color attachment point(s) named by GL_DRAW_BUFFERi.";
|
||||
}
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER: {
|
||||
return "GL_READ_BUFFER is not GL_NONE and the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE for the color attachment point named by GL_READ_BUFFER.";
|
||||
}
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED: {
|
||||
return "The combination of internal formats of the attached images violates an implementation-dependent set of restrictions.";
|
||||
}
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE: {
|
||||
return "The value of GL_RENDERBUFFER_SAMPLES is not the same for all attached renderbuffers; if the value of GL_TEXTURE_SAMPLES is the not same for all attached textures; or, if the attached images are a mix of renderbuffers and textures, the value of GL_RENDERBUFFER_SAMPLES does not match the value of GL_TEXTURE_SAMPLES.";
|
||||
}
|
||||
case 0: {
|
||||
return RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError());
|
||||
}
|
||||
}
|
||||
return "Unknown framebuffer status";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the mipmap level
|
||||
* @param mipMap The mipmap level
|
||||
*/
|
||||
public void setMipMapLevel(int mipMap){
|
||||
this.mipMap = mipMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color attachment
|
||||
* @param texturePointer The color attachment's pointer
|
||||
*/
|
||||
public void attachTexture(OpenGLState openGLState, int texturePointer){
|
||||
attachTexture(openGLState,texturePointer,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color attachment
|
||||
* @param texturePointer The color attachment's pointer
|
||||
* @param attachmentNum The number of the color attachment
|
||||
*/
|
||||
public void attachTexture(OpenGLState openGLState, int texturePointer, int attachmentNum){
|
||||
if(this.mipMap < 0){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Trying to attach a texture to a framebuffer where mipmap hasn't been set."));
|
||||
}
|
||||
this.texturePointer = texturePointer;
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, framebufferPointer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + attachmentNum, GL_TEXTURE_2D, this.texturePointer, this.mipMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a color texture to the default texture unit
|
||||
* @param texture
|
||||
*/
|
||||
public void attachTexture(OpenGLState openGLState, Texture texture){
|
||||
attachTexture(openGLState, texture, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches a texture to the framebuffer
|
||||
* @param texture The texture
|
||||
* @param attachmentNum The texture unit to attach to
|
||||
*/
|
||||
public void attachTexture(OpenGLState openGLState, Texture texture, int attachmentNum){
|
||||
this.attachTextureMap.put(attachmentNum,texture);
|
||||
attachTexture(openGLState, texture.getTexturePointer(), attachmentNum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the depth attachment for the framebuffer
|
||||
* @param texturePointer The depth attachment's pointer
|
||||
*/
|
||||
public void setDepthAttachment(OpenGLState openGLState, int texturePointer){
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, framebufferPointer);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texturePointer, this.mipMap);
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
checkStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pixels currently stored in this framebuffer
|
||||
*/
|
||||
public BufferedImage getPixels(OpenGLState openGLState){
|
||||
BufferedImage rVal = null;
|
||||
bind(openGLState);
|
||||
GL40.glReadBuffer(GL40.GL_COLOR_ATTACHMENT0);
|
||||
int offsetX = 0;
|
||||
int offsetY = 0;
|
||||
int width = openGLState.getViewport().x;
|
||||
int height = openGLState.getViewport().y;
|
||||
int pixelFormat = GL40.GL_RGBA;
|
||||
int type = GL40.GL_UNSIGNED_INT;
|
||||
if(attachTextureMap.containsKey(0)){
|
||||
Texture texture = attachTextureMap.get(0);
|
||||
pixelFormat = texture.getFormat();
|
||||
type = texture.getDataType();
|
||||
width = texture.getWidth();
|
||||
height = texture.getHeight();
|
||||
} else {
|
||||
throw new IllegalStateException("Tried to get pixels from a framebuffer that does not have a texture attached to attachment point 0.");
|
||||
}
|
||||
//get pixel data
|
||||
try {
|
||||
int bytesPerPixel = pixelFormatToBytes(pixelFormat,type);
|
||||
int bufferSize = width * height * bytesPerPixel;
|
||||
ByteBuffer buffer = MemoryUtil.memAlloc(bufferSize);
|
||||
openGLState.glViewport(width, height);
|
||||
GL40.glReadPixels(offsetX, offsetY, width, height, pixelFormat, type, buffer);
|
||||
Globals.renderingEngine.checkError();
|
||||
//convert to a buffered images
|
||||
rVal = new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
|
||||
for(int x = 0; x < width; x++){
|
||||
for(int y = 0; y < height; y++){
|
||||
int i = (x + (width * y)) * bytesPerPixel;
|
||||
int red = buffer.get(i) & 0xFF;
|
||||
int green = buffer.get(i + 1) & 0xFF;
|
||||
int blue = buffer.get(i + 2) & 0xFF;
|
||||
if(red != 0 || green != 0 || blue != 0){
|
||||
System.out.println(x + " " + y);
|
||||
System.out.println(red + " " + green + " " + blue);
|
||||
}
|
||||
int alpha = 255;
|
||||
if(pixelFormat == GL40.GL_RGBA){
|
||||
alpha = buffer.get(i + 3) & 0xFF;
|
||||
}
|
||||
rVal.setRGB(x, height - (y + 1), (alpha << 24) | (red << 16) | (green << 8) | blue);
|
||||
}
|
||||
}
|
||||
//write the buffered image out
|
||||
try {
|
||||
File outputFile = FileUtils.getAssetFile("Screenshots/" + System.currentTimeMillis() + ".png");
|
||||
if(!outputFile.getParentFile().exists()){
|
||||
outputFile.getParentFile().mkdirs();
|
||||
}
|
||||
if(!outputFile.exists()){
|
||||
outputFile.createNewFile();
|
||||
}
|
||||
ImageIO.write(rVal,"png",outputFile);
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerRenderer.ERROR(e);
|
||||
}
|
||||
//memory management
|
||||
MemoryUtil.memFree(buffer);
|
||||
} catch (OutOfMemoryError e){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException(e.getMessage()));
|
||||
}
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of bytes per pixel based on the format and type of pixel
|
||||
* @param format The format of the pixels
|
||||
* @param type The datatype of as single component of the pixel
|
||||
* @return The number of bytes
|
||||
*/
|
||||
private static int pixelFormatToBytes(int format, int type){
|
||||
int multiplier = 1;
|
||||
switch(format){
|
||||
case GL40.GL_RGBA: {
|
||||
multiplier = 4;
|
||||
} break;
|
||||
case GL40.GL_RGB: {
|
||||
multiplier = 3;
|
||||
} break;
|
||||
default: {
|
||||
LoggerInterface.loggerRenderer.WARNING("Trying to export framebuffer that has image of unsupported pixel format");
|
||||
} break;
|
||||
}
|
||||
int bytesPerComponent = 1;
|
||||
switch(type){
|
||||
case GL40.GL_UNSIGNED_INT: {
|
||||
bytesPerComponent = 4;
|
||||
} break;
|
||||
case GL40.GL_UNSIGNED_BYTE: {
|
||||
bytesPerComponent = 1;
|
||||
} break;
|
||||
default: {
|
||||
LoggerInterface.loggerRenderer.WARNING("Trying to export framebuffer that has image of unsupported datatype");
|
||||
} break;
|
||||
}
|
||||
return multiplier * bytesPerComponent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -1,13 +1,10 @@
|
||||
package electrosphere.renderer.framebuffer;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.lwjgl.BufferUtils;
|
||||
|
||||
@ -16,96 +13,72 @@ import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
||||
import static org.lwjgl.opengl.GL11.GL_LINEAR;
|
||||
import static org.lwjgl.opengl.GL11.GL_NEAREST;
|
||||
import static org.lwjgl.opengl.GL11.GL_NONE;
|
||||
import static org.lwjgl.opengl.GL11.GL_REPEAT;
|
||||
import static org.lwjgl.opengl.GL11.GL_RED;
|
||||
import static org.lwjgl.opengl.GL11.GL_RGB;
|
||||
import static org.lwjgl.opengl.GL11.GL_RGBA;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_BORDER_COLOR;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_SHORT;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_S;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_WRAP_T;
|
||||
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL11.glDrawBuffer;
|
||||
import static org.lwjgl.opengl.GL11.glGenTextures;
|
||||
import static org.lwjgl.opengl.GL11.glReadBuffer;
|
||||
import static org.lwjgl.opengl.GL11.glTexImage2D;
|
||||
import static org.lwjgl.opengl.GL11.glTexParameterfv;
|
||||
import static org.lwjgl.opengl.GL11.glTexParameteri;
|
||||
import static org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE;
|
||||
import static org.lwjgl.opengl.GL13.GL_CLAMP_TO_BORDER;
|
||||
import static org.lwjgl.opengl.GL20.glDrawBuffers;
|
||||
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT0;
|
||||
import static org.lwjgl.opengl.GL30.GL_COLOR_ATTACHMENT1;
|
||||
import static org.lwjgl.opengl.GL30.GL_DEPTH24_STENCIL8;
|
||||
import static org.lwjgl.opengl.GL30.GL_DEPTH_ATTACHMENT;
|
||||
import static org.lwjgl.opengl.GL30.GL_DEPTH_STENCIL_ATTACHMENT;
|
||||
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
|
||||
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER_COMPLETE;
|
||||
import static org.lwjgl.opengl.GL30.GL_RENDERBUFFER;
|
||||
import static org.lwjgl.opengl.GL30.GL_RGBA16F;
|
||||
import static org.lwjgl.opengl.GL30.GL_HALF_FLOAT;
|
||||
import static org.lwjgl.opengl.GL30.GL_R8;
|
||||
import static org.lwjgl.opengl.GL30.GL_RED;
|
||||
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
|
||||
import static org.lwjgl.opengl.GL30.glBindRenderbuffer;
|
||||
import static org.lwjgl.opengl.GL30.glCheckFramebufferStatus;
|
||||
import static org.lwjgl.opengl.GL30.glFramebufferRenderbuffer;
|
||||
import static org.lwjgl.opengl.GL30.glFramebufferTexture2D;
|
||||
import static org.lwjgl.opengl.GL30.glGenRenderbuffers;
|
||||
import static org.lwjgl.opengl.GL30.glRenderbufferStorage;
|
||||
import static org.lwjgl.system.MemoryUtil.NULL;
|
||||
import static org.lwjgl.opengl.GL45.glNamedFramebufferDrawBuffer;
|
||||
import static org.lwjgl.opengl.GL45.glNamedFramebufferDrawBuffers;
|
||||
import static org.lwjgl.opengl.GL45.glNamedFramebufferReadBuffer;
|
||||
|
||||
/**
|
||||
* Utilities for framebuffer creation
|
||||
*/
|
||||
public class FramebufferUtils {
|
||||
|
||||
public static Texture generateScreenTextureColor(int width, int height){
|
||||
int texturePtr = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texturePtr);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
public static Texture generateScreenTextureColor(OpenGLState openGLState, int width, int height){
|
||||
Texture texture = new Texture();
|
||||
texture.glTexImage2D(openGLState, width, height, GL_RGB, GL_UNSIGNED_BYTE);
|
||||
texture.setMinFilter(GL_LINEAR);
|
||||
texture.setMagFilter(GL_LINEAR);
|
||||
//these make sure the texture actually clamps to the borders of the quad
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
Texture texture = new Texture(texturePtr);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
texture.checkStatus(openGLState);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture generateScreenTextureColorAlpha(int width, int height){
|
||||
int texturePtr = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texturePtr);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
public static Texture generateScreenTextureColorAlpha(OpenGLState openGLState, int width, int height){
|
||||
Texture texture = new Texture();
|
||||
texture.glTexImage2D(openGLState, width, height, GL_RGBA, GL_UNSIGNED_BYTE);
|
||||
texture.setMinFilter(GL_LINEAR);
|
||||
texture.setMagFilter(GL_LINEAR);
|
||||
//these make sure the texture actually clamps to the borders of the quad
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
Texture texture = new Texture(texturePtr);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
texture.checkStatus(openGLState);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture generateScreenTextureDepth(int width, int height){
|
||||
int texturePtr = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texturePtr);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
|
||||
Texture texture = new Texture(texturePtr);
|
||||
public static Texture generateScreenTextureDepth(OpenGLState openGLState, int width, int height){
|
||||
Texture texture = new Texture();
|
||||
texture.glTexImage2D(openGLState, width, height, GL_DEPTH_COMPONENT, GL_FLOAT);
|
||||
|
||||
texture.checkStatus(openGLState);
|
||||
return texture;
|
||||
}
|
||||
|
||||
|
||||
public static Framebuffer generateScreenTextureFramebuffer(int width, int height, Texture colorTexture, Texture depthTexture){
|
||||
public static Framebuffer generateScreenTextureFramebuffer(OpenGLState openGLState, int width, int height, Texture colorTexture, Texture depthTexture){
|
||||
Framebuffer buffer = new Framebuffer();
|
||||
buffer.bind();
|
||||
//texture
|
||||
// int texture = glGenTextures();
|
||||
// glBindTexture(GL_TEXTURE_2D,texture);
|
||||
@ -115,22 +88,17 @@ public class FramebufferUtils {
|
||||
// //these make sure the texture actually clamps to the borders of the quad
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
buffer.setTexturePointer(colorTexture.getTexturePointer());
|
||||
//bind texture to fbo
|
||||
int mipMapLevel = 0;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture.getTexturePointer(), mipMapLevel);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture.getTexturePointer(), mipMapLevel);
|
||||
buffer.setMipMapLevel(0);
|
||||
buffer.attachTexture(openGLState,colorTexture);
|
||||
buffer.setDepthAttachment(openGLState,depthTexture.getTexturePointer());
|
||||
//check make sure compiled
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
|
||||
System.out.println("Framebuffer is not complete!");
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
buffer.checkStatus();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Framebuffer generateScreenTextureFramebuffer(int width, int height, Texture colorTexture){
|
||||
public static Framebuffer generateScreenTextureFramebuffer(OpenGLState openGLState, int width, int height, Texture colorTexture){
|
||||
Framebuffer buffer = new Framebuffer();
|
||||
buffer.bind();
|
||||
//texture
|
||||
// int texture = glGenTextures();
|
||||
// glBindTexture(GL_TEXTURE_2D,texture);
|
||||
@ -140,34 +108,29 @@ public class FramebufferUtils {
|
||||
// //these make sure the texture actually clamps to the borders of the quad
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
// glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
buffer.setTexturePointer(colorTexture.getTexturePointer());
|
||||
//bind texture to fbo
|
||||
int mipMapLevel = 0;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTexture.getTexturePointer(), mipMapLevel);
|
||||
buffer.setMipMapLevel(0);
|
||||
buffer.attachTexture(openGLState,colorTexture.getTexturePointer());
|
||||
//check make sure compiled
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
|
||||
System.out.println("Framebuffer is not complete!");
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
buffer.checkStatus();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Framebuffer generateScreensizeTextureFramebuffer(){
|
||||
public static Framebuffer generateScreensizeTextureFramebuffer(OpenGLState openGLState){
|
||||
Framebuffer buffer = new Framebuffer();
|
||||
buffer.bind();
|
||||
buffer.bind(openGLState);
|
||||
//texture
|
||||
int texture = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
Texture texture = new Texture();
|
||||
texture.glTexImage2D(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT, GL_RGB, GL_UNSIGNED_BYTE);
|
||||
texture.setMinFilter(GL_LINEAR);
|
||||
texture.setMagFilter(GL_LINEAR);
|
||||
//these make sure the texture actually clamps to the borders of the quad
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
buffer.setTexturePointer(texture);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
texture.checkStatus(openGLState);
|
||||
//bind texture to fbo
|
||||
int mipMapLevel = 0;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, mipMapLevel);
|
||||
buffer.setMipMapLevel(0);
|
||||
buffer.attachTexture(openGLState,texture);
|
||||
//renderbuffer
|
||||
int renderBuffer = glGenRenderbuffers();
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
|
||||
@ -175,28 +138,25 @@ public class FramebufferUtils {
|
||||
//bind rbo to fbo
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);
|
||||
//check make sure compiled
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
|
||||
System.out.println("Framebuffer is not complete!");
|
||||
}
|
||||
buffer.checkStatus();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Framebuffer generateTextureFramebuffer(int width, int height){
|
||||
public static Framebuffer generateTextureFramebuffer(OpenGLState openGLState, int width, int height){
|
||||
Framebuffer buffer = new Framebuffer();
|
||||
buffer.bind();
|
||||
buffer.bind(openGLState);
|
||||
//texture
|
||||
int texture = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
Texture texture = new Texture();
|
||||
texture.glTexImage2D(openGLState, width, height, GL_RGBA, GL_UNSIGNED_BYTE);
|
||||
texture.setMinFilter(GL_LINEAR);
|
||||
texture.setMagFilter(GL_LINEAR);
|
||||
//these make sure the texture actually clamps to the borders of the quad
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
buffer.setTexturePointer(texture);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
texture.checkStatus(openGLState);
|
||||
//bind texture to fbo
|
||||
int mipMapLevel = 0;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, mipMapLevel);
|
||||
buffer.setMipMapLevel(0);
|
||||
buffer.attachTexture(openGLState,texture);
|
||||
//renderbuffer
|
||||
int renderBuffer = glGenRenderbuffers();
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, renderBuffer);
|
||||
@ -204,9 +164,7 @@ public class FramebufferUtils {
|
||||
//bind rbo to fbo
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer);
|
||||
//check make sure compiled
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
|
||||
System.out.println("Framebuffer is not complete!");
|
||||
}
|
||||
buffer.checkStatus();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -214,10 +172,11 @@ public class FramebufferUtils {
|
||||
|
||||
|
||||
|
||||
public static Renderbuffer generateScreensizeStencilDepthRenderbuffer(){
|
||||
public static Renderbuffer generateScreensizeStencilDepthRenderbuffer(OpenGLState openGLState){
|
||||
Renderbuffer buffer = new Renderbuffer();
|
||||
buffer.bind();
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
|
||||
Globals.renderingEngine.checkError();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -225,121 +184,93 @@ public class FramebufferUtils {
|
||||
static int depthMapWidth = 4096;
|
||||
static int depthMapHeight = 4096;
|
||||
|
||||
public static Framebuffer generateDepthBuffer(){
|
||||
public static Framebuffer generateDepthBuffer(OpenGLState openGLState){
|
||||
Framebuffer buffer = new Framebuffer();
|
||||
buffer.bind();
|
||||
buffer.bind(openGLState);
|
||||
|
||||
|
||||
//texture
|
||||
int texture = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texture);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, depthMapWidth, depthMapHeight, 0, GL_DEPTH_COMPONENT, GL_FLOAT , NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||
buffer.setTexturePointer(texture);
|
||||
|
||||
|
||||
Texture texture = new Texture();
|
||||
texture.glTexImage2D(openGLState, depthMapWidth, depthMapHeight, GL_DEPTH_COMPONENT, GL_FLOAT);
|
||||
texture.setMinFilter(GL_NEAREST);
|
||||
texture.setMagFilter(GL_NEAREST);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
texture.setBorderColor(new float[]{ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
texture.checkStatus(openGLState);
|
||||
|
||||
//bind texture to fbo
|
||||
int mipMapLevel = 0;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture, mipMapLevel);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
buffer.setMipMapLevel(0);
|
||||
buffer.setDepthAttachment(openGLState,texture.getTexturePointer());
|
||||
glNamedFramebufferDrawBuffer(buffer.getFramebufferPointer(), GL_NONE);
|
||||
glNamedFramebufferReadBuffer(buffer.getFramebufferPointer(), GL_NONE);
|
||||
|
||||
|
||||
|
||||
//check make sure compiled
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
|
||||
System.out.println("Framebuffer is not complete!");
|
||||
}
|
||||
buffer.checkStatus();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
public static Texture generateDepthBufferTexture(int width, int height){
|
||||
int texturePtr = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texturePtr);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT , NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
float borderColor[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||
|
||||
Texture texture = new Texture(texturePtr);
|
||||
|
||||
public static Texture generateDepthBufferTexture(OpenGLState openGLState, int width, int height){
|
||||
Texture texture = new Texture();
|
||||
texture.glTexImage2D(openGLState, width, height, GL_DEPTH_COMPONENT, GL_SHORT);
|
||||
texture.setMinFilter(GL_NEAREST);
|
||||
texture.setMagFilter(GL_NEAREST);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
|
||||
texture.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
|
||||
texture.setBorderColor(new float[]{ 1.0f, 1.0f, 1.0f, 1.0f });
|
||||
texture.checkStatus(openGLState);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Framebuffer generateDepthBuffer(int width, int height, Texture texture){
|
||||
public static Framebuffer generateDepthBuffer(OpenGLState openGLState, int width, int height, Texture texture){
|
||||
Framebuffer buffer = new Framebuffer();
|
||||
buffer.bind();
|
||||
|
||||
|
||||
//texture
|
||||
buffer.setTexturePointer(texture.getTexturePointer());
|
||||
|
||||
buffer.bind(openGLState);
|
||||
|
||||
|
||||
//bind texture to fbo
|
||||
int mipMapLevel = 0;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texture.getTexturePointer(), mipMapLevel);
|
||||
glDrawBuffer(GL_NONE);
|
||||
glReadBuffer(GL_NONE);
|
||||
buffer.setMipMapLevel(0);
|
||||
buffer.setDepthAttachment(openGLState,texture.getTexturePointer());
|
||||
glNamedFramebufferDrawBuffer(buffer.getFramebufferPointer(), GL_NONE);
|
||||
glNamedFramebufferReadBuffer(buffer.getFramebufferPointer(), GL_NONE);
|
||||
|
||||
|
||||
|
||||
//check make sure compiled
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
|
||||
System.out.println("Framebuffer is not complete!");
|
||||
}
|
||||
buffer.checkStatus();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static Texture generateOITAccumulatorTexture(int width, int height){
|
||||
int texturePtr = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texturePtr);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, width, height, 0, GL_RGBA, GL_HALF_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
Texture texture = new Texture(texturePtr);
|
||||
|
||||
public static Texture generateOITAccumulatorTexture(OpenGLState openGLState, int width, int height){
|
||||
Texture texture = new Texture();
|
||||
texture.setMinFilter(GL_LINEAR);
|
||||
texture.setMagFilter(GL_LINEAR);
|
||||
texture.glTexImage2D(openGLState, width, height, GL_RGBA, GL_HALF_FLOAT);
|
||||
texture.checkStatus(openGLState);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture generateOITRevealageTexture(int width, int height){
|
||||
int texturePtr = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D,texturePtr);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, width, height, 0, GL_RED, GL_FLOAT, NULL);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
Texture texture = new Texture(texturePtr);
|
||||
|
||||
public static Texture generateOITRevealageTexture(OpenGLState openGLState, int width, int height){
|
||||
Texture texture = new Texture();
|
||||
texture.setMinFilter(GL_LINEAR);
|
||||
texture.setMagFilter(GL_LINEAR);
|
||||
texture.glTexImage2D(openGLState, width, height, GL_RED, GL_FLOAT);
|
||||
texture.checkStatus(openGLState);
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Framebuffer generateOITFramebuffer(int width, int height, Texture accumulatorTex, Texture revealageTex, Texture depthTexture){
|
||||
public static Framebuffer generateOITFramebuffer(OpenGLState openGLState, int width, int height, Texture accumulatorTex, Texture revealageTex, Texture depthTexture){
|
||||
Framebuffer buffer = new Framebuffer();
|
||||
buffer.bind();
|
||||
buffer.bind(openGLState);
|
||||
|
||||
|
||||
//texture
|
||||
buffer.setTexturePointer(accumulatorTex.getTexturePointer());
|
||||
|
||||
//bind texture to fbo
|
||||
int mipMapLevel = 0;
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, accumulatorTex.getTexturePointer(), mipMapLevel);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, revealageTex.getTexturePointer(), mipMapLevel);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthTexture.getTexturePointer(), mipMapLevel);
|
||||
buffer.setMipMapLevel(0);
|
||||
buffer.attachTexture(openGLState,accumulatorTex.getTexturePointer(),0);
|
||||
buffer.attachTexture(openGLState,revealageTex.getTexturePointer(),1);
|
||||
buffer.setDepthAttachment(openGLState,depthTexture.getTexturePointer());
|
||||
|
||||
// const GLenum transparentDrawBuffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
|
||||
// glDrawBuffers(2, transparentDrawBuffers);
|
||||
@ -347,13 +278,10 @@ public class FramebufferUtils {
|
||||
drawBuffers.put(GL_COLOR_ATTACHMENT0);
|
||||
drawBuffers.put(GL_COLOR_ATTACHMENT1);
|
||||
drawBuffers.flip();
|
||||
glDrawBuffers(drawBuffers);
|
||||
glNamedFramebufferDrawBuffers(buffer.getFramebufferPointer(),drawBuffers);
|
||||
|
||||
//check make sure compiled
|
||||
if(glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
|
||||
System.out.println("Framebuffer is not complete!");
|
||||
}
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
buffer.checkStatus();
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ import org.lwjgl.opengl.GL31;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.shader.ShaderProgram;
|
||||
|
||||
/**
|
||||
* Manages the light sources in the engine
|
||||
@ -155,11 +157,16 @@ public class LightManager {
|
||||
public void bindBuffer(int shaderIndex){
|
||||
//get position of lights object in shader
|
||||
int bufferIndex = GL31.glGetUniformBlockIndex(shaderIndex, "Lights");
|
||||
//bind that position to the slot '2'
|
||||
GL31.glUniformBlockBinding(shaderIndex, bufferIndex, BIND_POINT);
|
||||
//bind our buffer to slot '2' as well
|
||||
GL31.glBindBufferBase(GL_UNIFORM_BUFFER, BIND_POINT, uboIndex);
|
||||
if(bufferIndex == ShaderProgram.INVALID_UNIFORM_NAME){
|
||||
LoggerInterface.loggerRenderer.INFO("Tried to buffer light manager to shader that does not have it active.");
|
||||
} else {
|
||||
//bind that position to the slot '2'
|
||||
GL31.glUniformBlockBinding(shaderIndex, bufferIndex, BIND_POINT);
|
||||
//bind our buffer to slot '2' as well
|
||||
GL31.glBindBufferBase(GL_UNIFORM_BUFFER, BIND_POINT, uboIndex);
|
||||
}
|
||||
//alternatively if want to use range, do glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -5,11 +5,7 @@ import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.texture.Texture;
|
||||
import org.lwjgl.assimp.AIMaterial;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||
import static org.lwjgl.opengl.GL13.glActiveTexture;
|
||||
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
||||
import static org.lwjgl.opengl.GL20.glUniform1i;
|
||||
|
||||
/**
|
||||
*
|
||||
@ -91,16 +87,17 @@ public class Material {
|
||||
Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse);
|
||||
if(diffuseTexture != null){
|
||||
diffuseTexture.bind(openGLState,0);
|
||||
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getOpenGLState().getActiveShader().getShaderId(), "material.diffuse"), 0);
|
||||
openGLState.getActiveShader().setUniform(openGLState, "material.diffuse", 0);
|
||||
}
|
||||
Texture specularTexture = Globals.assetManager.fetchTexture(specular);
|
||||
if(specularTexture != null){
|
||||
specularTexture.bind(openGLState,1);
|
||||
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getOpenGLState().getActiveShader().getShaderId(), "material.specular"), 1);
|
||||
openGLState.getActiveShader().setUniform(openGLState, "material.specular", 1);
|
||||
}
|
||||
} else {
|
||||
openGLState.glBindTextureUnit(GL_TEXTURE0, texturePointer, GL_TEXTURE_2D);
|
||||
}
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
public void apply_material(OpenGLState openGLState, int diffuse_channel, int specular_channel){
|
||||
Texture diffuseTexture = Globals.assetManager.fetchTexture(diffuse);
|
||||
@ -111,6 +108,7 @@ public class Material {
|
||||
if(specularTexture != null){
|
||||
specularTexture.bind(openGLState,specular_channel);
|
||||
}
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
public boolean isTransparent(){
|
||||
|
||||
@ -4,7 +4,6 @@ import electrosphere.engine.Globals;
|
||||
import electrosphere.entity.types.camera.CameraEntityUtils;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderPipelineState;
|
||||
import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum;
|
||||
import electrosphere.renderer.actor.ActorTextureMask;
|
||||
import electrosphere.renderer.actor.instance.InstanceData;
|
||||
import electrosphere.renderer.buffer.HomogenousInstancedArray;
|
||||
@ -28,8 +27,6 @@ import org.lwjgl.BufferUtils;
|
||||
import org.lwjgl.opengl.GL11;
|
||||
import org.lwjgl.opengl.GL15;
|
||||
|
||||
import org.lwjgl.opengl.GL20;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
||||
import static org.lwjgl.opengl.GL11.GL_INT;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
@ -50,7 +47,6 @@ import static org.lwjgl.opengl.GL20.glUniformMatrix4fv;
|
||||
import static org.lwjgl.opengl.GL20.glVertexAttribPointer;
|
||||
import static org.lwjgl.opengl.GL30.glBindVertexArray;
|
||||
import static org.lwjgl.opengl.GL30.glGenVertexArrays;
|
||||
import static org.lwjgl.opengl.GL40.*;
|
||||
|
||||
import org.lwjgl.opengl.GL45;
|
||||
import org.lwjgl.system.MemoryStack;
|
||||
@ -365,6 +361,7 @@ public class Mesh {
|
||||
selectedProgram = shader;
|
||||
}
|
||||
openGLState.setActiveShader(renderPipelineState, selectedProgram);
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
if(renderPipelineState.getUseLight()){
|
||||
@ -376,20 +373,23 @@ public class Mesh {
|
||||
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
||||
lightManager.bindBuffer(openGLState.getActiveShader().getShaderId());
|
||||
}
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
if(renderPipelineState.getUseMaterial() && textureMask == null){
|
||||
Globals.renderingEngine.checkError();
|
||||
if(material == null){
|
||||
Globals.materialDefault.apply_material(openGLState,0,1);
|
||||
GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 0);
|
||||
openGLState.getActiveShader().setUniform(openGLState, "hasTransparency", 0);
|
||||
} else {
|
||||
material.apply_material(openGLState);
|
||||
if(material.hasTransparency){
|
||||
GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 1);
|
||||
openGLState.getActiveShader().setUniform(openGLState, "hasTransparency", 1);
|
||||
} else {
|
||||
GL20.glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasTransparency"), 0);
|
||||
openGLState.getActiveShader().setUniform(openGLState, "hasTransparency", 0);
|
||||
}
|
||||
}
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
|
||||
@ -415,12 +415,14 @@ public class Mesh {
|
||||
// glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + j + "]"),6+j);
|
||||
// }
|
||||
// glActiveTexture(GL_TEXTURE0);
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
if(renderPipelineState.getUseShadowMap()){
|
||||
openGLState.glActiveTexture(GL_TEXTURE3);
|
||||
openGLState.glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc);
|
||||
glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "shadowMap"), 3);
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
|
||||
@ -462,6 +464,7 @@ public class Mesh {
|
||||
} else {
|
||||
glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "hasBones"), 0);
|
||||
}
|
||||
Globals.renderingEngine.checkError();
|
||||
|
||||
|
||||
if(renderPipelineState.getBufferStandardUniforms()){
|
||||
@ -477,10 +480,12 @@ public class Mesh {
|
||||
glUniform1i(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "frame"), (int)Globals.timekeeper.getNumberOfRenderFramesElapsed());
|
||||
glUniform1f(glGetUniformLocation(openGLState.getActiveShader().getShaderId(), "time"), (float)Globals.timekeeper.getCurrentRendererTime());
|
||||
}
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
if(renderPipelineState.getBufferNonStandardUniforms()){
|
||||
bufferAllUniforms(openGLState);
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
|
||||
if(renderPipelineState.getInstanced()){
|
||||
@ -490,6 +495,7 @@ public class Mesh {
|
||||
Map<ShaderAttribute,HomogenousInstancedArray> glBufferMap = instanceData.getGlBufferMap();
|
||||
bufferInstanceData(renderPipelineState, buffers, glBufferMap);
|
||||
renderPipelineState.setInstanceCount(instanceData.getDrawCount());
|
||||
Globals.renderingEngine.checkError();
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,6 +509,7 @@ public class Mesh {
|
||||
GL11.glDrawArrays(GL_TRIANGLES, 0, elementCount);
|
||||
}
|
||||
}
|
||||
Globals.renderingEngine.checkError();
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ public class CompositePipeline implements RenderPipeline {
|
||||
GL40.glEnable(GL40.GL_BLEND);
|
||||
GL40.glBlendFunc(GL40.GL_SRC_ALPHA, GL40.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
RenderingEngine.screenFramebuffer.bind();
|
||||
RenderingEngine.screenFramebuffer.bind(openGLState);
|
||||
|
||||
GL40.glBindVertexArray(RenderingEngine.screenTextureVAO);
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ public class DebugContentPipeline implements RenderPipeline {
|
||||
Globals.profiler.beginCpuSample("DebugContentPipeline.render");
|
||||
|
||||
//bind screen fbo
|
||||
RenderingEngine.screenFramebuffer.bind();
|
||||
RenderingEngine.screenFramebuffer.bind(openGLState);
|
||||
openGLState.glDepthTest(true);
|
||||
openGLState.glDepthFunc(GL40.GL_LESS);
|
||||
GL40.glDepthMask(true);
|
||||
|
||||
@ -35,8 +35,8 @@ public class FirstPersonItemsPipeline implements RenderPipeline {
|
||||
/**
|
||||
* Initializes the pipeline
|
||||
*/
|
||||
public void init(){
|
||||
this.firstPersonFramebuffer = FramebufferUtils.generateTextureFramebuffer(Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
|
||||
public void init(OpenGLState openGLState){
|
||||
this.firstPersonFramebuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -48,7 +48,7 @@ public class FirstPersonItemsPipeline implements RenderPipeline {
|
||||
}
|
||||
|
||||
//setup opengl state
|
||||
this.firstPersonFramebuffer.bind();
|
||||
this.firstPersonFramebuffer.bind(openGLState);
|
||||
renderPipelineState.setUseBones(true);
|
||||
renderPipelineState.setUseLight(false);
|
||||
renderPipelineState.setUseMaterial(true);
|
||||
|
||||
@ -41,6 +41,9 @@ public class ImGuiPipeline implements RenderPipeline {
|
||||
public ImGuiPipeline(long windowId, String glslVersion){
|
||||
//init imgui (must happen after gl.createCapabilities)
|
||||
imGuiContext = ImGui.createContext();
|
||||
if(!imGuiContext.isValidPtr()){
|
||||
throw new IllegalStateException("Imgui failed to initialize.");
|
||||
}
|
||||
ImPlot.createContext();
|
||||
imGuiGlfw.init(Globals.window,true);
|
||||
imGuiGl13.init(glslVersion);
|
||||
|
||||
@ -25,7 +25,7 @@ public class MainContentNoOITPipeline implements RenderPipeline {
|
||||
Globals.profiler.beginCpuSample("MainContentNoOITPipeline.render");
|
||||
|
||||
//bind screen fbo
|
||||
RenderingEngine.screenFramebuffer.bind();
|
||||
RenderingEngine.screenFramebuffer.bind(openGLState);
|
||||
openGLState.glDepthTest(true);
|
||||
openGLState.glDepthFunc(GL40.GL_LESS);
|
||||
GL40.glDepthMask(true);
|
||||
|
||||
@ -34,7 +34,7 @@ public class MainContentPipeline implements RenderPipeline {
|
||||
Matrix4d modelTransformMatrix = new Matrix4d();
|
||||
|
||||
//bind screen fbo
|
||||
RenderingEngine.screenFramebuffer.bind();
|
||||
RenderingEngine.screenFramebuffer.bind(openGLState);
|
||||
openGLState.glDepthTest(true);
|
||||
openGLState.glDepthFunc(GL40.GL_LESS);
|
||||
GL40.glDepthMask(true);
|
||||
@ -131,7 +131,7 @@ public class MainContentPipeline implements RenderPipeline {
|
||||
GL40.glBlendFunci(1, GL40.GL_ZERO, GL40.GL_ONE_MINUS_SRC_COLOR);
|
||||
GL40.glBlendEquation(GL40.GL_FUNC_ADD);
|
||||
|
||||
RenderingEngine.transparencyBuffer.bind();
|
||||
RenderingEngine.transparencyBuffer.bind(openGLState);
|
||||
GL40.glClearBufferfv(GL40.GL_COLOR,0,RenderingEngine.transparencyAccumulatorClear);
|
||||
GL40.glClearBufferfv(GL40.GL_COLOR,1,RenderingEngine.transparencyRevealageClear);
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ public class NormalsForOutlinePipeline implements RenderPipeline {
|
||||
*/
|
||||
|
||||
//bind screen fbo
|
||||
RenderingEngine.gameImageNormalsFramebuffer.bind();
|
||||
RenderingEngine.gameImageNormalsFramebuffer.bind(openGLState);
|
||||
openGLState.glDepthTest(true);
|
||||
GL40.glDisable(GL40.GL_BLEND);
|
||||
GL40.glBlendFunc(GL40.GL_SRC_ALPHA, GL40.GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
@ -20,7 +20,7 @@ public class PostProcessingPipeline implements RenderPipeline {
|
||||
// Outline normals
|
||||
//
|
||||
|
||||
RenderingEngine.normalsOutlineFrambuffer.bind();
|
||||
RenderingEngine.normalsOutlineFrambuffer.bind(openGLState);
|
||||
ShaderProgram program = Globals.assetManager.fetchShader("Shaders/anime/outlineNormals.vs", null, "Shaders/anime/outlineNormals.fs");
|
||||
if(program != null){
|
||||
openGLState.setActiveShader(renderPipelineState, program);
|
||||
|
||||
@ -34,7 +34,7 @@ public class ShadowMapPipeline implements RenderPipeline {
|
||||
|
||||
openGLState.setActiveShader(renderPipelineState, RenderingEngine.lightDepthShaderProgram);
|
||||
|
||||
RenderingEngine.lightDepthBuffer.bind();
|
||||
RenderingEngine.lightDepthBuffer.bind(openGLState);
|
||||
GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT);
|
||||
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
|
||||
|
||||
|
||||
@ -38,7 +38,7 @@ public class VolumeBufferPipeline implements RenderPipeline {
|
||||
|
||||
openGLState.setActiveShader(renderPipelineState, RenderingEngine.volumeDepthShaderProgram);
|
||||
|
||||
RenderingEngine.volumeDepthBackfaceFramebuffer.bind();
|
||||
RenderingEngine.volumeDepthBackfaceFramebuffer.bind(openGLState);
|
||||
GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT);
|
||||
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
|
||||
// glBindTexture(GL_TEXTURE_2D, woodTexture);
|
||||
@ -137,7 +137,7 @@ public class VolumeBufferPipeline implements RenderPipeline {
|
||||
|
||||
openGLState.setActiveShader(renderPipelineState, RenderingEngine.volumeDepthShaderProgram);
|
||||
|
||||
RenderingEngine.volumeDepthFrontfaceFramebuffer.bind();
|
||||
RenderingEngine.volumeDepthFrontfaceFramebuffer.bind(openGLState);
|
||||
GL40.glClear(GL40.GL_DEPTH_BUFFER_BIT);
|
||||
openGLState.glActiveTexture(GL40.GL_TEXTURE0);
|
||||
// glBindTexture(GL_TEXTURE_2D, woodTexture);
|
||||
|
||||
@ -38,6 +38,7 @@ import org.lwjgl.opengl.GL40;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.util.FileUtils;
|
||||
|
||||
/**
|
||||
@ -763,6 +764,23 @@ public class ShaderProgram {
|
||||
}
|
||||
}
|
||||
|
||||
//returned if the uniform isn't found
|
||||
public static final int INVALID_UNIFORM_NAME = -1;
|
||||
|
||||
/**
|
||||
* Tries to set a uniform
|
||||
* @param uniformName The name of the uniform
|
||||
* @param value The value to set the uniform to
|
||||
*/
|
||||
public void setUniform(OpenGLState openGLState, String uniformName, Object value){
|
||||
int uniformLocation = glGetUniformLocation(this.getShaderId(), uniformName);
|
||||
if(uniformLocation == INVALID_UNIFORM_NAME){
|
||||
LoggerInterface.loggerRenderer.INFO("Searched for uniform in a shader that does not contain it. Uniform name: \"" + uniformName + "\"");
|
||||
} else {
|
||||
setUniform(uniformLocation, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the id of the shader
|
||||
|
||||
@ -1,64 +1,84 @@
|
||||
/*
|
||||
* 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 electrosphere.renderer.texture;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.engine.Main;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.renderer.OpenGLState;
|
||||
import electrosphere.renderer.RenderingEngine;
|
||||
import electrosphere.util.FileUtils;
|
||||
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 org.lwjgl.opengl.GL40;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.*;
|
||||
import static org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE;
|
||||
import static org.lwjgl.opengl.GL13.GL_TEXTURE0;
|
||||
import static org.lwjgl.opengl.GL14.*;
|
||||
import static org.lwjgl.opengl.GL30.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author amaterasu
|
||||
* A opengl in texture
|
||||
*/
|
||||
public class Texture {
|
||||
int texturePointer;
|
||||
int width;
|
||||
int height;
|
||||
|
||||
//the pointer for the texture
|
||||
int texturePointer = -1;
|
||||
//the width of the texture
|
||||
int width = -1;
|
||||
//the height of the texture
|
||||
int height = -1;
|
||||
//whether the texture has transparency or not
|
||||
boolean hasTransparency;
|
||||
//the path to the texture
|
||||
String path = "";
|
||||
//the border color
|
||||
float[] borderColor = null;
|
||||
|
||||
//the min and max filter
|
||||
int minFilter = -1;
|
||||
int maxFilter = -1;
|
||||
|
||||
private Texture(){
|
||||
//the pixel format (ie RGB, ARGB, etc)
|
||||
int pixelFormat = -1;
|
||||
|
||||
}
|
||||
//the data type of a single component of a pixel (IE UNSIGNED_INT, BYTE, etc)
|
||||
int datatype = -1;
|
||||
|
||||
/**
|
||||
* Constructs a texture from a pointer
|
||||
* @param pointer the pointer
|
||||
*/
|
||||
public Texture(int pointer){
|
||||
this.texturePointer = pointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a texture with a new opengl texture object
|
||||
*/
|
||||
public Texture(){
|
||||
this.texturePointer = glGenTextures();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an in engine texture object from a java bufferedimage object
|
||||
* @param bufferedImage The java bufferedimage object
|
||||
*/
|
||||
public Texture(BufferedImage bufferedImage){
|
||||
texturePointer = glGenTextures();
|
||||
this.texturePointer = glGenTextures();
|
||||
//bind the new texture
|
||||
glBindTexture(GL_TEXTURE_2D, texturePointer);
|
||||
//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);
|
||||
this.setWrap(GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
this.setWrap(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);
|
||||
this.setBorderColor(new float[]{ 0.0f, 0.0f, 0.0f, 1.0f });
|
||||
//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);
|
||||
this.setMinFilter(GL_LINEAR);
|
||||
this.setMagFilter(GL_LINEAR);
|
||||
//load the image here
|
||||
ByteBuffer data;
|
||||
width = 1;
|
||||
@ -101,30 +121,42 @@ public class Texture {
|
||||
}
|
||||
//buffer the texture information
|
||||
if(hasTransparency){
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
this.pixelFormat = GL_RGBA;
|
||||
this.datatype = GL_UNSIGNED_BYTE;
|
||||
this.glTexImage2D(width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
this.pixelFormat = GL_RGB;
|
||||
this.datatype = GL_UNSIGNED_BYTE;
|
||||
this.glTexImage2D(width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
}
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
//check build status
|
||||
String errorMessage = RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError());
|
||||
if(errorMessage != null){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Texture Constructor[from bufferedimage]: " + errorMessage));
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a texture from an existing file
|
||||
* @param path The path to the image file
|
||||
*/
|
||||
public Texture(String path){
|
||||
this.path = path;
|
||||
if(!Globals.HEADLESS){
|
||||
//generate the texture object on gpu
|
||||
texturePointer = glGenTextures();
|
||||
this.texturePointer = glGenTextures();
|
||||
//bind the new texture
|
||||
glBindTexture(GL_TEXTURE_2D, texturePointer);
|
||||
//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);
|
||||
this.setWrap(GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT);
|
||||
this.setWrap(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);
|
||||
this.setBorderColor(new float[]{ 0.0f, 0.0f, 0.0f, 1.0f });
|
||||
//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);
|
||||
this.setMinFilter(GL_LINEAR);
|
||||
this.setMagFilter(GL_LINEAR);
|
||||
//load the image here
|
||||
ByteBuffer data;
|
||||
width = 1;
|
||||
@ -192,13 +224,22 @@ public class Texture {
|
||||
}
|
||||
//buffer the texture information
|
||||
if(hasTransparency){
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
this.pixelFormat = GL_RGBA;
|
||||
this.datatype = GL_UNSIGNED_BYTE;
|
||||
this.glTexImage2D(width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
} else {
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||
this.pixelFormat = GL_RGB;
|
||||
this.datatype = GL_UNSIGNED_BYTE;
|
||||
this.glTexImage2D(width, height, 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();
|
||||
//check build status
|
||||
String errorMessage = RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError());
|
||||
if(errorMessage != null){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Texture Constructor[from bufferedimage]: " + errorMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -211,43 +252,257 @@ public class Texture {
|
||||
public Texture(ByteBuffer buffer, int width, int height){
|
||||
if(!Globals.HEADLESS){
|
||||
//generate the texture object on gpu
|
||||
texturePointer = glGenTextures();
|
||||
this.texturePointer = glGenTextures();
|
||||
//bind the new texture
|
||||
glBindTexture(GL_TEXTURE_2D, texturePointer);
|
||||
//how are we gonna wrap the texture??
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
this.setWrap(GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
this.setWrap(GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
//disable mipmap
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
this.setMinFilter(GL_LINEAR);
|
||||
//call if width != height so opengl figures out how to unpack it properly
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
//GL_RED = 32bit r value
|
||||
//buffer the texture information
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, buffer);
|
||||
this.pixelFormat = GL_RED;
|
||||
this.datatype = GL_FLOAT;
|
||||
GL40.glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, width, height, 0, GL_RED, GL_FLOAT, buffer);
|
||||
//check build status
|
||||
String errorMessage = RenderingEngine.getErrorInEnglish(Globals.renderingEngine.getError());
|
||||
if(errorMessage != null){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Texture Constructor[from bytebuffer]: " + errorMessage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the texture to unit 0
|
||||
* @param openGLState The opengl state
|
||||
*/
|
||||
public void bind(OpenGLState openGLState){
|
||||
if(texturePointer == -1){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Tring to bind a texture object that has not been initialized yet"));
|
||||
}
|
||||
if(texturePointer == 0){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Trying to bind texture object that has texturepointer of 0"));
|
||||
}
|
||||
// openGLState.glActiveTexture(GL_TEXTURE0);
|
||||
// openGLState.glBindTexture(GL_TEXTURE_2D, texturePointer);
|
||||
openGLState.glBindTextureUnit(GL_TEXTURE0,texturePointer,GL_TEXTURE_2D);
|
||||
openGLState.glBindTextureUnit(GL_TEXTURE0,this.texturePointer,GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the texture
|
||||
* @param openGLState The opengl state
|
||||
* @param attrib_val The texture unit number
|
||||
*/
|
||||
public void bind(OpenGLState openGLState, int attrib_val){
|
||||
openGLState.glBindTextureUnit(GL_TEXTURE0 + attrib_val,texturePointer,GL_TEXTURE_2D);
|
||||
if(texturePointer == -1){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Tring to bind a texture object that has not been initialized yet"));
|
||||
}
|
||||
if(texturePointer == 0){
|
||||
LoggerInterface.loggerRenderer.ERROR(new IllegalStateException("Trying to bind texture object that has texturepointer of 0"));
|
||||
}
|
||||
openGLState.glBindTextureUnit(GL_TEXTURE0 + attrib_val,this.texturePointer,GL_TEXTURE_2D);
|
||||
// openGLState.glActiveTexture(GL_TEXTURE0 + attrib_val);
|
||||
// openGLState.glBindTexture(GL_TEXTURE_2D, texturePointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the texture has transparency or not
|
||||
* @return true if transparent, false otherwise
|
||||
*/
|
||||
public boolean isTransparent(){
|
||||
return hasTransparency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path of the texture
|
||||
* @return The path
|
||||
*/
|
||||
public String getPath(){
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pointer of the texture
|
||||
* @return The pointer
|
||||
*/
|
||||
public int getTexturePointer(){
|
||||
return texturePointer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the wrap strategy of the texture
|
||||
* @param wrapDir The direction to wrap
|
||||
* @param wrapType The type of wrapping to perform
|
||||
*/
|
||||
public void setWrap(int wrapDir, int wrapType){
|
||||
//TODO: store wrap type for the direction in this object
|
||||
glBindTexture(GL_TEXTURE_2D,texturePointer);
|
||||
glTexParameteri(GL_TEXTURE_2D, wrapDir, wrapType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the border color
|
||||
* @param borderColor The color (must be 4 floats)
|
||||
*/
|
||||
public void setBorderColor(float borderColor[]){
|
||||
this.borderColor = borderColor;
|
||||
glBindTexture(GL_TEXTURE_2D,texturePointer);
|
||||
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, borderColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the min filter
|
||||
* @param minFilter The min filter
|
||||
*/
|
||||
public void setMinFilter(int minFilter){
|
||||
this.minFilter = minFilter;
|
||||
glBindTexture(GL_TEXTURE_2D,texturePointer);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, minFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the max filter
|
||||
* @param maxFilter The max filter
|
||||
*/
|
||||
public void setMagFilter(int maxFilter){
|
||||
this.maxFilter = maxFilter;
|
||||
glBindTexture(GL_TEXTURE_2D,texturePointer);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, maxFilter);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Specifies a 2d image
|
||||
* @param width The width of the image
|
||||
* @param height The height of the image
|
||||
* @param format The format of the pixels (ie GL_RGB, GL_RGBA, etc)
|
||||
* @param datatype The data type of a single component of a pixel (ie GL_BYTE, GL_UNSIGNED_INT, etc)
|
||||
*/
|
||||
public void glTexImage2D(OpenGLState openGLState, int width, int height, int format, int datatype){
|
||||
//store provided values
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.pixelFormat = format;
|
||||
this.datatype = datatype;
|
||||
//static values going into call
|
||||
int level = 0;
|
||||
int border = 0; //this must be 0 according to docs
|
||||
openGLState.glBindTexture(GL_TEXTURE_2D,texturePointer);
|
||||
GL40.glTexImage2D(GL_TEXTURE_2D, level, format, width, height, border, format, datatype, MemoryUtil.NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies a 2d image
|
||||
* @param width The width of the image
|
||||
* @param height The height of the image
|
||||
* @param format The format of the pixels (ie GL_RGB, GL_RGBA, etc)
|
||||
* @param datatype The data type of a single component of a pixel (ie GL_BYTE, GL_UNSIGNED_INT, etc)
|
||||
* @param data The data to populate the image with
|
||||
*/
|
||||
public void glTexImage2D(int width, int height, int format, int datatype, ByteBuffer data){
|
||||
//store provided values
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.pixelFormat = format;
|
||||
this.datatype = datatype;
|
||||
//static values going into call
|
||||
int level = 0;
|
||||
int border = 0; //this must be 0 according to docs
|
||||
glBindTexture(GL_TEXTURE_2D,texturePointer);
|
||||
GL40.glTexImage2D(GL_TEXTURE_2D, level, format, width, height, border, format, datatype, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the width of the texture
|
||||
* @return The width
|
||||
*/
|
||||
public int getWidth(){
|
||||
if(pixelFormat == -1){
|
||||
throw new IllegalStateException(
|
||||
"The width of the texture you are trying to query from has not been set yet." +
|
||||
" The texture was likely constructed by passing the opengl texture pointer into the texture object."
|
||||
);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the height of the texture
|
||||
* @return The height
|
||||
*/
|
||||
public int getHeight(){
|
||||
if(pixelFormat == -1){
|
||||
throw new IllegalStateException(
|
||||
"The height of the texture you are trying to query from has not been set yet." +
|
||||
" The texture was likely constructed by passing the opengl texture pointer into the texture object."
|
||||
);
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the format of the pixels
|
||||
* @return The format of the pixels (ie GL_RGBA, GL_RGB, etc)
|
||||
*/
|
||||
public int getFormat(){
|
||||
if(pixelFormat == -1){
|
||||
throw new IllegalStateException(
|
||||
"The pixel format of the texture you are trying to query from has not been set yet." +
|
||||
" The texture was likely constructed by passing the opengl texture pointer into the texture object."
|
||||
);
|
||||
}
|
||||
return pixelFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the datatype of the pixels
|
||||
* @return The datatype (IE GL_FLOAT, GL_BYTE, etc)
|
||||
*/
|
||||
public int getDataType(){
|
||||
if(datatype == -1){
|
||||
throw new IllegalStateException(
|
||||
"The datatype of the texture you are trying to query from has not been set yet." +
|
||||
" The texture was likely constructed by passing the opengl texture pointer into the texture object."
|
||||
);
|
||||
}
|
||||
return datatype;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets for errors with the texture
|
||||
* @param state The opengl state
|
||||
*/
|
||||
public void checkStatus(OpenGLState state){
|
||||
this.bind(state);
|
||||
int errorCode = Globals.renderingEngine.getError();
|
||||
if(errorCode != GL40.GL_NO_ERROR){
|
||||
switch(errorCode){
|
||||
case GL40.GL_INVALID_VALUE: {
|
||||
if(this.width < 0){
|
||||
LoggerInterface.loggerRenderer.ERROR("Texture has width less than 0", new IllegalStateException("Texture has width less than 0"));
|
||||
}
|
||||
if(this.width > state.getMAX_TEXTURE_WIDTH()){
|
||||
LoggerInterface.loggerRenderer.ERROR("Texture is greater width than environment allows", new IllegalStateException("Texture is greater width than environment allows"));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
String rVal = "" +
|
||||
"Texture[" +
|
||||
"path=\"" + path + "\", " +
|
||||
"texturePointer=\"" + texturePointer + "\", " +
|
||||
"width=\"" + width + "\", " +
|
||||
"height=\"" + height + "\", " +
|
||||
"]"
|
||||
;
|
||||
return rVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ public class WidgetUtils {
|
||||
int x = Globals.WINDOW_WIDTH - width;
|
||||
int y = Globals.WINDOW_HEIGHT - height;
|
||||
// Window rVal = new Window(x, 10, 100, 20);
|
||||
Window rVal = new Window(x,y,width,height,true);
|
||||
Window rVal = new Window(Globals.renderingEngine.getOpenGLState(),x,y,width,height,true);
|
||||
// Window rVal = new Window(100,100,100,100);
|
||||
// System.out.println(x + " " + y + " " + width + " " + height);
|
||||
// LayoutSchemeListScrollable rVal = new LayoutSchemeListScrollable(x, y, width, height, true);
|
||||
|
||||
@ -55,9 +55,9 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag
|
||||
|
||||
static final Vector3f windowDrawDebugColor = new Vector3f(0.0f,0.0f,1.0f);
|
||||
|
||||
public ActorPanel(int x, int y, int width, int height, Actor actor){
|
||||
public ActorPanel(OpenGLState openGLState, int x, int y, int width, int height, Actor actor){
|
||||
super();
|
||||
elementBuffer = FramebufferUtils.generateTextureFramebuffer(width, height);
|
||||
elementBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
|
||||
customMat.setTexturePointer(elementBuffer.getTexturePointer());
|
||||
this.actor = actor;
|
||||
this.internalPositionX = x;
|
||||
@ -81,7 +81,7 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag
|
||||
int parentHeight
|
||||
) {
|
||||
|
||||
elementBuffer.bind();
|
||||
elementBuffer.bind(openGLState);
|
||||
// Globals.renderingEngine.setViewportSize(width, height);
|
||||
|
||||
RenderingEngine.setFOV(FOV);
|
||||
@ -134,7 +134,7 @@ public class ActorPanel extends StandardElement implements DrawableElement, Drag
|
||||
|
||||
//this call binds the screen as the "texture" we're rendering to
|
||||
//have to call before actually rendering
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
|
||||
//set viewport
|
||||
openGLState.glViewport(parentWidth, parentHeight);
|
||||
|
||||
@ -149,7 +149,7 @@ public class Button extends StandardContainerElement implements DrawableElement,
|
||||
|
||||
//this call binds the screen as the "texture" we're rendering to
|
||||
//have to call before actually rendering
|
||||
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glViewport(parentWidth, parentHeight);
|
||||
|
||||
//error if assets are null
|
||||
|
||||
@ -151,7 +151,7 @@ public class ImagePanel extends StandardElement implements DrawableElement, Drag
|
||||
|
||||
//this call binds the screen as the "texture" we're rendering to
|
||||
//have to call before actually rendering
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glViewport(parentWidth, parentHeight);
|
||||
|
||||
if(planeModel != null){
|
||||
|
||||
@ -33,9 +33,9 @@ public class ScrollableContainer extends StandardContainerElement implements Dra
|
||||
Vector3f texScale = new Vector3f(1,1,0);
|
||||
|
||||
|
||||
public ScrollableContainer(int positionX, int positionY, int width, int height){
|
||||
public ScrollableContainer(OpenGLState openGLState, int positionX, int positionY, int width, int height){
|
||||
super();
|
||||
widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height);
|
||||
widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
|
||||
// widgetBuffer = FramebufferUtils.generateScreensizeTextureFramebuffer();
|
||||
customMat.setTexturePointer(widgetBuffer.getTexturePointer());
|
||||
// customMat.setTexturePointer(Globals.assetManager.fetchTexture("Textures/Testing1.png").getTexturePointer());
|
||||
@ -149,7 +149,7 @@ public class ScrollableContainer extends StandardContainerElement implements Dra
|
||||
Texture windowFrame = Globals.assetManager.fetchTexture("Textures/ui/uiFrame1.png");
|
||||
|
||||
|
||||
widgetBuffer.bind();
|
||||
widgetBuffer.bind(openGLState);
|
||||
openGLState.glViewport(width, height);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
@ -163,7 +163,7 @@ public class ScrollableContainer extends StandardContainerElement implements Dra
|
||||
}
|
||||
//this call binds the screen as the "texture" we're rendering to
|
||||
//have to call before actually rendering
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glViewport(parentWidth, parentHeight);
|
||||
|
||||
//render background of window
|
||||
|
||||
@ -159,7 +159,7 @@ public class TextInput extends StandardContainerElement implements DrawableEleme
|
||||
|
||||
//this call binds the screen as the "texture" we're rendering to
|
||||
//have to call before actually rendering
|
||||
GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glBindFramebuffer(GL30.GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glViewport(parentWidth, parentHeight);
|
||||
|
||||
//error if assets are null
|
||||
|
||||
@ -5,7 +5,6 @@ import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT;
|
||||
import static org.lwjgl.opengl.GL11.glClear;
|
||||
import static org.lwjgl.opengl.GL11.glClearColor;
|
||||
import static org.lwjgl.opengl.GL30.GL_FRAMEBUFFER;
|
||||
import static org.lwjgl.opengl.GL30.glBindFramebuffer;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -67,8 +66,8 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
public Window(int positionX, int positionY, int width, int height, boolean showDecorations){
|
||||
widgetBuffer = FramebufferUtils.generateTextureFramebuffer(width, height);
|
||||
public Window(OpenGLState openGLState, int positionX, int positionY, int width, int height, boolean showDecorations){
|
||||
widgetBuffer = FramebufferUtils.generateTextureFramebuffer(openGLState, width, height);
|
||||
customMat.setTexturePointer(widgetBuffer.getTexturePointer());
|
||||
float ndcWidth = (float)width/Globals.WINDOW_WIDTH;
|
||||
float ndcHeight = (float)height/Globals.WINDOW_HEIGHT;
|
||||
@ -108,7 +107,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
|
||||
boxPosition = new Vector3f(ndcX,ndcY,0);
|
||||
boxDimensions = new Vector3f(ndcWidth,ndcHeight,0);
|
||||
|
||||
widgetBuffer.bind();
|
||||
widgetBuffer.bind(openGLState);
|
||||
openGLState.glViewport(width, height);
|
||||
|
||||
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
@ -126,7 +125,7 @@ public class Window implements DrawableElement, ContainerElement, NavigableEleme
|
||||
}
|
||||
//this call binds the screen as the "texture" we're rendering to
|
||||
//have to call before actually rendering
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glBindFramebuffer(GL_FRAMEBUFFER, parentFramebufferPointer);
|
||||
openGLState.glViewport(parentWidth, parentHeight);
|
||||
|
||||
//error if assets are null
|
||||
|
||||
@ -7,11 +7,15 @@ import java.util.Map;
|
||||
|
||||
import org.graalvm.polyglot.Context;
|
||||
import org.graalvm.polyglot.Engine;
|
||||
import org.graalvm.polyglot.PolyglotException;
|
||||
import org.graalvm.polyglot.Source;
|
||||
import org.graalvm.polyglot.Source.Builder;
|
||||
import org.graalvm.polyglot.Value;
|
||||
|
||||
import electrosphere.engine.Globals;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.util.FileUtils;
|
||||
import electrosphere.util.MathUtils;
|
||||
|
||||
/**
|
||||
* Interface for executing scripts in the game engine
|
||||
@ -21,11 +25,44 @@ public class ScriptEngine {
|
||||
//the graal context
|
||||
Context context;
|
||||
|
||||
//used to build source objects
|
||||
Builder builder;
|
||||
|
||||
//the map of script filepaths to parsed, in-memory scripts
|
||||
Map<String,Source> sourceMap;
|
||||
|
||||
//the javascript object that stores values
|
||||
Value jsBindingsObject;
|
||||
Value topLevelValue;
|
||||
|
||||
//the object that contains all host values accessible to javascript land
|
||||
Value hostObject;
|
||||
|
||||
//The files that are loaded on init to bootstrap the script engine
|
||||
static final String[] filesToLoadOnInit = new String[]{
|
||||
//polyfills
|
||||
"Scripts/compiler/require_polyfill.js",
|
||||
|
||||
//main typescript engine
|
||||
"Scripts/compiler/typescript.js",
|
||||
|
||||
//compiler and utilities
|
||||
"Scripts/compiler/file_resolution.js",
|
||||
"Scripts/compiler/compiler.js",
|
||||
"Scripts/compiler/host_access.js",
|
||||
};
|
||||
|
||||
//The classes that will be provided to the scripting engine
|
||||
//https://stackoverflow.com/a/65942034
|
||||
static final Object[][] staticClasses = new Object[][]{
|
||||
{"mathUtils",MathUtils.class},
|
||||
};
|
||||
|
||||
//singletons from the host that are provided to the javascript context
|
||||
static final Object[][] hostSingletops = new Object[][]{
|
||||
{"timekeeper",Globals.timekeeper},
|
||||
{"currentPlayer",Globals.clientPlayer},
|
||||
{"loggerScripts",LoggerInterface.loggerScripts},
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the engine
|
||||
@ -36,11 +73,41 @@ public class ScriptEngine {
|
||||
//create engine with flag to disable warning
|
||||
Engine engine = Engine.newBuilder().option("engine.WarnInterpreterOnly", "false").build();
|
||||
//create context
|
||||
context = Context.newBuilder("js").engine(engine).build();
|
||||
//read scripts into source map
|
||||
readScriptsDirectory("/src/main/sql", FileUtils.getAssetFile("/src/main/sql"));
|
||||
context = Context.newBuilder("js")
|
||||
.allowNativeAccess(false)
|
||||
.engine(engine)
|
||||
.build();
|
||||
//save the js bindings object
|
||||
jsBindingsObject = context.getBindings("js");
|
||||
topLevelValue = context.getBindings("js");
|
||||
|
||||
//put host members into environment
|
||||
putTopLevelValue("loggerScripts",LoggerInterface.loggerScripts);
|
||||
|
||||
//load all files required to start the engine
|
||||
for(String fileToLoad : filesToLoadOnInit){
|
||||
loadDependency(fileToLoad);
|
||||
}
|
||||
|
||||
//define host members
|
||||
defineHostMembers();
|
||||
|
||||
//register engine files
|
||||
registerScriptDirectory("Scripts/engine",FileUtils.getAssetFile("Scripts/engine"));
|
||||
|
||||
//compile
|
||||
compile();
|
||||
|
||||
//run script for engine init
|
||||
requireModule("/Scripts/engine/engine-init.ts");
|
||||
invokeModuleFunction("/Scripts/engine/engine-init.ts","ENGINE_onInit");
|
||||
|
||||
|
||||
//call the engine initialization function
|
||||
// invokeFunction("ENGINE_onInit");
|
||||
|
||||
|
||||
//read scripts into source map
|
||||
// readScriptsDirectory("/src/main/sql", FileUtils.getAssetFile("/src/main/sql"));
|
||||
//create bindings
|
||||
// try {
|
||||
// String content = FileUtils.getAssetFileAsString("/Scripts/test.js");
|
||||
@ -59,7 +126,7 @@ public class ScriptEngine {
|
||||
* @param value The value that is stored at that variable
|
||||
*/
|
||||
public void putTopLevelValue(String valueName, Object value){
|
||||
jsBindingsObject.putMember(valueName, value);
|
||||
topLevelValue.putMember(valueName, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +135,16 @@ public class ScriptEngine {
|
||||
* @return The value of the variable
|
||||
*/
|
||||
public Value getTopLevelValue(String valueName){
|
||||
return jsBindingsObject.getMember(valueName);
|
||||
return topLevelValue.getMember(valueName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a top level member from the javascript context
|
||||
* @param valueName The name of the top level member
|
||||
* @return true if successfully removed, false otherwise
|
||||
*/
|
||||
public boolean removeTopLevelValue(String valueName){
|
||||
return topLevelValue.removeMember(valueName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,17 +152,18 @@ public class ScriptEngine {
|
||||
* @param path The
|
||||
* @param directory
|
||||
*/
|
||||
void readScriptsDirectory(String path, File directory){
|
||||
void registerScriptDirectory(String path, File directory){
|
||||
if(directory.exists() && directory.isDirectory()){
|
||||
File[] children = directory.listFiles();
|
||||
for(File childFile : children){
|
||||
String qualifiedName = path + "/" + childFile.getName();
|
||||
if(childFile.isDirectory()){
|
||||
readScriptsDirectory(qualifiedName,childFile);
|
||||
registerScriptDirectory(qualifiedName,childFile);
|
||||
} else {
|
||||
//add to source map
|
||||
String content = FileUtils.readFileToString(childFile);
|
||||
sourceMap.put(qualifiedName,Source.create("js",content));
|
||||
registerFile(qualifiedName);
|
||||
// String content = FileUtils.readFileToString(childFile);
|
||||
// sourceMap.put(qualifiedName,Source.create("js",content));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,15 +173,22 @@ public class ScriptEngine {
|
||||
* Loads a script from disk
|
||||
* @param path The path to the script file
|
||||
*/
|
||||
public void loadScript(String path){
|
||||
public void loadDependency(String path){
|
||||
String content;
|
||||
Source source = null;
|
||||
try {
|
||||
content = FileUtils.getAssetFileAsString(path);
|
||||
sourceMap.put(path,Source.create("js",content));
|
||||
source = Source.create("js",content);
|
||||
sourceMap.put(path,source);
|
||||
context.eval(source);
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
LoggerInterface.loggerScripts.ERROR("FAILED TO LOAD SCRIPT", e);
|
||||
} catch (PolyglotException e){
|
||||
if(source != null){
|
||||
LoggerInterface.loggerScripts.WARNING("Source language: " + source.getLanguage());
|
||||
}
|
||||
LoggerInterface.loggerScripts.ERROR("Script error", e);
|
||||
e.printStackTrace();
|
||||
LoggerInterface.loggerGameLogic.ERROR("FAILED TO LOAD SCRIPT", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,12 +197,95 @@ public class ScriptEngine {
|
||||
* @param path The filepath of the script
|
||||
*/
|
||||
public void runScript(String path){
|
||||
Source source = sourceMap.get(path);
|
||||
if(source != null){
|
||||
context.eval(source);
|
||||
invokeFunction("COMPILER_runFile", path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the content of a file
|
||||
* @param path The filepath of the script
|
||||
*/
|
||||
public void printScriptSource(String path){
|
||||
invokeFunction("COMPILER_printSource", path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a file with the scripting engine to be compiled into the full binary
|
||||
* @param path The path to the script file
|
||||
*/
|
||||
private void registerFile(String path){
|
||||
String content;
|
||||
try {
|
||||
content = FileUtils.getAssetFileAsString(path);
|
||||
sourceMap.put(path,Source.create("js",content));
|
||||
invokeFunction("COMPILER_registerFile",path,content);
|
||||
} catch (IOException e) {
|
||||
LoggerInterface.loggerScripts.ERROR("FAILED TO LOAD SCRIPT", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the project
|
||||
*/
|
||||
private void compile(){
|
||||
invokeFunction("COMPILER_run");
|
||||
Value compiledCode = topLevelValue.getMember("COMPILER_emitted_value");
|
||||
context.eval("js",compiledCode.asString());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calls a function defined in the global scope with the arguments provided
|
||||
* @param functionName The function name
|
||||
* @param args The arguments
|
||||
*/
|
||||
public Value invokeFunction(String functionName, Object... args){
|
||||
Value function = topLevelValue.getMember(functionName);
|
||||
if(function != null){
|
||||
return function.execute(args);
|
||||
} else {
|
||||
LoggerInterface.loggerScripts.WARNING("Failed to invoke function " + functionName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a function defined in a file
|
||||
* @param filePath The file the function is defined in
|
||||
* @param functionName The function's name
|
||||
* @param args The args to pass into the function
|
||||
*/
|
||||
public void invokeModuleFunction(String filePath, String functionName, Object ... args){
|
||||
Value filePathRaw = invokeFunction("FILE_RESOLUTION_getFilePath",filePath);
|
||||
Value requireCache = topLevelValue.getMember("REQUIRE_CACHE");
|
||||
Value module = requireCache.getMember(filePathRaw.asString());
|
||||
Value exports = module.getMember("exports");
|
||||
Value function = exports.getMember(functionName);
|
||||
if(function != null && function.canExecute()){
|
||||
function.execute(args);
|
||||
} else {
|
||||
LoggerInterface.loggerScripts.WARNING("Failed to invoke function " + functionName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires a module into the global space
|
||||
* @param filePath The filepath of the module
|
||||
*/
|
||||
public void requireModule(String filePath){
|
||||
invokeFunction("require", filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines host members within javascript context
|
||||
*/
|
||||
private void defineHostMembers(){
|
||||
hostObject = topLevelValue.getMember("HOST_ACCESS");
|
||||
//give guest access to static classes
|
||||
Value classes = hostObject.getMember("classes");
|
||||
for(Object[] currentClass : staticClasses){
|
||||
classes.putMember((String)currentClass[0], currentClass[1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
9
tsconfig.json
Normal file
9
tsconfig.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"paths" : {
|
||||
"/*" : [
|
||||
"./assets/Scripts/*"
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user