我正在尝试使用LWJGL创建一个基本的渲染引擎,我最近碰到了一个块。每当我尝试更改着色器制服时,对象在一帧中被绘制两次,程序就会显示清晰的颜色。我认为搞砸的是SceneLoader类的第82行,但我不知道。这是我第一次使用Lwjgl,所以对此的任何帮助将不胜感激。谢谢!
我在下面的问题中放了一些值得注意的类,但这里是完整的源代码: https://github.com/SomeRandomPerson9/3DT/tree/master/src/com/harry9137/api
SceneLoader.java
package com.harry9137.api.scenes;
import com.bulletphysics.linearmath.Transform;
import com.harry9137.api.main.Game;
import com.harry9137.api.physics.MathHelper;
import com.harry9137.api.render.Material;
import com.harry9137.api.render.Mesh;
import com.harry9137.api.render.math.Matrix4f;
import com.harry9137.api.render.math.Vector3f;
import com.harry9137.api.scenes.Objects.ChoiceMenuObject;
import com.harry9137.api.scenes.Objects.logic.GenericObject;
import com.harry9137.api.scenes.Objects.logic.RenderObject;
import com.harry9137.api.scenes.Objects.logic.TextObject;
import com.harry9137.api.util.ProgramRefrence;
import com.harry9137.api.util.RenderUtil;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.glu.GLU;
import org.lwjgl.util.glu.Sphere;
import org.newdawn.slick.Color;
import java.util.HashMap;
public class SceneLoader {
private static HashMap <Integer, SceneBase> scenes = new HashMap<>();
private static SceneBase selectedScene;
private static int selectedSceneNumber;
private static Sphere sphere = new Sphere();
public static void addScene(Integer integer, SceneBase scene){
scenes.put(integer, scene);
}
public static void selectScene(Integer integer){
if(selectedScene != null) {
selectedScene.cleanup();
//selectedScene.getRegShader().updateUniforms(new Matrix4f(),new Matrix4f(), null);
}
selectedScene = scenes.get(integer);
selectedSceneNumber = integer;
selectedScene.specialInit();
}
public static void updateScene(){
if(selectedScene != null) {
selectedScene.update();
if(selectedScene.getDynamicsWorld() != null) {
//System.out.println("blah");
GL11.glLoadIdentity();
selectedScene.getDynamicsWorld().stepSimulation(1.0f / 60.0f);
for(RenderObject renderObject : selectedScene.getObjects()){
if (renderObject.isPhys() && !MathHelper.anyGreaterThan(0.1f, renderObject.getRigidBodyShape().getLinearVelocity(new javax.vecmath.Vector3f(0,0,0)))) {
renderObject.setLocation(MathHelper.vecMathToBaked3f(renderObject.getRigidBodyShape().getMotionState().getWorldTransform(new Transform()).origin));
System.out.println(renderObject.getRigidBodyShape().getMotionState().getWorldTransform(new Transform()).origin);
}
}
}
for (int i = 0; i < scenes.size(); i++) {
if (scenes.get(i) != null) {
if (scenes.get(i).getBtsUpdateLvl() > 0) {
scenes.get(i).update();
}
if (selectedSceneNumber == i) {
selectedScene.update();
}
}
}
}
}
public static void renderScene(){
if(selectedScene.sceneType == SceneType.THREE_DIMENSIONAL) {
for (RenderObject renderObject : selectedScene.getObjects()) {
/*if(renderObject.isHeld()) {
Object[] temp = (renderObject.getTransform().getProjectedTransformationHeld(new Matrix4f().initTranslation(renderObject.getLocation().GetX(), renderObject.getLocation().GetY(), renderObject.getLocation().GetZ())));
selectedScene.getRegShader().updateUniforms(renderObject.getTransform().getTransformation(), (Matrix4f) temp[0], renderObject.getMaterial());
//renderObject.setLocation(((Matrix4f)temp[2]).get;
}
else{
selectedScene.getRegShader().updateUniforms(renderObject.getTransform().getTransformation(), renderObject.getTransform().getProjectedTransformation(new Matrix4f().initTranslation(renderObject.getLocation().GetX(), renderObject.getLocation().GetY(), renderObject.getLocation().GetZ())), renderObject.getMaterial());
}*/
for(Mesh meshyThing : renderObject.getMeshs().values()){
selectedScene.getRegShader().bind();
System.out.println("Object " + meshyThing.getObjName() + " has material " + meshyThing.getRequiredMtl());
selectedScene.getRegShader().updateUniforms(renderObject.getTransform().getTransformation(), renderObject.getTransform().getProjectedTransformation(new Matrix4f().initTranslation(renderObject.getLocation().GetX(), renderObject.getLocation().GetY(), renderObject.getLocation().GetZ())), renderObject.getMaterial(meshyThing.getRequiredMtl()));
meshyThing.draw();
}
//renderObject.getMesh().draw();
/*if(Game.showBoundingBoxes && selectedScene.getDynamicsWorld() != null && renderObject.isPhys()){
GL11.glPushMatrix();
javax.vecmath.Vector3f position = renderObject.getRigidBodyShape().getMotionState().getWorldTransform(new Transform()).origin;
sphere.setDrawStyle(GLU.GLU_SILHOUETTE);
GL11.glTranslatef(position.x, position.y, position.z);
GL11.glColor4f(0, 1, 0, 1);
sphere.draw(renderObject.getRigidBodyShape().getCollisionShape().getAngularMotionDisc(), 30, 30);
GL11.glPopMatrix();
*/
}
for(GenericObject genericObject : selectedScene.getOverlayObjects()){
/*if(genericObject instanceof TextObject){
TextObject textObj = (TextObject)genericObject;
try {
GL11.glPushMatrix();
selectedScene.getOverlayShader().bind();
selectedScene.getOverlayShader().updateUniforms(null, null, new Material(null, new Vector3f(0,0,0)));
ProgramRefrence.fonts.arialFont.drawString(textObj.getX(), textObj.getY(), textObj.getString(), Color.black);
GL11.glPopMatrix();
}catch(NullPointerException e){
if(ProgramRefrence.fonts.arialFont == null){
System.err.println("Global font is null");
}
//if(textObj.getFont() == null) {
// System.err.println("Text Object " + textObj.getObjName() + ": Font is Null");
//}
if(textObj.getString() == null){
System.err.println("Text Object " + textObj.getObjName() + ": String is Null");
}
}
}
else if(genericObject instanceof ChoiceMenuObject){
ChoiceMenuObject choiceMenuObject = (ChoiceMenuObject)genericObject;
try{
choiceMenuObject.mesh.draw(choiceMenuObject.xPos, choiceMenuObject.yPos);
}
catch(Exception e){
}
}*/
}
}
else if(selectedScene.sceneType == SceneType.TWO_DIMENSIONAL){
if(selectedScene instanceof Scene2DVideo){
((Scene2DVideo) selectedScene).render();
}
}
}
/* public static void calcPhysics(){
if(selectedScene != null) {
for (RenderObject object : selectedScene.getObjects()) {
if(object.isPhys()) {
object.getTransform().addTranslation(object.getLocation());
int tps = Game.getInstance().getTps();
//Gravity
if (object.getVelocity().GetY() >= ProgramRefrence.terminalVelocity) {
object.setAcceleration(new Vector3f((float) object.getAcceleration().GetX(), (float) (object.getAcceleration().GetY() - ProgramRefrence.gravity / tps), (float) object.getAcceleration().GetZ()));
}
//Acceleration to Velocity
if (object.getAcceleration().GetX() != 0) {
object.getVelocity().SetX((float) (object.getAcceleration().GetX() / tps) + object.getVelocity().GetX());
}
if (object.getAcceleration().GetY() != 0) {
object.getVelocity().SetY((float) (object.getAcceleration().GetY() * Launch.TPS / 100) + object.getVelocity().GetY());
}
if (object.getAcceleration().GetX() != 0) {
object.getVelocity().SetZ((float) (object.getAcceleration().GetZ() * Launch.TPS / 100) + object.getVelocity().GetZ());
}
object.setAcceleration(new Vector3f(0, 0, 0));
//Velocity to Location
if (object.getAcceleration().GetX() != 0) {
object.getLocation().SetX((float) (object.getAcceleration().GetX() / tps) + object.getVelocity().GetX());
}
if (object.getAcceleration().GetY() != 0) {
if(object.getLocation().GetY() > 0f) {
object.getLocation().SetY((float) (object.getAcceleration().GetY() * Launch.TPS / 100) + object.getVelocity().GetY());
}
}
if (object.getAcceleration().GetX() != 0) {
object.getLocation().SetZ((float) (object.getAcceleration().GetZ() * Launch.TPS / 100) + object.getVelocity().GetZ());
}
}
}
}
} */
public static void updateSceneInput(){
if(selectedScene != null) {
selectedScene.input();
}
}
public static int getSelectedSceneNumber(){
return selectedSceneNumber;
}
public static SceneBase getSelectedScene(){
return selectedScene;
}
public static HashMap<Integer, SceneBase> getScenes() {
return scenes;
}
}
PhongShader.java(我遇到问题的场景中的着色器)
package com.harry9137.api.render.shaders;
import com.harry9137.api.render.Material;
import com.harry9137.api.util.ResourceLoader;
import com.harry9137.api.render.math.Matrix4f;
import com.harry9137.api.render.math.Vector3f;
import com.harry9137.api.render.lighting.BaseLight;
import com.harry9137.api.render.lighting.DirectionalLight;
import com.harry9137.api.util.RenderUtil;
import org.newdawn.slick.Color;
import java.awt.*;
public class PhongShader extends Shader {
private static final PhongShader instance = new PhongShader();
public static PhongShader getInstance() {
return instance;
}
private static Vector3f ambientLight = new Vector3f(0.1f,0.1f,0.1f);
private static DirectionalLight directionalLight = new DirectionalLight(new BaseLight(new Vector3f(1,1,1), 0f), new Vector3f(0,0,0));
private PhongShader() {
super();
addVertexShader(ResourceLoader.loadShader("phongVertex.vs"));
addFragmentShader(ResourceLoader.loadShader("phongFragment.fs"));
compileShader();
addUniform("transform");
addUniform("baseColor");
addUniform("ambientLight");
addUniform("directionalLight.base.color");
addUniform("directionalLight.base.intensity");
addUniform("directionalLight.direction");
}
public static DirectionalLight getDirectionalLight() {
return directionalLight;
}
public static void setDirectionalLight(DirectionalLight directionalLight) {
PhongShader.directionalLight = directionalLight;
}
public void updateUniforms(Matrix4f worldMatrix, Matrix4f projectedMatrix, Material material) {
setUniform("transform", projectedMatrix.mul(worldMatrix));
if(material != null && material.getColor() != null) {
setUniform("baseColor", material.getColor());
}
else{
setUniform("baseColor", new Vector3f(255,255,255));
//Color.white.bind();
}
if (material != null && material.getTexture() != null) {
material.getTexture().bind();
}
else
RenderUtil.unbindTextures();
setUniform("ambientLight", ambientLight);
setUniform("directionalLight", directionalLight);
}
public static Vector3f getAmbientLight() {
return ambientLight;
}
public static void setAmbientLight(Vector3f ambientLight) {
PhongShader.ambientLight = ambientLight;
}
public void setUniform(String uniformName, BaseLight baseLight){
setUniform(uniformName + ".color", baseLight.getColor());
setUniformf(uniformName + ".intensity", baseLight.getIntensity());
}
public void setUniform(String uniformName, DirectionalLight directionalLight)
{
setUniform(uniformName + ".base", directionalLight.getBase());
setUniform(uniformName + ".direction", directionalLight.getDirection());
}
}
phongVertex.vs
#version 330
layout (location = 0) in vec3 position;
layout (location = 1) in vec2 texCoord;
layout (location = 2) in vec3 normal;
out vec2 texCoord0;
out vec3 normal0;
uniform mat4 transform;
void main()
{
gl_Position = transform * vec4(position, 1.0);
texCoord0 = texCoord;
normal0 = normal;
}
phongFragment.fs
#version 330
in vec2 texCoord0;
in vec3 normal0;
out vec4 fragColor;
struct BaseLight{
vec3 color;
float intensity;
};
struct DirectionalLight{
BaseLight base;
vec3 direction;
};
uniform DirectionalLight directionalLight;
uniform vec3 baseColor;
uniform vec3 ambientLight;
uniform sampler2D sampler;
vec4 calcLight(BaseLight base, vec3 direction, vec3 normal){
float diffuseFactor = dot(-direction, normal);
vec4 diffuseColor = vec4(0,0,0,0);
if(diffuseFactor > 0)
diffuseColor = vec4(base.color, 1.0) * base.intensity * diffuseFactor;
return diffuseColor;
}
vec4 calcDirectionalLight(DirectionalLight directionalLight, vec3 normal){
return calcLight(directionalLight.base, directionalLight.direction, normal);
}
void main()
{
vec4 totalLight = vec4(ambientLight, 1);
vec4 color = fragColor = vec4(baseColor, 1);
vec4 textureColor = texture(sampler, texCoord0.xy);
if(textureColor != vec4(0,0,0,0))
color *= textureColor;
vec3 normal = normalize(normal0);
totalLight += calcDirectionalLight(directionalLight, normal);
fragColor = color * totalLight;
}
Mesh.java
package com.harry9137.api.render;
import com.harry9137.api.render.math.Vector3f;
import com.harry9137.api.scenes.Objects.logic.GenericObject;
import com.harry9137.api.util.Util;
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import static org.lwjgl.opengl.GL20.*;
public class Mesh extends GenericObject {
private int vbo;
private int ibo;
private int size;
private String requiredMtl;
public Mesh(){
vbo = glGenBuffers();
ibo = glGenBuffers();
size = 0;
}
public void addVertices(Vertex[] data, int[] indices) {
addVertices(data, indices, false);
}
public void addVertices(Vertex[] data, int[] indices, boolean calcNormals){
if(calcNormals){
calcNormals(data, indices);
}
size = indices.length;
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, Util.createFlippedBuffer(data), GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, Util.createFlippedBuffer(indices), GL_STATIC_DRAW);
}
public void draw(){
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glVertexAttribPointer(0,3, GL_FLOAT, false, Vertex.SIZE * 4, 0);
glVertexAttribPointer(1,2, GL_FLOAT, false, Vertex.SIZE * 4, 12);
glVertexAttribPointer(2,3, GL_FLOAT, false, Vertex.SIZE * 4, 20);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,ibo);
glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0);
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
glDisableVertexAttribArray(2);
}
private void calcNormals(Vertex[] vertexes, int[] integers){
for(int i = 0; i < integers.length; i += 3){
int i0 = integers[i];
int i1 = integers[i + 1];
int i2 = integers[i + 2];
Vector3f v1 = vertexes[i1].getPos().Sub(vertexes[i0].getPos());
Vector3f v2 = vertexes[i2].getPos().Sub(vertexes[i0].getPos());
Vector3f normal = v1.cross(v2).Normalized();
vertexes[i0].setNormal(vertexes[i0].getNormal().Add(normal));
vertexes[i1].setNormal(vertexes[i0].getNormal().Add(normal));
vertexes[i2].setNormal(vertexes[i0].getNormal().Add(normal));
}
for(int i = 0; i < vertexes.length; i++){
vertexes[i].setNormal(vertexes[i].getNormal().Normalized());
}
}
public int getIbo() {
return ibo;
}
public int getVbo() {
return vbo;
}
public String getRequiredMtl() {
return requiredMtl;
}
public void setRequiredMtl(String requiredMtl) {
this.requiredMtl = requiredMtl;
}
}
答案 0 :(得分:0)
没关系。这是我导入模型的一个问题。