Как обычно, когда я пытаюсь намочить мои пальцы с помощью современного OpenGL, используя одну из умных демонстраций, которые можно найти в некоторых блогах, что-то пошло не так.Данные о цвете, которые не используются в OpenGL «Hello world»
Ожидаемое поведение: Нарисуйте треугольник, и цвета должны быть интерполированы между тремя вершинами.
Поведение: Треугольник красный. И неважно, какие цвета я пишу в массив цветов.
Код сначала (извините 160 строк - современный OpenGL - спам ...).
open System
open System.Drawing
open System.Collections.Generic
open OpenTK
open OpenTK.Graphics
open OpenTK.Graphics.OpenGL
open OpenTK.Input
module Shaders =
let vertexShader =
"""#version 330
in vec3 vPosition;
in vec3 vColor;
out vec4 color;
uniform mat4 modelview;
void
main()
{
gl_Position = modelview * vec4(vPosition, 1.0);
color = vec4(vColor, 1.0);
}
"""
let fragmentShader =
"""#version 330
in vec4 color;
out vec4 outputColor;
void
main()
{
outputColor = color;
}
"""
let initShaders() : int =
let makeShader shaderType src =
let sh = GL.CreateShader(shaderType)
GL.ShaderSource(sh,src)
GL.CompileShader(sh)
sh
let pgmId = GL.CreateProgram()
let vsh = makeShader ShaderType.VertexShader vertexShader
let fsh = makeShader ShaderType.FragmentShader fragmentShader
GL.AttachShader(pgmId,vsh)
GL.AttachShader(pgmId,fsh)
GL.LinkProgram(pgmId)
pgmId
let failMinusOne = function
| -1 -> failwith "Something is -1 which should not be -1!"
| x -> x
type Game(width,height) =
inherit GameWindow(width, height, GraphicsMode.Default, "F# OpenTK Sample")
do base.VSync <- VSyncMode.On
let mutable shaderProgramId = -1
let mutable attribute_vcol = -1
let mutable attribute_vpos = -1
let mutable uniform_mview = -1
let mutable vbo_col = 0
let mutable vbo_pos = 0
let vertex_data =
[|
Vector3(-0.8f, -0.8f, 0.f)
Vector3(0.8f, -0.8f, 0.f)
Vector3(0.f, 0.8f, 0.f)
|]
let col_data =
[|
Vector3(1.f, 1.f, 1.f)
Vector3(0.f, 0.f, 1.f)
Vector3(0.f, 1.f, 0.f)
|]
let mview_data = [| Matrix4.Identity |]
/// <summary>Load resources here.</summary>
/// <param name="e">Not used.</param>
override o.OnLoad e =
base.OnLoad(e)
o.Title <- "Hello OpenTK!"
shaderProgramId <- Shaders.initShaders()
GL.ClearColor(Color.CornflowerBlue)
GL.Enable(EnableCap.DepthTest)
attribute_vpos <- GL.GetAttribLocation(shaderProgramId, "vPosition") |> failMinusOne
attribute_vcol <- GL.GetAttribLocation(shaderProgramId, "vColor") |> failMinusOne
uniform_mview <- GL.GetUniformLocation(shaderProgramId, "modelview") |> failMinusOne
vbo_col <- GL.GenBuffer()
vbo_pos <- GL.GenBuffer()
/// <summary>
/// Called when your window is resized. Set your viewport here. It is also
/// a good place to set up your projection matrix (which probably changes
/// along when the aspect ratio of your window).
/// </summary>
/// <param name="e">Not used.</param>
override o.OnResize e =
base.OnResize e
GL.Viewport(base.ClientRectangle.X, base.ClientRectangle.Y, base.ClientRectangle.Width, base.ClientRectangle.Height)
let projection = Matrix4.CreatePerspectiveFieldOfView(float32 (Math.PI/4.), float32 base.Width/float32 base.Height, 1.f, 64.f)
GL.MatrixMode(MatrixMode.Projection)
GL.LoadMatrix(ref projection)
/// <summary>
/// Called when it is time to setup the next frame. Add you game logic here.
/// </summary>
/// <param name="e">Contains timing information for framerate independent logic.</param>
override o.OnUpdateFrame e =
base.OnUpdateFrame e
if base.Keyboard.[Key.Escape] then base.Close()
else
GL.BindBuffer(BufferTarget.ArrayBuffer,vbo_col)
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,Array.length col_data * Vector3.SizeInBytes,col_data,BufferUsageHint.StaticDraw)
GL.VertexAttribPointer(attribute_vcol, 3, VertexAttribPointerType.Float, false, 0, 0)
GL.BindBuffer(BufferTarget.ArrayBuffer,vbo_pos)
GL.BufferData<Vector3>(BufferTarget.ArrayBuffer,Array.length vertex_data * Vector3.SizeInBytes,vertex_data,BufferUsageHint.StaticDraw)
GL.VertexAttribPointer(attribute_vpos, 3, VertexAttribPointerType.Float, false, 0, 0)
GL.UniformMatrix4(uniform_mview,false,ref mview_data.[0])
GL.BindBuffer(BufferTarget.ArrayBuffer,0)
GL.UseProgram(shaderProgramId)
/// <summary>
/// Called when it is time to render the next frame. Add your rendering code here.
/// </summary>
/// <param name="e">Contains timing information.</param>
override o.OnRenderFrame(e) =
base.OnRenderFrame e
GL.Clear(ClearBufferMask.ColorBufferBit ||| ClearBufferMask.DepthBufferBit);
GL.EnableVertexArrayAttrib(attribute_vpos,0)
GL.EnableVertexArrayAttrib(attribute_vcol,0)
GL.DrawArrays(PrimitiveType.Triangles,0,Array.length vertex_data)
GL.DisableVertexArrayAttrib(attribute_vpos,0)
GL.DisableVertexArrayAttrib(attribute_vcol,0)
GL.Flush()
base.SwapBuffers()
[<EntryPoint>]
let main argv =
use game = new Game(800,600)
do game.Run(30.,30.)
0 // return an integer exit code
Спустя несколько часов, пытаясь найти то, что происходит, у меня кончились идеи. Добавление большего количества треугольников также кажется на флопе. Но тогда тот факт, что треугольник показывает, как показывают вершины, заставляет меня думать, что загрузка данных в gpu в порядке.
Но для вас, ребята, которые делают этот день в день, вероятно, будет легко обнаружить, где все пошло не так.
Это работает для меня на рабочем столе NVidia после изменения синтаксиса кода текущей версии OTK. Это может быть типичная, адски багги поддержка OpenGL. Проверьте, какие графические процессоры, драйверы и версии OTK происходят. Будьте готовы, чтобы современный OpenGL-код мог отображать пять разных результатов на пяти «типичных» компьютерах. Особенно старые драйверы AMD и Intel могут настолько ошибочно, что вызов современного OpenGL «поддерживается» является пограничным мошенничеством. Какой GPU, версия драйвера и версия OpenTK вы используете? – Vandroiy
My OpenTK - это текущий пакет nuget, который я получил только вчера (версия 2.0.0). Мой графический процессор NVIDIA немного старше (GTX 650). 3D-приложения обычно работают с обычной шаткой надежностью современной 3D-драйверов, багги и неустойчивостью. Я не знаю, что такое OTK (я ссылался на OpenTK.dll и ничего больше). Версия драйвера: 21.21.13.7290 (думаю, он поставляется с обновлениями Windows 10) – BitTickler
Oh! Мой плохой, по-видимому, обновление 2.0 удалило устаревшее предупреждение, поэтому я ошибочно предположил, что вы на старой версии. А я был. Похоже, что ошибка связана с индексом активации массива вершин; дайте мне минутку, чтобы ответить. – Vandroiy