Skip to content

Commit

Permalink
3: Get a texture loaded. The texture coordinate buffer is not complet…
Browse files Browse the repository at this point in the history
…ed yet.
  • Loading branch information
jamesaorson committed Jun 19, 2024
1 parent 694ea9f commit 5b0ca19
Show file tree
Hide file tree
Showing 10 changed files with 134 additions and 38 deletions.
12 changes: 9 additions & 3 deletions examples/Playground/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,19 @@ type GameState =
Triangles = Primitives.ShadedObject.Default }

let private initHandler (config:Config<GameState>) =
let fragmentPaths = ["Resources/Shaders/fragment.glsl"]
let vertexPaths = ["Resources/Shaders/vertex.glsl"]
let fragmentPaths = ["Resources/Shaders/Texture/fragment.glsl"]
let vertexPaths = ["Resources/Shaders/Texture/vertex.glsl"]
let transform =
{ Transform.Default() with
Scale = (1.0f, 1.0f, 1.0f)
Rotation = (0.0f, 0.0f, 0.0f) }
match Primitives.ShadedObject.CreateQuad vertexPaths fragmentPaths transform 1.8f 1.0f None with
match Primitives.ShadedObject.CreateQuad
vertexPaths
fragmentPaths
transform
1.8f
1.0f
(Types.Texture2D.FromPath "Resources/Textures/smiley.png" |> Some) with
| Some primitive ->
{ config with
State.Triangles = primitive }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#version 330 core

layout (location = 0) in vec3 in_position; // the in_position variable has attribute position 0
layout (location = 0) in vec3 in_position; // the in_position variable has attribute position 0\

void main()
{
Expand Down
19 changes: 19 additions & 0 deletions examples/Playground/Resources/Shaders/Texture/fragment.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#version 330 core

in vec2 out_texture_coordinate;

out vec4 out_frag_color;

uniform vec2 in_viewport;
uniform sampler2D in_texture;

void main()
{
// out_frag_color = texture(in_texture, TexCoord)
out_frag_color = vec4(
1.0f - out_texture_coordinate.x,
1.0f - out_texture_coordinate.y,
0.0f,
1.0f
);
}
12 changes: 12 additions & 0 deletions examples/Playground/Resources/Shaders/Texture/vertex.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#version 330 core

layout (location = 0) in vec3 in_position; // the in_position variable has attribute position 0
layout (location = 1) in vec2 in_tex_coordinate; // the in_tex_coordinate variable has attribute position 1

out vec2 out_texture_coordinate;

void main()
{
gl_Position = vec4(in_position.x, in_position.y, in_position.z, 1.0);
out_texture_coordinate = in_tex_coordinate;
}
6 changes: 3 additions & 3 deletions src/ThirdParty/SDL2/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ public static SDL.SDL_version IMG_Linked_Version()

/* IntPtr refers to an SDL_Surface* */
[DllImport(nativeLibName, EntryPoint = "IMG_Load", CallingConvention = CallingConvention.Cdecl)]
private static extern unsafe IntPtr INTERNAL_IMG_Load(
private static extern unsafe SDL.SDL_Surface* INTERNAL_IMG_Load(
byte* file
);
public static unsafe IntPtr IMG_Load(string file)
public static unsafe SDL.SDL_Surface* IMG_Load(string file)
{
byte* utf8File = SDL.Utf8EncodeHeap(file);
IntPtr handle = INTERNAL_IMG_Load(
SDL.SDL_Surface* handle = INTERNAL_IMG_Load(
utf8File
);
Marshal.FreeHGlobal((IntPtr)utf8File);
Expand Down
2 changes: 1 addition & 1 deletion src/ThirdParty/SDL2/SDL2Bindings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4319,7 +4319,7 @@ uint color

/* surface refers to an SDL_Surface* */
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
public static extern void SDL_FreeSurface(IntPtr surface);
public static extern unsafe void SDL_FreeSurface(SDL_Surface* surface);

/* surface refers to an SDL_Surface* */
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
Expand Down
2 changes: 1 addition & 1 deletion src/Womb/Backends/OpenGL/Api/Constants/OpenGL1_0.fs
Original file line number Diff line number Diff line change
Expand Up @@ -348,4 +348,4 @@ let GL_TEXTURE_WRAP_S = 0x2802u
[<Literal>]
let GL_TEXTURE_WRAP_T = 0x2803u
[<Literal>]
let GL_REPEAT = 0x2901u
let GL_REPEAT = 0x2901u
84 changes: 55 additions & 29 deletions src/Womb/Graphics/Primitives.fs
Original file line number Diff line number Diff line change
Expand Up @@ -15,46 +15,47 @@ type ShadedObjectContext =
EBO: uint;
Vertices: array<single>;
Indices: array<uint>;
Texture: option<uint>; }
Texture: uint; }

static member Default () =
{ VAO = 0u
VBO = 0u
EBO = 0u
Vertices = Array.empty
Indices = Array.empty
Texture = None }
Texture = 0u }

static member From (vertices) (indices) (textureOpt: option<SDL2Bindings.SDL.SDL_Surface>) : ShadedObjectContext =
static member From (vertices) (indices) (textureOpt: option<Texture2D>) : ShadedObjectContext =
let vao = glGenVertexArray()
let vbo = glGenBuffer()
let ebo = glGenBuffer()
let textureId =
match textureOpt with
| Some _ ->
| Some texture ->
let id = glGenTexture()
glBindTexture GL_TEXTURE_2D id

// TODO: Fix the type errors
// NOTE: Eventually we will add texturing options for the individual texture, but for now let's set some defaults
// NOTE: set the texture wrapping/filtering options (on the currently bound texture object)
// glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_S GL_REPEAT
// glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_T GL_REPEAT
// glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER GL_LINEAR_MIPMAP_LINEAR
// glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER GL_LINEAR
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_S (int GL_REPEAT)
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_WRAP_T (int GL_REPEAT)
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MIN_FILTER (int GL_LINEAR_MIPMAP_LINEAR)
glTexParameteri GL_TEXTURE_2D GL_TEXTURE_MAG_FILTER (int GL_LINEAR)

// TODO: Generate the texture and mipmap
// NOTE: glTexImage2d explanation...
// The first argument specifies the texture target; setting this to GL_TEXTURE_2D means this operation will generate a texture on the currently bound texture object at the same target (so any textures bound to targets GL_TEXTURE_1D or GL_TEXTURE_3D will not be affected).
// The second argument specifies the mipmap level for which we want to create a texture for if you want to set each mipmap level manually, but we'll leave it at the base level which is 0.
// The third argument tells OpenGL in what kind of format we want to store the texture. Our image has only RGB values so we'll store the texture with RGB values as well.
// The 4th and 5th argument sets the width and height of the resulting texture. We stored those earlier when loading the image so we'll use the corresponding variables.
// The next argument should always be 0 (some legacy stuff).
// The 7th and 8th argument specify the format and datatype of the source image. We loaded the image with RGB values and stored them as chars (bytes) so we'll pass in the corresponding values.
// The last argument is the actual image data.
// glTexImage2D GL_TEXTURE_2D 0 GL_RGB width height 0 GL_RGB GL_UNSIGNED_BYTE data
glTexImage2D
GL_TEXTURE_2D // specifies the dimensional behavior of a texture: 1D is a line, 2D is a normal flat texture, 3D is a volumetric texture, like when a model is cut open and you want to show the interior of the object: https://stackoverflow.com/a/7329678
0 // mipmap level to use (clamped to 0 for now)
(int GL_RGB) // format of output texture
texture.Width // width of resulting texture
texture.Height // height of resulting texture
0 // always 0, for legacy reasons
GL_RGB // format of source image
GL_UNSIGNED_BYTE // datatype of source image
texture.Data // image data
glGenerateMipmap GL_TEXTURE_2D
// TODO: Free the image data from SDL

match texture.Surface with
| Some surface -> SDL2Bindings.SDL.SDL_FreeSurface(surface)
| None -> ()
id
| None -> 0u

Expand All @@ -76,7 +77,6 @@ type ShadedObjectContext =
indices
GL_STATIC_DRAW

// TODO: Adjust the stride parameter if a texture is present
glVertexAttribPointer
0u
3u
Expand All @@ -86,12 +86,25 @@ type ShadedObjectContext =
0
glEnableVertexAttribArray 0u

match textureId with
| 0u ->
// TODO: This is not binding properly. Create a new buffer just for texture coordinates and bind it
glVertexAttribPointer
1u
2u
GL_FLOAT
false
2
4
glEnableVertexAttribArray 1u
| _ -> ()

{ VAO = vao
VBO = vbo
EBO = ebo
Vertices = vertices
Indices = indices
Texture = None }
Texture = textureId }

static member UpdateIndices (indices) (context: ShadedObjectContext) : ShadedObjectContext =
glBindBuffer
Expand Down Expand Up @@ -149,6 +162,7 @@ type ShadedObject =
fragmentPaths
) with
| Some shader ->
// TODO: Construct tex coords
let vertices = [|
// bottom left
-width / 2.0f; -height / 2.0f; 0.0f;
Expand Down Expand Up @@ -220,8 +234,7 @@ type ShadedObject =

let mvp = modelMatrix * viewMatrix * projectionMatrix
glUniformMatrix4fv mvpUniform 1 mvp

// TODO: See if texture data or coords are best passed through uniforms. If so, modify this, otherwise, leave it be

List.map
(
fun uniformData ->
Expand Down Expand Up @@ -298,12 +311,24 @@ type ShadedObject =
| 3 -> glUniform3ui location data[0] data[1] data[2]
| 4 -> glUniform4ui location data[0] data[1] data[2] data[3]
| len -> fail $"Unsupported UVectorUniform length {len} when trying to use shader"
| SamplerUniform(name, data) ->
let location = glGetUniformLocation shader.Id name
glUniform1i location data
)
uniforms |> ignore

static member Draw<'T> (config:Config<'T>) (viewMatrix:System.Numerics.Matrix4x4) (projectionMatrix:System.Numerics.Matrix4x4) (primitive:ShadedObject) (uniforms) =
match primitive with
| Quad(context, shader, transform, width, height) ->
let all_uniforms =
match context.Texture with
| 0u -> uniforms
| _ -> [
SamplerUniform(
"in_texture",
0
)
] @ uniforms
ShadedObject.UseMvpShader
config
shader
Expand All @@ -323,12 +348,13 @@ type ShadedObject =
config.DisplayConfig.Height |> single
)
);
] @ uniforms )
] @ all_uniforms )

match context.Texture with
| Some texture ->
glBindTexture GL_TEXTURE_2D texture
| None -> ()
| 0u -> ()
| _ ->
glActiveTexture GL_TEXTURE0
glBindTexture GL_TEXTURE_2D context.Texture
glBindVertexArray context.VAO
glBindBuffer
GL_ELEMENT_ARRAY_BUFFER
Expand Down
33 changes: 33 additions & 0 deletions src/Womb/Graphics/Types.fs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
module Womb.Graphics.Types

#nowarn "9" // unverifiable IL due to NativePtr library usage

open Microsoft.FSharp.NativeInterop

open SDL2Bindings
open Womb.Lib.Types
open Womb.Logging

type DisplayConfig =
{ Width: uint;
Expand Down Expand Up @@ -48,3 +53,31 @@ type Uniform =
| UVector3Uniform of Name:string * Data:UVector3
| UVector4Uniform of Name:string * Data:UVector4
| UVectorUniform of Name:string * Data:array<uint>
| SamplerUniform of Name:string * Data:IVector1

type Texture2D =
{ Surface: option<nativeptr<SDL.SDL_Surface>>;
Width: int;
Height: int;
Data: voidptr;
Format: nativeint; }

static member Default() =
{ Surface = None
Width = 0
Height = 0
Data = 0n.ToPointer()
Format = 0n }

static member FromPath path =
let surfacePtr = Image.IMG_Load(path)
if NativePtr.isNullPtr surfacePtr then
fail $"Failed to load surface from path - {path}"
Texture2D.Default()
else
let surface = NativePtr.get surfacePtr 0
{ Surface = Some surfacePtr
Width = surface.w
Height = surface.h
Data = surface.pixels.ToPointer()
Format = surface.format }

0 comments on commit 5b0ca19

Please sign in to comment.