Java 我能';t更改片段着色器中的颜色
我在学习OpenGL,我试图画一个红色的三角形,但我的三角形一直是黑色的 这是我的片段着色器的代码:Java 我能';t更改片段着色器中的颜色,java,opengl,shader,lwjgl,Java,Opengl,Shader,Lwjgl,我在学习OpenGL,我试图画一个红色的三角形,但我的三角形一直是黑色的 这是我的片段着色器的代码: #version 330 core out vec4 color; void main() { color = vec4(1,0,0,1); } 并且我的着色器编译没有问题,我使用这个类来使用着色器: public class ShaderProgram { private final int programId; private int vertexShader
#version 330 core
out vec4 color;
void main()
{
color = vec4(1,0,0,1);
}
并且我的着色器编译没有问题,我使用这个类来使用着色器:
public class ShaderProgram
{
private final int programId;
private int vertexShaderId;
private int fragmentShaderId;
public ShaderProgram() throws Exception
{
programId = glCreateProgram();
if (programId == 0) {
throw new Exception("Could not create Shader");
}
}
public void createVertexShader(String shaderCode) throws Exception {
vertexShaderId = createShader(shaderCode, GL_VERTEX_SHADER);
}
public void createFragmentShader(String shaderCode) throws Exception {
fragmentShaderId = createShader(shaderCode, GL_FRAGMENT_SHADER);
}
protected int createShader(String shaderCode, int shaderType) throws Exception {
int shaderId = glCreateShader(shaderType);
if (shaderId == 0) {
throw new Exception("Error creating shader. Code: " + shaderId);
}
glShaderSource(shaderId, shaderCode);
glCompileShader(shaderId);
if (glGetShaderi(shaderId, GL_COMPILE_STATUS) == 0) {
throw new Exception("Error compiling Shader code: " + glGetShaderInfoLog(shaderId, 1024));
}
glAttachShader(programId, shaderId);
return shaderId;
}
public void link() throws Exception {
glLinkProgram(programId);
if (glGetProgrami(programId, GL_LINK_STATUS) == 0) {
throw new Exception("Error linking Shader code: " + glGetShaderInfoLog(programId, 1024));
}
glValidateProgram(programId);
if (glGetProgrami(programId, GL_VALIDATE_STATUS) == 0) {
System.err.println("Warning validating Shader code: " + glGetShaderInfoLog(programId, 1024));
}
}
public void bind() {
glUseProgram(programId);
}
public void unbind() {
glUseProgram(0);
}
public void cleanup() {
unbind();
if (programId != 0) {
if (vertexShaderId != 0) {
glDetachShader(programId, vertexShaderId);
}
if (fragmentShaderId != 0) {
glDetachShader(programId, fragmentShaderId);
}
glDeleteProgram(programId);
}
}
}
这是我的游戏课:
public class Game {
int vertexArrayID;
int vertexBufferID;
ShaderProgram fragmentShader;
ShaderProgram vertexShader;
float[] vertexData =
{
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
FloatBuffer vertexBuffer;
public Game() throws Exception {
vertexArrayID = glGenVertexArrays();
glBindVertexArray(vertexArrayID);
vertexBufferID = glGenBuffers();
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
vertexBuffer = BufferUtils.createFloatBuffer(vertexData.length);
vertexBuffer.put(vertexData);
vertexBuffer.flip();
glBufferData(GL_ARRAY_BUFFER, vertexBuffer,GL_STATIC_DRAW);
fragmentShader = new ShaderProgram();
vertexShader = new ShaderProgram();
fragmentShader.createFragmentShader(loadShader("fragmentShader.glsl"));
vertexShader.createVertexShader(loadShader("vertexShader.glsl"));
fragmentShader.link();
vertexShader.link();
}
public void update()
{
fragmentShader.bind();
vertexShader.bind();
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,vertexBufferID);
glVertexAttribPointer(0,3,GL_FLOAT,false,0,0);
glDrawArrays(GL_TRIANGLES,0,3);
glDisableVertexAttribArray(0);
fragmentShader.unbind();
vertexShader.unbind();
}
private String loadShader(String input) {
String r = "";
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(Game.class.getResourceAsStream("/shaders/" + input)));
String buffer = "";
while ((buffer = reader.readLine()) != null) {
r += buffer + "\n";
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
return r;
}
}
为什么我的三角形在那之后保持黑色?看起来你误解了OpenGL中程序和着色器的使用
着色器
对象对应于OpenGL中的“着色器阶段”,即顶点着色器或片段着色器或OpenGL图形管道中的其他可编程阶段之一
Program
对象对应于组合的着色器阶段链,有时通俗地称为完整的“着色器”
但是,在您的程序中,您似乎正在创建两个程序,将顶点着色器附加到一个程序,将片段着色器附加到另一个程序,并同时使用这两个程序。据我所知,这不会导致OpenGL抛出错误(它只会对缺少的任何一个阶段使用基本的穿透着色器),但这也意味着在任何时候只有其中一个阶段处于活动状态,而另一个阶段处于非活动状态。在您的情况下,update
函数中的代码:
fragmentShader.bind();
vertexShader.bind();
意味着只使用顶点着色器,这就是为什么对片段着色器进行更改没有效果
若要解决此问题,请仅创建一个
ShaderProgram
对象,并分别调用create[X]shader
将顶点和片段着色器源代码附加到该对象。将其链接一次,然后在更新
功能中,仅调用使用
。完成此操作后,程序应能按预期工作。看起来您误解了OpenGL中程序和着色器的使用
着色器
对象对应于OpenGL中的“着色器阶段”,即顶点着色器或片段着色器或OpenGL图形管道中的其他可编程阶段之一
Program
对象对应于组合的着色器阶段链,有时通俗地称为完整的“着色器”
但是,在您的程序中,您似乎正在创建两个程序,将顶点着色器附加到一个程序,将片段着色器附加到另一个程序,并同时使用这两个程序。据我所知,这不会导致OpenGL抛出错误(它只会对缺少的任何一个阶段使用基本的穿透着色器),但这也意味着在任何时候只有其中一个阶段处于活动状态,而另一个阶段处于非活动状态。在您的情况下,update
函数中的代码:
fragmentShader.bind();
vertexShader.bind();
意味着只使用顶点着色器,这就是为什么对片段着色器进行更改没有效果
若要解决此问题,请仅创建一个ShaderProgram
对象,并分别调用create[X]shader
将顶点和片段着色器源代码附加到该对象。将其链接一次,然后在更新
功能中,仅调用使用
。完成此操作后,程序应按预期工作。请提供适当的解决方案。这几乎不足以正确诊断问题。特别是,了解着色器/程序是如何初始化和使用的将非常有价值。由于您声称正在学习OpenGL,您应该能够毫无问题地包含整个“主机”(即C++)代码。请提供适当的说明。这几乎不足以正确诊断问题。特别是,了解着色器/程序是如何初始化和使用的将非常有价值。既然您声称正在学习OpenGL,那么您应该能够毫无问题地包含整个“主机”(即C++)代码。