PDA

View Full Version : SharpGl Computer crash when pass data from vertex Shader to Fragment Shader



tn88test
05-01-2017, 01:41 AM
I did manage to draw a red triangle, but when I tried to pass data from vertex Shader to Fragment Shader. My computer screen is all black, and after a few second a windows popup a message "Display driver stopped responding and has recovered". The program didn't generate any error.


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpGL;
using SharpGL.Shaders;

namespace Vector
{
/// <summary>
/// The main form class.
/// </summary>
public partial class SharpGLForm : Form
{
/// <summary>
/// Initializes a new instance of the <see cref="SharpGLForm"/> class.
/// </summary>
public SharpGLForm()
{
InitializeComponent();
}

/// <summary>
/// Handles the OpenGLDraw event of the openGLControl control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="RenderEventArgs"/> instance containing the event data.</param>
private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e)
{

}



/// <summary>
/// Handles the OpenGLInitialized event of the openGLControl control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
{
// TODO: Initialise OpenGL here.

// Get the OpenGL object.
OpenGL gl = openGLControl.OpenGL;

// Set the clear color.
gl.ClearColor(0, 0, 0, 0);
}

/// <summary>
/// Handles the Resized event of the openGLControl control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void openGLControl_Resized(object sender, EventArgs e)
{
OpenGL gl = openGLControl.OpenGL;
Shader sd = new Shader(gl);

gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);

// Vertex Shader
string vertexShaderSource = System.IO.File.ReadAllText("shader.vert");
string fragmentShaderSource = System.IO.File.ReadAllText("shader.frag");


uint shaderProgram = sd.Loader(vertexShaderSource, fragmentShaderSource);
gl.UseProgram(shaderProgram);

float[] vertices = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};

uint[] VBO = new uint[1];
gl.GenBuffers(1, VBO);

gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, VBO[0]);
gl.BufferData(OpenGL.GL_ARRAY_BUFFER, vertices, OpenGL.GL_STATIC_DRAW);
gl.VertexAttribPointer(0, 3, OpenGL.GL_FLOAT, false, 12, IntPtr.Zero);
gl.EnableVertexAttribArray(0);

gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, 3);
}
}

class Shader
{
private uint vertexShader;
private uint fragmentShader;
private uint shaderProgram { get; set; }
private OpenGL gl;

public Shader(OpenGL gl)
{
this.gl = gl;
}

public uint Loader(string vertexShaderSource, string fragmentShaderSource)
{
// Vertex Shader
vertexShader = gl.CreateShader(OpenGL.GL_VERTEX_SHADER);
gl.ShaderSource(vertexShader, vertexShaderSource);
gl.CompileShader(vertexShader);

if (GetCompileStatus(gl, vertexShader) == false)
{
throw new ShaderCompilationException(string.Format("Failed to compile shader with ID {0}.", vertexShader), GetCompileInfoLog(vertexShader));
}

// Fragment Shader
fragmentShader = gl.CreateShader(OpenGL.GL_FRAGMENT_SHADER);
gl.ShaderSource(fragmentShader, fragmentShaderSource);
gl.CompileShader(fragmentShader);

if (GetCompileStatus(gl, fragmentShader) == false)
{
throw new ShaderCompilationException(string.Format("Failed to compile shader with ID {0}.", fragmentShader), GetCompileInfoLog(fragmentShader));
}

// Link shaders
shaderProgram = gl.CreateProgram();
gl.AttachShader(shaderProgram, vertexShader);
gl.AttachShader(shaderProgram, fragmentShader);
gl.LinkProgram(shaderProgram);

if (GetLinkStatus(gl) == false)
{
throw new ShaderCompilationException(string.Format("Failed to link shader program with ID {0}.", shaderProgram), GetLinkInfoLog(gl));
}

gl.DeleteShader(vertexShader);
gl.DeleteShader(fragmentShader);

return shaderProgram;

}

private string GetCompileInfoLog(uint shaderObject)
{
// Get the info log length.
int[] infoLength = new int[] { 0 };
gl.GetShader(shaderObject, OpenGL.GL_INFO_LOG_LENGTH, infoLength);
int bufSize = infoLength[0];

// Get the compile info.
StringBuilder il = new StringBuilder(bufSize);
gl.GetShaderInfoLog(shaderObject, bufSize, IntPtr.Zero, il);

return il.ToString();
}

private bool GetCompileStatus(OpenGL gl, uint shaderObject)
{
int[] parameters = new int[] { 0 };
gl.GetShader(shaderObject, OpenGL.GL_COMPILE_STATUS, parameters);
return parameters[0] == OpenGL.GL_TRUE;
}

public string GetLinkInfoLog(OpenGL gl)
{
// Get the info log length.
int[] infoLength = new int[] { 0 };
gl.GetProgram(shaderProgram, OpenGL.GL_INFO_LOG_LENGTH, infoLength);
int bufSize = infoLength[0];

// Get the compile info.
StringBuilder il = new StringBuilder(bufSize);
gl.GetProgramInfoLog(shaderProgram, bufSize, IntPtr.Zero, il);

return il.ToString();
}

public bool GetLinkStatus(OpenGL gl)
{
int[] parameters = new int[] { 0 };
gl.GetProgram(shaderProgram, OpenGL.GL_LINK_STATUS, parameters);
return parameters[0] == OpenGL.GL_TRUE;
}
}
}


I can draw a red triangle with this shader code
VertexShader

#version 330 core

layout(location = 0) in vec3 position;

void main(){
gl_Position = vec4(position ,1);
}


Fragment Shader

#version 330 core

out vec4 color;

void main()
{
color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}

but I can not with this code

VertexShader

#version 330 core

layout(location = 0) in vec3 position;
out vec4 vcolor;

void main(){
gl_Position = vec4(position ,1);
vcolor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}


Fragment Shader

#version 330 core

in vec4 vcolor;
out vec4 color;

void main()
{
color = vcolor;
}

Dark Photon
05-01-2017, 06:35 AM
This may not have anything to do with your problem, but...

Why are you loading and compiling shaders and allocating and populating VBOs and VAOs inside a resize callback (at least that's what it looks like)? All this should go in some init function and happen once.

Where does your program crash or appear to hang? Have you checked for GL errors prior to that point?

tn88test
05-01-2017, 08:23 AM
This may not have anything to do with your problem, but...

Why are you loading and compiling shaders and allocating and populating VBOs and VAOs inside a resize callback (at least that's what it looks like)? All this should go in some init function and happen once.

Where does your program crash or appear to hang? Have you checked for GL errors prior to that point?

Here is the video show my program crashes https://youtu.be/CUJSQ8hnApo

Here is my new rearrange code that can display red triangle:


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SharpGL;
using SharpGL.Shaders;

namespace Vector
{
/// <summary>
/// The main form class.
/// </summary>
public partial class SharpGLForm : Form
{
uint shaderProgram;

/// <summary>
/// Initializes a new instance of the <see cref="SharpGLForm"/> class.
/// </summary>
public SharpGLForm()
{
InitializeComponent();
}

/// <summary>
/// Handles the OpenGLDraw event of the openGLControl control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="RenderEventArgs"/> instance containing the event data.</param>
private void openGLControl_OpenGLDraw(object sender, RenderEventArgs e)
{
OpenGL gl = openGLControl.OpenGL;

gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT | OpenGL.GL_DEPTH_BUFFER_BIT);
gl.UseProgram(shaderProgram);
gl.DrawArrays(OpenGL.GL_TRIANGLES, 0, 3);
}



/// <summary>
/// Handles the OpenGLInitialized event of the openGLControl control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void openGLControl_OpenGLInitialized(object sender, EventArgs e)
{
// TODO: Initialise OpenGL here.

// Get the OpenGL object.
OpenGL gl = openGLControl.OpenGL;
Shader sd = new Shader(gl);

// Set the clear color.
gl.ClearColor(0, 0, 0, 0);

// Vertex Shader
shaderProgram = sd.Loader("shader.vert", "shader.frag");

float[] vertices = {
// Positions // Colors
0.5f, -0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // Bottom Right
-0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // Bottom Left
0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f // Top
};

uint[] VBO = new uint[1];
gl.GenBuffers(1, VBO);

gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, VBO[0]);
gl.BufferData(OpenGL.GL_ARRAY_BUFFER, vertices, OpenGL.GL_STATIC_DRAW);
gl.VertexAttribPointer(0, 3, OpenGL.GL_FLOAT, false, 6 * 4, IntPtr.Zero);
gl.EnableVertexAttribArray(0);
gl.VertexAttribPointer(1, 3, OpenGL.GL_FLOAT, false, 6 * 4, IntPtr.Zero);
gl.EnableVertexAttribArray(1);

}

/// <summary>
/// Handles the Resized event of the openGLControl control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void openGLControl_Resized(object sender, EventArgs e)
{

}
}

class Shader
{
private uint vertexShader;
private uint fragmentShader;
private uint shaderProgram { get; set; }
private OpenGL gl;

public Shader(OpenGL gl)
{
this.gl = gl;
}

public uint Loader(string vertexShaderPath, string fragmentShaderPath)
{
// Vertex Shader
string vertexShaderSource = System.IO.File.ReadAllText(vertexShaderPath);
string fragmentShaderSource = System.IO.File.ReadAllText(fragmentShaderPath);

vertexShader = gl.CreateShader(OpenGL.GL_VERTEX_SHADER);
gl.ShaderSource(vertexShader, vertexShaderSource);
gl.CompileShader(vertexShader);

if (GetCompileStatus(gl, vertexShader) == false)
{
throw new ShaderCompilationException(string.Format("Failed to compile shader with ID {0}.", vertexShader), GetCompileInfoLog(vertexShader));
}

// Fragment Shader
fragmentShader = gl.CreateShader(OpenGL.GL_FRAGMENT_SHADER);
gl.ShaderSource(fragmentShader, fragmentShaderSource);
gl.CompileShader(fragmentShader);

if (GetCompileStatus(gl, fragmentShader) == false)
{
throw new ShaderCompilationException(string.Format("Failed to compile shader with ID {0}.", fragmentShader), GetCompileInfoLog(fragmentShader));
}

// Link shaders
shaderProgram = gl.CreateProgram();
gl.AttachShader(shaderProgram, vertexShader);
gl.AttachShader(shaderProgram, fragmentShader);
gl.LinkProgram(shaderProgram);

if (GetLinkStatus(gl) == false)
{
throw new ShaderCompilationException(string.Format("Failed to link shader program with ID {0}.", shaderProgram), GetLinkInfoLog(gl));
}

gl.DeleteShader(vertexShader);
gl.DeleteShader(fragmentShader);

return shaderProgram;

}

private string GetCompileInfoLog(uint shaderObject)
{
// Get the info log length.
int[] infoLength = new int[] { 0 };
gl.GetShader(shaderObject, OpenGL.GL_INFO_LOG_LENGTH, infoLength);
int bufSize = infoLength[0];

// Get the compile info.
StringBuilder il = new StringBuilder(bufSize);
gl.GetShaderInfoLog(shaderObject, bufSize, IntPtr.Zero, il);

return il.ToString();
}

private bool GetCompileStatus(OpenGL gl, uint shaderObject)
{
int[] parameters = new int[] { 0 };
gl.GetShader(shaderObject, OpenGL.GL_COMPILE_STATUS, parameters);
return parameters[0] == OpenGL.GL_TRUE;
}

public string GetLinkInfoLog(OpenGL gl)
{
// Get the info log length.
int[] infoLength = new int[] { 0 };
gl.GetProgram(shaderProgram, OpenGL.GL_INFO_LOG_LENGTH, infoLength);
int bufSize = infoLength[0];

// Get the compile info.
StringBuilder il = new StringBuilder(bufSize);
gl.GetProgramInfoLog(shaderProgram, bufSize, IntPtr.Zero, il);

return il.ToString();
}

public bool GetLinkStatus(OpenGL gl)
{
int[] parameters = new int[] { 0 };
gl.GetProgram(shaderProgram, OpenGL.GL_LINK_STATUS, parameters);
return parameters[0] == OpenGL.GL_TRUE;
}
}
}

Vertex Shader

#version 330 core

layout(location = 0) in vec3 position;
layout (location = 1) in vec3 color;

out vec3 ourColor;

void main(){
gl_Position = vec4(position ,1);
ourColor = color;
}

Fragment Shader

#version 330 core

in vec3 ourColor;
out vec4 color;

void main()
{
color = vec4(0.5f, 0.0f, 0.0f, 1.0f);
}

tn88test
05-03-2017, 08:37 AM
Finally I found the problem :D . All I need to do was to put this code after drawing.
gl.UseProgram(0);