title: LWJGL - Vertex / Fragment Shader not working
body: <p>I have managed to open a window and render a triangle on the screen in LWJGL. I have now created two external files for the vertex shader &amp; fragment shader. However the triangle remains white.</p>
  <p>This is the main file, where it calls the method to load the vertex shader and compile it, I have added a simple system.out line to see if this is being called, which it is.</p>
  <pre class="lang-java prettyprint-override"><code>import org.lwjgl.*;
  import org.lwjgl.glfw.*;
  import org.lwjgl.opengl.*;
  import org.lwjgl.system.*;
  
  import java.io.BufferedReader;
  import java.io.FileReader;
  import java.io.IOException;
  import java.nio.*;
  
  import static org.lwjgl.glfw.Callbacks.*;
  import static org.lwjgl.glfw.GLFW.*;
  import static org.lwjgl.opengl.GL11.*;
  import static org.lwjgl.system.MemoryStack.*;
  import static org.lwjgl.system.MemoryUtil.*;
  
  public class Main {
      
       String TITLE = &quot;f&quot;;
      
      
  
      // The window handle
      private long window;
  
      public void run() {
          System.out.println(&quot;Hello LWJGL &quot; + Version.getVersion() + &quot;!&quot;);
  
          init();
          loop();
  
          // Free the window callbacks and destroy the window
          glfwFreeCallbacks(window);
          glfwDestroyWindow(window);
  
          // Terminate GLFW and free the error callback
          glfwTerminate();
          glfwSetErrorCallback(null).free();
      }
  
      private void init() {
          // Setup an error callback. The default implementation
          // will print the error message in System.err.
          GLFWErrorCallback.createPrint(System.err).set();
  
          // Initialize GLFW. Most GLFW functions will not work before doing this.
          if ( !glfwInit() )
              throw new IllegalStateException(&quot;Unable to initialize GLFW&quot;);
  
          // Configure GLFW
          glfwDefaultWindowHints(); // optional, the current window hints are already the default
          glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE); // the window will stay hidden after creation
          glfwWindowHint(GLFW_RESIZABLE, GLFW_TRUE); // the window will be resizable
  
          // Create the window
          window = glfwCreateWindow(300, 300, TITLE, NULL, NULL);
          if ( window == NULL )
              throw new RuntimeException(&quot;Failed to create the GLFW window&quot;);
  
          // Setup a key callback. It will be called every time a key is pressed, repeated or released.
          glfwSetKeyCallback(window, (window, key, scancode, action, mods) -&gt; {
              if ( key == GLFW_KEY_ESCAPE &amp;&amp; action == GLFW_RELEASE )
                  glfwSetWindowShouldClose(window, true); // We will detect this in the rendering loop
          });
  
          // Get the thread stack and push a new frame
          try ( MemoryStack stack = stackPush() ) {
              IntBuffer pWidth = stack.mallocInt(1); // int*
              IntBuffer pHeight = stack.mallocInt(1); // int*
  
              // Get the window size passed to glfwCreateWindow
              glfwGetWindowSize(window, pWidth, pHeight);
  
              // Get the resolution of the primary monitor
              GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
  
              // Center the window
              glfwSetWindowPos(
                  window,
                  (vidmode.width() - pWidth.get(0)) / 2,
                  (vidmode.height() - pHeight.get(0)) / 2
              );
          } // the stack frame is popped automatically
  
          // Make the OpenGL context current
          glfwMakeContextCurrent(window);
      
          
          // Enable v-sync
          glfwSwapInterval(1);
      
          // Make the window visible
          glfwShowWindow(window);
          
      }
  
      private void loop() {
          // This line is critical for LWJGL's interoperation with GLFW's
          // OpenGL context, or any context that is managed externally.
          // LWJGL detects the context that is current in the current thread,
          // creates the GLCapabilities instance and makes the OpenGL
          // bindings available for use.
          GL.createCapabilities();
          
          drawTriangle();
          loadShader(&quot;screenvertfilelocation&quot;, GL30.GL_VERTEX_SHADER);
          loadShader(&quot;screenvertfilelocation&quot;, GL30.GL_FRAGMENT_SHADER);
          
          
          
          // Set the clear color
          glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
  
          // Run the rendering loop until the user has attempted to close
          // the window or has pressed the ESCAPE key.
          while ( !glfwWindowShouldClose(window) ) {
              glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // clear the framebuffer
              
              processTriangle();
  
              glfwSwapBuffers(window); // swap the color buffers
  
              // Poll for window events. The key callback above will only be
              // invoked during this call.
              glfwPollEvents();
          }
      }
  
      public static void main(String[] args) {
          new Main().run();
      }
      
      int vertexCount = 0;
      int VAO = 0;
      int VBO = 0;
  
      public void drawTriangle() {
      
      float vertices[] = {
              -0.5f, -0.5f, 0.0f,
               0.5f, -0.5f, 0.0f,
               0.0f,  0.5f, 0.0f
          };  
  
  
      int VBO = GL30.glGenBuffers();
      int VAO = GL30.glGenBuffers();
   
      
      // Sending data to OpenGL requires the usage of (flipped) byte buffers
      FloatBuffer verticesBuffer = BufferUtils.createFloatBuffer(vertices.length);
      verticesBuffer.put(vertices);
      verticesBuffer.flip();
       
      vertexCount = 3;
      
      
      GL30.glBindVertexArray(VAO);
  
      GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, VBO);
  
      GL30.glBufferData(GL30.GL_ARRAY_BUFFER, verticesBuffer, GL30.GL_STATIC_DRAW);
      
  
      GL30.glVertexAttribPointer(0, 3, GL30.GL_FLOAT, false, 0, 0);
      
      GL30.glEnableVertexAttribArray(0);
      
      GL30.glBindBuffer(GL30.GL_ARRAY_BUFFER, 0); 
      GL30.glBindVertexArray(0); 
      
      }
      
      public void processTriangle() {
          GL30.glBindVertexArray(VAO);
          GL30.glDrawArrays(GL_TRIANGLES, 0, 3);
      }
      
      
      //Deals with the Shaders
      private static int loadShader(String file, int type){
            StringBuilder shaderSource = new StringBuilder();
            try{
             BufferedReader reader = new BufferedReader(new FileReader(file));
             String line;
             while((line = reader.readLine())!=null){
              shaderSource.append(line).append(&quot;//\n&quot;);
             }
             reader.close();
            }catch(IOException e){
             e.printStackTrace();
             System.exit(-1);
            }
            int shaderID = GL20.glCreateShader(type);
            GL20.glShaderSource(shaderID, shaderSource);
            GL20.glCompileShader(shaderID);
            
            int vertexShader;
            vertexShader = GL30.glCreateShader(GL30.GL_VERTEX_SHADER);
            int fragmentShader;
            fragmentShader = GL30.glCreateShader(GL30.GL_FRAGMENT_SHADER);
            
            
            
            
            int shaderProgram;
            shaderProgram = GL30.glCreateProgram();
            
            
            GL30.glAttachShader(shaderProgram, vertexShader);
            GL30. glAttachShader(shaderProgram, fragmentShader);
            GL30.glLinkProgram(shaderProgram);
           
           
            GL30.glUseProgram(shaderProgram);
            
           GL30.glDeleteShader(vertexShader);
           GL30.glDeleteShader(fragmentShader); 
            
            System.out.println(&quot;Hello&quot;);
            
            if(GL20.glGetShaderi(shaderID, GL20.GL_COMPILE_STATUS )== GL11.GL_FALSE){
             System.out.println(GL20.glGetShaderInfoLog(shaderID, 500));
             System.err.println(&quot;Could not compile shader!&quot;);
             System.exit(-1);
            }
            return shaderID;
           }
  
  }
  </code></pre>
  <p>Here is the vertex shader file:</p>
  <pre><code>    #version 330 core
  layout (location = 0) in vec3 aPos; 
    
  out vec4 vertexColor; 
  
  void main()
  {
      gl_Position = vec4(aPos, 1.0); 
      vertexColor = vec4(0.5, 4.0, 0.0, 1.0); 
  }
  </code></pre>
  <p>and here is the fragment shader file:</p>
  <pre><code>    #version 330 core
  out vec4 FragColor;
    
  in vec4 vertexColor; 
  
  void main()
  {
      FragColor = vertexColor;
  } 
  </code></pre>