LWJGL Forum

Programming => OpenGL => Topic started by: mymaksimus on February 10, 2014, 19:02:15

Title: Only the Background, nothing more
Post by: mymaksimus on February 10, 2014, 19:02:15
Hello.
Im new to Opengl and GLSL, so sorry for this maybe stupid question.
But i have no idea where to find my mistake.
So, the following thing: IM using Java and Lwjgl as Opengl Interface.
I worked on this Tutorial (http://tomdalling.com/blog/modern-opengl/), which is based on C++, and the first part worked. The second part, textures, im not able to implement. Im searching the web for 2 days now, but nothing wants work. Im getting a Invalid value error in the gameloop for this line:


    GL20.glUniform1i(GL20.glGetUniformLocation(shaderProgramID, "tex"), GL13.GL_TEXTURE0);
   
Heres my complete Code:

    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();
    }
    }


And here are the shaders:

fragment

   #version 150
   
    uniform sampler2D tex;
    in vec2 fragTexCoord;
    out vec4 finalColor;
   
    void main(void){
    finalColor = texture(tex, fragTexCoord);
    }


vertex

    #version 120
   
    attribute vec3 vert;
    attribute vec2 vertTexCoord;
    varying vec2 fragTexCoord;
   
    void main() {
        fragTexCoord = vertTexCoord;
        gl_Position = vec4(vert, 1);
    }


Someone has an idea where is the bug??
Thank you very much!!
Title: Re: Only the Background, nothing more
Post by: quew8 on February 12, 2014, 20:35:27
Well the only reason I can see that an Invalid Value error would be thrown is in glGetUniformLocation()

QuoteGL_INVALID_VALUE is generated if program is not a value generated by OpenGL.

Ie the value of "shaderPogramID" when you call this function is not any value returned by any of the glGenXXXX() functions. Most likely problem: you forget to initialize the value.

Also, I might be wrong but, I was under the impression that you have to pass in the index of the texture unit, not the enum referring to the texture unit. So:


GL20.glUniform1i(GL20.glGetUniformLocation(shaderProgramID, "tex"), 0);


But if it works, it works.