get textures halfway working
This commit is contained in:
parent
1714facb11
commit
e3be56ab6c
8 changed files with 136 additions and 31 deletions
|
@ -24,8 +24,11 @@ executable renderer-tutorial
|
||||||
, OpenGLRaw
|
, OpenGLRaw
|
||||||
, sdl2 >= 2.5.0.0
|
, sdl2 >= 2.5.0.0
|
||||||
, bytestring
|
, bytestring
|
||||||
|
, vector
|
||||||
|
, linear
|
||||||
, monad-loops
|
, monad-loops
|
||||||
, random
|
, random
|
||||||
|
, JuicyPixels
|
||||||
other-modules: BindableClass
|
other-modules: BindableClass
|
||||||
, BufferClass
|
, BufferClass
|
||||||
, VertexBuffer
|
, VertexBuffer
|
||||||
|
@ -33,5 +36,6 @@ executable renderer-tutorial
|
||||||
, IndexBuffer
|
, IndexBuffer
|
||||||
, Shader
|
, Shader
|
||||||
, Renderer
|
, Renderer
|
||||||
|
, Texture
|
||||||
hs-source-dirs: src
|
hs-source-dirs: src
|
||||||
default-language: Haskell2010
|
default-language: Haskell2010
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
out vec4 color;
|
layout(location = 0) out vec4 color;
|
||||||
|
|
||||||
|
in vec2 v_texCoord;
|
||||||
|
|
||||||
uniform vec4 u_color;
|
uniform vec4 u_color;
|
||||||
|
uniform sampler2D u_texture;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
color = u_color;
|
vec4 texColor = texture(u_texture, v_texCoord);
|
||||||
|
color = texColor;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
#version 330 core
|
#version 330 core
|
||||||
|
|
||||||
layout(location = 0) in vec4 position;
|
layout(location = 0) in vec3 position;
|
||||||
|
layout(location = 1) in vec2 texCoord;
|
||||||
|
|
||||||
|
out vec2 v_texCoord;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_Position = position;
|
gl_Position = position;
|
||||||
|
v_texCoord = texCoord;
|
||||||
}
|
}
|
||||||
|
|
BIN
res/textures/lynx.jpg
Normal file
BIN
res/textures/lynx.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 227 KiB |
|
@ -4,17 +4,18 @@ let
|
||||||
|
|
||||||
inherit (nixpkgs) pkgs;
|
inherit (nixpkgs) pkgs;
|
||||||
|
|
||||||
f = { mkDerivation, base, bytestring, monad-loops, OpenGL
|
f = { mkDerivation, base, bytestring, JuicyPixels, linear
|
||||||
, OpenGLRaw, random, sdl2, stdenv
|
, monad-loops, OpenGL, OpenGLRaw, random, sdl2, stdenv, vector
|
||||||
}:
|
}:
|
||||||
mkDerivation {
|
mkDerivation {
|
||||||
pname = "renderer";
|
pname = "renderer-tutorial";
|
||||||
version = "0.0.0.0";
|
version = "0.0.0.0";
|
||||||
src = ./.;
|
src = ./.;
|
||||||
isLibrary = false;
|
isLibrary = false;
|
||||||
isExecutable = true;
|
isExecutable = true;
|
||||||
executableHaskellDepends = [
|
executableHaskellDepends = [
|
||||||
base bytestring monad-loops OpenGL OpenGLRaw random sdl2
|
base bytestring JuicyPixels linear monad-loops OpenGL OpenGLRaw
|
||||||
|
random sdl2 vector
|
||||||
];
|
];
|
||||||
license = stdenv.lib.licenses.gpl3;
|
license = stdenv.lib.licenses.gpl3;
|
||||||
};
|
};
|
||||||
|
|
41
src/Main.hs
41
src/Main.hs
|
@ -38,6 +38,7 @@ import VertexBuffer
|
||||||
import IndexBuffer
|
import IndexBuffer
|
||||||
import Shader
|
import Shader
|
||||||
import Renderer
|
import Renderer
|
||||||
|
import Texture
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
main = do
|
main = do
|
||||||
|
@ -80,12 +81,14 @@ main = do
|
||||||
vao <- GL.genObjectName
|
vao <- GL.genObjectName
|
||||||
GL.bindVertexArrayObject $= Just vao
|
GL.bindVertexArrayObject $= Just vao
|
||||||
|
|
||||||
-- define vertices (positions of the triangle corners) as List of Floats
|
-- define vertices (positions of the rectangle corners) as List of Floats
|
||||||
|
-- with added in texture coordinates
|
||||||
let vertexPositions =
|
let vertexPositions =
|
||||||
[ (-0.5), (-0.5) -- 0
|
-- 3D positions | texture coordinates
|
||||||
, 0.5 , (-0.5) -- 1
|
[ (-0.5), (-0.5), 0, 0, 0 -- 0
|
||||||
, 0.5 , 0.5 -- 2
|
, 0.5 , (-0.5), 0, 1, 0 -- 1
|
||||||
, (-0.5), 0.5 -- 3
|
, 0.5 , 0.5 , 0, 1, 1 -- 2
|
||||||
|
, (-0.5), 0.5 , 0, 0, 1 -- 3
|
||||||
] :: [GL.GLfloat]
|
] :: [GL.GLfloat]
|
||||||
|
|
||||||
-- create draw order indices
|
-- create draw order indices
|
||||||
|
@ -100,23 +103,18 @@ main = do
|
||||||
|
|
||||||
-- enable and specify data layout of the in-memory vertices
|
-- enable and specify data layout of the in-memory vertices
|
||||||
layout <- newVertexBufferLayout
|
layout <- newVertexBufferLayout
|
||||||
|
-- push vertex positions
|
||||||
|
pushElements layout GL.Float 3
|
||||||
|
-- pusht texture coordinates
|
||||||
pushElements layout GL.Float 2
|
pushElements layout GL.Float 2
|
||||||
|
|
||||||
addBuffer vao vbo layout
|
addBuffer vao vbo layout
|
||||||
|
|
||||||
-- GL.vertexAttribPointer (GL.AttribLocation 0) $=
|
-- -- TEXTURE
|
||||||
-- ( GL.ToFloat
|
|
||||||
-- , GL.VertexArrayDescriptor
|
-- generate and bind texture
|
||||||
-- -- There are 2 components (Floats) to our attribute
|
tex <- newTexture "res/textures/lynx.jpg" 0
|
||||||
-- 2
|
bind tex
|
||||||
-- -- They are Floats
|
|
||||||
-- GL.Float
|
|
||||||
-- -- ???
|
|
||||||
-- 0
|
|
||||||
-- -- our attribute is directly at the beginning of each vertex
|
|
||||||
-- (plusPtr nullPtr 0)
|
|
||||||
-- )
|
|
||||||
-- GL.vertexAttribArray (GL.AttribLocation 0) $= GL.Enabled
|
|
||||||
|
|
||||||
-- construct new IndexBuffer and fill it with data
|
-- construct new IndexBuffer and fill it with data
|
||||||
ibo <- newIndexBuffer indices
|
ibo <- newIndexBuffer indices
|
||||||
|
@ -128,8 +126,13 @@ main = do
|
||||||
, ShaderSource GL.FragmentShader "./res/shaders/frag.shader"
|
, ShaderSource GL.FragmentShader "./res/shaders/frag.shader"
|
||||||
]
|
]
|
||||||
[ "u_color"
|
[ "u_color"
|
||||||
|
, "u_texture"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
-- -- tell the shader where to find the texture
|
||||||
|
bind sp
|
||||||
|
setUniform sp "u_texture" (texSlot tex)
|
||||||
|
|
||||||
-- -- UNIFORMS
|
-- -- UNIFORMS
|
||||||
|
|
||||||
-- create MVars for pulsating red channel
|
-- create MVars for pulsating red channel
|
||||||
|
@ -143,7 +146,7 @@ main = do
|
||||||
|
|
||||||
-- -- UNBINDING ALL BUFFERS AND VERTEX ARRAYS
|
-- -- UNBINDING ALL BUFFERS AND VERTEX ARRAYS
|
||||||
|
|
||||||
GL.bindVertexArrayObject $= Nothing
|
unbind vao
|
||||||
unbind vbo
|
unbind vbo
|
||||||
unbind ibo
|
unbind ibo
|
||||||
unbind sp
|
unbind sp
|
||||||
|
|
88
src/Texture.hs
Normal file
88
src/Texture.hs
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
module Texture where
|
||||||
|
|
||||||
|
import SDL (($=), get)
|
||||||
|
|
||||||
|
import qualified Graphics.Rendering.OpenGL as GL
|
||||||
|
|
||||||
|
import Codec.Picture
|
||||||
|
|
||||||
|
import Data.Either
|
||||||
|
|
||||||
|
import Data.Vector.Storable as VS
|
||||||
|
|
||||||
|
import Foreign.Ptr
|
||||||
|
import Foreign.Marshal.Alloc (free)
|
||||||
|
|
||||||
|
import Linear
|
||||||
|
|
||||||
|
-- internal imports
|
||||||
|
|
||||||
|
import BindableClass
|
||||||
|
|
||||||
|
data Texture = Texture
|
||||||
|
{ texId :: GL.TextureObject
|
||||||
|
, texSlot :: GL.TextureUnit
|
||||||
|
, texPath :: FilePath
|
||||||
|
, texDimensions :: V2 GL.GLsizei
|
||||||
|
, texBPP :: Int
|
||||||
|
, texData :: Ptr ()
|
||||||
|
}
|
||||||
|
|
||||||
|
instance Bindable Texture where
|
||||||
|
|
||||||
|
bind t = do
|
||||||
|
GL.activeTexture $= texSlot t
|
||||||
|
GL.textureBinding GL.Texture2D $= Just (texId t)
|
||||||
|
|
||||||
|
unbind _ = GL.textureBinding GL.Texture2D $= Nothing
|
||||||
|
|
||||||
|
newTexture :: FilePath -> GL.GLuint -> IO Texture
|
||||||
|
newTexture fp slot = do
|
||||||
|
|
||||||
|
-- read in image from filesystem
|
||||||
|
img <- convertRGBA8 <$>
|
||||||
|
either (error $ "reading image file " <> fp <> " failed!") id <$>
|
||||||
|
readImage fp
|
||||||
|
|
||||||
|
-- extract the raw pointer from vector
|
||||||
|
unsafeWith (imageData img) $ \ptr -> do
|
||||||
|
-- create texture object
|
||||||
|
tex <- Texture
|
||||||
|
<$> GL.genObjectName
|
||||||
|
<*> (pure $ GL.TextureUnit slot)
|
||||||
|
<*> (pure fp)
|
||||||
|
<*> (pure $ fmap fromIntegral $ V2 (imageWidth img) (imageHeight img))
|
||||||
|
<*> (pure $ componentCount (VS.head $ imageData img))
|
||||||
|
<*> (pure $ castPtr ptr)
|
||||||
|
|
||||||
|
-- bind texture
|
||||||
|
bind tex
|
||||||
|
|
||||||
|
-- set texture parameters
|
||||||
|
GL.textureFilter GL.Texture2D $= ((GL.Linear', Nothing), GL.Linear')
|
||||||
|
GL.textureWrapMode GL.Texture2D GL.S $= (GL.Repeated, GL.Clamp)
|
||||||
|
GL.textureWrapMode GL.Texture2D GL.T $= (GL.Repeated, GL.Clamp)
|
||||||
|
|
||||||
|
-- put data into GPU memory
|
||||||
|
loadTexture tex
|
||||||
|
|
||||||
|
-- unbind texture
|
||||||
|
unbind tex
|
||||||
|
|
||||||
|
-- -- throw away the data on the CPU side
|
||||||
|
-- free (texData tex)
|
||||||
|
|
||||||
|
-- pass texture object out
|
||||||
|
return tex
|
||||||
|
|
||||||
|
loadTexture :: Texture -> IO ()
|
||||||
|
loadTexture tex =
|
||||||
|
let (V2 w h) = texDimensions tex
|
||||||
|
in GL.texImage2D
|
||||||
|
GL.Texture2D
|
||||||
|
GL.NoProxy
|
||||||
|
0
|
||||||
|
GL.RGBA'
|
||||||
|
(GL.TextureSize2D w h)
|
||||||
|
0
|
||||||
|
(GL.PixelData GL.RGBA GL.UnsignedByte (texData tex))
|
|
@ -60,11 +60,12 @@ addBuffer va vb layout = do
|
||||||
(\(index, elem) -> do
|
(\(index, elem) -> do
|
||||||
let offset = fromIntegral $
|
let offset = fromIntegral $
|
||||||
foldl
|
foldl
|
||||||
(\acc (index, _) -> acc + index )
|
(\acc (index, elem) -> acc + vbleCount elem)
|
||||||
0
|
0
|
||||||
(filter ((<= index) . fst) indexed) :: Int
|
(filter ((< index) . fst) indexed) :: Int
|
||||||
GL.vertexAttribArray (GL.AttribLocation index) $= GL.Enabled
|
GL.vertexAttribArray (GL.AttribLocation $ fromIntegral index) $=
|
||||||
GL.vertexAttribPointer (GL.AttribLocation index) $=
|
GL.Enabled
|
||||||
|
GL.vertexAttribPointer (GL.AttribLocation $ fromIntegral index) $=
|
||||||
( vbleHandling elem
|
( vbleHandling elem
|
||||||
, GL.VertexArrayDescriptor
|
, GL.VertexArrayDescriptor
|
||||||
-- number of components to our attribute
|
-- number of components to our attribute
|
||||||
|
@ -72,7 +73,7 @@ addBuffer va vb layout = do
|
||||||
-- datatype of elements
|
-- datatype of elements
|
||||||
(vbleType elem)
|
(vbleType elem)
|
||||||
-- ???
|
-- ???
|
||||||
0
|
(sum (map vbleCount list) * fromIntegral (dataElementSize (vbleType elem)))
|
||||||
-- offset from beginnning of vertex
|
-- offset from beginnning of vertex
|
||||||
(plusPtr nullPtr (offset * dataElementSize (vbleType elem)))
|
(plusPtr nullPtr (offset * dataElementSize (vbleType elem)))
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue