1
\$\begingroup\$

Based on the giawa/nehe tutorials, how can I render 2 images with different shaders. I'm pretty new to OpenGl and shaders so I'm not completely sure whats happening in my code, but I think the shaders that is called last overwrites the first one.

private static void OnRenderFrame()
{
    // calculate how much time has elapsed since the last frame
    watch.Stop();
    float deltaTime = (float)watch.ElapsedTicks / System.Diagnostics.Stopwatch.Frequency;
    watch.Restart();

    // use the deltaTime to adjust the angle of the cube
    angle += deltaTime;

    // set up the OpenGL viewport and clear both the color and depth bits
    Gl.Viewport(0, 0, width, height);
    Gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    // use our shader program and bind the crate texture
    Gl.UseProgram(program);

    //<<<<<<<<<<<<   TOP PYRAMID
    // set the transformation of the top_pyramid
    program["model_matrix"].SetValue(Matrix4.CreateRotationY(angle * rotate_cube));
    program["enable_lighting"].SetValue(lighting);
    // bind the vertex positions, UV coordinates and element array
    Gl.BindBufferToShaderAttribute(top_pyramid, program, "vertexPosition");
    Gl.BindBufferToShaderAttribute(top_pyramidNormals, program, "vertexNormal");
    Gl.BindBufferToShaderAttribute(top_pyramidUV, program, "vertexUV");
    Gl.BindBuffer(top_pyramidTrianlges);
    // draw the textured top_pyramid
    Gl.DrawElements(BeginMode.Triangles, top_pyramidTrianlges.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);


    //<<<<<<<<<<    CUBE
    // set the transformation of the cube
    program["model_matrix"].SetValue(Matrix4.CreateRotationY(angle * rotate_cube));
    program["enable_lighting"].SetValue(lighting);
    // bind the vertex positions, UV coordinates and element array
    Gl.BindBufferToShaderAttribute(cube, program, "vertexPosition");
    Gl.BindBufferToShaderAttribute(cubeNormals, program, "vertexNormal");
    Gl.BindBufferToShaderAttribute(cubeUV, program, "vertexUV");
    Gl.BindBuffer(cubeQuads);
    // draw the textured cube
    Gl.DrawElements(BeginMode.Quads, cubeQuads.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);

    //<<<<<<<<<<<<   BOTTOM PYRAMID
    // set the transformation of the bottom_pyramid
    program["model_matrix"].SetValue(Matrix4.CreateRotationY(angle * rotate_cube));
    program["enable_lighting"].SetValue(lighting);
    // bind the vertex positions, UV coordinates and element array
    Gl.BindBufferToShaderAttribute(bottom_pyramid, program, "vertexPosition");
    Gl.BindBufferToShaderAttribute(bottom_pyramidNormals, program, "vertexNormal");
    Gl.BindBufferToShaderAttribute(bottom_pyramidUV, program, "vertexUV");
    Gl.BindBuffer(bottom_pyramidTrianlges);
    // draw the textured bottom_pyramid
    Gl.DrawElements(BeginMode.Triangles, bottom_pyramidTrianlges.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);


     //<<<<<<<<<<<<<     STAR
     Gl.Disable(EnableCap.DepthTest);
     Gl.Enable(EnableCap.Blend);
     Gl.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.One);

     Gl.BindTexture(starTexture);
     //calculate the camera position using some fancy polar co-ordinates
      Vector3 position = 20 * new Vector3(Math.Cos(phi) * Math.Sin(theta), Math.Cos(theta), Math.Sin(phi) * Math.Sin(theta));
      Vector3 upVector = ((theta % (Math.PI * 2)) > Math.PI) ? Vector3.Up : Vector3.Down;
      program_2["view_matrix"].SetValue(Matrix4.LookAt(position, Vector3.Zero, upVector));


     // make sure the shader program and texture are being used
     Gl.UseProgram(program_2);

     // loop through the stars, drawing each one
     for (int i = 0; i < stars.Count; i++)
     {
         // set the position and color of this star
         program_2["model_matrix"].SetValue(Matrix4.CreateTranslation(new Vector3(stars[i].dist, 0, 0)) * Matrix4.CreateRotationZ(stars[i].angle));
         program_2["color"].SetValue(stars[i].color);

         Gl.BindBufferToShaderAttribute(star, program_2, "vertexPosition");
         Gl.BindBufferToShaderAttribute(starUV, program_2, "vertexUV");
         Gl.BindBuffer(starQuads);

         Gl.DrawElements(BeginMode.Quads, starQuads.Count, DrawElementsType.UnsignedInt, IntPtr.Zero);

         // update the position of the star
         stars[i].angle += (float)i / stars.Count * deltaTime * 2 * rotate_stars;
         stars[i].dist -= 0.2f * deltaTime * rotate_stars;

         // if we've reached the center then move this star outwards and give it a new color
         if (stars[i].dist < 0f)
         {
             stars[i].dist += 5f;
             stars[i].color = new Vector3(generator.NextDouble(), generator.NextDouble(), generator.NextDouble());
         }
     }
    Glut.glutSwapBuffers();
}

The same goes for the textures, whichever one I mention last gets applied to both object?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

The word you are looking for is bind. When you bind a texture or shader, that will be the "active" texture or shader.

For shaders it looks like this:

Gl.UseProgram(program);

And for textures it looks like this:

Gl.BindTexture(texture);
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .