im用lwjgl3编码游戏。我最初使用了lwjgl 2.但是在主要的chanllenges中,我切换到lwjgl3。
我浏览了几个教程,并用窗口类组合了一个gameloop,并试图实现我已经拥有的代码。
我不得不改变多个事情,面临着像光滑的Util TextureLoDoder这样的挑战,但是现在我坚持了:
基本上我看到的是窗口,但是上面没有显示任何内容。到目前为止,我的引擎已经很大,但是我将尝试实施重要的方法。当您需要更多时,我可以发布更多。
我将发布用于实体和Skybox的Shaderfiles(目前我要显示的内容)也
我只看到一个窗口,没有任何显示
主类
package main;
import static org.lwjgl.glfw.GLFW.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.glfw.GLFWErrorCallback;
import org.lwjgl.opengl.GL;
import entities.Camera;
import entities.Light;
import entities.Player;
import graphics.Window;
import graphics.models.RawModel;
import graphics.models.TexturedModel;
import graphics.renderEngine.Loader;
import graphics.renderEngine.MasterRenderer;
import graphics.renderEngine.OBJLoader;
import graphics.textures.ModelTexture;
import toolbox.Vector3f;
public class Main
{
private GLFWErrorCallback errorCallback = GLFWErrorCallback.createPrint(System.err);
private Window window;
private MasterRenderer renderer;
private Loader loader;
private int Width;
private int Height;
private boolean running = false;
private double delta;
List<Light> lights = new ArrayList<Light>();
Camera camera = null;
private Player player;
public Main()
{
init();
}
private void input()
{
glfwPollEvents();
if(window.shouldClose()) stop();
}
private void update()
{
renderer.setHeight(Height);
renderer.setWidth(Width);
renderer.setDelta(delta);
}
private void render()
{
renderer.processEntity(player);
renderer.render(lights, camera);
window.render();
}
private void run()
{
long lastTime = System.nanoTime();
long currentTime = lastTime;
long diff = 0;
long timer = System.currentTimeMillis();
double ns = 1000000000 / 60.0;
delta = 0.0;
double dfps = 1000000000 / 60.0;
double d = 0.0;
int fps = 0;
int ups = 0;
while(running)
{
currentTime = System.nanoTime();
diff = currentTime - lastTime;
delta += (diff)/ ns;
d += diff/dfps;
lastTime = currentTime;
while(delta >= 1.0)
{
input();
update();
ups++;
delta--;
}
if(d >- 1.0)
{
render();
fps++;
d = 0.0;
}
if(System.currentTimeMillis() > timer + 1000)
{
window.setTitle("Junker.5 | ups: "+ups+"| fps: "+fps+"");
ups = 0;
fps = 0;
timer += 1000;
}
}
cleanUp();
}
public void start()
{
if(running) return;
running = true;
run();
}
public void stop()
{
if(!running) return;
running = false;
}
private void init()
{
Width = 1280;
Height = 720;
glfwSetErrorCallback(errorCallback);
glfwInit();
window = new Window(Width, Height, "Junker.5");
GL.createCapabilities();
loader = new Loader();
renderer = new MasterRenderer(loader);
renderer.setHeight(Height);
renderer.setWidth(Width);
renderer.setDelta(delta);
RawModel playerShip = OBJLoader.loadObjModel("Puddle Jumper", loader);
TexturedModel playership = new TexturedModel(playerShip, ModelTexture.loadTexture("white"));
player = new Player(playership, new Vector3f(0, 0, -50),0,0,0,1);
lights.add(new Light(new Vector3f(0,1000,-5000), new Vector3f(0f,0.4f,5f)));
lights.add(new Light(new Vector3f(0,0,-10), new Vector3f(1,0,1), new Vector3f(1, 0.01f, 0.002f)));
try
{
camera = new Camera(player);
}
catch (IOException e)
{
e.printStackTrace();
}
}
private void cleanUp()
{
window.hide();
//guiRenderer.cleanUp();
renderer.cleanUp();
loader.cleanUp();
window.dispose();
}
public static void main(String[] args)
{
Main main = new Main();
main.start();
}
public int getWidth()
{
return window.getWidth();
}
public int getheight()
{
return window.getHeight();
}
public double getDelta()
{
return delta;
}
}
主渲染器类
package graphics.renderEngine;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.lwjgl.opengl.GL11;
import entities.Camera;
import entities.Entity;
import entities.Light;
import entities.Player;
import graphics.models.RawModel;
import graphics.models.TexturedModel;
import graphics.shaders.StaticShader;
import graphics.shaders.TerrainShader;
import graphics.skybox.SkyboxRenderer;
import graphics.terrains.Terrain;
import graphics.textures.ModelTexture;
import toolbox.Matrix4f;
import toolbox.Vector3f;
public class MasterRenderer
{
private static final float FOV = 70;
private static final float NEAR_PLANE = 0.01f;
private static final float FAR_PLANE = 1000;
public int Width;
public double delta;
public int Height;
private Matrix4f projectionMatrix;
private StaticShader shader = new StaticShader();
private TerrainRenderer terrainRenderer;
private TerrainShader terrainShader = new TerrainShader();
private EntityRenderer renderer;
private Map<TexturedModel, List<Entity>> entities = new HashMap<TexturedModel, List<Entity>>();
private List<Terrain> terrains = new ArrayList<Terrain>();
private SkyboxRenderer skyboxRenderer ;
public MasterRenderer(Loader loader)
{
enableCulling();
createProjectionMatrix();
renderer = new EntityRenderer(shader, projectionMatrix);
terrainRenderer = new TerrainRenderer(terrainShader, projectionMatrix);
skyboxRenderer = new SkyboxRenderer(loader, projectionMatrix);
}
public static void enableCulling()
{
GL11.glEnable(GL11.GL_CULL_FACE);
GL11.glCullFace(GL11.GL_BACK);
}
public static void disableCullig()
{
GL11.glDisable(GL11.GL_CULL_FACE);
}
public void render(List<Light> lights, Camera camera)
{
prepare();
shader.start();
shader.loadLights(lights);
shader.loadViewMatrix(camera);
renderer.render(entities);
shader.stop();
terrainShader.start();
terrainShader.loadLights(lights);
terrainShader.loadViewMatrix(camera);
terrainRenderer.render(terrains);
terrainShader.stop();
skyboxRenderer.render(camera);
terrains.clear();
entities.clear();
}
public void processTerrain(Terrain terrain)
{
terrains.add(terrain);
}
public void processEntity(Entity entity)
{
TexturedModel entityModel = entity.getModel();
List<Entity> batch = entities.get(entityModel);
if(batch != null)
{
batch.add(entity);
}
else
{
List<Entity> newBatch = new ArrayList<Entity>();
newBatch.add(entity);
entities.put(entityModel, newBatch);
}
}
private void createProjectionMatrix()
{
float aspectRatio = (float) Width / (float) Height;
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV / 2f))) * aspectRatio);
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;
projectionMatrix = new Matrix4f();
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m33 = 0;
}
public void prepare()
{
GL11.glEnable(GL11.GL_DEPTH_TEST);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT|GL11.GL_DEPTH_BUFFER_BIT);
GL11.glClearColor(0.03f, 0f, 0.0f, 1);
}
public void cleanUp()
{
shader.cleanUp();
terrainShader.cleanUp();
}
public void setWidth(int width)
{
Width = width;
}
public void setHeight(int height)
{
Height = height;
}
public void setDelta(double delta)
{
this.delta = delta;
}
}
静态着色器类
package graphics.shaders;
import java.util.List;
import entities.Camera;
import entities.Light;
import toolbox.Maths;
import toolbox.Matrix4f;
import toolbox.Vector3f;
public class StaticShader extends ShaderProgram
{
public static final String VERTEX_FILE = "./Ressources/Shaders/VertexShader.shd";
public static final String FRAGMENT_FILE = "./Ressources/Shaders/FragmentShader.shd";
public static final int MAX_LIGHTS = 4;
private int location_transformationMatrix;
private int location_projectionMatrix;
private int location_viewMatrix;
private int location_lightPosition[];
private int location_lightColour[];
private int location_attenuation[];
private int location_shineDamper;
private int location_reflectivity;
private int location_useFakeLighting;
public StaticShader()
{
super(VERTEX_FILE, FRAGMENT_FILE);
}
@Override
protected void bindAttributes()
{
super.bindAttribute(0, "position");
super.bindAttribute(1, "textureCoords");
super.bindAttribute(2, "normal");
}
protected void getAllUniformLocations()
{
location_transformationMatrix = super.getUniformLocation("transformationMatrix");
location_projectionMatrix = super.getUniformLocation("projectionMatrix");
location_viewMatrix = super.getUniformLocation("viewMatrix");
location_shineDamper = super.getUniformLocation("shineDamper");
location_reflectivity = super.getUniformLocation("reflectivity");
location_useFakeLighting = super.getUniformLocation("useFakeLighting");
location_lightPosition = new int[MAX_LIGHTS];
location_attenuation = new int[MAX_LIGHTS];
location_lightColour = new int[MAX_LIGHTS];
for(int i = 0;i<MAX_LIGHTS;i++)
{
location_lightPosition[i] = super.getUniformLocation("lightPosition["+i+"]");
location_lightColour[i] = super.getUniformLocation("lightColour["+i+"]");
location_attenuation[i] = super.getUniformLocation("attenuation["+i+"]");
}
}
public void loadFakeLightingVariable(boolean useFake)
{
super.loadBoolean(location_useFakeLighting, useFake);
}
public void loadShineVariables(float damper, float reflectivity)
{
super.LoadFloat(location_shineDamper, damper);
super.LoadFloat(location_reflectivity, reflectivity);
}
public void loadTreansformationMatrix(Matrix4f matrix)
{
super.loadMatrix(location_transformationMatrix, matrix);
}
public void loadLights(List<Light> lights)
{
for(int i = 0;i<MAX_LIGHTS;i++)
{
if(i<lights.size())
{
super.LoadVector(location_lightPosition[i], lights.get(i).getPosition());
super.LoadVector(location_lightColour[i], lights.get(i).getColour());
super.LoadVector(location_attenuation[i], lights.get(i).getAttenuation());
}
else
{
super.LoadVector(location_lightPosition[i], new Vector3f(0,0,0));
super.LoadVector(location_lightColour[i], new Vector3f(0,0,0));
super.LoadVector(location_attenuation[i], new Vector3f(1,0,0));
}
}
}
public void loadViewMatrix(Camera camera)
{
Matrix4f viewMatrix = Maths.createViewMatrix(camera);
super.loadMatrix(location_viewMatrix, viewMatrix);
}
public void loadProjectionMatrix(Matrix4f projection)
{
super.loadMatrix(location_projectionMatrix, projection);
}
}
Shaderfiles:
碎片着色器
#version 400 core
in vec2 pass_textureCoords;
in vec3 surfaceNormal;
in vec3 toLightVector[4];
in vec3 toCameraVector;
out vec4 out_Color;
uniform sampler2D textureSampler;
uniform vec3 lightColour[4];
uniform float shineDamper;
uniform float reflectivity;
uniform vec3 attenuation[4];
void main(void)
{
vec3 unitNormal = normalize(surfaceNormal);
vec3 unitVectorToCamera = normalize(toCameraVector);
vec3 totalDiffuse = vec3(0.0);
vec3 totalSpecular = vec3(0.0);
for(int i=0;i<4;i++)
{
float distance = length(toLightVector[i]);
float attFactor = attenuation[i].x + (attenuation[i].y * distance) + (attenuation[i].z * distance * distance);
vec3 unitLightVector = normalize(toLightVector[i]);
float nDot1 = dot(unitNormal, unitLightVector);
float brightness = max(nDot1,0.0);
vec3 lightDirection = -unitLightVector;
vec3 reflectedLightDirection = reflect(lightDirection,unitNormal);
float specularFactor = dot(reflectedLightDirection, unitVectorToCamera);
specularFactor = max(specularFactor,0.0);
float dampedFactor = pow(specularFactor,shineDamper);
totalSpecular = totalSpecular + (dampedFactor * reflectivity * lightColour[i])/attFactor;
totalDiffuse = totalDiffuse + (brightness * lightColour[i])/attFactor;
}
totalDiffuse = max(totalDiffuse, 0.2);
vec4 textureColour = texture(textureSampler, pass_textureCoords);
if(textureColour.a<0.5)
{
discard;
}
out_Color = vec4(totalDiffuse,1.0) * texture(textureSampler, pass_textureCoords) + vec4(totalSpecular,1.0);
}
顶点着色器
#version 400 core
in vec3 position;
in vec2 textureCoords;
in vec3 normal;
out vec2 pass_textureCoords;
out vec3 surfaceNormal;
out vec3 toLightVector[4];
out vec3 toCameraVector;
uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition[4];
uniform float useFakeLighting;
void main(void)
{
vec4 worldPosition = transformationMatrix * vec4(position,1.0);
gl_Position = projectionMatrix * viewMatrix * worldPosition;
pass_textureCoords = textureCoords;
vec3 actualNormal = normal;
if(useFakeLighting > 0.5)
{
actualNormal = vec3(0.0,1.0,0.0);
}
surfaceNormal = (transformationMatrix * vec4(actualNormal,0.0)).xyz;
for(int i=0;i<4;i++)
{
toLightVector[i] = lightPosition[i] - worldPosition.xyz;
}
toCameraVector = (inverse(viewMatrix) * vec4(0.0,0.0,0.0,1.0)).xyz - worldPosition.xyz;
}
我绝对不知道我在做什么错。如果有人想真正帮助我在这个问题上有更多的个人帮助,请随时与我联系。
谢谢你!
编辑:
是的,ClearColor的作品,这就是为什么我感到困惑的一部分。在我将lwjgl2代码效法到新的lwjgl3代码之前,lwjgl3窗口确实显示了简单的图形,例如3D Cube
这是我的窗口类
窗口
package graphics;
import static org.lwjgl.glfw.GLFW.*;
import static org.lwjgl.system.MemoryUtil.*;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.system.MemoryUtil;
public class Window
{
private long window;
private int Width;
private int Height;
public Window(int width, int height, String title)
{
this.Width = width;
this.Height = height;
glfwDefaultWindowHints();
glfwWindowHint(GLFW_RESIZABLE, GL11.GL_FALSE);
glfwWindowHint(GLFW_VISIBLE, GL11.GL_TRUE);
//DECORATION
glfwWindowHint(GLFW_DECORATED, GL11.GL_TRUE);
glfwWindowHint(GLFW_FOCUSED, GL11.GL_TRUE);
window = glfwCreateWindow(Width,Height,"Junker.5",NULL,NULL);
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
glfwSetWindowPos(
window,
(vidmode.width() - width) / 2,
(vidmode.height() - height) / 2
);
glfwMakeContextCurrent(window);
}
public void dispose()
{
glfwDestroyWindow(window);
}
public void hide()
{
glfwHideWindow(window);
}
public void render()
{
glfwSwapBuffers(window);
}
public void show()
{
glfwShowWindow(window);
}
public void setTitle(String title)
{
glfwSetWindowTitle(window, title);
}
public boolean shouldClose()
{
if(!glfwWindowShouldClose(window))
{
return false;
}
else
{
return true;
}
}
public int getWidth()
{
return Width;
}
public void setWidth(int width)
{
Width = width;
}
public int getHeight()
{
return Height;
}
public void setHeight(int height)
{
Height = height;
}
public void changecursor()
{
// Create the cursor object
//long cursor = GLFW.glfwCreateCursor(imageBuffer, 0, 0);
/*if (cursor == MemoryUtil.NULL)
throw new RuntimeException("Error creating cursor");
// Set the cursor on a window
GLFW.glfwSetCursor(window, cursor);*/
}
}
我确实设法自己解决了问题,至少现在显示内容:)
我现在只是硬编码的宽度和高度。在主阶段中进行敏捷()的方法必须使我的createproctionmatrix()函数的神灵愤怒。但是,ID知道如何为将来的目的进行这种动态