问题描述
我使用thinmatrix 的tutoterial 编写游戏代码,并在向水中添加几何着色器时。比水不显示。
这是我的着色器程序:
package shaders;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.FloatBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL32;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.util.vector.Vector4f;
public abstract class ShaderProgram {
private int programID;
private int vertexShadreID;
private int fragmentShaderID;
private int geometryShaderID;
private boolean havegeometry = false;
private static FloatBuffer matrixBuffer = BufferUtils.createFloatBuffer(16);
public ShaderProgram(String vertexFile,String fragmentFile) {
vertexShadreID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID,vertexShadreID);
GL20.glAttachShader(programID,fragmentShaderID);
bindAttributes();
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
getAllUniformlocations();
}
public ShaderProgram(String vertexFile,String fragmentFile,String geometry) {
vertexShadreID = loadShader(vertexFile,GL20.GL_VERTEX_SHADER);
geometryShaderID = loadShader(geometry,GL32.GL_GEOMETRY_SHADER);
fragmentShaderID = loadShader(fragmentFile,GL20.GL_FRAGMENT_SHADER);
programID = GL20.glCreateProgram();
GL20.glAttachShader(programID,vertexShadreID);
GL20.glAttachShader(programID,geometryShaderID);
GL20.glAttachShader(programID,fragmentShaderID);
bindAttributes();
havegeometry = true;
GL20.glLinkProgram(programID);
GL20.glValidateProgram(programID);
getAllUniformlocations();
}
protected abstract void getAllUniformlocations();
protected int getUniformlocation(String uniformName) {
return GL20.glGetUniformlocation(programID,uniformName);
}
public void start() {
GL20.gluseProgram(programID);
}
public void stop() {
GL20.gluseProgram(0);
}
public void cleanUp() {
stop();
GL20.glDetachShader(programID,vertexShadreID);
GL20.glDetachShader(programID,fragmentShaderID);
if(havegeometry) {
GL20.glDetachShader(programID,geometryShaderID);
GL20.glDeleteShader(geometryShaderID);
}
GL20.glDeleteShader(vertexShadreID);
GL20.glDeleteShader(fragmentShaderID);
GL20.glDeleteShader(programID);
}
protected abstract void bindAttributes();
protected void bindAttribute(int attribute,String variableName) {
GL20.glBindAttribLocation(programID,attribute,variableName);
}
protected void loadFloat(int location,float value) {
GL20.gluniform1f(location,value);
}
protected void loadInt(int location,int value) {
GL20.gluniform1i(location,value);
}
protected void loadVector(int location,Vector3f vector) {
GL20.gluniform3f(location,vector.x,vector.y,vector.z);
}
protected void loadVector(int location,Vector4f vector) {
GL20.gluniform4f(location,vector.z,vector.w);
}
protected void load2DVector(int location,Vector2f vector) {
GL20.gluniform2f(location,vector.y);
}
protected void loadBoolean(int location,boolean value) {
float toLoad = 0;
if(value) {
toLoad = 1;
}
GL20.gluniform1f(location,toLoad);
}
protected void loadMatrix(int location,Matrix4f matrix) {
matrix.store(matrixBuffer);
matrixBuffer.flip();
GL20.gluniformMatrix4(location,false,matrixBuffer);
}
private static int loadShader(String file,int type) {
StringBuilder shaderSource = new StringBuilder();
InputStream in = ShaderProgram.class.getResourceAsstream(file);
try (BufferedReader reader = new BufferedReader(new InputStreamReader(in))) {
String line;
while((line = reader.readLine()) != null) {
shaderSource.append(line).append("\n");
}
} catch (IOException e) {
System.err.println("Could not read file!");
e.printstacktrace();
System.exit(-1);
}
int shaderID = GL20.glCreateShader(type);
GL20.glShaderSource(shaderID,shaderSource);
GL20.glCompileShader(shaderID);
if(GL20.glGetShaderi(shaderID,GL20.GL_COMPILE_STATUS) == GL11.GL_FALSE){
System.out.println(GL20.glGetShaderInfoLog(shaderID,500));
System.err.println("Could not compile shader.");
System.exit(-1);
}
return shaderID;
}
}
这是我的 WaterShader:
package water;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
import entities.Camera;
import entities.Light;
import shaders.ShaderProgram;
import toolBox.Maths;
public class WaterShader extends ShaderProgram {
private final static String VERTEX_FILE = "/water/waterVertex.txt";
private final static String FRAGMENT_FILE = "/water/waterFragment.txt";
private final static String GEOMETRY_FILE = "/water/waterGeometry.txt";
private int location_modelMatrix;
private int location_viewMatrix;
private int location_projectionMatrix;
private int location_reflection;
private int location_refraction;
private int location_dudvMap;
private int location_moveFactor;
private int location_cameraPosition;
private int location_normalMap;
private int location_lightColour;
private int location_lightPosition;
private int location_depthMap;
private int location_skyColour;
public WaterShader() {
super(VERTEX_FILE,FRAGMENT_FILE,GEOMETRY_FILE);
}
@Override
protected void bindAttributes() {
bindAttribute(0,"position");
}
@Override
protected void getAllUniformlocations() {
location_projectionMatrix = getUniformlocation("projectionMatrix");
location_viewMatrix = getUniformlocation("viewMatrix");
location_modelMatrix = getUniformlocation("modelMatrix");
location_reflection = getUniformlocation("reflectionTexture");
location_refraction = getUniformlocation("refractionTexture");
location_dudvMap = getUniformlocation("dudvMap");
location_moveFactor = getUniformlocation("moveFactor");
location_cameraPosition = getUniformlocation("cameraPosition");
location_normalMap = getUniformlocation("normalMap");
location_lightColour = getUniformlocation("lightColour");
location_lightPosition = getUniformlocation("lightPosition");
location_depthMap = getUniformlocation("depthMap");
location_skyColour = super.getUniformlocation("skyColour");
}
public void connectTextureUnits() {
super.loadInt(location_reflection,0);
super.loadInt(location_refraction,1);
super.loadInt(location_dudvMap,2);
super.loadInt(location_normalMap,3);
super.loadInt(location_depthMap,4);
}
public void loadLight(Light sun) {
super.loadVector(location_lightColour,sun.getColour());
super.loadVector(location_lightPosition,sun.getPosition());
}
public void loadSkyColour(Vector3f colour){
super.loadVector(location_skyColour,colour);
}
public void loadMoveFactor(float factor) {
super.loadFloat(location_moveFactor,factor);
}
public void loadProjectionMatrix(Matrix4f projection) {
loadMatrix(location_projectionMatrix,projection);
}
public void loadViewMatrix(Camera camera){
Matrix4f viewMatrix = Maths.createViewMatrix(camera);
loadMatrix(location_viewMatrix,viewMatrix);
super.loadVector(location_cameraPosition,camera.getPosition());
}
public void loadModelMatrix(Matrix4f modelMatrix){
loadMatrix(location_modelMatrix,modelMatrix);
}
}
这是我的几何着色器:
#version 430 core
void main(void)
{
}
我想创建 FFTwater。
解决方法
您有一个空的几何着色器,这就是没有渲染任何内容的原因。更准确地说,几何着色器应明确输出顶点和图元(参见 EndVertex() 和 EndPrimitive())。您的几何着色器不这样做,有效地输出零基元。我建议您探索一些有关几何着色器的资源,例如 https://www.khronos.org/opengl/wiki/Geometry_Shader 或 https://learnopengl.com/Advanced-OpenGL/Geometry-Shader。