{- Vivant: Haskell OpenGL game. Copyright (C) 2020 Yann Herklotz This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. -} module Main where import Control.Monad import Foreign.C.Types import SDL.Vect import qualified Data.ByteString as BS import qualified Data.Vector.Storable as V import System.Exit (exitFailure) import System.IO import SDL (($=)) import qualified SDL import SDL.Time (ticks) import qualified Graphics.Rendering.OpenGL as GL import Paths_vivant (getDataDir) import Vivant.Shader (initShaders) screenWidth, screenHeight :: CInt (screenWidth, screenHeight) = (640, 480) main :: IO () main = do SDL.initialize [SDL.InitVideo] SDL.HintRenderScaleQuality $= SDL.ScaleLinear do renderQuality <- SDL.get SDL.HintRenderScaleQuality when (renderQuality /= SDL.ScaleLinear) $ putStrLn "Warning: Linear texture filtering not enabled!" window <- SDL.createWindow "SDL / OpenGL Example" SDL.defaultWindow {SDL.windowInitialSize = V2 screenWidth screenHeight, SDL.windowGraphicsContext = SDL.OpenGLContext SDL.defaultOpenGL} SDL.showWindow window _ <- SDL.glCreateContext window (prog, attrib) <- initShaders let loop = do events <- SDL.pollEvents let quit = elem SDL.QuitEvent $ map SDL.eventPayload events GL.clear [GL.ColorBuffer] draw prog attrib SDL.glSwapWindow window unless quit loop loop SDL.destroyWindow window SDL.quit draw :: GL.Program -> GL.AttribLocation -> IO () draw program attrib = do GL.clearColor $= GL.Color4 1 1 1 1 GL.clear [GL.ColorBuffer] GL.viewport $= (GL.Position 0 0, GL.Size (fromIntegral screenWidth) (fromIntegral screenHeight)) GL.currentProgram $= Just program ourColorLoc <- GL.uniformLocation program "ourColour" tick <- ticks GL.uniform ourColorLoc $= (GL.Vector4 (1::Float) (sin (fromIntegral tick / 500) / 2 + 0.5) 1 1) GL.vertexAttribArray attrib $= GL.Enabled V.unsafeWith vertices $ \ptr -> GL.vertexAttribPointer attrib $= (GL.ToFloat, GL.VertexArrayDescriptor 2 GL.Float 0 ptr) GL.drawArrays GL.Triangles 0 3 -- 3 is the number of vertices GL.vertexAttribArray attrib $= GL.Disabled vertices :: V.Vector Float vertices = V.fromList [ 0.0, 0.8 , -0.8, -0.8 , 0.8, -0.8 ] texCoords :: V.Vector Float texCoords = V.fromList [ 0, 0 , 1, 0 , 0.5, 1 ]