Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 28.02.2017, 23:53   #1
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию C#/OpenTK. Не устанавливается размер точки в вершинном шейдере

Здравствуйте,

Пытаюсь создать точку размером 10px, красного цвета, как этом в примере на WebGL: HelloPoint1

У меня выводится белая точка размером 1px.

Я сделал маленький пример, чтобы продемонстрировать проблему. Проект должен запуститься в VS2012-VS2015: PointWithCustomSizeAndColour_1px.zi p

Подозреваю, что это баг библиотеки OpenTK и я покажу ниже, что вроде бы я всё сделал правильно. Если у вас тоже такое мнение, то напишите.

В методе Load я не забыл активировать задание размера точки Enable(GL_PROGRAM_POINT_SIZE);

Как того требует документация:

Цитата:
If GL_PROGRAM_POINT_SIZE is enabled, gl_PointSize is used to determine the size of rasterized points, otherwise it is ignored by the rasterization stage.
Вот так я активировал:

Код:
GL.Enable(EnableCap.ProgramPointSize);
Но всё равно gl_PointSize продолжает игнорироваться в вершинном шейдере. Координаты, размер и цвет точки я определил сразу в шейдерах.

Полностью весь исходный код проекта:

vShader.glsl
Код:
#version 330

void main()
{
    gl_Position = vec4(0.0, 0.0, 0.0, 1,0);
    gl_PointSize = 10.0;
}
fShader.glsl
Код:
#version 330

out fragColor;

void main()
{
    fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Program.cs
Код:
namespace PointWithCustomSizeAndColour
{
    class Program
    {
        static void Main(string[] args)
        {
            using (MainWindow mainWindow = new MainWindow())
            {
                mainWindow.Run(30);
            }
        }
    }
}
MainWindow.cs
Код:
using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics.OpenGL;

namespace PointWithCustomSizeAndColour
{
    class MainWindow : GameWindow
    {
        string vShaderSource = null;
        string fShaderSource = null;

        bool canDraw = false;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // Load shaders from files
            ShaderLoader.LoadShader("./Shaders/vShader.glsl", out vShaderSource);
            ShaderLoader.LoadShader("./Shaders/fShader.glsl", out fShaderSource);
            if (vShaderSource == null || fShaderSource == null)
            {
                Console.WriteLine("Failed to load shaders from files");
                return;
            }

            // Specify the color for clearing
            GL.ClearColor(Color.Black);

            GL.Enable(EnableCap.ProgramPointSize);

            canDraw = true;
        }

        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);
            GL.Viewport(0, 0, Width, Height);

            if (!canDraw) return;

            GL.Clear(ClearBufferMask.ColorBufferBit);

            // Draw a point
            GL.DrawArrays(PrimitiveType.Points, 0, 1);

            GL.Flush();
            SwapBuffers();
        }
    }
}
ShaderLoader.cs
Код:
using System.IO;
using OpenTK.Graphics.OpenGL;

namespace PointWithCustomSizeAndColour
{
    class ShaderLoader
    {
        private static string infoFileName = null;

        ///<summary>
        ///Create a program object and make current
        ///</summary>
        ///<param name="infoFileName">a file name for errors</param>
        ///<param name="vShader">a vertex shader program</param>
        ///<param name="fShader">a fragment shader program</param>
        ///<param name="program">created program</param>
        ///<returns>
        ///return true, if the program object was created and successfully made current
        ///</returns>
        private static bool InitShaders(string infoFileName, string vShader, string fShader, out int program)
        {
            ShaderLoader.infoFileName = infoFileName;

            program = CreateProgram(vShader, fShader);
            if (program == 0)
            {
                File.AppendAllText(infoFileName, "Failed to create program");
                return false;
            }

            GL.UseProgram(program);

            return true;
        }

        /// <summary>
        /// Load a shader from a file
        /// </summary>
        /// <param name="fileName">a file name to a shader</param>
        /// <param name="shaderSource">a shader source string</param>
        public static void LoadShader(string fileName, out string shaderSource)
        {
            if (File.Exists(infoFileName))
            {
                // Clear File
                File.WriteAllText(infoFileName, "");
            }

            shaderSource = null;

            using (StreamReader sr = new StreamReader(fileName))
            {
                shaderSource = sr.ReadToEnd();
            }
        }

        private static int CreateProgram(string vShader, string fShader)
        {
            // Create shader object
            int vertexShader = LoadShader(ShaderType.VertexShader, vShader);
            int fragmentShader = LoadShader(ShaderType.FragmentShader, fShader);
            if (vertexShader == 0 || fragmentShader == 0)
            {
                return 0;
            }

            // Create a program object
            int program = GL.CreateProgram();
            if (program == 0)
            {
                return 0;
            }

            // Attach the shader objects
            GL.AttachShader(program, vertexShader);
            GL.AttachShader(program, fragmentShader);

            // Link the program object
            GL.LinkProgram(program);

            // Check the result of linking
            int status;
            GL.GetProgram(program, GetProgramParameterName.LinkStatus, out status);
            if (status == 0)
            {
                string errorString = string.Format("Failed to link program: {0}", GL.GetProgramInfoLog(program));
                File.AppendAllText(infoFileName, errorString);
                GL.DeleteProgram(program);
                GL.DeleteShader(vertexShader);
                GL.DeleteShader(fragmentShader);
                return 0;
            }

            return program;
        }

        private static int LoadShader(ShaderType shaderType, string shaderSource)
        {
            // Create shader object
            int shader = GL.CreateShader(shaderType);
            if (shader == 0)
            {
                File.AppendAllText(infoFileName, "Unable to create shader");
                return 0;
            }

            // Set the shader program
            GL.ShaderSource(shader, shaderSource);

            // Compile the shader
            GL.CompileShader(shader);

            // Check the result of compilation
            int status;
            GL.GetShader(shader, ShaderParameter.CompileStatus, out status);
            if (status == 0)
            {
                string errorString = string.Format("Failed to compile {0} shader: {1}", shaderType.ToString(), GL.GetShaderInfoLog(shader));
                File.AppendAllText(infoFileName, errorString);
                GL.DeleteShader(shader);
                return 0;
            }

            return shader;
        }
    }
}
8Observer8 вне форума Ответить с цитированием
Старый 01.03.2017, 07:50   #2
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Очень странно, что вообще рисуется точка, потому что я загрузил шейдеры только в строковые переменные и не откомпилировал их, то есть не вызвал метод InitShaders() из файла ShaderLoader.cs
8Observer8 вне форума Ответить с цитированием
Старый 01.03.2017, 08:36   #3
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Сейчас всё работает!



Исправленный проект: PointWithCustomSizeAndColour.zip

Кроме того, что забыл инициализировать шейдеры, допустил мелкие ошибки: в вершинном шейдере в последнем аргументе поставил запятую вместо точки, а в фрагментном забыл vec4 перед fragColor. И ещё кое-какие ошибки исправил в ShaderLoader.cs

Файлы исправленного проекта, если вдруг удалиться с dropbox или если кому-то или мне пригодится:

vShader.glsl
Код:
#version 330

void main()
{
    gl_Position = vec4(0.8, 0.0, 0.0, 1.0);
    gl_PointSize = 10.0;
}
fShader.glsl
Код:
#version 330

out vec4 fragColor;

void main()
{
    fragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
Program.cs
Код:
namespace PointWithCustomSizeAndColour
{
    class Program
    {
        static void Main(string[] args)
        {
            using (MainWindow mainWindow = new MainWindow())
            {
                mainWindow.Run(30);
            }
        }
    }
}
MainWindow.cs
Код:
using System;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using System.IO;

namespace PointWithCustomSizeAndColour
{
    class MainWindow : GameWindow
    {
        string vShaderSource = null;
        string fShaderSource = null;

        bool canDraw = false;

        string infoFileName = "info.txt";

        int program;

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            // Load shaders from files
            ShaderLoader.LoadShader(infoFileName, "./Shaders/vShader.glsl", out vShaderSource);
            ShaderLoader.LoadShader(infoFileName, "./Shaders/fShader.glsl", out fShaderSource);
            if (vShaderSource == null || fShaderSource == null)
            {
                File.AppendAllText(infoFileName, "Failed to load shaders from files" + Environment.NewLine);
                return;
            }

            // Initialize shaders
            if (!ShaderLoader.InitShaders(vShaderSource, fShaderSource, out program))
            {
                File.AppendAllText(infoFileName, "Failed to initialize the shaders" + Environment.NewLine);
                return;
            }

            // Specify the color for clearing
            GL.ClearColor(Color.Black);

            GL.Enable(EnableCap.ProgramPointSize);

            canDraw = true;
        }

        protected override void OnRenderFrame(FrameEventArgs e)
        {
            base.OnRenderFrame(e);
            GL.Viewport(0, 0, Width, Height);

            if (!canDraw) return;

            GL.Clear(ClearBufferMask.ColorBufferBit);

            // Draw a point
            GL.DrawArrays(PrimitiveType.Points, 0, 1);

            GL.Flush();
            SwapBuffers();
        }
    }
}
ShaderLoader.cs
Код:
using System.IO;
using OpenTK.Graphics.OpenGL;
using System;

namespace PointWithCustomSizeAndColour
{
    class ShaderLoader
    {
        private static string infoFileName = null;

        ///<summary>
        ///Create a program object and make current
        ///</summary>
       ///<param name="vShader">a vertex shader program</param>
        ///<param name="fShader">a fragment shader program</param>
        ///<param name="program">created program</param>
        ///<returns>
        ///return true, if the program object was created and successfully made current
        ///</returns>
        public static bool InitShaders(string vShader, string fShader, out int program)
        {
            program = CreateProgram(vShader, fShader);
            if (program == 0)
            {
                File.AppendAllText(infoFileName, "Failed to create program" + Environment.NewLine);
                return false;
            }

            GL.UseProgram(program);

            return true;
        }

        ///<summary>
        ///Load a shader from a file
        ///</summary>
        ///<param name="infoFileName">a file name for errors</param>
        ///<param name="fileName">a file name to a shader</param>
        ///<param name="shaderSource">a shader source string</param>
        public static void LoadShader(string infoFileName, string fileName, out string shaderSource)
        {
            ShaderLoader.infoFileName = infoFileName;

            if (File.Exists(infoFileName))
            {
                // Clear File
                File.WriteAllText(infoFileName, "");
            }

            shaderSource = null;

            using (StreamReader sr = new StreamReader(fileName))
            {
                shaderSource = sr.ReadToEnd();
            }
        }

        private static int CreateProgram(string vShader, string fShader)
        {
            // Create shader object
            int vertexShader = LoadShader(ShaderType.VertexShader, vShader);
            int fragmentShader = LoadShader(ShaderType.FragmentShader, fShader);
            if (vertexShader == 0 || fragmentShader == 0)
            {
                return 0;
            }

            // Create a program object
            int program = GL.CreateProgram();
            if (program == 0)
            {
                return 0;
            }

            // Attach the shader objects
            GL.AttachShader(program, vertexShader);
            GL.AttachShader(program, fragmentShader);

            // Link the program object
            GL.LinkProgram(program);

            // Check the result of linking
            int status;
            GL.GetProgram(program, GetProgramParameterName.LinkStatus, out status);
            if (status == 0)
            {
                string errorString = string.Format("Failed to link program: {0}" + Environment.NewLine, GL.GetProgramInfoLog(program));
                File.AppendAllText(infoFileName, errorString);
                GL.DeleteProgram(program);
                GL.DeleteShader(vertexShader);
                GL.DeleteShader(fragmentShader);
                return 0;
            }

            return program;
        }

        private static int LoadShader(ShaderType shaderType, string shaderSource)
        {
            // Create shader object
            int shader = GL.CreateShader(shaderType);
            if (shader == 0)
            {
                File.AppendAllText(infoFileName, "Unable to create shader" + Environment.NewLine);
                return 0;
            }

            // Set the shader program
            GL.ShaderSource(shader, shaderSource);

            // Compile the shader
            GL.CompileShader(shader);

            // Check the result of compilation
            int status;
            GL.GetShader(shader, ShaderParameter.CompileStatus, out status);
            if (status == 0)
            {
                string errorString = string.Format("Failed to compile {0} shader: {1}" + Environment.NewLine, shaderType.ToString(), GL.GetShaderInfoLog(shader));
                File.AppendAllText(infoFileName, errorString);
                GL.DeleteShader(shader);
                return 0;
            }

            return shader;
        }
    }
}

Последний раз редактировалось 8Observer8; 01.03.2017 в 10:25.
8Observer8 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с OpenTK ! MorphyrE C# (си шарп) 0 27.03.2013 14:50
Проблема с OpenGL(OpenTK) Truepak C# (си шарп) 2 15.01.2013 12:22
Генетический алгоритм. Задача о вершинном покрытии. CannibalCorpse Помощь студентам 0 14.04.2012 11:56
Можно ли юзать OpenTK в С++ samouelson Visual C++ 1 05.06.2011 16:53
Увеличить размер точки OptionButton Sergey112233 Microsoft Office Excel 4 30.12.2010 22:47