title: How do I render a scene to a cubemaptexture and then use the cubemaptexture in another shader as cubesampler?
body: <p>I am writing a 3D engine that uses Phong shaders and point lights in C# using the OpenTK library (OpenGL). I am now trying to create a shadowmap (cubemap) of the scene for each light I have, but I don't know how to see if the rendering of the cubemap worked and I don't know how to then pass the cubemap as uniform CubeSampler to the shader.</p>
  
  <p>I have tried to (for each light) create a new cubemap texture with GenTexture, then bind the texture and use TexImage2D on each face of the cubemap. Then create a framebuffer with the cube texture and a depthbuffer. Then render the scene using said framebuffer to color Attachment0.</p>
  
  <p>For using it in the shader, I just get the uniform location and bind the id of the cubemap texture.</p>
  
  <p>Where I create the cubemap</p>
  
  <pre><code> public Light Init(Scene scene)
          {
              texId = GL.GenTexture();
              GL.BindTexture(TextureTarget.TextureCubeMap, texId);
              for (int i = 0; i &lt; 6; i++)
              {
                  GL.TexImage2D(TextureTarget.TextureCubeMapPositiveX + i, 0, PixelInternalFormat.Rgba8, 512, 512, 0, PixelFormat.Rgba, PixelType.UnsignedByte, (IntPtr)null);
              }
              GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMagFilter, (float)TextureMagFilter.Linear);
              GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureMinFilter, (float)TextureMinFilter.Linear);
              GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapS, (float)TextureWrapMode.ClampToEdge);
              GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapT, (float)TextureWrapMode.ClampToEdge);
              GL.TexParameter(TextureTarget.TextureCubeMap, TextureParameterName.TextureWrapR, (float)TextureWrapMode.ClampToEdge);
              GL.BindTexture(TextureTarget.TextureCubeMap, 0);
  
              fbo = GL.GenFramebuffer();
              GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbo);
              GL.DrawBuffer(DrawBufferMode.ColorAttachment0);
  
  
              fbo_depth = GL.GenRenderbuffer();
              GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, fbo_depth);
              GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.DepthComponent24, 512, 512);
              GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, RenderbufferTarget.Renderbuffer, fbo_depth);
              GL.Viewport(0, 0, 512, 512);
  
              for (int i = 0; i &lt; 6; i++)
              {
                  GL.FramebufferTexture2D(FramebufferTarget.Framebuffer,
                      FramebufferAttachment.ColorAttachment0,
                      TextureTarget.TextureCubeMapPositiveX + i, texId, 0);
                  cam.SwitchFace(i);
                  scene.RenderLowRes(cam);
              }
  
              GL.BindFramebuffer(FramebufferTarget.Framebuffer, 0);
              GL.Viewport(0, 0, 1024, 1024);
  
  
              return this;
  
          }
  </code></pre>
  
  <p>Rendering the cubemap</p>
  
  <pre><code> public void RenderLowRes(CubeCamera cam)
          {
              GL.ClearColor(1, 1, 1, 1);
              GL.Clear(ClearBufferMask.ColorBufferBit);
              GL.Clear(ClearBufferMask.DepthBufferBit);
              sceneTree.RenderShade(shady, cam.view, cam.projection);
  
          }
  </code></pre>
  
  <p>Render each mesh (where I want to pass the cubemap) </p>
  
  <pre><code>// render the mesh using the supplied shader and matrix
          public void Render( Shader shader, Matrix4 transform, Texture texture)
          {
              // on first run, prepare buffers
              Prepare( shader );
  
              // safety dance
              GL.PushClientAttrib( ClientAttribMask.ClientVertexArrayBit );
  
              // enable texture
              int texLoc = GL.GetUniformLocation( shader.programID, "pixels" );
              GL.Uniform1( texLoc, 0 );
              GL.ActiveTexture( TextureUnit.Texture0 );
              GL.BindTexture( TextureTarget.Texture2D, texture.id );
  
              // enable shader
              GL.UseProgram( shader.programID );
  
              // pass the cubesamplers.For now only pass one of them to test
              int map3Loc = GL.GetUniformLocation(shader.programID, "lamp3Map");
              GL.Uniform1(map3Loc,  0);
              GL.ActiveTexture(TextureUnit.Texture1);
              GL.BindTexture(TextureTarget.TextureCubeMap, Scene.lights[3].texId);
  
              // pass lamps to vertex shader
              Matrix2x3 lamp1data = new Matrix2x3(Scene.lights[0].node.myTrans.Row3.Xyz, Scene.lights[0].color);
              GL.UniformMatrix2x3(shader.uniform_lamp1, false, ref lamp1data);
              Matrix2x3 lamp2data = new Matrix2x3(Scene.lights[1].node.myTrans.Row3.Xyz, Scene.lights[1].color);
              GL.UniformMatrix2x3(shader.uniform_lamp2, false, ref lamp2data);
              Matrix2x3 lamp3data = new Matrix2x3(Scene.lights[2].node.myTrans.Row3.Xyz, Scene.lights[2].color);
              GL.UniformMatrix2x3(shader.uniform_lamp3, false, ref lamp3data);
              Matrix2x3 lamp4data = new Matrix2x3(Scene.lights[3].node.myTrans.Row3.Xyz, Scene.lights[3].color);
              GL.UniformMatrix2x3(shader.uniform_lamp4, false, ref lamp4data);
  
  
  
             // Console.WriteLine(lamp1data.Row0.ToString());
  
              //Matrix2x3 lamp1 = new Matrix2x3(lamp, new Vector3(1, 1, 1));  //pos, color
  
              // pass transform to vertex shader
              GL.UniformMatrix4( shader.uniform_mview, false, ref transform );
  
              // enable position, normal and uv attributes
              GL.EnableVertexAttribArray( shader.attribute_vpos );
              GL.EnableVertexAttribArray( shader.attribute_vnrm );
              GL.EnableVertexAttribArray( shader.attribute_vuvs );
  
              // bind interleaved vertex data
              GL.EnableClientState( ArrayCap.VertexArray );
              GL.BindBuffer( BufferTarget.ArrayBuffer, vertexBufferId );
              GL.InterleavedArrays( InterleavedArrayFormat.T2fN3fV3f, Marshal.SizeOf( typeof( ObjVertex ) ), IntPtr.Zero );
  
              // link vertex attributes to shader parameters 
              GL.VertexAttribPointer( shader.attribute_vuvs, 2, VertexAttribPointerType.Float, false, 32, 0 );
              GL.VertexAttribPointer( shader.attribute_vnrm, 3, VertexAttribPointerType.Float, true, 32, 2 * 4 );
              GL.VertexAttribPointer( shader.attribute_vpos, 3, VertexAttribPointerType.Float, false, 32, 5 * 4 );
  
              // bind triangle index data and render
              GL.BindBuffer( BufferTarget.ElementArrayBuffer, triangleBufferId );
              GL.DrawArrays( PrimitiveType.Triangles, 0, triangles.Length * 3 );
  
              // bind quad index data and render
              if( quads.Length &gt; 0 )
              {
                  GL.BindBuffer( BufferTarget.ElementArrayBuffer, quadBufferId );
                  GL.DrawArrays( PrimitiveType.Quads, 0, quads.Length * 4 );
              }
  
              // restore previous OpenGL state
              GL.UseProgram( 0 );
              GL.PopClientAttrib();
          }
  </code></pre>
  
  <p>After doing all that, the CubeSamplers in the shader appear to be empty (all values 0).</p>
  
  <p>This is the first time I post something here. Sorry if I did anything wrong.</p>