I’m trying to do an assignment for college and I don’t know why it shows me a black window below, I send the Program, fragment_shader and vertex_shader, when I change the background color to, for example, gray, my object is shown as black, as if light did not exist, these are my tasks that I have to do, obj rendered correctly:
Texturing
The letter “M” is textured to resemble it being sculpted from marble.
Marbling
Adjust the textures to make it appear as if the entire object was sculpted from a single block. Pay close attention to the edges of the shape.
Shading
Implement the Phong lighting model correctly where most calculations occur in the fragment shader. Adjust the alpha coefficient to blend well with the marble surface.
Lighting Color
While the material color should be derived from the texture, the lighting color should be a proper shade of blue.
Variable Lighting Color
Set up the light source so that its color cycles smoothly between three primary shades of blue (#141e50, #006cfa, #23bdff). The transition should be seamless over time.
using GLFW;
using GlmSharp;
using ObjLoader;
using OpenTK;
using OpenTK.Graphics.OpenGL4;
using Shaders;
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace PMLabs
{
public class BC : IBindingsContext
{
public IntPtr GetProcAddress(string procName)
{
return Glfw.GetProcAddress(procName);
}
}
class Program
{
static ShaderProgram shader;
static float speed_y;
static float speed_x;
static int tex;
static KeyCallback kc = KeyProcessor;
static int vertexArray;
static int vertexBuffer;
static int indexBuffer;
static int indexCount;
static vec3 lightColor = new vec3(0.0f, 0.0f, 1.0f);
static vec3 lightPos = new vec3(1.0f, 1.0f, 1.0f);
static vec3 viewPos = new vec3(0.0f, 0.0f, 5.0f);
static float shininess = 32.0f;
public static void KeyProcessor(IntPtr window, Keys key, int scanCode, InputState state, ModifierKeys mods)
{
if (state == InputState.Press)
{
if (key == Keys.Left) speed_y = -3.14f;
if (key == Keys.Right) speed_y = 3.14f;
if (key == Keys.Up) speed_x = -3.14f;
if (key == Keys.Down) speed_x = 3.14f;
}
if (state == InputState.Release)
{
if (key == Keys.Left || key == Keys.Right) speed_y = 0;
if (key == Keys.Up || key == Keys.Down) speed_x = 0;
}
}
public static void InitOpenGLProgram(Window window)
{
GL.ClearColor(Color.Black);
shader = new ShaderProgram("vertex_shader.glsl", "fragment_shader.glsl");
Glfw.SetKeyCallback(window, kc);
GL.Enable(EnableCap.DepthTest);
tex = ReadTexture("marble.jpg");
try
{
var objParser = new ObjParser("triangle.obj");
vertexArray = GL.GenVertexArray();
GL.BindVertexArray(vertexArray);
vertexBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ArrayBuffer, vertexBuffer);
GL.BufferData(BufferTarget.ArrayBuffer, objParser.Vertices.Count * Marshal.SizeOf(typeof(vec3)), objParser.Vertices.ToArray(), BufferUsageHint.StaticDraw);
var positionLocation = shader.A("aPosition");
GL.EnableVertexAttribArray(positionLocation);
GL.VertexAttribPointer(positionLocation, 3, VertexAttribPointerType.Float, false, Marshal.SizeOf(typeof(vec3)), 0);
// Dodaj obsługę normalnych wierzchołków
var normalLocation = shader.A("aNormal");
GL.EnableVertexAttribArray(normalLocation);
GL.VertexAttribPointer(normalLocation, 3, VertexAttribPointerType.Float, false, Marshal.SizeOf(typeof(vec3)), objParser.Vertices.Count * Marshal.SizeOf(typeof(vec3)));
indexBuffer = GL.GenBuffer();
GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBuffer);
GL.BufferData(BufferTarget.ElementArrayBuffer, objParser.Indices.Count * sizeof(int), objParser.Indices.ToArray(), BufferUsageHint.StaticDraw);
indexCount = objParser.Indices.Count;
var texCoordLocation = shader.A("aTexCoord");
GL.VertexAttribPointer(texCoordLocation, 2, VertexAttribPointerType.Float, false, Marshal.SizeOf(typeof(vec2)), 0);
GL.EnableVertexAttribArray(texCoordLocation);
GL.BindVertexArray(0);
}
catch (SystemException ex)
{
Console.WriteLine($"Error initializing OpenGL program: {ex.Message}");
}
}
public static void FreeOpenGLProgram(Window window)
{
GL.DeleteVertexArray(vertexArray);
GL.DeleteBuffer(vertexBuffer);
GL.DeleteBuffer(indexBuffer);
GL.DeleteTexture(tex);
}
public static int ReadTexture(string filename)
{
var tex = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, tex);
Bitmap bitmap = new Bitmap(filename);
bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);
System.Drawing.Imaging.BitmapData data = bitmap.LockBits(
new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
OpenTK.Graphics.OpenGL4.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
bitmap.UnlockBits(data);
bitmap.Dispose();
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
return tex;
}
public static void DrawScene(Window window, float angle_x, float angle_y)
{
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
mat4 P = mat4.Perspective(glm.Radians(60.0f), 1, 0.1f, 100.0f);
mat4 V = mat4.LookAt(new vec3(0, 0, -5), new vec3(0, 0, 0), new vec3(0, 1, 0));
shader.Use();
GL.UniformMatrix4(shader.U("P"), 1, false, P.Values1D);
GL.UniformMatrix4(shader.U("V"), 1, false, V.Values1D);
mat4 M = mat4.Identity;
M = mat4.Rotate(angle_y, new vec3(0, 1, 0)) * mat4.Rotate(angle_x, new vec3(1, 0, 0));
M *= mat4.Scale(0.5f);
GL.UniformMatrix4(shader.U("M"), 1, false, M.Values1D);
GL.Uniform3(shader.U("light.position"), lightPos.x, lightPos.y, lightPos.z);
GL.Uniform3(shader.U("viewPos"), viewPos.x, viewPos.y, viewPos.z);
GL.Uniform3(shader.U("light.color"), lightColor.x, lightColor.y, lightColor.z);
GL.Uniform1(shader.U("material.shininess"), shininess);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, tex);
GL.Uniform1(shader.U("tex"), 0);
GL.BindVertexArray(vertexArray);
GL.DrawElements(PrimitiveType.Triangles, indexCount, DrawElementsType.UnsignedInt, 0);
Glfw.SwapBuffers(window);
}
static void Main(string[] args)
{
Glfw.Init();
Window window = Glfw.CreateWindow(500, 500, "OpenGL", GLFW.Monitor.None, Window.None);
Glfw.MakeContextCurrent(window);
Glfw.SwapInterval(1);
GL.LoadBindings(new BC());
InitOpenGLProgram(window);
Glfw.Time = 0;
float angle_x = 0;
float angle_y = 0;
while (!Glfw.WindowShouldClose(window))
{
angle_x += speed_x * (float)Glfw.Time;
angle_y += speed_y * (float)Glfw.Time;
Glfw.Time = 0;
DrawScene(window, angle_x, angle_y);
Glfw.PollEvents();
}
FreeOpenGLProgram(window);
Glfw.Terminate();
}
}
}
#version 330 core
layout(location = 0) in vec3 aPosition;
layout(location = 1) in vec3 aNormal;
layout(location = 2) in vec2 aTexCoord;
out vec3 FragPos;
out vec3 Normal;
out vec2 TexCoord;
uniform mat4 P;
uniform mat4 V;
uniform mat4 M;
void main()
{
gl_Position = P * V * M * vec4(aPosition, 1.0);
FragPos = vec3(M * vec4(aPosition, 1.0));
Normal = mat3(transpose(inverse(M))) * aNormal;
TexCoord = aTexCoord;
}
#version 330 core
in vec3 FragPos;
in vec3 Normal;
in vec2 TexCoord;
out vec4 FragColor;
struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
struct Light {
vec3 position;
vec3 color;
};
uniform vec3 viewPos;
uniform Light light;
uniform Material material;
uniform sampler2D tex;
void main()
{
vec3 ambient = material.ambient * texture(tex, TexCoord).rgb;
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(light.position - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = material.diffuse * diff * light.color * texture(tex, TexCoord).rgb;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = material.specular * spec * light.color;
vec3 result = ambient + diffuse + specular;
FragColor = vec4(result, 1.0);
}
I’ve tried everything, I’ve debugged whether it sends it to the shaders correctly and I can’t come up with anything