audio with OpenAL

This commit is contained in:
Halbear 2026-06-13 02:16:12 +01:00
parent 5943effa4e
commit f212c6f3d8
15 changed files with 353 additions and 50 deletions

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,125 @@
package net.halbear.Terrain4J.EngineCore.Audio;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera;
import org.joml.Matrix4f;
import org.joml.Vector3f;
import org.lwjgl.openal.AL;
import org.lwjgl.openal.ALC;
import org.lwjgl.openal.ALCCapabilities;
import org.tinylog.Logger;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.HashMap;
import java.util.Map;
import static java.sql.Types.NULL;
import static org.lwjgl.openal.AL10.alDistanceModel;
import static org.lwjgl.openal.ALC10.*;
public class AudioManager {
private final long Context;
private final long Device;
private final Map<String, SoundBuffer> SoundBufferMap;
private final Map<String, AudioSource> SoundSourceMap;
private SoundListener listener;
public AudioManager(){
SoundBufferMap = new HashMap<>();
SoundSourceMap = new HashMap<>();
Device = alcOpenDevice((ByteBuffer)null);
if(Device == NULL){
throw new IllegalStateException("Failed to open default OpenAL device");
}
ALCCapabilities deviceCapabilies = ALC.createCapabilities(Device);
this.Context = alcCreateContext(Device,(IntBuffer) null);
if(Context == NULL){
throw new IllegalStateException("Failed to create OpenAL context.");
}
alcMakeContextCurrent(Context);
AL.createCapabilities(deviceCapabilies);
}
public void AddSoundBuffer(String name, SoundBuffer soundBuffer){
this.SoundBufferMap.put(name,soundBuffer);
}
public void AddSoundSource(String name, AudioSource source){
this.SoundSourceMap.put(name,source);
}
public void CleanUp(){
SoundSourceMap.values().forEach(AudioSource::CleanUp);
SoundSourceMap.clear();
SoundBufferMap.values().forEach(SoundBuffer::CleanUp);
SoundBufferMap.clear();
if(Context != NULL){
alcDestroyContext(Context);
}
if(Device != NULL){
alcCloseDevice(Device);
}
}
public AudioSource GetAudioSource(String Name){
return this.SoundSourceMap.get(Name);
}
public void Pause(String SourceID){
AudioSource source = SoundSourceMap.get(SourceID);
if (source == null) {
Logger.warn("Unknown audio source [{}]", SourceID);
return;
}
source.Pause();
}
public void Play(String SourceID, String BufferID){
AudioSource audioSource = SoundSourceMap.get(SourceID);
if (audioSource == null) {
Logger.warn("Unknown audio source [{}]", SourceID);
return;
}
SoundBuffer soundBuffer = SoundBufferMap.get(BufferID);
if (soundBuffer == null) {
Logger.warn("Unknown audio buffer [{}]", BufferID);
return;
}
audioSource.SetBuffer(soundBuffer.GetBufferID());
audioSource.Play();
}
public void PlayAudioSource(String name){
AudioSource audioSource = this.SoundSourceMap.get(name);
if(audioSource != null && !audioSource.isPlaying()){
audioSource.Play();
}
}
public void RemoveAudioSource(String name){
this.SoundSourceMap.remove(name);
}
public void SetAttenuationModel(int model){
alDistanceModel(model);
}
public void SetListener(SoundListener listener){
this.listener = listener;
}
public void Stop(String SourceID){
AudioSource source = SoundSourceMap.get(SourceID);
if (source == null) {
Logger.warn("Unknown audio source [{}]", SourceID);
return;
}
source.Stop();
}
public void UpdateListenerPosition(Camera camera){
Matrix4f viewMatrix = camera.GetViewMatrix();
listener.SetPosition(camera.GetPosition());
Vector3f at = new Vector3f();
viewMatrix.positiveZ(at).negate();
Vector3f up = new Vector3f();
viewMatrix.positiveY(up);
listener.SetOrientation(at,up);
}
}

View file

@ -0,0 +1,29 @@
package net.halbear.Terrain4J.EngineCore.Audio;
import org.joml.Vector3f;
import static org.lwjgl.openal.AL10.*;
public class AudioSource {
private final int SourceID;
public AudioSource(boolean loop, boolean relative){
this.SourceID = alGenSources();
alSourcei(SourceID, AL_LOOPING, loop ? AL_TRUE: AL_FALSE);
alSourcei(SourceID, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE);
}
public void CleanUp(){
Stop();
alDeleteSources(SourceID);
}
public void SetBuffer(int Buffer){
Stop();
alSourcei(SourceID, AL_BUFFER, Buffer);
}
public boolean isPlaying(){return alGetSourcei(SourceID, AL_SOURCE_STATE) == AL_PLAYING;}
public void Pause(){alSourcePause(SourceID);}
public void Play(){alSourcePlay(SourceID);}
public void SetGain(float gain){alSourcef(SourceID, AL_GAIN, gain);}
public void SetPosition(Vector3f position){alSource3f(SourceID, AL_POSITION, position.x,position.y,position.z);}
public void Stop(){alSourceStop(SourceID);}
}

View file

@ -0,0 +1,52 @@
package net.halbear.Terrain4J.EngineCore.Audio;
import org.lwjgl.stb.STBVorbisInfo;
import org.lwjgl.system.MemoryStack;
import org.lwjgl.system.MemoryUtil;
import java.nio.IntBuffer;
import java.nio.ShortBuffer;
import static java.sql.Types.NULL;
import static org.lwjgl.openal.AL10.*;
import static org.lwjgl.stb.STBVorbis.*;
public class SoundBuffer {
private final int BufferID;
private final ShortBuffer pcm;
public SoundBuffer(String FilePath){
this.BufferID = alGenBuffers();
try(STBVorbisInfo info = STBVorbisInfo.malloc()){
pcm = ReadVorbis(FilePath, info);
alBufferData(BufferID, info.channels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, pcm, info.sample_rate());
}
}
public void CleanUp(){
alDeleteBuffers(this.BufferID);
if(pcm != null){
MemoryUtil.memFree(pcm);
}
}
public int GetBufferID(){
return this.BufferID;
}
private ShortBuffer ReadVorbis(String FilePath, STBVorbisInfo info){
try(var MemStack = MemoryStack.stackPush()){
IntBuffer error = MemStack.mallocInt(1);
long Decoder = stb_vorbis_open_filename(FilePath,error,null);
if(Decoder == NULL){
throw new RuntimeException("Failed to open OGG Vorbis File, error -> " + error.get(0));
}
stb_vorbis_get_info(Decoder, info);
int Channels = info.channels();
int LengthSamples = stb_vorbis_stream_length_in_samples(Decoder);
ShortBuffer result = MemoryUtil.memAllocShort(LengthSamples * Channels);
result.limit(stb_vorbis_get_samples_short_interleaved(Decoder,Channels,result) * Channels);
stb_vorbis_close(Decoder);
return result;
}
}
}

View file

@ -0,0 +1,28 @@
package net.halbear.Terrain4J.EngineCore.Audio;
import org.joml.Vector3f;
import static org.lwjgl.openal.AL10.*;
public class SoundListener {
public SoundListener(Vector3f Position){
alListener3f(AL_POSITION, Position.x, Position.y, Position.z);
alListener3f(AL_VELOCITY, 0,0,0);
}
public void SetOrientation(Vector3f at, Vector3f up){
float[] data = new float[6];
data[0] = at.x;
data[1] = at.y;
data[2] = at.z;
data[3] = up.x;
data[4] = up.y;
data[5] = up.z;
alListenerfv(AL_ORIENTATION,data);
}
public void SetPosition(Vector3f Position){
alListener3f(AL_POSITION, Position.x,Position.y,Position.z);
}
public void SetSpeed(Vector3f Speed){
alListener3f(AL_VELOCITY,Speed.x,Speed.y,Speed.z);
}
}

View file

@ -1,5 +1,6 @@
package net.halbear.Terrain4J.EngineCore.Logic;
import net.halbear.Terrain4J.EngineCore.Audio.AudioManager;
import net.halbear.Terrain4J.EngineCore.Display.Render;
import net.halbear.Terrain4J.EngineCore.Main.PrimaryRuntime;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
@ -8,8 +9,9 @@ import net.halbear.Terrain4J.EngineCore.Threads.FastTickThread;
import net.halbear.Terrain4J.EngineCore.Threads.MainThread;
import net.halbear.Terrain4J.EngineCore.Threads.RenderThread;
public record EngineInstance(Window window, Scene scene, PrimaryRuntime PrimaryThread) {
public record EngineInstance(Window window, Scene scene, PrimaryRuntime PrimaryThread, AudioManager audioManager) {
public void cleanup(){
window.cleanup();
audioManager.CleanUp();
}
}

View file

@ -6,6 +6,10 @@ import imgui.ImGuiViewport;
import imgui.ImVec2;
import imgui.flag.ImGuiCond;
import imgui.flag.ImGuiWindowFlags;
import net.halbear.Terrain4J.EngineCore.Audio.AudioManager;
import net.halbear.Terrain4J.EngineCore.Audio.AudioSource;
import net.halbear.Terrain4J.EngineCore.Audio.SoundBuffer;
import net.halbear.Terrain4J.EngineCore.Audio.SoundListener;
import net.halbear.Terrain4J.EngineCore.Display.Window;
import net.halbear.Terrain4J.EngineCore.Input.KeyboardInput;
import net.halbear.Terrain4J.EngineCore.Input.MouseListener;
@ -13,6 +17,7 @@ import net.halbear.Terrain4J.EngineCore.Logic.*;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.ModelLoader;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Actor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Camera;
import net.halbear.Terrain4J.EngineCore.Main.Scene.ParticleActor;
import net.halbear.Terrain4J.EngineCore.Main.Scene.Scene;
import net.halbear.Terrain4J.EngineCore.Profiling.CPUMonitor;
import net.halbear.Terrain4J.EngineCore.Profiling.GPUProfiler;
@ -22,6 +27,7 @@ import net.halbear.Terrain4J.EngineCore.Vulkan.Rendering.VkModel.ModelData;
import net.halbear.Terrain4J.EngineCore.Vulkan.Structure.DisplayToScreen.SceneRender;
import org.joml.Vector2f;
import org.joml.Vector3f;
import org.lwjgl.openal.AL11;
import java.util.ArrayList;
import java.util.List;
@ -32,7 +38,13 @@ import static org.lwjgl.glfw.GLFW.*;
public class GameCore implements GameLogic {
private static final float MOUSE_SENSITIVITY = 0.1f;
private static final float MOVEMENT_SPEED = 0.05f;
private static final float MOVEMENT_SPEED = 0.025f;
private static final String SOUND_BUFFER_MUSIC = "music-sound-buffer";
private static final String SOUND_BUFFER_PLAYER = "player-sound-buffer";
private static final String SOUND_SOURCE_MUSIC = "music-sound-source";
private static final String SOUND_SOURCE_PLAYER = "player-sound-source";
private final Vector3f rotatingAngle = new Vector3f(0, 1, 0);
private float angle = 180;
private List<Float> angles = new ArrayList<>();
@ -40,6 +52,7 @@ public class GameCore implements GameLogic {
private List<Vector3f> Velocities = new ArrayList<>();
private Actor CubeActor;
private List<Actor> CubeActors = new ArrayList<>();
private List<ParticleActor> particleActors = new ArrayList<>();
private Vector2f LastMousePos = new Vector2f(0,0);
private int Ticks = 0;
private int GUI_MODE = 0;
@ -51,6 +64,7 @@ public class GameCore implements GameLogic {
private int NextAAMode = -1;
private long LastFrameTime = 0;
private long CoolDown = 1000;
private ModelData MusicParticle;
@Override
public void cleanup() {
@ -61,15 +75,18 @@ public class GameCore implements GameLogic {
public InitData Initialise(EngineInstance engineInstance) {
Scene scene = engineInstance.scene();
List<ModelData> models = new ArrayList<>();
MusicParticle = ModelLoader.LoadModel("resources/models/MusicParticle/MusicParticle.json");
List<MaterialData> MusicParticleMat = ModelLoader.LoadMaterials("resources/models/MusicParticle/MusicParticle_mat.json");
ModelData SponzaData = ModelLoader.LoadModel("resources/models/Forest/forest.json");
List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Forest/forest_mat.json");
ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/radio/radio.json");
List<MaterialData> SponzaMaterial1 = ModelLoader.LoadMaterials("resources/models/radio/radio_mat.json");
//ModelData SponzaData = ModelLoader.LoadModel("resources/models/Cafe/exterior.json");
//List<MaterialData> SponzaMaterial = ModelLoader.LoadMaterials("resources/models/Cafe/exterior_mat.json");
//ModelData SponzaData1 = ModelLoader.LoadModel("resources/models/Cafe/interior.json");
//List<MaterialData> SponzaMaterial1= ModelLoader.LoadMaterials("resources/models/Cafe/interior_mat.json");
scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0,-5f)));
//scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(0,0,-5f)));
scene.AddActor(new Actor("Sponza1", SponzaData.ID(), new Vector3f(0,0f,-5f)));
scene.AddActor(new Actor("Sponza2", SponzaData1.ID(), new Vector3f(40.0f, 155.0f, -42.0f)).SetScale(0.01f));
models.add(ModelLoader.LoadModel("resources/models/Metro/OBJ/MetroLeadCar.json"));
models.add(ModelLoader.LoadModel("resources/models/melona/melona.json"));
@ -91,22 +108,47 @@ public class GameCore implements GameLogic {
materials.addAll(ModelLoader.LoadMaterials("resources/models/Alice/Welsh040Alice_mat.json"));
materials.addAll(ModelLoader.LoadMaterials("resources/models/Sloop/SloopOBJ_mat.json"));
materials.addAll(SponzaMaterial);
//materials.addAll(SponzaMaterial1);
materials.addAll(MusicParticleMat);
materials.addAll(SponzaMaterial1);
models.add(SponzaData);
//models.add(SponzaData1);
models.add(MusicParticle);
models.add(SponzaData1);
Camera camera = scene.GetCamera();
camera.SetPosition(40.0f, 155.0f, -42.0f);
camera.SetPosition(0,0,0);
//camera.SetPosition(0,0,0);
camera.SetRotation((float) Math.toRadians(10.0f), (float) Math.toRadians(-90.0f),0);
camera.SetRotation(0,0,0);
//camera.SetRotation(0,0,0);
guiTexture = new GuiTexture("resources/EngineResources/Texture/DefaultTexture.png");
List<GuiTexture> guiTextures = new ArrayList<>();
guiTextures.add(guiTexture);
InitiateAudio(engineInstance);
return new InitData(models,materials,guiTextures);
}
private void InitiateAudio(EngineInstance engineInstance){
AudioManager audioManager = engineInstance.audioManager();
Camera camera = engineInstance.scene().GetCamera();
audioManager.SetAttenuationModel(AL11.AL_EXPONENT_DISTANCE);
audioManager.SetListener(new SoundListener(camera.GetPosition()));
SoundBuffer buffer = new SoundBuffer("resources/EngineResources/audio/sounds/LaidBackLobby.ogg");
audioManager.AddSoundBuffer(SOUND_BUFFER_PLAYER, buffer);
AudioSource playerAudioSource = new AudioSource(true,false);
playerAudioSource.SetPosition(new Vector3f(40.0f, 155.0f, -42.0f));
playerAudioSource.SetBuffer(buffer.GetBufferID());
audioManager.AddSoundSource(SOUND_SOURCE_PLAYER,playerAudioSource);
playerAudioSource.Play();
buffer = new SoundBuffer("resources/EngineResources/audio/music/chimken_wing.ogg");
audioManager.AddSoundBuffer(SOUND_BUFFER_MUSIC,buffer);
AudioSource source = new AudioSource(true, true);
source.SetBuffer(buffer.GetBufferID());
audioManager.AddSoundSource(SOUND_SOURCE_MUSIC,source);
//source.Play();
}
@Override
public void CameraInput(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
float Multiplier = MOUSE_SENSITIVITY;
@ -129,6 +171,7 @@ public class GameCore implements GameLogic {
camera.AddRotation((float)Math.toRadians(-deltaPos.y * Multiplier),(float)Math.toRadians(-deltaPos.x * Multiplier),0);
}
engineInstance.audioManager().UpdateListenerPosition(camera);
}
@Override
@ -326,12 +369,28 @@ public class GameCore implements GameLogic {
@Override
public void UpdateFastThread(EngineInstance engineInstance, long FrameDiffNanoSeconds) {
float DeltaTime = (float)(FrameDiffNanoSeconds/16000000.0);
List<Integer> ParticlesToDelete = new ArrayList<>();
if((int)(Math.random() * 60) == 0){
ParticleActor particle = new ParticleActor("particle" + particleActors.size(), MusicParticle.ID(), new Vector3f(40.0f, 155.0f, -42.0f),new Vector3f(1,1,1),0,new Vector3f(-1f + (float)Math.random() * 2,-1f + (float)Math.random() * 2,-1f + (float)Math.random() * 2),0.0005f,1000);
particleActors.add(particle);
engineInstance.scene().AddActor(particle);
}
for(int i = 0; i < angles.size(); i++) {
angles.set(i, (angles.get(i) + 1.0f* DeltaTime) % 360);
CubeActors.get(i).GetRotation().identity().rotateAxis((float) EngineConfig.DegToRad * angles.get(i), rotatingAngles.get(i));
CubeActors.get(i).GetPosition().add((Velocities.get(i).x/100.0f) * DeltaTime,(Velocities.get(i).y/100.0f) * DeltaTime,(Velocities.get(i).z/100.0f) * DeltaTime);
CubeActors.get(i).UpdateModelMatrix();
}
for(int i = 0; i < particleActors.size(); i++){
particleActors.get(i).TickUpdate();
if(particleActors.get(i).TicksLeft() <= 0){
engineInstance.scene().RemoveActor(particleActors.get(i));
ParticlesToDelete.add(i);
}
}
for(int i = ParticlesToDelete.size() - 1; i >= 0; i--){
particleActors.remove((int)ParticlesToDelete.get(i));
}
}
@Override

View file

@ -1,5 +1,6 @@
package net.halbear.Terrain4J.EngineCore.Main;
import net.halbear.Terrain4J.EngineCore.Audio.AudioManager;
import net.halbear.Terrain4J.EngineCore.Display.Window;
import net.halbear.Terrain4J.EngineCore.Logic.*;
import net.halbear.Terrain4J.EngineCore.Logic.Rendering.VulkanContext;
@ -53,7 +54,7 @@ public class PrimaryRuntime {
}
window = new Window(windowTitle);
gameLogic = appLogic;
engineInstance = new EngineInstance(window, new Scene(window),this);
engineInstance = new EngineInstance(window, new Scene(window),this, new AudioManager());
InitData initData = appLogic.Initialise(engineInstance);
PrimaryThread = new MainThread(engineInstance, appLogic);
FastThread = new FastTickThread(engineInstance, appLogic);

View file

@ -36,9 +36,10 @@ public class Actor{
UpdateModelMatrix();
}
public void SetScale(float Scale){
public Actor SetScale(float Scale){
this.Scale = Scale;
UpdateModelMatrix();
return this;
}
public void UpdateModelMatrix(){

View file

@ -0,0 +1,38 @@
package net.halbear.Terrain4J.EngineCore.Main.Scene;
import net.halbear.Terrain4J.EngineCore.Logic.EngineConfig;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
public class ParticleActor extends Actor {
private Vector3f Velocity;
private Vector3f RotatingAngles;
private float Angle = 0.0f;
private int LifeTicks = 1000;
private float decelerationRate = 0.1f;
public ParticleActor(String ID, String ModelID, Vector3f Position, Vector3f RotatingAngles, float Rotation, Vector3f Velocity, float Deceleration, int LifeTicks){
super(ID,ModelID,Position);
this.Angle = Rotation;
this.RotatingAngles = RotatingAngles;
this.decelerationRate = Deceleration;
this.LifeTicks = LifeTicks;
this.Velocity = Velocity;
}
public int TicksLeft(){return LifeTicks;}
public float Deleration(){return decelerationRate;}
public Vector3f GetVelocity(){return Velocity;}
public void TickUpdate(){
Angle = (Angle + 1.0f) % 360;
GetRotation().identity().rotateAxis((float) EngineConfig.DegToRad * Angle, RotatingAngles);
GetPosition().add((Velocity.x/100.0f),(Velocity.y/100.0f) ,(Velocity.z/100.0f));
Velocity.x = Velocity.x != 0? Velocity.x > 0 ? Math.max(Velocity.x - decelerationRate, 0) : Math.min(Velocity.x + decelerationRate, 0) : 0;
Velocity.y = Velocity.y != 0? Velocity.y > 0 ? Math.max(Velocity.y - decelerationRate, 0) : Math.min(Velocity.y + decelerationRate, 0) : 0;
Velocity.z = Velocity.z != 0? Velocity.z > 0 ? Math.max(Velocity.z - decelerationRate, 0) : Math.min(Velocity.z + decelerationRate, 0) : 0;
UpdateModelMatrix();
LifeTicks--;
}
}

View file

@ -312,53 +312,21 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
int ActorCount = Actors.size();
List<Actor> translucentObjects = new ArrayList<>();
for(int i = 0; i < ActorCount; i++){
if(i < Actors.size()) {
var Actor = Actors.get(i);
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
int MeshCount = VkMeshList.size();
for(int j = 0; j < MeshCount; j++){
for (int j = 0; j < MeshCount; j++) {
var VkMesh = VkMeshList.get(j);
String MaterialID = VkMesh.MaterialID();
int MaterialIndex = materialsCache.GetPosition(MaterialID);
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID);
if(vulkanMaterial == null){
Logger.warn("Mesh [{}] in model [{}] does not have material",j,model.GetID());
if (vulkanMaterial == null) {
Logger.warn("Mesh [{}] in model [{}] does not have material", j, model.GetID());
continue;
}
if( DualPassRendering || vulkanMaterial.HasTransparency() == Transparent) {
//if(Transparent){
// if(!translucentObjects.contains(Actor))translucentObjects.add(Actor);
//}else {
SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex);
vertexBuffer.put(0, VkMesh.VerticesBuffer().GetBuffer());
vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets);
vkCmdBindIndexBuffer(CommandHandle, VkMesh.IndicesBuffer().GetBuffer(), 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(CommandHandle, VkMesh.IndicesCount(), 1, 0, 0, 0);
//}
}
}
}
/*if(Transparent){
translucentObjects.sort((actor1, actor2) -> {
float distSq1 = actor1.GetPosition().distanceSquared(scene.GetCamera().GetPosition());
float distSq2 = actor2.GetPosition().distanceSquared(scene.GetCamera().GetPosition());
return Float.compare(distSq2, distSq1);
});
for(int i = 0; i < translucentObjects.size(); i++){
var Actor = translucentObjects.get(i);
VulkanModel model = modelsCache.GetModel(Actor.GetModelID());
List<VulkanMesh> VkMeshList = model.GetVkMeshList();
int MeshCount = VkMeshList.size();
for(int j = 0; j < MeshCount; j++){
var VkMesh = VkMeshList.get(j);
String MaterialID = VkMesh.MaterialID();
int MaterialIndex = materialsCache.GetPosition(MaterialID);
VulkanMaterial vulkanMaterial = materialsCache.GetMaterial(MaterialID);
if(vulkanMaterial == null){
Logger.warn("Mesh [{}] in model [{}] does not have material",j,model.GetID());
continue;
}
if(vulkanMaterial.HasTransparency() == Transparent) {
if (DualPassRendering || vulkanMaterial.HasTransparency() == Transparent) {
SetPushConstants(CommandHandle, Actor.GetModelMatrix(), MaterialIndex);
vertexBuffer.put(0, VkMesh.VerticesBuffer().GetBuffer());
vkCmdBindVertexBuffers(CommandHandle, 0, vertexBuffer, offsets);
@ -367,7 +335,7 @@ public class SceneRender implements SceneRenderer {//dynamic rendering
}
}
}
}*/
}
}
}