LWJGL绑定着色器两次无法渲染

时间:2016-04-23 21:19:24

标签: java opengl lwjgl

我正在尝试使用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;
}
}

1 个答案:

答案 0 :(得分:0)

没关系。这是我导入模型的一个问题。