所以我尝试了一些关于 OpenGL 和 GLSL 的教程。我使用 JOGL2 用 Java 编写它们,但Original是用 C++ 编写的。所有代码编译没有任何问题,着色器设计器中的着色器预览甚至显示正确的效果,但是当我运行我的应用程序时,它只绘制空白的白色三角形。我根本找不到我在哪里犯错-.-顺便说一句,我的显卡是 Geforce GT330M,支持 OpenGL 3.3、GLSL 3.30。安装了最新的驱动程序,所以我猜这应该不是问题。
我用于加载和创建着色器的代码:
package OpenGL33.Utils;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import javax.media.opengl.GL3;
public class ShaderUtils {
public int createProgram(GL3 gl, String vertexSource, String fragmentSource) throws IOException{
int v = gl.glCreateShader(GL3.GL_VERTEX_SHADER);
int f = gl.glCreateShader(GL3.GL_FRAGMENT_SHADER);
String[] strings;
/*
* vertex shader
*/
strings = loadResource(vertexSource);
gl.glShaderSource(v, strings.length, strings, (int[]) null, 0);
gl.glCompileShader(v);
/*
* fragment shader
*/
strings = loadResource(fragmentSource);
gl.glShaderSource(f, strings.length, strings, (int[]) null, 0);
gl.glCompileShader(f);
/*
* Create shader program and attach shaders
*/
int program = gl.glCreateProgram();
gl.glAttachShader(program, v);
gl.glAttachShader(program, f);
gl.glLinkProgram(program);
gl.glValidateProgram(program);
return program;
}
private String[] loadResource(String resource) throws IOException{
BufferedReader reader;
ArrayList<String> input = new ArrayList<String>();
String line;
reader = new BufferedReader(new InputStreamReader(getClass().getResource(resource).openStream()));
while ((line = reader.readLine()) != null) {
input.add(line);
}
String[] strings = new String[input.size()];
input.toArray(strings);
return strings;
}
}
顶点着色器:
#version 330
layout(location = 0) in vec4 position;
void main()
{
gl_Position = position;
}
片段着色器:
#version 330
out vec4 outputColor;
void main()
{
float lerpValue = gl_FragCoord.y / 500.0f;
outputColor = mix(vec4(1.0f, 1.0f, 1.0f, 1.0f),
vec4(0.0f, 0.0f, 0.0f, 1.0f), lerpValue);
}
和 OpenGLListener 类:
package OpenGL33;
import OpenGL33.Utils.ShaderUtils;
import com.jogamp.common.nio.Buffers;
import com.jogamp.opengl.util.gl2.GLUT;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.media.opengl.GL3;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;
class OpenGlListener implements GLEventListener{
private GLU glu = new GLU();
private GLUT glut = new GLUT();
// vertex buffer
private FloatBuffer vertices;
private int[] verticesBuffer = new int[1];
private int shaderProgram;
private ShaderUtils sUtils;
// triangle coords
public static final float[] vertexPositions = {
0.0f, 0.5f, 0.0f, 1.0f,
0.5f, -0.366f, 0.0f, 1.0f,
-0.5f, -0.366f, 0.0f, 1.0f};
public OpenGlListener(){
sUtils = new ShaderUtils();
}
public void initializeVertexBuffer(GLAutoDrawable drawable){
GL3 gl = drawable.getGL().getGL3bc();
vertices = Buffers.newDirectFloatBuffer(vertexPositions.length);
vertices.put(vertexPositions);
vertices.position(0);
gl.glGenBuffers(1, verticesBuffer, 0);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, verticesBuffer[0]);
gl.glBufferData(GL3.GL_ARRAY_BUFFER, vertexPositions.length * 4 * Buffers.SIZEOF_FLOAT, vertices, GL3.GL_STATIC_DRAW);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, 0);
}
@Override
public void init(GLAutoDrawable drawable) {
GL3 gl = drawable.getGL().getGL3();
// check VBO support
if(!gl.isExtensionAvailable("GL_ARB_vertex_buffer_object")){
System.err.println("Error - missing VBO support");
}
// load shaders
try{
//tutorial 1
shaderProgram = sUtils.createProgram(gl, "/resources/shaders/FragPosition.vert", "/resources/shaders/FragPosition.frag");
//tutorial 2
//shaderProgram = sUtils.createProgram(gl, "/resources/shaders/MultiInput.vert", "/resources/shaders/MultiInput.frag");
}
catch (IOException ex) {
Logger.getLogger(OpenGlListener.class.getName()).log(Level.SEVERE, null, ex);
}
initializeVertexBuffer(drawable);
}
@Override
public void dispose(GLAutoDrawable drawable) {
//To change body of generated methods, choose Tools | Templates.
}
@Override
public void display(GLAutoDrawable drawable) {
GL3 gl = drawable.getGL().getGL3();
gl.glClear(GL3.GL_COLOR_BUFFER_BIT);
gl.glUseProgram(shaderProgram);
gl.glBindBuffer(GL3.GL_ARRAY_BUFFER, verticesBuffer[0]);
gl.glEnableVertexAttribArray(0);
gl.glVertexAttribPointer(0, 4, GL3.GL_FLOAT, false, 0, 0);
gl.glDrawArrays(GL3.GL_TRIANGLES, 0, 3);
gl.glDisableVertexAttribArray(0);
gl.glUseProgram(0);
drawable.swapBuffers();
}
@Override
public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
GL3 gl = drawable.getGL().getGL3bc();
gl.glViewport(0, 0, width, height);
}
}
应用程序在摆动窗口中运行,在 GLJPanel 中绘图。