0

glsl バージョン 4.2 を使用するプロジェクトに SharpGL を使用しています。

過去数日間、いくつかの例を試しましたが、どれも機能していません。OpenTK 用に記述された同様のコードが機能したため、何が間違っているのかわかりませんが、シェーダーと VBO を使用している場合、SharpGL では画面に何も描画されません。気を失っているか、SharpGL 自体で何かが正しく機能していないかのどちらかです。

WPF コントロールには SharpGL を使用したいと思います。非常に簡単なサンプルコードを添付しています。この問題について何か助けていただければ幸いです。わずかな変更を加えた同じコードが OpenTK で機能することに注意してください。

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;

using System.Runtime.InteropServices;
using System.IO;

using SharpGL;
using SharpGL.SceneGraph;

namespace SharpGLTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        OpenGL gl;
        uint theProgram, positionBufferObject;
        string strVertexShader = "test.vert";
        string strFragmentShader = "test.frag";

        public MainWindow()
        {
            InitializeComponent();
        }

        private void OpenGLControl_OpenGLInitialized(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            gl = args.OpenGL;

            InitializeVertexBuffer();
            InitializeProgram();
        }

        private uint CreateProgram(List<uint> shaderList)
        {
            uint program = gl.CreateProgram();

            foreach (uint shader in shaderList)
                gl.AttachShader(program, shader);

            gl.LinkProgram(program);

            ProgramErrorInfo(program);

            foreach (uint shader in shaderList)
                gl.DetachShader(program, shader);

            return program;
        }

        private uint CreateShader(uint eShaderType, string strShaderFile)
        {
            uint shader = gl.CreateShader(eShaderType);
            string[] strFileData = { File.ReadAllText(strShaderFile) };

            gl.ShaderSource(shader, strFileData);

            gl.CompileShader(shader);

            ShaderErrorInfo(shader);

            return shader;
        }

        private void InitializeProgram()
        {
            List<uint> shaderList = new List<uint>();

            shaderList.Add(CreateShader(OpenGL.GL_VERTEX_SHADER, strVertexShader));
            shaderList.Add(CreateShader(OpenGL.GL_FRAGMENT_SHADER, strFragmentShader));

            theProgram = CreateProgram(shaderList);

            foreach (uint shader in shaderList)
                gl.DeleteShader(shader);

        }

        private void InitializeVertexBuffer()
        {
            float[] vertexPositions = {
                0.75f, 0.75f, 0.0f, 1.0f,
                0.75f, -0.75f, 0.0f, 1.0f,
                -0.75f, -0.75f, 0.0f, 1.0f,
            };
            GCHandle handle = GCHandle.Alloc(vertexPositions, GCHandleType.Pinned);
            IntPtr vertexPtr = handle.AddrOfPinnedObject();
            var size = Marshal.SizeOf(typeof(float)) * vertexPositions.Length;

            uint[] pbo = new uint[1];
            gl.GenBuffers(1, pbo);
            positionBufferObject = pbo[0];

            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, positionBufferObject);
            gl.BufferData(OpenGL.GL_ARRAY_BUFFER, size, vertexPtr, OpenGL.GL_STATIC_DRAW);
            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, 0);

            handle.Free();
        }

        private void OpenGLControl_OpenGLDraw(object sender, SharpGL.SceneGraph.OpenGLEventArgs args)
        {
            gl.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
            gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT);

            gl.UseProgram(theProgram);

            gl.BindBuffer(OpenGL.GL_ARRAY_BUFFER, positionBufferObject);
            gl.EnableVertexAttribArray(0);
            gl.VertexAttribPointer(0, 4, OpenGL.GL_FLOAT, false, 0, IntPtr.Zero);

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

            gl.DisableVertexAttribArray(0);
            gl.UseProgram(0);

            gl.Flush();
        }

        private void OpenGLControl_Resized(object sender, OpenGLEventArgs args)
        {
            gl.Viewport(0, 0, gl.RenderContextProvider.Width, gl.RenderContextProvider.Height);
        }

        private bool ShaderErrorInfo(uint shaderId)
        {
            StringBuilder builder = new StringBuilder(2048);
            gl.GetShaderInfoLog(shaderId, 2048, IntPtr.Zero, builder);
            string res = builder.ToString();
            if (!res.Equals(""))
            {
                System.Console.WriteLine(res);
                return false;
            }

            return true;
        }

        private bool ProgramErrorInfo(uint programId)
        {
            StringBuilder builder = new StringBuilder(2048);
            gl.GetProgramInfoLog(programId, 2048, IntPtr.Zero, builder);
            string res = builder.ToString();
            if (!res.Equals(""))
            {
                System.Console.WriteLine(res);
                return false;
            }

            return true;
        }

    }
}

test.vert

#version 330

layout(location = 0) in vec4 position;
void main()
{
    gl_Position = position;
}

test.frag

#version 330

out vec4 outputColor;
void main()
{
   outputColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}

MainWindow.xaml

<Window x:Class="SharpGLTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:sharpGL="clr-namespace:SharpGL.WPF;assembly=SharpGL.WPF">
    <Grid>
        <sharpGL:OpenGLControl x:Name="OpenGLControl"
            OpenGLInitialized="OpenGLControl_OpenGLInitialized"
            OpenGLDraw="OpenGLControl_OpenGLDraw" 
            RenderContextType="FBO"
            Resized="OpenGLControl_Resized"
                               />
    </Grid>
</Window>
4

2 に答える 2

1

この質問はかなり古いことは知っていますが、最初にここに来たときに gl.GetShaderInfoLog を使用する方法をグーグルで検索し、次に SharpGL のソース コードの Shader.cs を検索しました。

実際、SharpGl には glGetShaderiv/glGetProgramiv はありません。ただし、これはコンパイル ステータスを示す情報ログではありません。次のように取得されます (Shader.cs からの抜粋)。

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

私の場合、これはエラーを示しましたが、あなたの方法では何も発生しませんでした。

最終的に、Tim はコンパイル エラーについて正しい方向に進んでいました。さて、あなたは本当にコンパイルエラーを抱えていますか? わかりませんが、これに答えるには、コンパイルエラーを適切にチェックすることが重要です。

于 2015-05-17T16:13:02.770 に答える
0

SharpGL がエラー チェックを行うかどうかはわかりませんが、そうでない場合は、どこかで glGetError をテストする必要があります。

何が問題なのか正確にはわかりませんが、情報ログの長さを確認するだけでは、操作が成功したかどうかをテストするのに十分ではないと思います。

シェーダーのコンパイル/リンクでエラーをテストするglGetShaderiv/glGetProgramivには、ターゲットGL_COMPILE_STATUSまたはGL_LINK_STATUS. このブール値の結果は、コンパイル/リンクが成功したかどうかを決定します。

情報ログの長さを使用することは、ほとんどの場合正しいと思われますが、保証されていません。一部のプラットフォームでは、リンクが失敗してエラー ログがないというバグを見てきました。また、コンパイル/リンクが成功してもメッセージが出力される可能性があることも知っています。

于 2012-11-22T19:46:17.360 に答える