Direct3D9 wrapper for Go.

Related tags

Images tools d3d9
Overview

d3d9

This library is a pure Go wrapper for Microsoft's Direct3D9 API.

Games

Here you can see the library in action, it was used for two 48 hour game jams.

This is my entry to the GopherGala 2016:

Gophette Screenshot

And here is my entry for the Ludum Dare Game Jam 2016:

Reinventing the Wheel Screenshot

Installation

Get and build the library with:

go get -u github.com/gonutz/d3d9

To run a Direct3D9 application you need to have d3d9.dll installed on your system. Luckily, all Windows versions starting with Windows XP have this pre-installed. This means that you will not need to ship any additional DLL with your application when using this library.

Obsolete CGo Version 1

This library does not use CGo anymore. With this change the API has incompatibly changed in some places. If you have a project using the old API and do not want to update everything right now, you can use a copy of version 1.0.0 of this library at github.com/gonutz/cgo/d3d9. All you have to do is go get that library and update your imports from github.com/gonutz/d3d9 to github.com/gonutz/cgo/d3d9.

Usage

All Direct3D9 interfaces are translated to Go types and their methods are translated to functions on the types so the usage is very close to the C++ API.

There are some differences in the names in Go, since the package is named d3d9, all names in that package drop the D3D and 9 parts because they would be redundant. The changes are:

  • Interfaces drop the IDirect3D prefix and the 9 suffix, e.g. IDirect3DDevice9 becomes d3d9.Device. The only exception is IDirect3D9 which in Go becomes Direct3D.
  • Constants and enumerations drop the D3D prefix, otherwise they are the same and keep the upper case convention so users of Direct3D can easily find what they are looking for. For example D3DADAPTER_DEFAULT becomes d3d9.ADAPTER_DEFAULT, D3DFMT_R8G8B8 becomes d3d9.FMT_R8G8B8 etc.
  • Structs, like constants, only drop the D3D prefix, they too keep the upper case naming convention, so D3DRANGE becomes d3d9.RANGE.
  • Error constants also drop the D3D prefix so D3DERR_OUTOFVIDEOMEMORY becomes ERR_OUTOFVIDEOMEMORY. However, the interface functions do not return these constants, they return Go errors instead of HRESULTs.
  • Instead of returning HRESULT, functions return d3d9.Error which implements the standard Go error interface and has an additional function Code() int32 which returns the error code. This code can be checked against the defined error constants. If a function succeeds it returns nil (and not D3D_OK) as the d3d9.Error.

Note that Direct3D9 needs a window handle for setting it up. This means that you need some way to create a native window and get the handle to pass it to d3d9. In the samples you can see how to do it using the SDL2 Go wrapper and Allen Dang's w32. You could also use other Windows wrapper libraries, like the walk library, or just write a little CGo code to set up a window yourself. This library does not provide window creation or event handling functionality, only the Direct3D9 wrapper.

All calls to Direct3D9 must happen from the same thread that creates the Direct3D9 object so make sure to add this code in your main package:

func init() {
    runtime.LockOSThread()
}

There are some additional convenience functions. IndexBuffer and VertexBuffer have Lock functions which return void* pointers in the C API and would thus return uintptrs in Go. You can use these pointers to read and write various types from/to that memory. However, using uintptr or unsafe.Pointer is not idiomatic Go so the Lock functions return a wrapper around the uintptr instead, providing functions of the form GetFloat32s and SetFloat32s which take a slice of []float32 and handle copying the data for you. See the documentation of these functions for further information.

Similarly, when locking a two-dimensional resource, like a texture, you will get a d3d9.LOCKED_RECT. It too has a wrapper function for setting its 2D data. There is however no function to read the data, yet, and no functions for reading and writing sub-rectangles which could be useful. These functions can be added when needed by a real application to see the use case first and implement the functions according to that instead of guessing what might work. If you need such a function, create a pull request or an issue and it can be incorporated in this library.

Documentation

See the GoDoc for the Go API. The functions are only documented very generally, to get more detailed information about the Direct3D9 API see the MSDN documentation.

Examples

The samples folder contains some example programs that show the basics of setting up and using the library.

A real world usage of this library is my entry to the GopherGala 2016. It was first built using SDL2 and after the competition I ported it to DirectX, see main_windows.go for the implementation.

Another real world example is my entry for the Ludum Dare Game Jam 2016 which is Windows only.

The prototype library also uses d3d9 on Windows.

Status

The code started out as a rough version generated from the MSDN online documentation and was then manually refined to work well with Go and its conventions. It wraps the whole Direct3D9 API right now and adds some additional convenience functions for easy Go usage. However, LOCKED_RECT only has one function for setting the whole data rectangle at once, there is no simple way to set only sub-rectangles right now. Similarly the CubeTexture's LOCKED_BOX has no wrapper functions for getting and setting its data, yet. For now the raw uintptr memory pointers can be used along with the pitch values and in the future such functions can be added when needed.

Help improve this library

Only real world use and feedback can improve the usability of this library, so please use it, fork it, send pull requests and create issues to help improve this library.

Comments
  • panic: calling Direct3DCreate9: The specified program requires a newer version of Windows.

    panic: calling Direct3DCreate9: The specified program requires a newer version of Windows.

    Hello. Really glad somebody decided to do this, this will probably be priceless for me.

    I tried to compile samples\rotating_quad, it compiled, but it gives me this error:

    panic: calling Direct3DCreate9: The specified program requires a newer version of Windows.
    
    goroutine 1 [running, locked to thread]:
    panic(0x514200, 0x12840110)
        C:/Go/src/runtime/panic.go:464 +0x326
    main.check(0x25a0018, 0x12840110)
        C:/Users/User/GoPath/src/github.com/gonutz/d3d9/samples/rotating_quad/main.go:123 +0x44
    main.main()
        C:/Users/User/GoPath/src/github.com/gonutz/d3d9/samples/rotating_quad/main.go:33 +0x1d8
    

    I'm on windows 7, and I'm really puzzled by necessity of using anything newer for just calling a dll. Can you give me a hint on what to do? I'm ready to test anything for as long as it will take.

    Probably this will work if this program would use syscall.NewLazyDLL or syscall.MustLoadDLL instead of syscall.Syscall, at least I was told so. Here are a few links:

    http://noypi-linux.blogspot.ru/2012/04/golang-using-shared-libraries.html Method 1 from here

    https://github.com/golang/go/wiki/WindowsDLLs Example two from here

    http://stackoverflow.com/questions/22949444/using-go-golang-to-get-windows-idle-time-getlastinputinfo-or-similar

    https://golang.org/src/syscall/dll_windows.go

    opened by mzbab88 32
  • Not an issue: drawing using vertex buffers?

    Not an issue: drawing using vertex buffers?

    I'm trying to make a window, and draw a rectangle in it without using shaders. I want to use Vertex Buffers, but I failed to do so.

    here's my code

    package main
      
      import (
          "syscall"
          "time"
      
          "github.com/gonutz/d3d9"
          "github.com/gonutz/w32/v2"
      )
      
      type Vertex struct {
          X, Y, Z, RHW float32
          Color        d3d9.COLOR
      }
      
      func main() {
          className := "test"
          instance := w32.GetModuleHandle("")
      
          w32.RegisterClassEx(&w32.WNDCLASSEX{
    	      ClassName:  syscall.StringToUTF16Ptr(className),
    	      Background: w32.CreateSolidBrush(RGB(255, 255, 255)),
    	      WndProc:    syscall.NewCallback(EventHandler),
    	      Instance:   instance,
          })
      
          window := w32.CreateWindowStr(className, "test", w32.WS_VISIBLE|w32.WS_OVERLAPPEDWINDOW,
    	      w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, 640, 480, 0, 0, instance, nil)
      
          d3d, err := d3d9.Create(d3d9.SDK_VERSION)
          check(err)
          defer d3d.Release()
      
          device, _, err := d3d.CreateDevice(
    	      d3d9.ADAPTER_DEFAULT,
    	      d3d9.DEVTYPE_HAL,
    	      d3d9.HWND(window),
    	      d3d9.CREATE_HARDWARE_VERTEXPROCESSING,
    	      d3d9.PRESENT_PARAMETERS{
    		      Windowed:                   1,
    		      SwapEffect:                 d3d9.SWAPEFFECT_DISCARD,
    		      HDeviceWindow:              d3d9.HWND(window),
    		      BackBufferWidth:            640,
    		      BackBufferHeight:           480,
    		      BackBufferFormat:           d3d9.FMT_X8R8G8B8,
    		      BackBufferCount:            0,
    		      MultiSampleType:            d3d9.MULTISAMPLE_NONE,
    		      MultiSampleQuality:         0,
    		      EnableAutoDepthStencil:     0,
    		      AutoDepthStencilFormat:     d3d9.FMT_UNKNOWN,
    		      FullScreen_RefreshRateInHz: 0,
    		      PresentationInterval:       0,
    	      })
          check(err)
          defer device.Release()
      
          const customFVF = d3d9.FVF_XYZRHW | d3d9.FVF_DIFFUSE
          const vertexSize = 16 //4*3+4
      
          vertecies := [...]Vertex{
    	      {400, 50, 0.5, 1, d3d9.ColorXRGB(0, 0, 255)},
    	      {100, 500, 0.5, 1, d3d9.ColorXRGB(0, 255, 0)},
    	      {700, 500, 0.5, 1, d3d9.ColorXRGB(255, 0, 0)},
          }
      
          buffer, err := device.CreateVertexBuffer(uint(3*vertexSize), 0,
    	      customFVF, d3d9.POOL_MANAGED, 0)
          check(err)
          defer buffer.Release()
      
          data, err := buffer.Lock(0, 0, 0)
          check(err)
      
          for i, vertex := range vertecies {
    	      data.SetFloat32s(i*int(vertexSize),
    		      []float32{
    			      vertex.X,
    			      vertex.Y,
    			      vertex.RHW,
    		      })
    	      offset := i*int(vertexSize) + 12
    	      data.SetUint32s(offset, []uint32{uint32(vertex.Color)})
          }
          err = buffer.Unlock()
          check(err)
      
          device.Clear(nil, d3d9.CLEAR_TARGET, d3d9.ColorXRGB(0, 0, 0), 1, 0)
          device.BeginScene()
          device.SetFVF(customFVF)
          device.SetStreamSource(0, buffer, 0, uint(vertexSize))
          device.DrawPrimitive(d3d9.PT_TRIANGLELIST, 0, 1)
          device.EndScene()
          device.Present(nil, nil, 0, nil)
      
          time.Sleep(5 * time.Second)
      
      }
      
      func check(err error) {
          if err != nil {
    	      panic(err)
          }
      }
      
      func EventHandler(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) uintptr {
          switch msg {
          case 0x0010: //close
    	      w32.DestroyWindow(w32.HWND(hwnd))
          case 0x0002: //destroy
    	      w32.PostQuitMessage(0)
          default:
    	      ret := w32.DefWindowProc(w32.HWND(hwnd), msg, wparam, lparam)
    	      return ret
          }
          return 0
      }
      
      func RGB(r, g, b uint8) uint32 {
          return uint32(r) | uint32(g)<<8 | uint32(b)<<16
      }
    
    opened by mrg0lden 12
  • I want to make a generic DirectX screenshot tool with d3d9

    I want to make a generic DirectX screenshot tool with d3d9

    I would like to make a generic DirectX screenshot tool with d3d9. But I'm not really sure how to go about implementing it. I found an example of a screenshot tool for C++. https://github.com/broija/d3dscreencapture/blob/93f936e4f511204d9398e49f7609babb7a98d270/d3dcapture.cpp#L109 But I ran into a bottleneck when converting to Go. I don't know how to continue.I don't know how to convert lockedRect.Pitch to Go type and write it to image. Here is my code.

            // ... omitting the device binding
    
    	err=device.GetFrontBufferData(0,&surface)
    	if err!=nil{
    		fmt.Printf("获取surface前景数据出错了:%s",err)
    		return
    	}
    
    	surface_desc,err:=surface.GetDesc()
    	if err!=nil{
    		fmt.Printf("获取surface_desc出错了:%s",err)
    		return
    	}
    
    	//var d3dlockedRect d3d9.RECT
    	// rect  is NULL ,Coverage of the entire region
    	lockedRect,err:=surface.LockRect(nil,0)
    	if err!=nil{
    		fmt.Printf("获取lockedRect出错了:%s",err)
    		return
    	}
    
    	img:=image.NewNRGBA(image.Rect(0,0,int(surface_desc.Width),int(surface_desc.Height)))
    	
    

    I need some help, thanks!

    opened by sirodeneko 9
  • cannot use flag (type uint32) as type uintptr in argument to procRedrawWindow.Call

    cannot use flag (type uint32) as type uintptr in argument to procRedrawWindow.Call

    Hi. I am trying to build on Windows 10.

    go\src\github.com\gonutz\d3d9\samples\fullscreen>go get -u github.com/AllenDang/gform

    github.com/AllenDang/w32

    ........\AllenDang\w32\user32.go:1039:10: cannot use flag (type uint32) as type uintptr in argument to procRedrawWindow.Call

    go env set GO111MODULE= set GOARCH=amd64 set GOBIN= set GOCACHE=C:\Users\Worker\AppData\Local\go-build set GOENV=C:\Users\Worker\AppData\Roaming\go\env set GOEXE=.exe set GOFLAGS= set GOHOSTARCH=amd64 set GOHOSTOS=windows set GOINSECURE= set GOMODCACHE=C:\Users\Worker\go\pkg\mod set GONOPROXY= set GONOSUMDB= set GOOS=windows set GOPATH=C:\Users\Worker\go set GOPRIVATE= set GOPROXY=https://proxy.golang.org,direct set GOROOT=c:\go set GOSUMDB=sum.golang.org set GOTMPDIR= set GOTOOLDIR=c:\go\pkg\tool\windows_amd64 set GCCGO=gccgo set AR=ar set CC=gcc set CXX=g++ set CGO_ENABLED=1 set GOMOD= set CGO_CFLAGS=-g -O2 set CGO_CPPFLAGS= set CGO_CXXFLAGS=-g -O2 set CGO_FFLAGS=-g -O2 set CGO_LDFLAGS=-g -O2 set PKG_CONFIG=pkg-config set GOGCCFLAGS=-m64 -mthreads -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=C:\Users\Worker\AppData\Local\Temp\go-build907535614=/tmp/go-build -gno-record-gcc-switches

    go version go version go1.15.2 windows/amd64

    opened by advancedwebdeveloper 7
  • Surface.LockRect -> Invalid call

    Surface.LockRect -> Invalid call

    I got error when use lockrect from backbuffer surface:

    var rc d3d9.RECT
    surface, err := device.GetBackBuffer(0, 0, d3d9.BACKBUFFER_TYPE_MONO)
    defer surface.Release()
    lockedRect, err := surface.LockRect(&rc, 0)
    ... err here.
    
    opened by namkazt 4
  • cannot use flag (type uint32) as type uintptr in argument to procRedrawWindow.Call

    cannot use flag (type uint32) as type uintptr in argument to procRedrawWindow.Call

    I wouldn't be too verbose, this time. I have cleaned up all packages ("src", "pkg","bin) and installed your package (and all dependencies) as expected.

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>build_all.bat

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>REM see README.md for how to use this script

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>set FXC="C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe"

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe" /WX /T vs_2_0 /Fo vs.object vs.code Системе не удается найти указанный путь.

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>"C:\Program Files (x86)\Windows Kits\8.1\bin\x86\fxc.exe" /WX /T ps_2_0 /Fo ps.object ps.code Системе не удается найти указанный путь.

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>go get github.com/gonutz/bin2go

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>bin2go -s -v vso -o vso.go vs.object

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>bin2go -s -v pso -o pso.go ps.object

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>go build -ldflags -H=windowsgui main.go:7:2: cannot find package "github.com/AllenDang/gform" in any of: c:\go\src\github.com\AllenDang\gform (from $GOROOT) C:\Users\Worker\go\src\github.com\AllenDang\gform (from $GOPATH)

    C:\Users\Worker\go\src\github.com\gonutz\d3d9\samples\rotating_quad>go get -u github.com/AllenDang/gform

    github.com/AllenDang/w32

    ........\AllenDang\w32\user32.go:1039:10: cannot use flag (type uint32) as type uintptr in argument to procRedrawWindow.Call

    opened by advancedwebdeveloper 1
  • Window client size is incorrect due not using AdjustWindowRect

    Window client size is incorrect due not using AdjustWindowRect

    The problem

    When you create a window using the Win32 API, it assumes you're giving the width / height including border sizes. This means when you create a window, it ends up being off by a few pixels or so.

    image The above is a screenshot of the static_triangle sample. The size here is: 624x441 not the expected 640x480.

    Found the solution via this stack overflow answer:

    • https://stackoverflow.com/questions/4843806/winapi-create-a-window-with-a-specified-client-area-size
    • https://stackoverflow.com/a/25879124/5013410

    The solution

    Examples should be updated to make this API call so that the client window size is correct. If we do that, then the window will be correct.

    image Size of this image is 640x480

    opened by silbinarywolf 1
Owner
null
A golang wrapper module to interact with `fit-statUSB` device over serial.

go-fitstatusb A golang wrapper module to interact with fit-statUSB device over serial. This is experimental at best, not ready for production. Backgro

Nicholas Granado 0 Feb 4, 2022
Go-video-preview-ffmpeg-wrapper - A simple helper wrapper to generate small webm video previews using ffmpeg, useful for web previews.

Go-video-preview-ffmpeg-wrapper A simple helper wrapper to generate small webm video previews using ffmpeg, useful for web previews. Getting Started u

Robert van Alphen 0 Jan 5, 2022
Via Cep Wrapper is a api wrapper used to find address by zipcode (Brazil only)

Viacep Wrapper Viacep Wrapper is an API wrapper built with Golang used to find address by zipcode (Brazil only). This project was developed for study

PATRICK SEGANTINE 1 Jan 25, 2022
Golang telegram bot API wrapper, session-based router and middleware

go-tgbot Pure Golang telegram bot API wrapper generated from swagger definition, session-based routing and middlewares. Usage benefits No need to lear

Oleg Lebedev 118 Nov 16, 2022
JSON or YAML configuration wrapper with convenient access methods.

Config Package config provides convenient access methods to configuration stored as JSON or YAML. This is a fork of the original version. This version

Oleg Lebedev 260 Dec 16, 2022
Go wrapper for LZO compression library

This is a cgo wrapper around the LZO real-time compression library. LZO is available at http://www.oberhumer.com/opensource/lzo/ lzo.go is the go pack

Damian Gryski 13 Mar 4, 2022
An easy-to-use XChaCha20-encryption wrapper for io.ReadWriteCloser (even lossy UDP) using ECDH key exchange algorithm, ED25519 signatures and Blake3+Poly1305 checksums/message-authentication for Go (golang). Also a multiplexer.

Quick start Prepare keys (on both sides): [ -f ~/.ssh/id_ed25519 ] && [ -f ~/.ssh/id_ed25519.pub ] || ssh-keygen -t ed25519 scp ~/.ssh/id_ed25519.pub

null 26 Dec 30, 2022
A light libxml wrapper for Go

Gokogiri LibXML bindings for the Go programming language. By Zhigang Chen and Hampton Catlin This is a major rewrite from v0 in the following places:

Moovweb 593 Dec 27, 2022
goxml - A thin wrapper around libxml2

golibxml golibxml is a simple wrapper for libxml. The goal is to avoid any extra magic so that a more friendly library can be written to sit on top of

Joshua Bussdieker 11 Oct 25, 2020
levigo is a Go wrapper for LevelDB

levigo levigo is a Go wrapper for LevelDB. The API has been godoc'ed and is available on the web. Questions answered at [email protected].

Jeff Hodges 412 Jan 5, 2023
Database wrapper that manage read write connections

rwdb Database wrapper that manage read write connections Install go get github.com/andizzle/rwdb Create connections package main import "github.com/

Andy Zhang 17 Dec 10, 2022
A simple wrapper around sql.DB to help with structs. Not quite an ORM.

go-modeldb A simple wrapper around sql.DB to help with structs. Not quite an ORM. Philosophy: Don't make an ORM Example: // Setup require "modeldb" db

Jae Kwon 17 Nov 16, 2019
levigo is a Go wrapper for LevelDB

levigo levigo is a Go wrapper for LevelDB. The API has been godoc'ed and is available on the web. Questions answered at [email protected].

Jeff Hodges 412 Jan 5, 2023
Golang wrapper for Exiftool : extract as much metadata as possible (EXIF, ...) from files (pictures, pdf, office documents, ...)

go-exiftool go-exiftool is a golang library that wraps ExifTool. ExifTool's purpose is to extract as much metadata as possible (EXIF, IPTC, XMP, GPS,

null 154 Dec 28, 2022
Go (golang) wrapper for GDAL, the Geospatial Data Abstraction Library

------------- About ------------- The gdal.go package provides a go wrapper for GDAL, the Geospatial Data Abstraction Library. More information about

null 236 Dec 24, 2022
Go wrapper for taglib

go-taglib Go wrapper for taglib Dependencies You must have the static taglib libraries installed in order to compile go-taglib. OSX: brew install tagl

Trevor Olson 81 Dec 18, 2022
Go wrapper around the Iup GUI toolset

Iup Go Wrapper iup is a Go wrapper around the Iup GUI toolkit. The project was started on April 27, 2011. Fork https://github.com/grd/iup is a fork of

grd 24 Nov 28, 2020
Go Wrapper for the wxWidgets GUI

This is the source code for wxGo a Go wrapper of the wxWidgets library. The actuall wxWidgets source code is not included and will need to be downloa

Jeroen Dirks 58 Nov 30, 2022
A simple wrapper around libpcap for the Go programming language

PCAP This is a simple wrapper around libpcap for Go. Originally written by Andreas Krennmair [email protected] and only minorly touched up by Mark Smith

Andreas Krennmair 460 Dec 5, 2022
A protoc-gen-go wrapper including an RPC stub generator

// Copyright 2013 Google. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE fi

Kyle Lemons 37 Nov 17, 2022