Lwjgl代码仅显示背景

时间:2014-02-10 18:55:37

标签: java opengl glsl lwjgl

IM使用Java和Lwjgl作为Opengl接口。

我参与了基于C ++的this Tutorial,第一部分工作。第二部分,纹理,我无法实现。我现在在网上搜索了2天,但没有什么比这更好的了。

运行此程序会创建一个窗口,我可以看到浅蓝色背景,仅此而已。

我在游戏圈中获得此行的无效值错误:

GL20.glUniform1i(GL20.glGetUniformLocation(shaderProgramID, "tex"), GL13.GL_TEXTURE0);

继承我的完整代码:

package de.skysoldier.lwjgltest;

import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.ComponentColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.util.glu.GLU;

public class Main {

    private int shaderProgramID;
    private int vertexArrayObjectID;
    private int vertexBufferObjectID;
    private int textureID;
    private float vertices[];

    public Main(){
        initDisplay();
        initTexture();
        initShaders();
        initGl();
        startGameLoop();
    }

    private void initDisplay(){
        try{
            Display.setDisplayMode(new DisplayMode(800, 600));
            Display.create();
        }
        catch(Exception e){
            e.printStackTrace();
        }
    }

    private void initTexture(){
        ColorModel RGBA8_COLOR_MODEL = new ComponentColorModel(
                ColorSpace.getInstance(ColorSpace.CS_sRGB),
                new int[] { 8, 8, 8, 8 }, true, false,
                ComponentColorModel.TRANSLUCENT, DataBuffer.TYPE_BYTE);

        BufferedImage source = null;
        try{
            source = ImageIO.read(getClass().getClassLoader().getResourceAsStream("pic.png"));
        }
        catch(Exception e){

        }

        IntBuffer textureBuffer = ByteBuffer.allocateDirect(4).asIntBuffer();
        GL11.glGenTextures(textureBuffer);

        WritableRaster raster;
        BufferedImage textureImage;

        int textureWidth = 2;
        int textureHeight = 2;

        while (textureWidth < source.getWidth())
                textureWidth *= 2;
        while (textureHeight < source.getHeight())
                textureHeight *= 2;

        textureID = textureBuffer.get();

        raster = Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, textureWidth, textureHeight, 4, null);
        textureImage = new BufferedImage(RGBA8_COLOR_MODEL, raster, false, new Hashtable<String, Object>());

        textureImage.getGraphics().drawImage(source, 0, 0, null);

        byte[] data = (byte[]) textureImage.getRaster().getDataElements(0, 0,
                        textureImage.getWidth(), textureImage.getHeight(), null);

        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(textureImage
                        .getColorModel().getPixelSize()
                        / 8
                        * textureImage.getWidth()
                        * textureImage.getHeight());
        byteBuffer.put(data);
        byteBuffer.rewind();

        GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_NEAREST);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL11.GL_REPEAT);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL11.GL_REPEAT);
        GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, textureWidth,
                        textureHeight, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE,
                        byteBuffer);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
    }

    private void initShaders(){
        String vertexShaderCode = readFile("test.vert");
        String fragmentShaderCode = readFile("test.frag");

        int vertexShaderID = GL20.glCreateShader(GL20.GL_VERTEX_SHADER);
        GL20.glShaderSource(vertexShaderID, vertexShaderCode);
        GL20.glCompileShader(vertexShaderID);

        int fragmentShaderID = GL20.glCreateShader(GL20.GL_FRAGMENT_SHADER);
        GL20.glShaderSource(fragmentShaderID, fragmentShaderCode);
        GL20.glCompileShader(fragmentShaderID);

        shaderProgramID = GL20.glCreateProgram();
        GL20.glAttachShader(shaderProgramID, vertexShaderID);
        GL20.glAttachShader(shaderProgramID, fragmentShaderID);
        GL20.glLinkProgram(shaderProgramID);

        int compileStatus = GL20.glGetShaderi(vertexShaderID, GL20.GL_COMPILE_STATUS);
        if (compileStatus == GL11.GL_FALSE) {
            int infoLogLength = GL20.glGetShaderi(vertexShaderID, GL20.GL_INFO_LOG_LENGTH);
            String infoLog = GL20.glGetShaderInfoLog(vertexShaderID, infoLogLength);
            throw new RuntimeException(infoLog);
        }
    }

    private void initGl(){
        vertices = new float[]{
                 // X     Y     Z       U     V
                 0.0f, 0.8f, 0.0f,   0.5f, 1.0f,
                -0.8f,-0.8f, 0.0f,   0.0f, 0.0f,
                 0.8f,-0.8f, 0.0f,   1.0f, 0.0f,
        };
        FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
        verticesBuffer.put(vertices);
        verticesBuffer.flip(); 

        vertexArrayObjectID = GL30.glGenVertexArrays();
        GL30.glBindVertexArray(vertexArrayObjectID);

        vertexBufferObjectID = GL15.glGenBuffers();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferObjectID);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, verticesBuffer, GL15.GL_STATIC_DRAW);
        GL20.glVertexAttribPointer(GL20.glGetAttribLocation(shaderProgramID, "vert"), 3, GL11.GL_FLOAT, false, Float.SIZE / 8, 0);

        GL20.glEnableVertexAttribArray(GL20.glGetAttribLocation(shaderProgramID, "vertTexCoord"));
        GL20.glVertexAttribPointer(GL20.glGetAttribLocation(shaderProgramID, "vertTexCoord"), 2, GL11.GL_FLOAT, true, Float.SIZE / 8, Float.SIZE / 8);

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        GL30.glBindVertexArray(0);
    }

    private void startGameLoop(){

        while(!Display.isCloseRequested()){
            GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
            GL11.glClearColor(0.4f, 0.6f, 0.9f, 1);
            GL20.glEnableVertexAttribArray(0);
            GL30.glBindVertexArray(vertexArrayObjectID);

            GL20.glUseProgram(shaderProgramID);

            GL13.glActiveTexture(GL13.GL_TEXTURE0);
            GL11.glBindTexture(GL11.GL_TEXTURE_2D, textureID);
            GL20.glUniform1i(GL20.glGetUniformLocation(shaderProgramID, "tex"), GL13.GL_TEXTURE0);

            GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, vertices.length);

            GL20.glDisableVertexAttribArray(0);
            GL30.glBindVertexArray(0);

            Display.sync(60);
            Display.update();
        }
        destroy();
    }

    private void destroy(){
        GL20.glDisableVertexAttribArray(0);

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        GL15.glDeleteBuffers(vertexBufferObjectID);

        GL30.glBindVertexArray(0);
        GL30.glDeleteVertexArrays(vertexArrayObjectID);

        Display.destroy();
    }

    public String readFile(String fileName){
        try{
            BufferedReader reader = new BufferedReader(new InputStreamReader(getClass().getClassLoader().getResourceAsStream(fileName)));
            String content = "";
            String line;
            while((line = reader.readLine()) != null){
                content += line + "\n";
            }
            return content;
        }
        catch(Exception e){
            e.printStackTrace();
            return null;
        }
    }

    public static void main(String[] args) {
        new Main();
    }
}

以下是着色器:

片段

#version 150

uniform sampler2D tex;
in vec2 fragTexCoord;
out vec4 finalColor;

void main(void){
    finalColor = texture(tex, fragTexCoord);
}

顶点

#version 120

attribute vec3 vert;
attribute vec2 vertTexCoord;
varying vec2 fragTexCoord;

void main() {
    fragTexCoord = vertTexCoord;
    gl_Position = vec4(vert, 1);
}

有人知道这个错误在哪里?

1 个答案:

答案 0 :(得分:1)

GL20.glUniform1i(GL20.glGetUniformLocation(shaderProgramID, "tex"), GL13.GL_TEXTURE0);

纹理单位索引是制服,而不是GL枚举值。

尝试使用0代替GL13.GL_TEXTURE0