├── LICENSE ├── README.md ├── base_texture_windows.go ├── color_windows.go ├── constants_windows.go ├── cube_texture_windows.go ├── device_windows.go ├── direct3d9_windows.go ├── enums_windows.go ├── error_windows.go ├── go.mod ├── index_buffer_windows.go ├── macros_windows.go ├── pixel_shader_windows.go ├── query_windows.go ├── resource_windows.go ├── samples ├── display_info │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── main.go ├── fullscreen │ ├── README.md │ ├── build.bat │ ├── go.mod │ ├── go.sum │ └── main.go ├── glow │ ├── build.bat │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── readme.md ├── readme.md ├── rotating_quad │ ├── build.bat │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── readme.md ├── screenshot │ ├── README.md │ ├── go.mod │ ├── go.sum │ └── main.go └── static_triangle │ ├── build.bat │ ├── go.mod │ ├── go.sum │ ├── main.go │ └── readme.md ├── state_block_windows.go ├── surface_windows.go ├── swap_chain_windows.go ├── texture_windows.go ├── types_windows.go ├── vertex_buffer_windows.go ├── vertex_declaration_windows.go ├── vertex_shader_windows.go ├── volume_texture_windows.go └── volume_windows.go /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 gonutz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # d3d9 2 | This library is a pure Go wrapper for Microsoft's Direct3D9 API. 3 | 4 | # Games 5 | Here you can see the library in action, it was used for two 48 hour game jams. 6 | 7 | This is [my entry](https://github.com/gonutz/gophette) to the [GopherGala 2016](http://gophergala.com/): 8 | 9 | ![Gophette Screenshot](https://raw.githubusercontent.com/gonutz/gophette/master/screenshots/race.png) 10 | 11 | And here is [my entry](https://github.com/gonutz/ld36) for the [Ludum Dare Game Jam 2016](http://ludumdare.com/compo/ludum-dare-36/?action=preview&uid=110557): 12 | 13 | ![Reinventing the Wheel Screenshot](http://ludumdare.com/compo/wp-content/compo2//570486/110557-shot0-1472432554.png-eq-900-500.jpg) 14 | 15 | # Installation 16 | Get and build the library with: 17 | 18 | go get -u github.com/gonutz/d3d9 19 | 20 | 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. 21 | 22 | # Obsolete CGo Version 1 23 | 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](https://github.com/gonutz/cgo/tree/master/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`. 24 | 25 | # Usage 26 | 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. 27 | 28 | 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: 29 | 30 | - 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`. 31 | - 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. 32 | - Structs, like constants, only drop the `D3D` prefix, they too keep the upper case naming convention, so `D3DRANGE` becomes `d3d9.RANGE`. 33 | - 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 `error`s instead of `HRESULT`s. 34 | - 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. 35 | 36 | 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](https://github.com/veandco/go-sdl2) and [Allen Dang's w32](https://github.com/AllenDang/w32). You could also use other Windows wrapper libraries, like the [walk library](https://github.com/lxn/walk), 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. 37 | 38 | 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: 39 | 40 | func init() { 41 | runtime.LockOSThread() 42 | } 43 | 44 | There are some additional convenience functions. `IndexBuffer` and `VertexBuffer` have `Lock` functions which return `void*` pointers in the C API and would thus return `uintptr`s 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. 45 | 46 | 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. 47 | 48 | # Documentation 49 | See the [GoDoc](https://godoc.org/github.com/gonutz/d3d9) for the Go API. The functions are only documented very generally, to get more detailed information about the Direct3D9 API see the [MSDN documentation](https://msdn.microsoft.com/en-us/library/windows/desktop/bb172964%28v=vs.85%29.aspx). 50 | 51 | # Examples 52 | The samples folder contains some example programs that show the basics of setting up and using the library. 53 | 54 | A real world usage of this library is [my entry](https://github.com/gonutz/gophette) to the [GopherGala 2016](http://gophergala.com/). It was first built using SDL2 and after the competition I ported it to DirectX, see [`main_windows.go`](https://github.com/gonutz/gophette/blob/master/main_windows.go) for the implementation. 55 | 56 | Another real world example is [my entry](https://github.com/gonutz/ld36) for the [Ludum Dare Game Jam 2016](http://ludumdare.com/compo/ludum-dare-36/?action=preview&uid=110557) which is Windows only. 57 | 58 | The [prototype library](https://github.com/gonutz/prototype) also uses `d3d9` on Windows. 59 | 60 | # Status 61 | 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. 62 | 63 | # Help improve this library 64 | 65 | 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. 66 | -------------------------------------------------------------------------------- /base_texture_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // BaseTexture and its methods are used to manipulate texture resources 9 | // including cube and volume textures. 10 | type BaseTexture struct { 11 | vtbl *baseTextureVtbl 12 | } 13 | 14 | type baseTextureVtbl struct { 15 | QueryInterface uintptr 16 | AddRef uintptr 17 | Release uintptr 18 | 19 | GetDevice uintptr 20 | SetPrivateData uintptr 21 | GetPrivateData uintptr 22 | FreePrivateData uintptr 23 | SetPriority uintptr 24 | GetPriority uintptr 25 | PreLoad uintptr 26 | GetType uintptr 27 | SetLOD uintptr 28 | GetLOD uintptr 29 | GetLevelCount uintptr 30 | SetAutoGenFilterType uintptr 31 | GetAutoGenFilterType uintptr 32 | GenerateMipSubLevels uintptr 33 | } 34 | 35 | // AddRef increments the reference count for an interface on an object. This 36 | // method should be called for every new copy of a pointer to an interface on an 37 | // object. 38 | func (obj *BaseTexture) AddRef() uint32 { 39 | ret, _, _ := syscall.Syscall( 40 | obj.vtbl.AddRef, 41 | 1, 42 | uintptr(unsafe.Pointer(obj)), 43 | 0, 44 | 0, 45 | ) 46 | return uint32(ret) 47 | } 48 | 49 | // Release has to be called when finished using the object to free its 50 | // associated resources. 51 | func (obj *BaseTexture) Release() uint32 { 52 | ret, _, _ := syscall.Syscall( 53 | obj.vtbl.Release, 54 | 1, 55 | uintptr(unsafe.Pointer(obj)), 56 | 0, 57 | 0, 58 | ) 59 | return uint32(ret) 60 | } 61 | 62 | // GetDevice retrieves the device associated with a resource. 63 | // Call Release on the returned device when finished using it. 64 | func (obj *BaseTexture) GetDevice() (device *Device, err Error) { 65 | ret, _, _ := syscall.Syscall( 66 | obj.vtbl.GetDevice, 67 | 2, 68 | uintptr(unsafe.Pointer(obj)), 69 | uintptr(unsafe.Pointer(&device)), 70 | 0, 71 | ) 72 | err = toErr(ret) 73 | return 74 | } 75 | 76 | // SetPrivateData associates data with the resource that is intended for use by 77 | // the application, not by Direct3D. Data is passed by value, and multiple sets 78 | // of data can be associated with a single resource. 79 | func (obj *BaseTexture) SetPrivateData( 80 | refguid GUID, 81 | data uintptr, 82 | sizeOfData uint32, 83 | flags uint32, 84 | ) Error { 85 | ret, _, _ := syscall.Syscall6( 86 | obj.vtbl.SetPrivateData, 87 | 5, 88 | uintptr(unsafe.Pointer(obj)), 89 | uintptr(unsafe.Pointer(&refguid)), 90 | data, 91 | uintptr(sizeOfData), 92 | uintptr(flags), 93 | 0, 94 | ) 95 | return toErr(ret) 96 | } 97 | 98 | // SetPrivateDataBytes associates data with the resource that is intended for 99 | // use by the application, not by Direct3D. Data is passed by value, and 100 | // multiple sets of data can be associated with a single resource. 101 | func (obj *BaseTexture) SetPrivateDataBytes( 102 | refguid GUID, 103 | data []byte, 104 | flags uint32, 105 | ) Error { 106 | return obj.SetPrivateData( 107 | refguid, 108 | uintptr(unsafe.Pointer(&data[0])), 109 | uint32(len(data)), 110 | flags, 111 | ) 112 | } 113 | 114 | // GetPrivateData copies the private data associated with the resource to a 115 | // provided buffer. 116 | func (obj *BaseTexture) GetPrivateData(refguid GUID) (data []byte, err Error) { 117 | // first get the data size by passing nil as the data pointer 118 | var sizeInBytes uint 119 | ret, _, _ := syscall.Syscall6( 120 | obj.vtbl.GetPrivateData, 121 | 4, 122 | uintptr(unsafe.Pointer(obj)), 123 | uintptr(unsafe.Pointer(&refguid)), 124 | 0, 125 | uintptr(unsafe.Pointer(&sizeInBytes)), 126 | 0, 127 | 0, 128 | ) 129 | if err := toErr(ret); err != nil { 130 | return nil, err 131 | } 132 | data = make([]byte, sizeInBytes) 133 | ret, _, _ = syscall.Syscall6( 134 | obj.vtbl.GetPrivateData, 135 | 4, 136 | uintptr(unsafe.Pointer(obj)), 137 | uintptr(unsafe.Pointer(&refguid)), 138 | uintptr(unsafe.Pointer(&data[0])), 139 | uintptr(unsafe.Pointer(&sizeInBytes)), 140 | 0, 141 | 0, 142 | ) 143 | return data, toErr(ret) 144 | } 145 | 146 | // FreePrivateData frees the specified private data associated with this 147 | // resource. 148 | func (obj *BaseTexture) FreePrivateData(refguid GUID) Error { 149 | ret, _, _ := syscall.Syscall( 150 | obj.vtbl.FreePrivateData, 151 | 2, 152 | uintptr(unsafe.Pointer(obj)), 153 | uintptr(unsafe.Pointer(&refguid)), 154 | 0, 155 | ) 156 | return toErr(ret) 157 | } 158 | 159 | // SetPriority assigns the priority of a resource for scheduling purposes. 160 | func (obj *BaseTexture) SetPriority(priorityNew uint32) uint32 { 161 | ret, _, _ := syscall.Syscall( 162 | obj.vtbl.SetPriority, 163 | 2, 164 | uintptr(unsafe.Pointer(obj)), 165 | uintptr(priorityNew), 166 | 0, 167 | ) 168 | return uint32(ret) 169 | } 170 | 171 | // GetPriority retrieves the priority for this resource. 172 | func (obj *BaseTexture) GetPriority() uint32 { 173 | ret, _, _ := syscall.Syscall( 174 | obj.vtbl.GetPriority, 175 | 1, 176 | uintptr(unsafe.Pointer(obj)), 177 | 0, 178 | 0, 179 | ) 180 | return uint32(ret) 181 | } 182 | 183 | // PreLoad preloads a managed resource. 184 | func (obj *BaseTexture) PreLoad() { 185 | syscall.Syscall( 186 | obj.vtbl.PreLoad, 187 | 1, 188 | uintptr(unsafe.Pointer(obj)), 189 | 0, 190 | 0, 191 | ) 192 | } 193 | 194 | // GetType returns the type of the resource. 195 | func (obj *BaseTexture) GetType() RESOURCETYPE { 196 | ret, _, _ := syscall.Syscall( 197 | obj.vtbl.GetType, 198 | 1, 199 | uintptr(unsafe.Pointer(obj)), 200 | 0, 201 | 0, 202 | ) 203 | return RESOURCETYPE(ret) 204 | } 205 | 206 | // SetLOD sets the most detailed level-of-detail for a managed texture. 207 | func (obj *BaseTexture) SetLOD(lodNew uint32) uint32 { 208 | ret, _, _ := syscall.Syscall( 209 | obj.vtbl.SetLOD, 210 | 2, 211 | uintptr(unsafe.Pointer(obj)), 212 | uintptr(lodNew), 213 | 0, 214 | ) 215 | return uint32(ret) 216 | } 217 | 218 | // GetLOD returns a value clamped to the maximum level-of-detail set for a 219 | // managed texture (this method is not supported for an unmanaged texture). 220 | func (obj *BaseTexture) GetLOD() uint32 { 221 | ret, _, _ := syscall.Syscall( 222 | obj.vtbl.GetLOD, 223 | 1, 224 | uintptr(unsafe.Pointer(obj)), 225 | 0, 226 | 0, 227 | ) 228 | return uint32(ret) 229 | } 230 | 231 | // GetLevelCount returns the number of texture levels in a multilevel texture. 232 | func (obj *BaseTexture) GetLevelCount() uint32 { 233 | ret, _, _ := syscall.Syscall( 234 | obj.vtbl.GetLevelCount, 235 | 1, 236 | uintptr(unsafe.Pointer(obj)), 237 | 0, 238 | 0, 239 | ) 240 | return uint32(ret) 241 | } 242 | 243 | // SetAutoGenFilterType sets the filter type that is used for automatically 244 | // generated mipmap sublevels. 245 | func (obj *BaseTexture) SetAutoGenFilterType(typ TEXTUREFILTERTYPE) Error { 246 | ret, _, _ := syscall.Syscall( 247 | obj.vtbl.SetAutoGenFilterType, 248 | 2, 249 | uintptr(unsafe.Pointer(obj)), 250 | uintptr(typ), 251 | 0, 252 | ) 253 | return toErr(ret) 254 | } 255 | 256 | // GetAutoGenFilterType returns the filter type that is used for automatically 257 | // generated mipmap sublevels. 258 | func (obj *BaseTexture) GetAutoGenFilterType() TEXTUREFILTERTYPE { 259 | ret, _, _ := syscall.Syscall( 260 | obj.vtbl.GetAutoGenFilterType, 261 | 1, 262 | uintptr(unsafe.Pointer(obj)), 263 | 0, 264 | 0, 265 | ) 266 | return TEXTUREFILTERTYPE(ret) 267 | } 268 | 269 | // GenerateMipSubLevels generates mip sub levels. 270 | func (obj *BaseTexture) GenerateMipSubLevels() { 271 | syscall.Syscall( 272 | obj.vtbl.GenerateMipSubLevels, 273 | 1, 274 | uintptr(unsafe.Pointer(obj)), 275 | 0, 276 | 0, 277 | ) 278 | } 279 | -------------------------------------------------------------------------------- /color_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | // COLOR represents a color with red, green, blue and alpha channels, 8 bits 4 | // each, in a 32 bit unsinged integer. 5 | type COLOR uint32 6 | 7 | // ColorARGB converts the given color channel values to a color. Each channel 8 | // ranges from 0 (no intensity) to 255 (full intensity). 9 | func ColorARGB(a, r, g, b uint8) COLOR { 10 | return COLOR(a)<<24 | COLOR(r)<<16 | COLOR(g)<<8 | COLOR(b) 11 | } 12 | 13 | // ColorRGBA converts the given color channel values to a color. Each channel 14 | // ranges from 0 (no intensity) to 255 (full intensity). 15 | func ColorRGBA(r, g, b, a uint8) COLOR { 16 | return ColorARGB(a, r, g, b) 17 | } 18 | 19 | // ColorXRGB converts the given color channel values to a color. Each channel 20 | // ranges from 0 (no intensity) to 255 (full intensity). 21 | func ColorXRGB(r, g, b uint8) COLOR { 22 | return ColorARGB(0xFF, r, g, b) 23 | } 24 | 25 | // ColorRGB converts the given color channel values to a color. Each channel 26 | // ranges from 0 (no intensity) to 255 (full intensity). 27 | func ColorRGB(r, g, b uint8) COLOR { 28 | return ColorARGB(0xFF, r, g, b) 29 | } 30 | 31 | // ColorXYUV converts the given color channel values to a color. Each channel 32 | // ranges from 0 (no intensity) to 255 (full intensity). 33 | func ColorXYUV(y, u, v uint8) COLOR { 34 | return ColorARGB(0xFF, y, u, v) 35 | } 36 | 37 | // ColorYUV converts the given color channel values to a color. Each channel 38 | // ranges from 0 (no intensity) to 255 (full intensity). 39 | func ColorYUV(y, u, v uint8) COLOR { 40 | return ColorARGB(0xFF, y, u, v) 41 | } 42 | 43 | // ColorAYUV converts the given color channel values to a color. Each channel 44 | // ranges from 0 (no intensity) to 255 (full intensity). 45 | func ColorAYUV(a, y, u, v uint8) COLOR { 46 | return ColorARGB(a, y, u, v) 47 | } 48 | 49 | // ColorValue converts the given color channel values to a color. Each channel 50 | // ranges from 0.0 (no intensity) to 1.0 (full intensity). 51 | func ColorValue(r, g, b, a float32) COLOR { 52 | return ColorARGB(uint8(a*255), uint8(r*255), uint8(g*255), uint8(b*255)) 53 | } 54 | -------------------------------------------------------------------------------- /cube_texture_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // CubeTexture and its methods are used to manipulate a cube texture resource. 9 | type CubeTexture struct { 10 | vtbl *cubeTextureVtbl 11 | } 12 | 13 | type cubeTextureVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | SetPrivateData uintptr 20 | GetPrivateData uintptr 21 | FreePrivateData uintptr 22 | SetPriority uintptr 23 | GetPriority uintptr 24 | PreLoad uintptr 25 | GetType uintptr 26 | SetLOD uintptr 27 | GetLOD uintptr 28 | GetLevelCount uintptr 29 | SetAutoGenFilterType uintptr 30 | GetAutoGenFilterType uintptr 31 | GenerateMipSubLevels uintptr 32 | GetLevelDesc uintptr 33 | GetCubeMapSurface uintptr 34 | LockRect uintptr 35 | UnlockRect uintptr 36 | AddDirtyRect uintptr 37 | } 38 | 39 | func (obj *CubeTexture) baseTexturePointer() uintptr { 40 | return uintptr(unsafe.Pointer(obj)) 41 | } 42 | 43 | // AddRef increments the reference count for an interface on an object. This 44 | // method should be called for every new copy of a pointer to an interface on an 45 | // object. 46 | func (obj *CubeTexture) AddRef() uint32 { 47 | ret, _, _ := syscall.Syscall( 48 | obj.vtbl.AddRef, 49 | 1, 50 | uintptr(unsafe.Pointer(obj)), 51 | 0, 52 | 0, 53 | ) 54 | return uint32(ret) 55 | } 56 | 57 | // Release has to be called when finished using the object to free its 58 | // associated resources. 59 | func (obj *CubeTexture) Release() uint32 { 60 | ret, _, _ := syscall.Syscall( 61 | obj.vtbl.Release, 62 | 1, 63 | uintptr(unsafe.Pointer(obj)), 64 | 0, 65 | 0, 66 | ) 67 | return uint32(ret) 68 | } 69 | 70 | // GetDevice retrieves the device associated with a resource. 71 | // Call Release on the returned device when finished using it. 72 | func (obj *CubeTexture) GetDevice() (device *Device, err Error) { 73 | ret, _, _ := syscall.Syscall( 74 | obj.vtbl.GetDevice, 75 | 2, 76 | uintptr(unsafe.Pointer(obj)), 77 | uintptr(unsafe.Pointer(&device)), 78 | 0, 79 | ) 80 | err = toErr(ret) 81 | return 82 | } 83 | 84 | // SetPrivateData associates data with the resource that is intended for use by 85 | // the application, not by Direct3D. Data is passed by value, and multiple sets 86 | // of data can be associated with a single resource. 87 | func (obj *CubeTexture) SetPrivateData( 88 | refguid GUID, 89 | data uintptr, 90 | sizeOfData uint32, 91 | flags uint32, 92 | ) Error { 93 | ret, _, _ := syscall.Syscall6( 94 | obj.vtbl.SetPrivateData, 95 | 5, 96 | uintptr(unsafe.Pointer(obj)), 97 | uintptr(unsafe.Pointer(&refguid)), 98 | data, 99 | uintptr(sizeOfData), 100 | uintptr(flags), 101 | 0, 102 | ) 103 | return toErr(ret) 104 | } 105 | 106 | // SetPrivateDataBytes associates data with the resource that is intended for 107 | // use by the application, not by Direct3D. Data is passed by value, and 108 | // multiple sets of data can be associated with a single resource. 109 | func (obj *CubeTexture) SetPrivateDataBytes( 110 | refguid GUID, 111 | data []byte, 112 | flags uint32, 113 | ) Error { 114 | return obj.SetPrivateData( 115 | refguid, 116 | uintptr(unsafe.Pointer(&data[0])), 117 | uint32(len(data)), 118 | flags, 119 | ) 120 | } 121 | 122 | // GetPrivateData copies the private data associated with the resource to a 123 | // provided buffer. 124 | func (obj *CubeTexture) GetPrivateData(refguid GUID) (data []byte, err Error) { 125 | // first get the data size by passing nil as the data pointer 126 | var sizeInBytes uint 127 | ret, _, _ := syscall.Syscall6( 128 | obj.vtbl.GetPrivateData, 129 | 4, 130 | uintptr(unsafe.Pointer(obj)), 131 | uintptr(unsafe.Pointer(&refguid)), 132 | 0, 133 | uintptr(unsafe.Pointer(&sizeInBytes)), 134 | 0, 135 | 0, 136 | ) 137 | if err := toErr(ret); err != nil { 138 | return nil, err 139 | } 140 | data = make([]byte, sizeInBytes) 141 | ret, _, _ = syscall.Syscall6( 142 | obj.vtbl.GetPrivateData, 143 | 4, 144 | uintptr(unsafe.Pointer(obj)), 145 | uintptr(unsafe.Pointer(&refguid)), 146 | uintptr(unsafe.Pointer(&data[0])), 147 | uintptr(unsafe.Pointer(&sizeInBytes)), 148 | 0, 149 | 0, 150 | ) 151 | return data, toErr(ret) 152 | } 153 | 154 | // FreePrivateData frees the specified private data associated with this 155 | // resource. 156 | func (obj *CubeTexture) FreePrivateData(refguid GUID) Error { 157 | ret, _, _ := syscall.Syscall( 158 | obj.vtbl.FreePrivateData, 159 | 2, 160 | uintptr(unsafe.Pointer(obj)), 161 | uintptr(unsafe.Pointer(&refguid)), 162 | 0, 163 | ) 164 | return toErr(ret) 165 | } 166 | 167 | // SetPriority assigns the priority of a resource for scheduling purposes. 168 | func (obj *CubeTexture) SetPriority(priorityNew uint32) uint32 { 169 | ret, _, _ := syscall.Syscall( 170 | obj.vtbl.SetPriority, 171 | 2, 172 | uintptr(unsafe.Pointer(obj)), 173 | uintptr(priorityNew), 174 | 0, 175 | ) 176 | return uint32(ret) 177 | } 178 | 179 | // GetPriority retrieves the priority for this resource. 180 | func (obj *CubeTexture) GetPriority() uint32 { 181 | ret, _, _ := syscall.Syscall( 182 | obj.vtbl.GetPriority, 183 | 1, 184 | uintptr(unsafe.Pointer(obj)), 185 | 0, 186 | 0, 187 | ) 188 | return uint32(ret) 189 | } 190 | 191 | // PreLoad preloads a managed resource. 192 | func (obj *CubeTexture) PreLoad() { 193 | syscall.Syscall( 194 | obj.vtbl.PreLoad, 195 | 1, 196 | uintptr(unsafe.Pointer(obj)), 197 | 0, 198 | 0, 199 | ) 200 | } 201 | 202 | // GetType returns the type of the resource. 203 | func (obj *CubeTexture) GetType() RESOURCETYPE { 204 | ret, _, _ := syscall.Syscall( 205 | obj.vtbl.GetType, 206 | 1, 207 | uintptr(unsafe.Pointer(obj)), 208 | 0, 209 | 0, 210 | ) 211 | return RESOURCETYPE(ret) 212 | } 213 | 214 | // SetLOD sets the most detailed level-of-detail for a managed texture. 215 | func (obj *CubeTexture) SetLOD(lodNew uint32) uint32 { 216 | ret, _, _ := syscall.Syscall( 217 | obj.vtbl.SetLOD, 218 | 2, 219 | uintptr(unsafe.Pointer(obj)), 220 | uintptr(lodNew), 221 | 0, 222 | ) 223 | return uint32(ret) 224 | } 225 | 226 | // GetLOD returns a value clamped to the maximum level-of-detail set for a 227 | // managed texture (this method is not supported for an unmanaged texture). 228 | func (obj *CubeTexture) GetLOD() uint32 { 229 | ret, _, _ := syscall.Syscall( 230 | obj.vtbl.GetLOD, 231 | 1, 232 | uintptr(unsafe.Pointer(obj)), 233 | 0, 234 | 0, 235 | ) 236 | return uint32(ret) 237 | } 238 | 239 | // GetLevelCount returns the number of texture levels in a multilevel texture. 240 | func (obj *CubeTexture) GetLevelCount() uint32 { 241 | ret, _, _ := syscall.Syscall( 242 | obj.vtbl.GetLevelCount, 243 | 1, 244 | uintptr(unsafe.Pointer(obj)), 245 | 0, 246 | 0, 247 | ) 248 | return uint32(ret) 249 | } 250 | 251 | // SetAutoGenFilterType sets the filter type that is used for automatically 252 | // generated mipmap sublevels. 253 | func (obj *CubeTexture) SetAutoGenFilterType(typ TEXTUREFILTERTYPE) Error { 254 | ret, _, _ := syscall.Syscall( 255 | obj.vtbl.SetAutoGenFilterType, 256 | 2, 257 | uintptr(unsafe.Pointer(obj)), 258 | uintptr(typ), 259 | 0, 260 | ) 261 | return toErr(ret) 262 | } 263 | 264 | // GetAutoGenFilterType returns the filter type that is used for automatically 265 | // generated mipmap sublevels. 266 | func (obj *CubeTexture) GetAutoGenFilterType() TEXTUREFILTERTYPE { 267 | ret, _, _ := syscall.Syscall( 268 | obj.vtbl.GetAutoGenFilterType, 269 | 1, 270 | uintptr(unsafe.Pointer(obj)), 271 | 0, 272 | 0, 273 | ) 274 | return TEXTUREFILTERTYPE(ret) 275 | } 276 | 277 | // GenerateMipSubLevels generates mip sub levels. 278 | func (obj *CubeTexture) GenerateMipSubLevels() { 279 | syscall.Syscall( 280 | obj.vtbl.GenerateMipSubLevels, 281 | 1, 282 | uintptr(unsafe.Pointer(obj)), 283 | 0, 284 | 0, 285 | ) 286 | } 287 | 288 | // GetLevelDesc retrieves a description of one face of the specified cube 289 | // texture level. 290 | func (obj *CubeTexture) GetLevelDesc(level uint) (desc SURFACE_DESC, err Error) { 291 | ret, _, _ := syscall.Syscall( 292 | obj.vtbl.GetLevelDesc, 293 | 3, 294 | uintptr(unsafe.Pointer(obj)), 295 | uintptr(level), 296 | uintptr(unsafe.Pointer(&desc)), 297 | ) 298 | err = toErr(ret) 299 | return 300 | } 301 | 302 | // GetCubeMapSurface retrieves a cube texture map surface. 303 | func (obj *CubeTexture) GetCubeMapSurface( 304 | faceType CUBEMAP_FACES, 305 | level uint, 306 | ) (surface *Surface, err Error) { 307 | ret, _, _ := syscall.Syscall6( 308 | obj.vtbl.GetCubeMapSurface, 309 | 4, 310 | uintptr(unsafe.Pointer(obj)), 311 | uintptr(faceType), 312 | uintptr(level), 313 | uintptr(unsafe.Pointer(&surface)), 314 | 0, 315 | 0, 316 | ) 317 | err = toErr(ret) 318 | return 319 | } 320 | 321 | // LockRect locks a rectangle on a cube texture resource. 322 | func (obj *CubeTexture) LockRect( 323 | faceType CUBEMAP_FACES, 324 | level uint, 325 | rect *RECT, 326 | flags uint32, 327 | ) (lockedRect LOCKED_RECT, err Error) { 328 | ret, _, _ := syscall.Syscall6( 329 | obj.vtbl.LockRect, 330 | 6, 331 | uintptr(unsafe.Pointer(obj)), 332 | uintptr(faceType), 333 | uintptr(level), 334 | uintptr(unsafe.Pointer(&lockedRect)), 335 | uintptr(unsafe.Pointer(rect)), 336 | uintptr(flags), 337 | ) 338 | err = toErr(ret) 339 | return 340 | } 341 | 342 | // UnlockRect unlocks a rectangle on a cube texture resource. 343 | func (obj *CubeTexture) UnlockRect(faceType CUBEMAP_FACES, level uint) Error { 344 | ret, _, _ := syscall.Syscall( 345 | obj.vtbl.UnlockRect, 346 | 3, 347 | uintptr(unsafe.Pointer(obj)), 348 | uintptr(faceType), 349 | uintptr(level), 350 | ) 351 | return toErr(ret) 352 | } 353 | 354 | // AddDirtyRect adds a dirty region to a cube texture resource. 355 | func (obj *CubeTexture) AddDirtyRect(faceType CUBEMAP_FACES, dirtyRect *RECT) Error { 356 | ret, _, _ := syscall.Syscall( 357 | obj.vtbl.AddDirtyRect, 358 | 3, 359 | uintptr(unsafe.Pointer(obj)), 360 | uintptr(faceType), 361 | uintptr(unsafe.Pointer(dirtyRect)), 362 | ) 363 | return toErr(ret) 364 | } 365 | -------------------------------------------------------------------------------- /direct3d9_windows.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package d3d9 provides a wrapper for Microsoft's Direct3D9 API in pure Go. 3 | It can only be used on Windows. 4 | 5 | When running a Direct3D application you need to have d3d9.dll installed on the 6 | system, which fortunately has been deployed with all Windows versions since XP. 7 | This means if you have Go installed, you also have the DLL installed. This also 8 | means that your application can be deployed without the DirectX DLLs and if you 9 | have no other dependencies you can just give the executable file to the users. 10 | 11 | To get going with this wrapper there are some basic samples that demonstrate how 12 | to set up and use the library at: 13 | https://github.com/gonutz/d3d9/tree/master/samples 14 | */ 15 | package d3d9 16 | 17 | import ( 18 | "errors" 19 | "syscall" 20 | "unsafe" 21 | ) 22 | 23 | var ( 24 | dll = syscall.NewLazyDLL("d3d9.dll") 25 | direct3DCreate9 = dll.NewProc("Direct3DCreate9") 26 | ) 27 | 28 | // Create takes the SDK version as argument and returns a new Direct3D object. 29 | // Use SDK_VERSION as the parameter. 30 | func Create(version uint) (*Direct3D, error) { 31 | obj, _, _ := direct3DCreate9.Call(uintptr(version)) 32 | if obj == 0 { 33 | return nil, errors.New("Direct3DCreate9 returned nil") 34 | } 35 | return (*Direct3D)(unsafe.Pointer(obj)), nil 36 | } 37 | 38 | // Direct3D and its methods are used to create Direct3D objects and set up the 39 | // environment. Its interface includes methods for enumerating and retrieving 40 | // capabilities of the device. 41 | type Direct3D struct { 42 | vtbl *direct3DVtbl 43 | } 44 | 45 | type direct3DVtbl struct { 46 | QueryInterface uintptr 47 | AddRef uintptr 48 | Release uintptr 49 | 50 | RegisterSoftwareDevice uintptr 51 | GetAdapterCount uintptr 52 | GetAdapterIdentifier uintptr 53 | GetAdapterModeCount uintptr 54 | EnumAdapterModes uintptr 55 | GetAdapterDisplayMode uintptr 56 | CheckDeviceType uintptr 57 | CheckDeviceFormat uintptr 58 | CheckDeviceMultiSampleType uintptr 59 | CheckDepthStencilMatch uintptr 60 | CheckDeviceFormatConversion uintptr 61 | GetDeviceCaps uintptr 62 | GetAdapterMonitor uintptr 63 | CreateDevice uintptr 64 | } 65 | 66 | // AddRef increments the reference count for an interface on an object. This 67 | // method should be called for every new copy of a pointer to an interface on an 68 | // object. 69 | func (obj *Direct3D) AddRef() uint32 { 70 | ret, _, _ := syscall.Syscall( 71 | obj.vtbl.AddRef, 72 | 1, 73 | uintptr(unsafe.Pointer(obj)), 74 | 0, 75 | 0, 76 | ) 77 | return uint32(ret) 78 | } 79 | 80 | // Release has to be called when finished using the object to free its 81 | // associated resources. 82 | func (obj *Direct3D) Release() uint32 { 83 | ret, _, _ := syscall.Syscall( 84 | obj.vtbl.Release, 85 | 1, 86 | uintptr(unsafe.Pointer(obj)), 87 | 0, 88 | 0, 89 | ) 90 | return uint32(ret) 91 | } 92 | 93 | // RegisterSoftwareDevice registers a pluggable software device. Software 94 | // devices provide software rasterization enabling applications to access a 95 | // variety of software rasterizers. 96 | func (obj *Direct3D) RegisterSoftwareDevice(initFunc uintptr) Error { 97 | ret, _, _ := syscall.Syscall( 98 | obj.vtbl.RegisterSoftwareDevice, 99 | 2, 100 | uintptr(unsafe.Pointer(obj)), 101 | initFunc, 102 | 0, 103 | ) 104 | return toErr(ret) 105 | } 106 | 107 | // GetAdapterCount returns the number of adapters on the system. 108 | func (obj *Direct3D) GetAdapterCount() uint { 109 | ret, _, _ := syscall.Syscall( 110 | obj.vtbl.GetAdapterCount, 111 | 1, 112 | uintptr(unsafe.Pointer(obj)), 113 | 0, 114 | 0, 115 | ) 116 | return uint(ret) 117 | } 118 | 119 | // GetAdapterIdentifier describes the physical display adapters present in the 120 | // system when the IDirect3D9 interface was instantiated. 121 | // Adapter must be a value from 0 to GetAdapterCount()-1. 122 | func (obj *Direct3D) GetAdapterIdentifier( 123 | adapter uint, 124 | flags uint32, 125 | ) (id ADAPTER_IDENTIFIER, err Error) { 126 | ret, _, _ := syscall.Syscall6( 127 | obj.vtbl.GetAdapterIdentifier, 128 | 4, 129 | uintptr(unsafe.Pointer(obj)), 130 | uintptr(adapter), 131 | uintptr(flags), 132 | uintptr(unsafe.Pointer(&id)), 133 | 0, 134 | 0, 135 | ) 136 | err = toErr(ret) 137 | return 138 | } 139 | 140 | // GetAdapterModeCount returns the number of display modes available on this 141 | // adapter. 142 | func (obj *Direct3D) GetAdapterModeCount(adapter uint, format FORMAT) uint { 143 | ret, _, _ := syscall.Syscall( 144 | obj.vtbl.GetAdapterModeCount, 145 | 3, 146 | uintptr(unsafe.Pointer(obj)), 147 | uintptr(adapter), 148 | uintptr(format), 149 | ) 150 | return uint(ret) 151 | } 152 | 153 | // EnumAdapterModes queries the device to determine whether the specified 154 | // adapter supports the requested format and display mode. This method could be 155 | // used in a loop to enumerate all the available adapter modes. 156 | // 157 | // Allowed formats are as follows: 158 | // 159 | // FMT_A1R5G5B5 160 | // FMT_A2R10G10B10 161 | // FMT_A8R8G8B8 162 | // FMT_R5G6B5 163 | // FMT_X1R5G5B5 164 | // FMT_X8R8G8B8 165 | // 166 | // EnumAdapterModes treats pixel formats 565 and 555 as equivalent, and returns 167 | // the correct version. The difference comes into play only when the application 168 | // locks the back buffer and there is an explicit flag that the application must 169 | // set in order to accomplish this. 170 | func (obj *Direct3D) EnumAdapterModes( 171 | adapter uint, 172 | format FORMAT, 173 | mode uint, 174 | ) (displayMode DISPLAYMODE, err Error) { 175 | ret, _, _ := syscall.Syscall6( 176 | obj.vtbl.EnumAdapterModes, 177 | 5, 178 | uintptr(unsafe.Pointer(obj)), 179 | uintptr(adapter), 180 | uintptr(format), 181 | uintptr(mode), 182 | uintptr(unsafe.Pointer(&displayMode)), 183 | 0, 184 | ) 185 | err = toErr(ret) 186 | return 187 | } 188 | 189 | // GetAdapterDisplayMode retrieves the current display mode of the adapter. 190 | func (obj *Direct3D) GetAdapterDisplayMode( 191 | adapter uint, 192 | ) (mode DISPLAYMODE, err Error) { 193 | ret, _, _ := syscall.Syscall( 194 | obj.vtbl.GetAdapterDisplayMode, 195 | 3, 196 | uintptr(unsafe.Pointer(obj)), 197 | uintptr(adapter), 198 | uintptr(unsafe.Pointer(&mode)), 199 | ) 200 | err = toErr(ret) 201 | return 202 | } 203 | 204 | // CheckDeviceType verifies whether a hardware accelerated device type can be 205 | // used on this adapter. 206 | func (obj *Direct3D) CheckDeviceType( 207 | adapter uint, 208 | deviceType DEVTYPE, 209 | displayFormat FORMAT, 210 | backBufferFormat FORMAT, 211 | windowed bool, 212 | ) Error { 213 | ret, _, _ := syscall.Syscall6( 214 | obj.vtbl.CheckDeviceType, 215 | 6, 216 | uintptr(unsafe.Pointer(obj)), 217 | uintptr(adapter), 218 | uintptr(deviceType), 219 | uintptr(displayFormat), 220 | uintptr(backBufferFormat), 221 | uintptrBool(windowed), 222 | ) 223 | return toErr(ret) 224 | } 225 | 226 | func uintptrBool(b bool) uintptr { 227 | if b { 228 | return 1 229 | } 230 | return 0 231 | } 232 | 233 | // CheckDeviceFormat determines whether a surface format is available as a 234 | // specified resource type and can be used as a texture, depth-stencil buffer, 235 | // or render target, or any combination of the three, on a device representing 236 | // this adapter. 237 | func (obj *Direct3D) CheckDeviceFormat( 238 | adapter uint, 239 | deviceType DEVTYPE, 240 | adapterFormat FORMAT, 241 | usage uint32, 242 | resType RESOURCETYPE, 243 | checkFormat FORMAT, 244 | ) Error { 245 | ret, _, _ := syscall.Syscall9( 246 | obj.vtbl.CheckDeviceFormat, 247 | 7, 248 | uintptr(unsafe.Pointer(obj)), 249 | uintptr(adapter), 250 | uintptr(deviceType), 251 | uintptr(adapterFormat), 252 | uintptr(usage), 253 | uintptr(resType), 254 | uintptr(checkFormat), 255 | 0, 256 | 0, 257 | ) 258 | return toErr(ret) 259 | } 260 | 261 | // CheckDeviceMultiSampleType determines if a multisampling technique is 262 | // available on this device. 263 | func (obj *Direct3D) CheckDeviceMultiSampleType( 264 | adapter uint, 265 | deviceType DEVTYPE, 266 | surfaceFormat FORMAT, 267 | windowed bool, 268 | multiSampleType MULTISAMPLE_TYPE, 269 | ) (qualityLevels uint32, err Error) { 270 | ret, _, _ := syscall.Syscall9( 271 | obj.vtbl.CheckDeviceMultiSampleType, 272 | 7, 273 | uintptr(unsafe.Pointer(obj)), 274 | uintptr(adapter), 275 | uintptr(deviceType), 276 | uintptr(surfaceFormat), 277 | uintptrBool(windowed), 278 | uintptr(multiSampleType), 279 | uintptr(unsafe.Pointer(&qualityLevels)), 280 | 0, 281 | 0, 282 | ) 283 | err = toErr(ret) 284 | return 285 | } 286 | 287 | // CheckDepthStencilMatch determines whether a depth-stencil format is 288 | // compatible with a render-target format in a particular display mode. 289 | func (obj *Direct3D) CheckDepthStencilMatch( 290 | adapter uint, 291 | deviceType DEVTYPE, 292 | adapterFormat FORMAT, 293 | renderTargetFormat FORMAT, 294 | depthStencilFormat FORMAT, 295 | ) Error { 296 | ret, _, _ := syscall.Syscall6( 297 | obj.vtbl.CheckDepthStencilMatch, 298 | 6, 299 | uintptr(unsafe.Pointer(obj)), 300 | uintptr(adapter), 301 | uintptr(deviceType), 302 | uintptr(adapterFormat), 303 | uintptr(renderTargetFormat), 304 | uintptr(depthStencilFormat), 305 | ) 306 | return toErr(ret) 307 | } 308 | 309 | // CheckDeviceFormatConversion tests the device to see if it supports conversion 310 | // from one display format to another. 311 | func (obj *Direct3D) CheckDeviceFormatConversion( 312 | adapter uint, 313 | deviceType DEVTYPE, 314 | sourceFormat FORMAT, 315 | targetFormat FORMAT, 316 | ) Error { 317 | ret, _, _ := syscall.Syscall6( 318 | obj.vtbl.CheckDeviceFormatConversion, 319 | 5, 320 | uintptr(unsafe.Pointer(obj)), 321 | uintptr(adapter), 322 | uintptr(deviceType), 323 | uintptr(sourceFormat), 324 | uintptr(targetFormat), 325 | 0, 326 | ) 327 | return toErr(ret) 328 | } 329 | 330 | // GetDeviceCaps retrieves device-specific information about a device. 331 | func (obj *Direct3D) GetDeviceCaps( 332 | adapter uint, 333 | deviceType DEVTYPE, 334 | ) (caps CAPS, err Error) { 335 | ret, _, _ := syscall.Syscall6( 336 | obj.vtbl.GetDeviceCaps, 337 | 4, 338 | uintptr(unsafe.Pointer(obj)), 339 | uintptr(adapter), 340 | uintptr(deviceType), 341 | uintptr(unsafe.Pointer(&caps)), 342 | 0, 343 | 0, 344 | ) 345 | err = toErr(ret) 346 | return 347 | } 348 | 349 | // GetAdapterMonitor returns the handle of the monitor associated with the 350 | // Direct3D object. 351 | func (obj *Direct3D) GetAdapterMonitor(adapter uint) HMONITOR { 352 | ret, _, _ := syscall.Syscall( 353 | obj.vtbl.GetAdapterMonitor, 354 | 2, 355 | uintptr(unsafe.Pointer(obj)), 356 | uintptr(adapter), 357 | 0, 358 | ) 359 | return HMONITOR(ret) 360 | } 361 | 362 | // CreateDevice creates a device to represent the display adapter. 363 | func (obj *Direct3D) CreateDevice( 364 | adapter uint, 365 | deviceType DEVTYPE, 366 | focusWindow HWND, 367 | behaviorFlags uint32, 368 | params PRESENT_PARAMETERS, 369 | ) (*Device, PRESENT_PARAMETERS, Error) { 370 | var device *Device 371 | ret, _, _ := syscall.Syscall9( 372 | obj.vtbl.CreateDevice, 373 | 7, 374 | uintptr(unsafe.Pointer(obj)), 375 | uintptr(adapter), 376 | uintptr(deviceType), 377 | uintptr(focusWindow), 378 | uintptr(behaviorFlags), 379 | uintptr(unsafe.Pointer(¶ms)), 380 | uintptr(unsafe.Pointer(&device)), 381 | 0, 382 | 0, 383 | ) 384 | return device, params, toErr(ret) 385 | } 386 | -------------------------------------------------------------------------------- /error_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import "strconv" 4 | 5 | // Error is returned by all Direct3D9 functions. It encapsulates the error code 6 | // returned by Direct3D. If a function succeeds it will return nil as the Error 7 | // and if it fails you can retrieve the error code using the Code() function. 8 | // You can check the result against the predefined error codes (like 9 | // ERR_DEVICELOST, E_OUTOFMEMORY etc). 10 | type Error interface { 11 | error 12 | // Code returns the Direct3D error code for a function. Call this function 13 | // only if the Error is not nil, if the error code is D3D_OK or any other 14 | // code that signifies success, a function will return nil as the Error 15 | // instead of a non-nil error with that code in it. This way, functions 16 | // behave in a standard Go way, returning nil as the error in case of 17 | // success and only returning non-nil errors if something went wrong. 18 | Code() int32 19 | } 20 | 21 | func toErr(result uintptr) Error { 22 | res := hResultError(result) // cast to signed int 23 | if res >= 0 { 24 | return nil 25 | } 26 | return res 27 | } 28 | 29 | type hResultError int32 30 | 31 | func (r hResultError) Code() int32 { return int32(r) } 32 | 33 | func (r hResultError) Error() string { 34 | switch r { 35 | case ERR_CONFLICTINGRENDERSTATE: 36 | return "conflicting render state" 37 | case ERR_CONFLICTINGTEXTUREFILTER: 38 | return "conflicting texture filter" 39 | case ERR_CONFLICTINGTEXTUREPALETTE: 40 | return "conflicting texture palette" 41 | case ERR_DEVICEHUNG: 42 | return "device hung" 43 | case ERR_DEVICELOST: 44 | return "device lost" 45 | case ERR_DEVICENOTRESET: 46 | return "device not reset" 47 | case ERR_DEVICEREMOVED: 48 | return "device removed" 49 | case ERR_DRIVERINTERNALERROR: 50 | return "driver internal error" 51 | case ERR_DRIVERINVALIDCALL: 52 | return "driver invalid call" 53 | case ERR_INVALIDCALL: 54 | return "invalid call" 55 | case ERR_INVALIDDEVICE: 56 | return "invalid device" 57 | case ERR_MOREDATA: 58 | return "more data" 59 | case ERR_NOTAVAILABLE: 60 | return "not available" 61 | case ERR_NOTFOUND: 62 | return "not found" 63 | case ERR_OUTOFVIDEOMEMORY: 64 | return "out of video memory" 65 | case ERR_TOOMANYOPERATIONS: 66 | return "too many operations" 67 | case ERR_UNSUPPORTEDALPHAARG: 68 | return "unsupported alpha argument" 69 | case ERR_UNSUPPORTEDALPHAOPERATION: 70 | return "unsupported alpha operation" 71 | case ERR_UNSUPPORTEDCOLORARG: 72 | return "unsupported color argument" 73 | case ERR_UNSUPPORTEDCOLOROPERATION: 74 | return "unsupported color operation" 75 | case ERR_UNSUPPORTEDFACTORVALUE: 76 | return "unsupported factor value" 77 | case ERR_UNSUPPORTEDTEXTUREFILTER: 78 | return "unsupported texture filter" 79 | case ERR_WASSTILLDRAWING: 80 | return "was still drawing" 81 | case ERR_WRONGTEXTUREFORMAT: 82 | return "wrong texture format" 83 | case ERR_UNSUPPORTEDOVERLAY: 84 | return "unsupported overlay" 85 | case ERR_UNSUPPORTEDOVERLAYFORMAT: 86 | return "unsupported overlay format" 87 | case ERR_CANNOTPROTECTCONTENT: 88 | return "cannot protect content" 89 | case ERR_UNSUPPORTEDCRYPTO: 90 | return "unsupported crypto" 91 | 92 | case E_FAIL: 93 | return "fail" 94 | case E_INVALIDARG: 95 | return "invalid argument" 96 | case E_NOINTERFACE: 97 | return "no interface" 98 | case E_NOTIMPL: 99 | return "not implemented" 100 | case E_OUTOFMEMORY: 101 | return "out of memory" 102 | 103 | case S_NOT_RESIDENT: 104 | return "not resident" 105 | case S_RESIDENT_IN_SHARED_MEMORY: 106 | return "resident in shared memory" 107 | 108 | default: 109 | return "unknown error code " + strconv.Itoa(int(r)) 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gonutz/d3d9 2 | 3 | go 1.11 4 | -------------------------------------------------------------------------------- /index_buffer_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // IndexBuffer and its methods are used to manipulate an index buffer resource. 9 | type IndexBuffer struct { 10 | vtbl *indexBufferVtbl 11 | } 12 | 13 | type indexBufferVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | SetPrivateData uintptr 20 | GetPrivateData uintptr 21 | FreePrivateData uintptr 22 | SetPriority uintptr 23 | GetPriority uintptr 24 | PreLoad uintptr 25 | GetType uintptr 26 | Lock uintptr 27 | Unlock uintptr 28 | GetDesc uintptr 29 | } 30 | 31 | // AddRef increments the reference count for an interface on an object. This 32 | // method should be called for every new copy of a pointer to an interface on an 33 | // object. 34 | func (obj *IndexBuffer) AddRef() uint32 { 35 | ret, _, _ := syscall.Syscall( 36 | obj.vtbl.AddRef, 37 | 1, 38 | uintptr(unsafe.Pointer(obj)), 39 | 0, 40 | 0, 41 | ) 42 | return uint32(ret) 43 | } 44 | 45 | // Release has to be called when finished using the object to free its 46 | // associated resources. 47 | func (obj *IndexBuffer) Release() uint32 { 48 | ret, _, _ := syscall.Syscall( 49 | obj.vtbl.Release, 50 | 1, 51 | uintptr(unsafe.Pointer(obj)), 52 | 0, 53 | 0, 54 | ) 55 | return uint32(ret) 56 | } 57 | 58 | // GetDevice retrieves the device associated with a resource. 59 | // Call Release on the returned device when finished using it. 60 | func (obj *IndexBuffer) GetDevice() (device *Device, err Error) { 61 | ret, _, _ := syscall.Syscall( 62 | obj.vtbl.GetDevice, 63 | 2, 64 | uintptr(unsafe.Pointer(obj)), 65 | uintptr(unsafe.Pointer(&device)), 66 | 0, 67 | ) 68 | err = toErr(ret) 69 | return 70 | } 71 | 72 | // SetPrivateData associates data with the resource that is intended for use by 73 | // the application, not by Direct3D. Data is passed by value, and multiple sets 74 | // of data can be associated with a single resource. 75 | func (obj *IndexBuffer) SetPrivateData( 76 | refguid GUID, 77 | data uintptr, 78 | sizeOfData uint32, 79 | flags uint32, 80 | ) Error { 81 | ret, _, _ := syscall.Syscall6( 82 | obj.vtbl.SetPrivateData, 83 | 5, 84 | uintptr(unsafe.Pointer(obj)), 85 | uintptr(unsafe.Pointer(&refguid)), 86 | data, 87 | uintptr(sizeOfData), 88 | uintptr(flags), 89 | 0, 90 | ) 91 | return toErr(ret) 92 | } 93 | 94 | // SetPrivateDataBytes associates data with the resource that is intended for 95 | // use by the application, not by Direct3D. Data is passed by value, and 96 | // multiple sets of data can be associated with a single resource. 97 | func (obj *IndexBuffer) SetPrivateDataBytes( 98 | refguid GUID, 99 | data []byte, 100 | flags uint32, 101 | ) Error { 102 | return obj.SetPrivateData( 103 | refguid, 104 | uintptr(unsafe.Pointer(&data[0])), 105 | uint32(len(data)), 106 | flags, 107 | ) 108 | } 109 | 110 | // GetPrivateData copies the private data associated with the resource to a 111 | // provided buffer. 112 | func (obj *IndexBuffer) GetPrivateData(refguid GUID) (data []byte, err Error) { 113 | // first get the data size by passing nil as the data pointer 114 | var sizeInBytes uint 115 | ret, _, _ := syscall.Syscall6( 116 | obj.vtbl.GetPrivateData, 117 | 4, 118 | uintptr(unsafe.Pointer(obj)), 119 | uintptr(unsafe.Pointer(&refguid)), 120 | 0, 121 | uintptr(unsafe.Pointer(&sizeInBytes)), 122 | 0, 123 | 0, 124 | ) 125 | if err := toErr(ret); err != nil { 126 | return nil, err 127 | } 128 | data = make([]byte, sizeInBytes) 129 | ret, _, _ = syscall.Syscall6( 130 | obj.vtbl.GetPrivateData, 131 | 4, 132 | uintptr(unsafe.Pointer(obj)), 133 | uintptr(unsafe.Pointer(&refguid)), 134 | uintptr(unsafe.Pointer(&data[0])), 135 | uintptr(unsafe.Pointer(&sizeInBytes)), 136 | 0, 137 | 0, 138 | ) 139 | return data, toErr(ret) 140 | } 141 | 142 | // FreePrivateData frees the specified private data associated with this 143 | // resource. 144 | func (obj *IndexBuffer) FreePrivateData(refguid GUID) Error { 145 | ret, _, _ := syscall.Syscall( 146 | obj.vtbl.FreePrivateData, 147 | 2, 148 | uintptr(unsafe.Pointer(obj)), 149 | uintptr(unsafe.Pointer(&refguid)), 150 | 0, 151 | ) 152 | return toErr(ret) 153 | } 154 | 155 | // SetPriority assigns the priority of a resource for scheduling purposes. 156 | func (obj *IndexBuffer) SetPriority(priorityNew uint32) uint32 { 157 | ret, _, _ := syscall.Syscall( 158 | obj.vtbl.SetPriority, 159 | 2, 160 | uintptr(unsafe.Pointer(obj)), 161 | uintptr(priorityNew), 162 | 0, 163 | ) 164 | return uint32(ret) 165 | } 166 | 167 | // GetPriority retrieves the priority for this resource. 168 | func (obj *IndexBuffer) GetPriority() uint32 { 169 | ret, _, _ := syscall.Syscall( 170 | obj.vtbl.GetPriority, 171 | 1, 172 | uintptr(unsafe.Pointer(obj)), 173 | 0, 174 | 0, 175 | ) 176 | return uint32(ret) 177 | } 178 | 179 | // PreLoad preloads a managed resource. 180 | func (obj *IndexBuffer) PreLoad() { 181 | syscall.Syscall( 182 | obj.vtbl.PreLoad, 183 | 1, 184 | uintptr(unsafe.Pointer(obj)), 185 | 0, 186 | 0, 187 | ) 188 | } 189 | 190 | // GetType returns the type of the resource. 191 | func (obj *IndexBuffer) GetType() RESOURCETYPE { 192 | ret, _, _ := syscall.Syscall( 193 | obj.vtbl.GetType, 194 | 1, 195 | uintptr(unsafe.Pointer(obj)), 196 | 0, 197 | 0, 198 | ) 199 | return RESOURCETYPE(ret) 200 | } 201 | 202 | // Lock locks a range of index data and obtains a pointer to the index buffer 203 | // memory. 204 | func (obj *IndexBuffer) Lock( 205 | offsetToLock uint, 206 | sizeToLock uint, 207 | flags uint32, 208 | ) (data IndexBufferMemory, err Error) { 209 | var dataPtr uintptr 210 | ret, _, _ := syscall.Syscall6( 211 | obj.vtbl.Lock, 212 | 5, 213 | uintptr(unsafe.Pointer(obj)), 214 | uintptr(offsetToLock), 215 | uintptr(sizeToLock), 216 | uintptr(unsafe.Pointer(&dataPtr)), 217 | uintptr(flags), 218 | 0, 219 | ) 220 | err = toErr(ret) 221 | data = IndexBufferMemory{Memory: dataPtr} 222 | return 223 | } 224 | 225 | // Unlock unlocks index data. 226 | func (obj *IndexBuffer) Unlock() Error { 227 | ret, _, _ := syscall.Syscall( 228 | obj.vtbl.Unlock, 229 | 1, 230 | uintptr(unsafe.Pointer(obj)), 231 | 0, 232 | 0, 233 | ) 234 | return toErr(ret) 235 | } 236 | 237 | // GetDesc retrieves a description of the index buffer resource. 238 | func (obj *IndexBuffer) GetDesc() (desc INDEXBUFFER_DESC, err Error) { 239 | ret, _, _ := syscall.Syscall( 240 | obj.vtbl.GetDesc, 241 | 2, 242 | uintptr(unsafe.Pointer(obj)), 243 | uintptr(unsafe.Pointer(&desc)), 244 | 0, 245 | ) 246 | err = toErr(ret) 247 | return 248 | } 249 | 250 | // IndexBufferMemory encapsulates a raw memory pointer and provides methods to 251 | // get and set typical slice types. 252 | type IndexBufferMemory struct { 253 | Memory uintptr 254 | } 255 | 256 | // SetUint32s copies the given slice to the memory, starting at the given 257 | // offset in bytes. 258 | func (m IndexBufferMemory) SetUint32s(offsetInBytes int, data []uint32) { 259 | if len(data) > 0 { 260 | dest := m.Memory + uintptr(offsetInBytes) 261 | for i := range data { 262 | *((*uint32)(unsafe.Pointer(dest))) = data[i] 263 | dest += 4 264 | } 265 | } 266 | } 267 | 268 | // SetUint16s copies the given slice to the memory, starting at the given 269 | // offset in bytes. 270 | func (m IndexBufferMemory) SetUint16s(offsetInBytes int, data []uint16) { 271 | if len(data) > 0 { 272 | dest := m.Memory + uintptr(offsetInBytes) 273 | for i := range data { 274 | *((*uint16)(unsafe.Pointer(dest))) = data[i] 275 | dest += 2 276 | } 277 | } 278 | } 279 | 280 | // SetUint8s copies the given slice to the memory, starting at the given 281 | // offset in bytes. 282 | func (m IndexBufferMemory) SetUint8s(offsetInBytes int, data []uint8) { 283 | if len(data) > 0 { 284 | dest := m.Memory + uintptr(offsetInBytes) 285 | for i := range data { 286 | *((*uint8)(unsafe.Pointer(dest))) = data[i] 287 | dest++ 288 | } 289 | } 290 | } 291 | 292 | // GetUint32s copies data from memory to the given slice, starting at the given 293 | // offset in bytes. 294 | func (m IndexBufferMemory) GetUint32s(offsetInBytes int, data []uint32) { 295 | if len(data) > 0 { 296 | src := m.Memory + uintptr(offsetInBytes) 297 | for i := range data { 298 | data[i] = *((*uint32)(unsafe.Pointer(src))) 299 | src += 4 300 | } 301 | } 302 | } 303 | 304 | // GetUint16s copies data from memory to the given slice, starting at the given 305 | // offset in bytes. 306 | func (m IndexBufferMemory) GetUint16s(offsetInBytes int, data []uint16) { 307 | if len(data) > 0 { 308 | src := m.Memory + uintptr(offsetInBytes) 309 | for i := range data { 310 | data[i] = *((*uint16)(unsafe.Pointer(src))) 311 | src += 2 312 | } 313 | } 314 | } 315 | 316 | // GetUint8s copies data from memory to the given slice, starting at the given 317 | // offset in bytes. 318 | func (m IndexBufferMemory) GetUint8s(offsetInBytes int, data []uint8) { 319 | if len(data) > 0 { 320 | src := m.Memory + uintptr(offsetInBytes) 321 | for i := range data { 322 | data[i] = *((*uint8)(unsafe.Pointer(src))) 323 | src++ 324 | } 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /macros_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | // PSVersion creates a pixel shader version token. 4 | func PSVersion(major, minor uint) uint32 { 5 | return uint32(0xFFFF0000 | ((major) << 8) | (minor)) 6 | } 7 | 8 | // VSVersion creates a vertex shader version token. 9 | func VSVersion(major, minor uint) uint32 { 10 | return uint32(0xFFFE0000 | ((major) << 8) | (minor)) 11 | } 12 | 13 | // TSWorldMatrix maps indices in the range 0 through 255 to the corresponding 14 | // transform states. 15 | func TSWorldMatrix(index int) TRANSFORMSTATETYPE { 16 | return TRANSFORMSTATETYPE(index + 256) 17 | } 18 | 19 | // FVFTexCoordSize1 constructs bit patterns that are used to identify texture 20 | // coordinate formats within a FVF description. The results of these macros can 21 | // be combined within a FVF description by using the OR operator. 22 | func FVFTexCoordSize1(CoordIndex uint) uint32 { 23 | return uint32(int(FVF_TEXTUREFORMAT1) << (CoordIndex*2 + 16)) 24 | } 25 | 26 | // FVFTexCoordSize2 constructs bit patterns that are used to identify texture 27 | // coordinate formats within a FVF description. The results of these macros can 28 | // be combined within a FVF description by using the OR operator. 29 | func FVFTexCoordSize2(CoordIndex uint) uint32 { 30 | return FVF_TEXTUREFORMAT2 31 | } 32 | 33 | // FVFTexCoordSize3 constructs bit patterns that are used to identify texture 34 | // coordinate formats within a FVF description. The results of these macros can 35 | // be combined within a FVF description by using the OR operator. 36 | func FVFTexCoordSize3(CoordIndex uint) uint32 { 37 | return FVF_TEXTUREFORMAT3 << (CoordIndex*2 + 16) 38 | } 39 | 40 | // FVFTexCoordSize4 constructs bit patterns that are used to identify texture 41 | // coordinate formats within a FVF description. The results of these macros can 42 | // be combined within a FVF description by using the OR operator. 43 | func FVFTexCoordSize4(CoordIndex uint) uint32 { 44 | return FVF_TEXTUREFORMAT4 << (CoordIndex*2 + 16) 45 | } 46 | -------------------------------------------------------------------------------- /pixel_shader_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // PixelShader and its methods are used to manipulate a pixel shader resource. 9 | type PixelShader struct { 10 | vtbl *pixelShaderVtbl 11 | } 12 | 13 | type pixelShaderVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | GetFunction uintptr 20 | } 21 | 22 | // AddRef increments the reference count for an interface on an object. This 23 | // method should be called for every new copy of a pointer to an interface on an 24 | // object. 25 | func (obj *PixelShader) AddRef() uint32 { 26 | ret, _, _ := syscall.Syscall( 27 | obj.vtbl.AddRef, 28 | 1, 29 | uintptr(unsafe.Pointer(obj)), 30 | 0, 31 | 0, 32 | ) 33 | return uint32(ret) 34 | } 35 | 36 | // Release has to be called when finished using the object to free its 37 | // associated resources. 38 | func (obj *PixelShader) Release() uint32 { 39 | ret, _, _ := syscall.Syscall( 40 | obj.vtbl.Release, 41 | 1, 42 | uintptr(unsafe.Pointer(obj)), 43 | 0, 44 | 0, 45 | ) 46 | return uint32(ret) 47 | } 48 | 49 | // GetDevice retrieves the associated device. 50 | // Call Release on the returned device when finished using it. 51 | func (obj *PixelShader) GetDevice() (device *Device, err Error) { 52 | ret, _, _ := syscall.Syscall( 53 | obj.vtbl.GetDevice, 54 | 2, 55 | uintptr(unsafe.Pointer(obj)), 56 | uintptr(unsafe.Pointer(&device)), 57 | 0, 58 | ) 59 | err = toErr(ret) 60 | return 61 | } 62 | 63 | // GetFunction returns the shader data. 64 | func (obj *PixelShader) GetFunction() (data []byte, err Error) { 65 | // first get the needed buffer size, pass nil as the data pointer 66 | var sizeInBytes uint 67 | ret, _, _ := syscall.Syscall( 68 | obj.vtbl.GetFunction, 69 | 3, 70 | uintptr(unsafe.Pointer(obj)), 71 | 0, 72 | uintptr(unsafe.Pointer(&sizeInBytes)), 73 | ) 74 | if err := toErr(ret); err != nil { 75 | return nil, err 76 | } 77 | 78 | data = make([]byte, sizeInBytes) 79 | ret, _, _ = syscall.Syscall( 80 | obj.vtbl.GetFunction, 81 | 3, 82 | uintptr(unsafe.Pointer(obj)), 83 | uintptr(unsafe.Pointer(&data[0])), 84 | uintptr(unsafe.Pointer(&sizeInBytes)), 85 | ) 86 | err = toErr(ret) 87 | return 88 | } 89 | -------------------------------------------------------------------------------- /query_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // Query and its methods are used to perform asynchronous queries on a driver. 9 | type Query struct { 10 | vtbl *queryVtbl 11 | } 12 | 13 | type queryVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | GetType uintptr 20 | GetDataSize uintptr 21 | Issue uintptr 22 | GetData uintptr 23 | } 24 | 25 | // AddRef increments the reference count for an interface on an object. This 26 | // method should be called for every new copy of a pointer to an interface on an 27 | // object. 28 | func (obj *Query) AddRef() uint32 { 29 | ret, _, _ := syscall.Syscall( 30 | obj.vtbl.AddRef, 31 | 1, 32 | uintptr(unsafe.Pointer(obj)), 33 | 0, 34 | 0, 35 | ) 36 | return uint32(ret) 37 | } 38 | 39 | // Release has to be called when finished using the object to free its 40 | // associated resources. 41 | func (obj *Query) Release() uint32 { 42 | ret, _, _ := syscall.Syscall( 43 | obj.vtbl.Release, 44 | 1, 45 | uintptr(unsafe.Pointer(obj)), 46 | 0, 47 | 0, 48 | ) 49 | return uint32(ret) 50 | } 51 | 52 | // GetDevice retrieves the associated device. 53 | // Call Release on the returned device when finished using it. 54 | func (obj *Query) GetDevice() (device *Device, err Error) { 55 | ret, _, _ := syscall.Syscall( 56 | obj.vtbl.GetDevice, 57 | 2, 58 | uintptr(unsafe.Pointer(obj)), 59 | uintptr(unsafe.Pointer(&device)), 60 | 0, 61 | ) 62 | err = toErr(ret) 63 | return 64 | } 65 | 66 | // GetType returns the query type. 67 | func (obj *Query) GetType() QUERYTYPE { 68 | ret, _, _ := syscall.Syscall( 69 | obj.vtbl.GetType, 70 | 1, 71 | uintptr(unsafe.Pointer(obj)), 72 | 0, 73 | 0, 74 | ) 75 | return QUERYTYPE(ret) 76 | } 77 | 78 | // GetDataSize returns the number of bytes in the query data. 79 | func (obj *Query) GetDataSize() uint32 { 80 | ret, _, _ := syscall.Syscall( 81 | obj.vtbl.GetDataSize, 82 | 1, 83 | uintptr(unsafe.Pointer(obj)), 84 | 0, 85 | 0, 86 | ) 87 | return uint32(ret) 88 | } 89 | 90 | // Issue issues a query. 91 | func (obj *Query) Issue(issueFlags uint32) Error { 92 | ret, _, _ := syscall.Syscall( 93 | obj.vtbl.Issue, 94 | 2, 95 | uintptr(unsafe.Pointer(obj)), 96 | uintptr(issueFlags), 97 | 0, 98 | ) 99 | return toErr(ret) 100 | } 101 | 102 | // GetData polls a queried resource to get the query state or a query result. 103 | func (obj *Query) GetData(data []byte, flags uint32) Error { 104 | var dataPtr uintptr 105 | if len(data) > 0 { 106 | dataPtr = uintptr(unsafe.Pointer(&data[0])) 107 | } 108 | ret, _, _ := syscall.Syscall6( 109 | obj.vtbl.GetData, 110 | 4, 111 | uintptr(unsafe.Pointer(obj)), 112 | dataPtr, 113 | uintptr(len(data)), 114 | uintptr(flags), 115 | 0, 116 | 0, 117 | ) 118 | return toErr(ret) 119 | } 120 | -------------------------------------------------------------------------------- /resource_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // Resource and its methods are used to query and prepare resources. 9 | type Resource struct { 10 | vtbl *resourceVtbl 11 | } 12 | 13 | type resourceVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | SetPrivateData uintptr 20 | GetPrivateData uintptr 21 | FreePrivateData uintptr 22 | SetPriority uintptr 23 | GetPriority uintptr 24 | PreLoad uintptr 25 | GetType uintptr 26 | } 27 | 28 | // AddRef increments the reference count for an interface on an object. This 29 | // method should be called for every new copy of a pointer to an interface on an 30 | // object. 31 | func (obj *Resource) AddRef() uint32 { 32 | ret, _, _ := syscall.Syscall( 33 | obj.vtbl.AddRef, 34 | 1, 35 | uintptr(unsafe.Pointer(obj)), 36 | 0, 37 | 0, 38 | ) 39 | return uint32(ret) 40 | } 41 | 42 | // Release has to be called when finished using the object to free its 43 | // associated resources. 44 | func (obj *Resource) Release() uint32 { 45 | ret, _, _ := syscall.Syscall( 46 | obj.vtbl.Release, 47 | 1, 48 | uintptr(unsafe.Pointer(obj)), 49 | 0, 50 | 0, 51 | ) 52 | return uint32(ret) 53 | } 54 | 55 | // GetDevice retrieves the device associated with a resource. 56 | // Call Release on the returned device when finished using it. 57 | func (obj *Resource) GetDevice() (device *Device, err Error) { 58 | ret, _, _ := syscall.Syscall( 59 | obj.vtbl.GetDevice, 60 | 2, 61 | uintptr(unsafe.Pointer(obj)), 62 | uintptr(unsafe.Pointer(&device)), 63 | 0, 64 | ) 65 | err = toErr(ret) 66 | return 67 | } 68 | 69 | // SetPrivateData associates data with the resource that is intended for use by 70 | // the application, not by Direct3D. Data is passed by value, and multiple sets 71 | // of data can be associated with a single resource. 72 | func (obj *Resource) SetPrivateData( 73 | refguid GUID, 74 | data uintptr, 75 | sizeOfData uint32, 76 | flags uint32, 77 | ) Error { 78 | ret, _, _ := syscall.Syscall6( 79 | obj.vtbl.SetPrivateData, 80 | 5, 81 | uintptr(unsafe.Pointer(obj)), 82 | uintptr(unsafe.Pointer(&refguid)), 83 | data, 84 | uintptr(sizeOfData), 85 | uintptr(flags), 86 | 0, 87 | ) 88 | return toErr(ret) 89 | } 90 | 91 | // SetPrivateDataBytes associates data with the resource that is intended for 92 | // use by the application, not by Direct3D. Data is passed by value, and 93 | // multiple sets of data can be associated with a single resource. 94 | func (obj *Resource) SetPrivateDataBytes( 95 | refguid GUID, 96 | data []byte, 97 | flags uint32, 98 | ) Error { 99 | return obj.SetPrivateData( 100 | refguid, 101 | uintptr(unsafe.Pointer(&data[0])), 102 | uint32(len(data)), 103 | flags, 104 | ) 105 | } 106 | 107 | // GetPrivateData copies the private data associated with the resource to a 108 | // provided buffer. 109 | func (obj *Resource) GetPrivateData(refguid GUID) (data []byte, err Error) { 110 | // first get the data size by passing nil as the data pointer 111 | var sizeInBytes uint 112 | ret, _, _ := syscall.Syscall6( 113 | obj.vtbl.GetPrivateData, 114 | 4, 115 | uintptr(unsafe.Pointer(obj)), 116 | uintptr(unsafe.Pointer(&refguid)), 117 | 0, 118 | uintptr(unsafe.Pointer(&sizeInBytes)), 119 | 0, 120 | 0, 121 | ) 122 | if err := toErr(ret); err != nil { 123 | return nil, err 124 | } 125 | data = make([]byte, sizeInBytes) 126 | ret, _, _ = syscall.Syscall6( 127 | obj.vtbl.GetPrivateData, 128 | 4, 129 | uintptr(unsafe.Pointer(obj)), 130 | uintptr(unsafe.Pointer(&refguid)), 131 | uintptr(unsafe.Pointer(&data[0])), 132 | uintptr(unsafe.Pointer(&sizeInBytes)), 133 | 0, 134 | 0, 135 | ) 136 | return data, toErr(ret) 137 | } 138 | 139 | // FreePrivateData frees the specified private data associated with this 140 | // resource. 141 | func (obj *Resource) FreePrivateData(refguid GUID) Error { 142 | ret, _, _ := syscall.Syscall( 143 | obj.vtbl.FreePrivateData, 144 | 2, 145 | uintptr(unsafe.Pointer(obj)), 146 | uintptr(unsafe.Pointer(&refguid)), 147 | 0, 148 | ) 149 | return toErr(ret) 150 | } 151 | 152 | // SetPriority assigns the priority of a resource for scheduling purposes. 153 | func (obj *Resource) SetPriority(priorityNew uint32) uint32 { 154 | ret, _, _ := syscall.Syscall( 155 | obj.vtbl.SetPriority, 156 | 2, 157 | uintptr(unsafe.Pointer(obj)), 158 | uintptr(priorityNew), 159 | 0, 160 | ) 161 | return uint32(ret) 162 | } 163 | 164 | // GetPriority retrieves the priority for this resource. 165 | func (obj *Resource) GetPriority() uint32 { 166 | ret, _, _ := syscall.Syscall( 167 | obj.vtbl.GetPriority, 168 | 1, 169 | uintptr(unsafe.Pointer(obj)), 170 | 0, 171 | 0, 172 | ) 173 | return uint32(ret) 174 | } 175 | 176 | // PreLoad preloads a managed resource. 177 | func (obj *Resource) PreLoad() { 178 | syscall.Syscall( 179 | obj.vtbl.PreLoad, 180 | 1, 181 | uintptr(unsafe.Pointer(obj)), 182 | 0, 183 | 0, 184 | ) 185 | } 186 | 187 | // GetType returns the type of the resource. 188 | func (obj *Resource) GetType() RESOURCETYPE { 189 | ret, _, _ := syscall.Syscall( 190 | obj.vtbl.GetType, 191 | 1, 192 | uintptr(unsafe.Pointer(obj)), 193 | 0, 194 | 0, 195 | ) 196 | return RESOURCETYPE(ret) 197 | } 198 | -------------------------------------------------------------------------------- /samples/display_info/README.md: -------------------------------------------------------------------------------- 1 | This sample enumerates the connected monitors and their display modes. 2 | 3 | It does not create a window and you must compile it without the windowsgui 4 | flag, unlike the other samples, because it prints its output to the console 5 | which will not work when compiling with the windowsgui flag. 6 | 7 | Example output: 8 | 9 | ``` 10 | 1 adapter(s) detected 11 | adapter 0 has 23 R8G8B8 modes: 12 | mode 0: 640x480 60Hz 13 | mode 1: 640x480 75Hz 14 | mode 2: 720x400 70Hz 15 | mode 3: 720x400 60Hz 16 | mode 4: 800x600 60Hz 17 | mode 5: 800x600 75Hz 18 | mode 6: 832x624 75Hz 19 | mode 7: 832x624 60Hz 20 | mode 8: 1024x768 60Hz 21 | mode 9: 1024x768 75Hz 22 | mode 10: 1128x634 60Hz 23 | mode 11: 1128x634 75Hz 24 | mode 12: 1152x870 75Hz 25 | mode 13: 1152x870 60Hz 26 | mode 14: 1280x720 60Hz 27 | mode 15: 1280x800 60Hz 28 | mode 16: 1280x1024 60Hz 29 | mode 17: 1280x1024 75Hz 30 | mode 18: 1366x768 60Hz 31 | mode 19: 1600x900 60Hz 32 | mode 20: 1680x1050 60Hz 33 | mode 21: 1760x990 60Hz 34 | mode 22: 1920x1080 60Hz 35 | current display mode: 1920x1080 60Hz, format X8R8G8B8 36 | driver: atidx9loader64.dll (AMD Radeon RX 6600) 37 | ``` 38 | -------------------------------------------------------------------------------- /samples/display_info/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gonutz/d3d9/samples/display_info 2 | 3 | go 1.11 4 | 5 | require github.com/gonutz/d3d9 v1.2.3 6 | -------------------------------------------------------------------------------- /samples/display_info/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gonutz/d3d9 v1.2.3 h1:DmsDobNJDN3B5gk3AGcpKq8xZfLbVJ1C6H3bVn4GKKQ= 2 | github.com/gonutz/d3d9 v1.2.3/go.mod h1:q74g3QbR280b+qYauwEV0N9SVadszWPLZ4l/wHiD/AA= 3 | -------------------------------------------------------------------------------- /samples/display_info/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/gonutz/d3d9" 7 | ) 8 | 9 | func main() { 10 | d3d, err := d3d9.Create(d3d9.SDK_VERSION) 11 | check(err) 12 | defer d3d.Release() 13 | 14 | adapterCount := d3d.GetAdapterCount() 15 | fmt.Println(adapterCount, "adapter(s) detected") 16 | 17 | for adapter := uint(0); adapter < adapterCount; adapter++ { 18 | modeCount := d3d.GetAdapterModeCount(adapter, d3d9.FMT_X8R8G8B8) 19 | fmt.Printf("adapter %v has %v R8G8B8 modes:\n", adapter, modeCount) 20 | 21 | for mode := uint(0); mode < modeCount; mode++ { 22 | adapterMode, err := d3d.EnumAdapterModes( 23 | adapter, 24 | d3d9.FMT_X8R8G8B8, 25 | mode, 26 | ) 27 | check(err) 28 | fmt.Printf( 29 | " mode %2d: %vx%v %vHz\n", 30 | mode, 31 | adapterMode.Width, 32 | adapterMode.Height, 33 | adapterMode.RefreshRate, 34 | ) 35 | } 36 | 37 | displayMode, err := d3d.GetAdapterDisplayMode(adapter) 38 | check(err) 39 | fmt.Printf( 40 | "current display mode: %vx%v %vHz, format %v\n", 41 | displayMode.Width, 42 | displayMode.Height, 43 | displayMode.RefreshRate, 44 | displayMode.Format, 45 | ) 46 | 47 | id, err := d3d.GetAdapterIdentifier(adapter, 0) 48 | check(err) 49 | fmt.Printf( 50 | "driver: %v (%v)\n", 51 | toString(id.Driver), 52 | toString(id.Description), 53 | ) 54 | } 55 | } 56 | 57 | func toString(cString [512]byte) string { 58 | for i, b := range cString { 59 | if b == 0 { 60 | return string(cString[:i]) 61 | } 62 | } 63 | return string(cString[:]) 64 | } 65 | 66 | func check(err error) { 67 | if err != nil { 68 | panic(err) 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /samples/fullscreen/README.md: -------------------------------------------------------------------------------- 1 | This sample switches to fullscreen mode and displays a pink background. There 2 | is no interactivity, to quit the program use Alt+F4 or ESCAPE. 3 | 4 | Note that this uses "real fullscreen" as opposed to "windowed fullscreen". That 5 | means that this program really switches your monitor's display mode. This 6 | typically takes time and does not play nicely with switching windows, e.g. 7 | Alt+Tab is often a problem in games going full screen to a different 8 | resolution. 9 | You usually want to go fullscreen to the same resolution that the monitor is in 10 | right now, or use windowed fullscreen where you really just set up a window 11 | without borders that covers the whole screen and run your game in windowed 12 | mode. 13 | 14 | For window creation this sample uses 15 | [the Windows API](https://github.com/gonutz/w32). Direct3D needs a handle to 16 | the window it runs in so you need a method for setting this up. Other libraries 17 | that you can use include [SDL2](https://github.com/veandco/go-sdl2), 18 | [Allen Dang's gform library](https://github.com/AllenDang/gform) and the 19 | [walk library](https://github.com/lxn/walk). 20 | 21 | If you simply build this sample with `go build` the resulting program will keep 22 | a console window open while running. Use the `build.bat` to build instead, it 23 | passes the flag `-H=windowsgui` to the linker which gets rid of the console 24 | window, like so: 25 | 26 | go build -ldflags="-H=windowsgui" 27 | -------------------------------------------------------------------------------- /samples/fullscreen/build.bat: -------------------------------------------------------------------------------- 1 | go build -ldflags -H=windowsgui -------------------------------------------------------------------------------- /samples/fullscreen/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gonutz/d3d9/samples/fullscreen 2 | 3 | go 1.11 4 | 5 | require ( 6 | github.com/gonutz/d3d9 v1.2.3 7 | github.com/gonutz/w32/v2 v2.11.1 8 | ) 9 | -------------------------------------------------------------------------------- /samples/fullscreen/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gonutz/d3d9 v1.2.3 h1:DmsDobNJDN3B5gk3AGcpKq8xZfLbVJ1C6H3bVn4GKKQ= 2 | github.com/gonutz/d3d9 v1.2.3/go.mod h1:q74g3QbR280b+qYauwEV0N9SVadszWPLZ4l/wHiD/AA= 3 | github.com/gonutz/w32/v2 v2.11.1 h1:plG738ZY7VIkPGf3adZ6lFeAf2evCKrULKyZT5GrPoc= 4 | github.com/gonutz/w32/v2 v2.11.1/go.mod h1:MgtHx0AScDVNKyB+kjyPder4xIi3XAcHS6LDDU2DmdE= 5 | -------------------------------------------------------------------------------- /samples/fullscreen/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | "syscall" 6 | 7 | "github.com/gonutz/d3d9" 8 | "github.com/gonutz/w32/v2" 9 | ) 10 | 11 | func main() { 12 | runtime.LockOSThread() 13 | 14 | // Set up a window using the Win32 API. 15 | const className = "fullscreen_window_class" 16 | classNamePtr, _ := syscall.UTF16PtrFromString(className) 17 | w32.RegisterClassEx(&w32.WNDCLASSEX{ 18 | Cursor: w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW)), 19 | WndProc: syscall.NewCallback(func(window w32.HWND, msg uint32, w, l uintptr) uintptr { 20 | switch msg { 21 | case w32.WM_KEYDOWN: 22 | if w == w32.VK_ESCAPE { 23 | w32.SendMessage(window, w32.WM_CLOSE, 0, 0) 24 | } 25 | return 0 26 | case w32.WM_DESTROY: 27 | w32.PostQuitMessage(0) 28 | return 0 29 | default: 30 | return w32.DefWindowProc(window, msg, w, l) 31 | } 32 | }), 33 | ClassName: classNamePtr, 34 | }) 35 | 36 | windowNamePtr, _ := syscall.UTF16PtrFromString("Fullscreen") 37 | window := w32.CreateWindow( 38 | classNamePtr, 39 | windowNamePtr, 40 | w32.WS_OVERLAPPEDWINDOW|w32.WS_VISIBLE, 41 | w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, 640, 480, 42 | 0, 0, 0, nil, 43 | ) 44 | 45 | // Initialize Direct3D9. 46 | d3d, err := d3d9.Create(d3d9.SDK_VERSION) 47 | check(err) 48 | defer d3d.Release() 49 | 50 | // EnumAdapterModes lets us inspect all supported graphics modes for our 51 | // graphics card. We use the first one at index 0 to go full screen. 52 | mode, err := d3d.EnumAdapterModes(0, d3d9.FMT_X8R8G8B8, 0) 53 | check(err) 54 | 55 | device, _, err := d3d.CreateDevice( 56 | d3d9.ADAPTER_DEFAULT, 57 | d3d9.DEVTYPE_HAL, 58 | d3d9.HWND(window), 59 | // We use software emulation for this sample, as we do not render 60 | // anything. In reality you would check for hardware support by 61 | // inspecting the device capabilities and use hardware mode if 62 | // available. 63 | d3d9.CREATE_SOFTWARE_VERTEXPROCESSING, 64 | d3d9.PRESENT_PARAMETERS{ 65 | Windowed: 0, 66 | HDeviceWindow: d3d9.HWND(window), 67 | SwapEffect: d3d9.SWAPEFFECT_DISCARD, 68 | BackBufferFormat: d3d9.FMT_X8R8G8B8, 69 | BackBufferWidth: mode.Width, 70 | BackBufferHeight: mode.Height, 71 | }, 72 | ) 73 | check(err) 74 | defer device.Release() 75 | 76 | // Fill the screen with magic pink and call Present to show it. 77 | check(device.Clear(nil, d3d9.CLEAR_TARGET, d3d9.ColorRGB(255, 0, 255), 0, 1)) 78 | check(device.Present(nil, nil, 0, nil)) 79 | 80 | // This is the main message loop that runs until the window is closed. 81 | var msg w32.MSG 82 | for w32.GetMessage(&msg, 0, 0, 0) != 0 { 83 | w32.TranslateMessage(&msg) 84 | w32.DispatchMessage(&msg) 85 | } 86 | } 87 | 88 | func check(err error) { 89 | if err != nil { 90 | panic(err) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /samples/glow/build.bat: -------------------------------------------------------------------------------- 1 | go build -ldflags -H=windowsgui -------------------------------------------------------------------------------- /samples/glow/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gonutz/d3d9/samples/glow 2 | 3 | go 1.11 4 | 5 | require ( 6 | github.com/gonutz/d3d9 v1.2.3 7 | github.com/gonutz/w32/v2 v2.11.1 8 | ) 9 | -------------------------------------------------------------------------------- /samples/glow/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gonutz/d3d9 v1.2.3 h1:DmsDobNJDN3B5gk3AGcpKq8xZfLbVJ1C6H3bVn4GKKQ= 2 | github.com/gonutz/d3d9 v1.2.3/go.mod h1:q74g3QbR280b+qYauwEV0N9SVadszWPLZ4l/wHiD/AA= 3 | github.com/gonutz/w32/v2 v2.11.1 h1:plG738ZY7VIkPGf3adZ6lFeAf2evCKrULKyZT5GrPoc= 4 | github.com/gonutz/w32/v2 v2.11.1/go.mod h1:MgtHx0AScDVNKyB+kjyPder4xIi3XAcHS6LDDU2DmdE= 5 | -------------------------------------------------------------------------------- /samples/glow/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | "syscall" 6 | 7 | "github.com/gonutz/d3d9" 8 | "github.com/gonutz/w32/v2" 9 | ) 10 | 11 | func main() { 12 | runtime.LockOSThread() 13 | 14 | const className = "glowing_window_class" 15 | classNamePtr, _ := syscall.UTF16PtrFromString(className) 16 | w32.RegisterClassEx(&w32.WNDCLASSEX{ 17 | Cursor: w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW)), 18 | WndProc: syscall.NewCallback(func(window w32.HWND, msg uint32, w, l uintptr) uintptr { 19 | switch msg { 20 | case w32.WM_KEYDOWN: 21 | if w == w32.VK_ESCAPE { 22 | w32.SendMessage(window, w32.WM_CLOSE, 0, 0) 23 | } 24 | return 0 25 | case w32.WM_DESTROY: 26 | w32.PostQuitMessage(0) 27 | return 0 28 | default: 29 | return w32.DefWindowProc(window, msg, w, l) 30 | } 31 | }), 32 | ClassName: classNamePtr, 33 | }) 34 | 35 | windowNamePtr, _ := syscall.UTF16PtrFromString("Glow") 36 | windowHandle := w32.CreateWindow( 37 | classNamePtr, 38 | windowNamePtr, 39 | w32.WS_OVERLAPPEDWINDOW|w32.WS_VISIBLE, 40 | w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, 640, 480, 41 | 0, 0, 0, nil, 42 | ) 43 | 44 | d3d, err := d3d9.Create(d3d9.SDK_VERSION) 45 | check(err) 46 | defer d3d.Release() 47 | 48 | device, _, err := d3d.CreateDevice( 49 | d3d9.ADAPTER_DEFAULT, 50 | d3d9.DEVTYPE_HAL, 51 | d3d9.HWND(windowHandle), 52 | d3d9.CREATE_HARDWARE_VERTEXPROCESSING, 53 | d3d9.PRESENT_PARAMETERS{ 54 | Windowed: 1, 55 | SwapEffect: d3d9.SWAPEFFECT_DISCARD, 56 | HDeviceWindow: d3d9.HWND(windowHandle), 57 | }, 58 | ) 59 | check(err) 60 | defer device.Release() 61 | 62 | // Create a timer that ticks every 10ms and register a callback for it. 63 | w32.SetTimer(windowHandle, 1, 10, 0) 64 | red, dRed := 255, -1 65 | 66 | // This is the main message loop that runs until the window is closed. 67 | var msg w32.MSG 68 | for w32.GetMessage(&msg, 0, 0, 0) != 0 { 69 | w32.TranslateMessage(&msg) 70 | 71 | // Clear the screen to the current color. 72 | check(device.Clear( 73 | nil, 74 | d3d9.CLEAR_TARGET, 75 | d3d9.ColorRGB(uint8(red), 92, 128), 76 | 0, 77 | 0, 78 | )) 79 | if red == 0 { 80 | dRed = +1 81 | } 82 | if red == 255 { 83 | dRed = -1 84 | } 85 | red += dRed 86 | check(device.Present(nil, nil, 0, nil)) 87 | 88 | w32.DispatchMessage(&msg) 89 | } 90 | } 91 | 92 | func check(err error) { 93 | if err != nil { 94 | panic(err) 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /samples/glow/readme.md: -------------------------------------------------------------------------------- 1 | This example initializes Direct3D9 and changes the background color in an 2 | endless loop. It shows the basic setup and teardown of the library. 3 | 4 | For window creation this sample uses 5 | [the Windows API](https://github.com/gonutz/w32). Direct3D needs a handle to 6 | the window it runs in so you need a method for setting this up. Other libraries 7 | that you can use include [SDL2](https://github.com/veandco/go-sdl2), 8 | [Allen Dang's gform library](https://github.com/AllenDang/gform) and the 9 | [walk library](https://github.com/lxn/walk). 10 | 11 | If you simply build this sample with `go build` the resulting program will keep 12 | a console window open while running. Use the `build.bat` to build instead, it 13 | passes the flag `-H=windowsgui` to the linker which gets rid of the console 14 | window, like so: 15 | 16 | go build -ldflags="-H=windowsgui" 17 | -------------------------------------------------------------------------------- /samples/readme.md: -------------------------------------------------------------------------------- 1 | D3D9 Sample Programs 2 | ==================== 3 | 4 | These samples show some basic D3D9 features with minimal code examples. 5 | 6 | 1. display_info 7 | --------------- 8 | 9 | This sample enumerates the graphics card's supported screen resolutions and 10 | color formats. It is a console programm that prints to stdout. 11 | 12 | 2. screenshot 13 | ------------- 14 | 15 | This sample takes a screenshot of your desktop and saves it to `screen.png`. It 16 | is a console program that does not create a window. 17 | 18 | 3. fullscreen 19 | ------------- 20 | 21 | This sample displays a fullscreen pink window. It changes the monitor to 22 | fullscreen mode, possibly changing its resolution and color format. This takes 23 | a moment and may move your open windows when you quit the program. Quit this 24 | sample with Alt+F4. 25 | 26 | 4. glow 27 | ------- 28 | 29 | This sample displays a window and uses the `Clear` function to change its 30 | background color over time. 31 | 32 | 5. static_triangle 33 | ------------------ 34 | 35 | This sample uses vertex and pixel shaders to display a static pink triangle on 36 | a black background. 37 | 38 | 6. rotating_quad 39 | ---------------- 40 | 41 | This sample uses vertex and pixel shaders to display a rotating red rectangle 42 | on a blue background. 43 | -------------------------------------------------------------------------------- /samples/rotating_quad/build.bat: -------------------------------------------------------------------------------- 1 | go build -ldflags -H=windowsgui -------------------------------------------------------------------------------- /samples/rotating_quad/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gonutz/d3d9/samples/rotating_quad 2 | 3 | go 1.11 4 | 5 | require ( 6 | github.com/gonutz/d3d9 v1.2.3 7 | github.com/gonutz/dxc v1.1.0 8 | github.com/gonutz/w32/v2 v2.11.1 9 | ) 10 | -------------------------------------------------------------------------------- /samples/rotating_quad/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gonutz/d3d9 v1.2.3 h1:DmsDobNJDN3B5gk3AGcpKq8xZfLbVJ1C6H3bVn4GKKQ= 2 | github.com/gonutz/d3d9 v1.2.3/go.mod h1:q74g3QbR280b+qYauwEV0N9SVadszWPLZ4l/wHiD/AA= 3 | github.com/gonutz/dxc v1.1.0 h1:IOFuTlTiSZCIL34CXJFbZFCxWjj7cRbVbyfdPLsdJCg= 4 | github.com/gonutz/dxc v1.1.0/go.mod h1:SMdn5oWWIFnNdVM/BSLp7QwvC15S/dgabQsajOlk9x8= 5 | github.com/gonutz/w32/v2 v2.11.1 h1:plG738ZY7VIkPGf3adZ6lFeAf2evCKrULKyZT5GrPoc= 6 | github.com/gonutz/w32/v2 v2.11.1/go.mod h1:MgtHx0AScDVNKyB+kjyPder4xIi3XAcHS6LDDU2DmdE= 7 | -------------------------------------------------------------------------------- /samples/rotating_quad/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "math" 5 | "runtime" 6 | "syscall" 7 | 8 | "github.com/gonutz/d3d9" 9 | "github.com/gonutz/dxc" 10 | "github.com/gonutz/w32/v2" 11 | ) 12 | 13 | const vertexShaderCode = ` 14 | float4x4 mvp : register(c0); 15 | 16 | struct input { 17 | float4 position : POSITION; 18 | }; 19 | 20 | struct output { 21 | float4 position : POSITION; 22 | }; 23 | 24 | void main(in input IN, out output OUT) { 25 | OUT.position = mul(IN.position, mvp); 26 | } 27 | ` 28 | 29 | const pixelShaderCode = ` 30 | struct input {}; 31 | 32 | struct output { 33 | float4 color : COLOR0; 34 | }; 35 | 36 | void main(in input IN, out output OUT) { 37 | OUT.color = float4(1, 0, 0, 1); 38 | } 39 | ` 40 | 41 | func main() { 42 | runtime.LockOSThread() 43 | 44 | vertexShaderObject, err := dxc.Compile( 45 | []byte(vertexShaderCode), 46 | "main", 47 | "vs_2_0", 48 | dxc.WARNINGS_ARE_ERRORS, 49 | 0, 50 | ) 51 | check(err) 52 | 53 | pixelShaderObject, err := dxc.Compile( 54 | []byte(pixelShaderCode), 55 | "main", 56 | "ps_2_0", 57 | dxc.WARNINGS_ARE_ERRORS, 58 | 0, 59 | ) 60 | check(err) 61 | 62 | const className = "quad_window_class" 63 | classNamePtr, _ := syscall.UTF16PtrFromString(className) 64 | w32.RegisterClassEx(&w32.WNDCLASSEX{ 65 | Cursor: w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW)), 66 | WndProc: syscall.NewCallback(func(window w32.HWND, msg uint32, w, l uintptr) uintptr { 67 | switch msg { 68 | case w32.WM_KEYDOWN: 69 | if w == w32.VK_ESCAPE { 70 | w32.SendMessage(window, w32.WM_CLOSE, 0, 0) 71 | } 72 | return 0 73 | case w32.WM_DESTROY: 74 | w32.PostQuitMessage(0) 75 | return 0 76 | default: 77 | return w32.DefWindowProc(window, msg, w, l) 78 | } 79 | }), 80 | ClassName: classNamePtr, 81 | }) 82 | 83 | windowNamePtr, _ := syscall.UTF16PtrFromString("Rotating Quad") 84 | windowHandle := w32.CreateWindow( 85 | classNamePtr, 86 | windowNamePtr, 87 | w32.WS_OVERLAPPEDWINDOW|w32.WS_VISIBLE, 88 | w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, 640, 480, 89 | 0, 0, 0, nil, 90 | ) 91 | 92 | d3d, err := d3d9.Create(d3d9.SDK_VERSION) 93 | check(err) 94 | defer d3d.Release() 95 | 96 | device, _, err := d3d.CreateDevice( 97 | d3d9.ADAPTER_DEFAULT, 98 | d3d9.DEVTYPE_HAL, 99 | d3d9.HWND(windowHandle), 100 | d3d9.CREATE_HARDWARE_VERTEXPROCESSING, 101 | d3d9.PRESENT_PARAMETERS{ 102 | Windowed: 1, 103 | SwapEffect: d3d9.SWAPEFFECT_DISCARD, 104 | HDeviceWindow: d3d9.HWND(windowHandle), 105 | }, 106 | ) 107 | check(err) 108 | defer device.Release() 109 | 110 | vertices := []float32{ 111 | -0.5, -0.5, 112 | -0.5, 0.5, 113 | 0.5, -0.5, 114 | 0.5, 0.5, 115 | } 116 | vb, err := device.CreateVertexBuffer( 117 | uint(len(vertices)*4), 118 | d3d9.USAGE_WRITEONLY, 119 | 0, 120 | d3d9.POOL_DEFAULT, 121 | 0, 122 | ) 123 | check(err) 124 | defer vb.Release() 125 | vbMem, err := vb.Lock(0, 0, d3d9.LOCK_DISCARD) 126 | check(err) 127 | vbMem.SetFloat32s(0, vertices) 128 | check(vb.Unlock()) 129 | 130 | check(device.SetStreamSource(0, vb, 0, 2*4)) 131 | 132 | decl, err := device.CreateVertexDeclaration([]d3d9.VERTEXELEMENT{ 133 | {Type: d3d9.DECLTYPE_FLOAT2, Usage: d3d9.DECLUSAGE_POSITION}, 134 | d3d9.DeclEnd(), 135 | }) 136 | check(err) 137 | defer decl.Release() 138 | check(device.SetVertexDeclaration(decl)) 139 | 140 | vs, err := device.CreateVertexShaderFromBytes(vertexShaderObject) 141 | check(err) 142 | defer vs.Release() 143 | check(device.SetVertexShader(vs)) 144 | 145 | ps, err := device.CreatePixelShaderFromBytes(pixelShaderObject) 146 | check(err) 147 | defer ps.Release() 148 | check(device.SetPixelShader(ps)) 149 | 150 | // create a timer that ticks every 10ms and register a callback for it 151 | rotation := float32(0) 152 | w32.SetTimer(windowHandle, 1, 10, 0) 153 | var msg w32.MSG 154 | for w32.GetMessage(&msg, 0, 0, 0) != 0 { 155 | w32.TranslateMessage(&msg) 156 | // create a 4x4 model-view-projection matrix that rotates the 157 | // rectangle about the Z-axis 158 | s, c := math.Sincos(float64(rotation)) 159 | sin, cos := float32(s), float32(c) 160 | mvp := [16]float32{ 161 | cos, sin, 0, 0, 162 | -sin, cos, 0, 0, 163 | 0, 0, 1, 0, 164 | 0, 0, 0, 1, 165 | } 166 | rotation += 0.1 167 | check(device.SetVertexShaderConstantF(0, mvp[:])) 168 | check(device.Clear(nil, d3d9.CLEAR_TARGET, 255, 1, 0)) 169 | check(device.BeginScene()) 170 | check(device.DrawPrimitive(d3d9.PT_TRIANGLESTRIP, 0, 2)) 171 | check(device.EndScene()) 172 | check(device.Present(nil, nil, 0, nil)) 173 | w32.DispatchMessage(&msg) 174 | } 175 | } 176 | 177 | func check(err error) { 178 | if err != nil { 179 | panic(err) 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /samples/rotating_quad/readme.md: -------------------------------------------------------------------------------- 1 | This sample displays a rotating rectangle. It shows you how to use vertex 2 | buffers and shaders with a transformation matrix. The shaders are compiled on 3 | from source using the [dxc](https://github.com/gonutz/dxc) library, which 4 | provides a wrapper around the DirectX compiler DLL. 5 | 6 | Note that the rectangle's aspect ratio is that of the window, so if you resize 7 | the window, the rectangle changes size. That is because we use the virtual 8 | coordinate system of Direct3D which has x and y axes go from -1 to 1. Usually 9 | you would scale these to the window resolution. This is omitted for simplicity 10 | of the example. 11 | 12 | For window creation this sample uses 13 | [the Windows API](https://github.com/gonutz/w32). Direct3D needs a handle to 14 | the window it runs in so you need a method for setting this up. Other libraries 15 | that you can use include [SDL2](https://github.com/veandco/go-sdl2), 16 | [Allen Dang's gform library](https://github.com/AllenDang/gform) and the 17 | [walk library](https://github.com/lxn/walk). 18 | 19 | If you simply build this sample with `go build` the resulting program will keep 20 | a console window open while running. Use the `build.bat` to build instead, it 21 | passes the flag `-H=windowsgui` to the linker which gets rid of the console 22 | window, like so: 23 | 24 | go build -ldflags="-H=windowsgui" 25 | -------------------------------------------------------------------------------- /samples/screenshot/README.md: -------------------------------------------------------------------------------- 1 | This example shows how to use Direct3D to capture a screenshot of your desktop. 2 | The image is saved to "screen.png". 3 | -------------------------------------------------------------------------------- /samples/screenshot/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gonutz/d3d9/samples/screenshot 2 | 3 | go 1.11 4 | 5 | require github.com/gonutz/d3d9 v1.2.3 6 | -------------------------------------------------------------------------------- /samples/screenshot/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gonutz/d3d9 v1.2.3 h1:DmsDobNJDN3B5gk3AGcpKq8xZfLbVJ1C6H3bVn4GKKQ= 2 | github.com/gonutz/d3d9 v1.2.3/go.mod h1:q74g3QbR280b+qYauwEV0N9SVadszWPLZ4l/wHiD/AA= 3 | -------------------------------------------------------------------------------- /samples/screenshot/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "image" 5 | "image/png" 6 | "os" 7 | "unsafe" 8 | 9 | "github.com/gonutz/d3d9" 10 | ) 11 | 12 | func main() { 13 | d3d, err := d3d9.Create(d3d9.SDK_VERSION) 14 | check(err) 15 | defer d3d.Release() 16 | 17 | mode, err := d3d.GetAdapterDisplayMode(d3d9.ADAPTER_DEFAULT) 18 | check(err) 19 | if mode.Format != d3d9.FMT_X8R8G8B8 && mode.Format != d3d9.FMT_A8R8G8B8 { 20 | panic("We assume the mode is ARGB.") 21 | } 22 | 23 | device, _, err := d3d.CreateDevice( 24 | d3d9.ADAPTER_DEFAULT, 25 | d3d9.DEVTYPE_HAL, 26 | 0, 27 | d3d9.CREATE_SOFTWARE_VERTEXPROCESSING, 28 | d3d9.PRESENT_PARAMETERS{ 29 | Windowed: 1, 30 | BackBufferCount: 1, 31 | BackBufferWidth: mode.Width, 32 | BackBufferHeight: mode.Height, 33 | SwapEffect: d3d9.SWAPEFFECT_DISCARD, 34 | }, 35 | ) 36 | check(err) 37 | defer device.Release() 38 | 39 | surface, err := device.CreateOffscreenPlainSurface( 40 | uint(mode.Width), 41 | uint(mode.Height), 42 | d3d9.FMT_A8R8G8B8, 43 | d3d9.POOL_SYSTEMMEM, 44 | 0, 45 | ) 46 | check(err) 47 | defer surface.Release() 48 | 49 | check(device.GetFrontBufferData(0, surface)) 50 | 51 | r, err := surface.LockRect(nil, 0) 52 | check(err) 53 | defer surface.UnlockRect() 54 | 55 | // Pitch says how many bytes there are in one line of pixels of the surface. 56 | // This may include padding bytes that would need to be handled correctly 57 | // if not 0. 58 | if r.Pitch != int32(mode.Width*4) { 59 | panic("We assume that there is no padding in the surface data.") 60 | } 61 | 62 | // Create an image of the same size as the surface and copy it. 63 | img := image.NewRGBA(image.Rect(0, 0, int(mode.Width), int(mode.Height))) 64 | for i := range img.Pix { 65 | // Do the magic to use r.PBits as a byte pointer. 66 | img.Pix[i] = *((*byte)(unsafe.Pointer(r.PBits + uintptr(i)))) 67 | } 68 | // We want RGBA for our Go image but have ARGB in our surface. Swap some 69 | // bytes to make it fit. 70 | for i := 0; i < len(img.Pix); i += 4 { 71 | img.Pix[i+0], img.Pix[i+2] = img.Pix[i+2], img.Pix[i+0] 72 | } 73 | 74 | f, err := os.Create("screen.png") 75 | check(err) 76 | defer f.Close() 77 | check(png.Encode(f, img)) 78 | } 79 | 80 | func check(err error) { 81 | if err != nil { 82 | panic(err) 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /samples/static_triangle/build.bat: -------------------------------------------------------------------------------- 1 | go build -ldflags -H=windowsgui -------------------------------------------------------------------------------- /samples/static_triangle/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gonutz/d3d9/samples/static_triangle 2 | 3 | go 1.11 4 | 5 | require ( 6 | github.com/gonutz/d3d9 v1.2.3 7 | github.com/gonutz/dxc v1.1.0 8 | github.com/gonutz/w32/v2 v2.11.1 9 | ) 10 | -------------------------------------------------------------------------------- /samples/static_triangle/go.sum: -------------------------------------------------------------------------------- 1 | github.com/gonutz/d3d9 v1.2.3 h1:DmsDobNJDN3B5gk3AGcpKq8xZfLbVJ1C6H3bVn4GKKQ= 2 | github.com/gonutz/d3d9 v1.2.3/go.mod h1:q74g3QbR280b+qYauwEV0N9SVadszWPLZ4l/wHiD/AA= 3 | github.com/gonutz/dxc v1.1.0 h1:IOFuTlTiSZCIL34CXJFbZFCxWjj7cRbVbyfdPLsdJCg= 4 | github.com/gonutz/dxc v1.1.0/go.mod h1:SMdn5oWWIFnNdVM/BSLp7QwvC15S/dgabQsajOlk9x8= 5 | github.com/gonutz/w32/v2 v2.11.1 h1:plG738ZY7VIkPGf3adZ6lFeAf2evCKrULKyZT5GrPoc= 6 | github.com/gonutz/w32/v2 v2.11.1/go.mod h1:MgtHx0AScDVNKyB+kjyPder4xIi3XAcHS6LDDU2DmdE= 7 | -------------------------------------------------------------------------------- /samples/static_triangle/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "runtime" 5 | "syscall" 6 | 7 | "github.com/gonutz/d3d9" 8 | "github.com/gonutz/dxc" 9 | "github.com/gonutz/w32/v2" 10 | ) 11 | 12 | const vertexShaderCode = ` 13 | struct input { 14 | float4 position : POSITION; 15 | }; 16 | 17 | struct output { 18 | float4 position : POSITION; 19 | }; 20 | 21 | void main(in input IN, out output OUT) { 22 | OUT.position = IN.position; 23 | } 24 | ` 25 | 26 | const pixelShaderCode = ` 27 | struct input {}; 28 | 29 | struct output { 30 | float4 color : COLOR0; 31 | }; 32 | 33 | void main(in input IN, out output OUT) { 34 | OUT.color = float4(1, 0, 1, 1); 35 | } 36 | ` 37 | 38 | func main() { 39 | runtime.LockOSThread() 40 | 41 | vertexShaderObject, err := dxc.Compile( 42 | []byte(vertexShaderCode), 43 | "main", 44 | "vs_2_0", 45 | dxc.WARNINGS_ARE_ERRORS, 46 | 0, 47 | ) 48 | check(err) 49 | 50 | pixelShaderObject, err := dxc.Compile( 51 | []byte(pixelShaderCode), 52 | "main", 53 | "ps_2_0", 54 | dxc.WARNINGS_ARE_ERRORS, 55 | 0, 56 | ) 57 | check(err) 58 | 59 | const className = "fullscreen_window_class" 60 | classNamePtr, _ := syscall.UTF16PtrFromString(className) 61 | w32.RegisterClassEx(&w32.WNDCLASSEX{ 62 | Cursor: w32.LoadCursor(0, w32.MakeIntResource(w32.IDC_ARROW)), 63 | WndProc: syscall.NewCallback(func(window w32.HWND, msg uint32, w, l uintptr) uintptr { 64 | switch msg { 65 | case w32.WM_KEYDOWN: 66 | if w == w32.VK_ESCAPE { 67 | w32.SendMessage(window, w32.WM_CLOSE, 0, 0) 68 | } 69 | return 0 70 | case w32.WM_DESTROY: 71 | w32.PostQuitMessage(0) 72 | return 0 73 | default: 74 | return w32.DefWindowProc(window, msg, w, l) 75 | } 76 | }), 77 | ClassName: classNamePtr, 78 | }) 79 | 80 | windowNamePtr, _ := syscall.UTF16PtrFromString("Static Triangle") 81 | windowHandle := w32.CreateWindow( 82 | classNamePtr, 83 | windowNamePtr, 84 | w32.WS_OVERLAPPEDWINDOW|w32.WS_VISIBLE, 85 | w32.CW_USEDEFAULT, w32.CW_USEDEFAULT, 640, 480, 86 | 0, 0, 0, nil, 87 | ) 88 | 89 | d3d, err := d3d9.Create(d3d9.SDK_VERSION) 90 | check(err) 91 | defer d3d.Release() 92 | 93 | device, _, err := d3d.CreateDevice( 94 | d3d9.ADAPTER_DEFAULT, 95 | d3d9.DEVTYPE_HAL, 96 | d3d9.HWND(windowHandle), 97 | d3d9.CREATE_HARDWARE_VERTEXPROCESSING, 98 | d3d9.PRESENT_PARAMETERS{ 99 | Windowed: 1, 100 | SwapEffect: d3d9.SWAPEFFECT_DISCARD, 101 | HDeviceWindow: d3d9.HWND(windowHandle), 102 | }, 103 | ) 104 | check(err) 105 | defer device.Release() 106 | 107 | check(device.SetRenderState(d3d9.RS_CULLMODE, uint32(d3d9.CULL_NONE))) 108 | 109 | vs, err := device.CreateVertexShaderFromBytes(vertexShaderObject) 110 | check(err) 111 | defer vs.Release() 112 | check(device.SetVertexShader(vs)) 113 | 114 | ps, err := device.CreatePixelShaderFromBytes(pixelShaderObject) 115 | check(err) 116 | defer ps.Release() 117 | check(device.SetPixelShader(ps)) 118 | 119 | vertices := []float32{ 120 | -0.5, -0.5, 121 | 0, 0.5, 122 | 0.5, -0.5, 123 | } 124 | vb, err := device.CreateVertexBuffer(uint(len(vertices)*4), 125 | d3d9.USAGE_WRITEONLY, 0, d3d9.POOL_DEFAULT, 0) 126 | check(err) 127 | defer vb.Release() 128 | data, err := vb.Lock(0, 0, d3d9.LOCK_DISCARD) 129 | check(err) 130 | data.SetFloat32s(0, vertices) 131 | check(vb.Unlock()) 132 | check(device.SetStreamSource(0, vb, 0, 2*4)) 133 | 134 | decl, err := device.CreateVertexDeclaration([]d3d9.VERTEXELEMENT{ 135 | {Type: d3d9.DECLTYPE_FLOAT2, Usage: d3d9.DECLUSAGE_POSITION}, 136 | d3d9.DeclEnd(), 137 | }) 138 | check(err) 139 | defer decl.Release() 140 | check(device.SetVertexDeclaration(decl)) 141 | 142 | // Create a timer that ticks every 100ms and register a callback for it. 143 | w32.SetTimer(windowHandle, 1, 100, 0) 144 | var msg w32.MSG 145 | for w32.GetMessage(&msg, 0, 0, 0) != 0 { 146 | w32.TranslateMessage(&msg) 147 | check(device.Clear(nil, d3d9.CLEAR_TARGET, 0, 0, 0)) 148 | check(device.BeginScene()) 149 | check(device.DrawPrimitive(d3d9.PT_TRIANGLELIST, 0, 1)) 150 | check(device.EndScene()) 151 | check(device.Present(nil, nil, 0, nil)) 152 | w32.DispatchMessage(&msg) 153 | } 154 | } 155 | 156 | func check(err error) { 157 | if err != nil { 158 | panic(err) 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /samples/static_triangle/readme.md: -------------------------------------------------------------------------------- 1 | This example initializes Direct3D9 and draws a static pink triangle in the 2 | center of a black background. It shows how to create and use vertex buffers and 3 | shaders. The shaders are compiled on from source using the 4 | [dxc](https://github.com/gonutz/dxc) library, which provides a wrapper around 5 | the DirectX compiler DLL. 6 | 7 | For window creation this sample uses 8 | [the Windows API](https://github.com/gonutz/w32). Direct3D needs a handle to 9 | the window it runs in so you need a method for setting this up. Other libraries 10 | that you can use include [SDL2](https://github.com/veandco/go-sdl2), 11 | [Allen Dang's gform library](https://github.com/AllenDang/gform) and the 12 | [walk library](https://github.com/lxn/walk). 13 | 14 | If you simply build this sample with `go build` the resulting program will keep 15 | a console window open while running. Use the `build.bat` to build instead, it 16 | passes the flag `-H=windowsgui` to the linker which gets rid of the console 17 | window, like so: 18 | 19 | go build -ldflags="-H=windowsgui" 20 | -------------------------------------------------------------------------------- /state_block_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // StateBlock and its methods are used to encapsulate render states. 9 | type StateBlock struct { 10 | vtbl *stateBlockVtbl 11 | } 12 | 13 | type stateBlockVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | Capture uintptr 20 | Apply uintptr 21 | } 22 | 23 | // AddRef increments the reference count for an interface on an object. This 24 | // method should be called for every new copy of a pointer to an interface on an 25 | // object. 26 | func (obj *StateBlock) AddRef() uint32 { 27 | ret, _, _ := syscall.Syscall( 28 | obj.vtbl.AddRef, 29 | 1, 30 | uintptr(unsafe.Pointer(obj)), 31 | 0, 32 | 0, 33 | ) 34 | return uint32(ret) 35 | } 36 | 37 | // Release has to be called when finished using the object to free its 38 | // associated resources. 39 | func (obj *StateBlock) Release() uint32 { 40 | ret, _, _ := syscall.Syscall( 41 | obj.vtbl.Release, 42 | 1, 43 | uintptr(unsafe.Pointer(obj)), 44 | 0, 45 | 0, 46 | ) 47 | return uint32(ret) 48 | } 49 | 50 | // GetDevice retrieves the associated device. 51 | // Call Release on the returned device when finished using it. 52 | func (obj *StateBlock) GetDevice() (device *Device, err Error) { 53 | ret, _, _ := syscall.Syscall( 54 | obj.vtbl.GetDevice, 55 | 2, 56 | uintptr(unsafe.Pointer(obj)), 57 | uintptr(unsafe.Pointer(&device)), 58 | 0, 59 | ) 60 | err = toErr(ret) 61 | return 62 | } 63 | 64 | // Capture captures the current value of states that are included in a 65 | // stateblock. 66 | func (obj *StateBlock) Capture() Error { 67 | ret, _, _ := syscall.Syscall( 68 | obj.vtbl.Capture, 69 | 1, 70 | uintptr(unsafe.Pointer(obj)), 71 | 0, 72 | 0, 73 | ) 74 | return toErr(ret) 75 | } 76 | 77 | // Apply applies the state block to the current device state. 78 | func (obj *StateBlock) Apply() Error { 79 | ret, _, _ := syscall.Syscall( 80 | obj.vtbl.Apply, 81 | 1, 82 | uintptr(unsafe.Pointer(obj)), 83 | 0, 84 | 0, 85 | ) 86 | return toErr(ret) 87 | } 88 | -------------------------------------------------------------------------------- /surface_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // Surface and its methods are used to query and prepare surfaces. 9 | type Surface struct { 10 | vtbl *surfaceVtbl 11 | } 12 | 13 | type surfaceVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | SetPrivateData uintptr 20 | GetPrivateData uintptr 21 | FreePrivateData uintptr 22 | SetPriority uintptr 23 | GetPriority uintptr 24 | PreLoad uintptr 25 | GetType uintptr 26 | GetContainer uintptr 27 | GetDesc uintptr 28 | LockRect uintptr 29 | UnlockRect uintptr 30 | GetDC uintptr 31 | ReleaseDC uintptr 32 | } 33 | 34 | // AddRef increments the reference count for an interface on an object. This 35 | // method should be called for every new copy of a pointer to an interface on an 36 | // object. 37 | func (obj *Surface) AddRef() uint32 { 38 | ret, _, _ := syscall.Syscall( 39 | obj.vtbl.AddRef, 40 | 1, 41 | uintptr(unsafe.Pointer(obj)), 42 | 0, 43 | 0, 44 | ) 45 | return uint32(ret) 46 | } 47 | 48 | // Release has to be called when finished using the object to free its 49 | // associated resources. 50 | func (obj *Surface) Release() uint32 { 51 | ret, _, _ := syscall.Syscall( 52 | obj.vtbl.Release, 53 | 1, 54 | uintptr(unsafe.Pointer(obj)), 55 | 0, 56 | 0, 57 | ) 58 | return uint32(ret) 59 | } 60 | 61 | // GetDevice retrieves the device associated with a resource. 62 | // Call Release on the returned device when finished using it. 63 | func (obj *Surface) GetDevice() (device *Device, err Error) { 64 | ret, _, _ := syscall.Syscall( 65 | obj.vtbl.GetDevice, 66 | 2, 67 | uintptr(unsafe.Pointer(obj)), 68 | uintptr(unsafe.Pointer(&device)), 69 | 0, 70 | ) 71 | err = toErr(ret) 72 | return 73 | } 74 | 75 | // SetPrivateData associates data with the resource that is intended for use by 76 | // the application, not by Direct3D. Data is passed by value, and multiple sets 77 | // of data can be associated with a single resource. 78 | func (obj *Surface) SetPrivateData( 79 | refguid GUID, 80 | data uintptr, 81 | sizeOfData uint32, 82 | flags uint32, 83 | ) Error { 84 | ret, _, _ := syscall.Syscall6( 85 | obj.vtbl.SetPrivateData, 86 | 5, 87 | uintptr(unsafe.Pointer(obj)), 88 | uintptr(unsafe.Pointer(&refguid)), 89 | data, 90 | uintptr(sizeOfData), 91 | uintptr(flags), 92 | 0, 93 | ) 94 | return toErr(ret) 95 | } 96 | 97 | // SetPrivateDataBytes associates data with the resource that is intended for 98 | // use by the application, not by Direct3D. Data is passed by value, and 99 | // multiple sets of data can be associated with a single resource. 100 | func (obj *Surface) SetPrivateDataBytes( 101 | refguid GUID, 102 | data []byte, 103 | flags uint32, 104 | ) Error { 105 | return obj.SetPrivateData( 106 | refguid, 107 | uintptr(unsafe.Pointer(&data[0])), 108 | uint32(len(data)), 109 | flags, 110 | ) 111 | } 112 | 113 | // GetPrivateData copies the private data associated with the resource to a 114 | // provided buffer. 115 | func (obj *Surface) GetPrivateData(refguid GUID) (data []byte, err Error) { 116 | // first get the data size by passing nil as the data pointer 117 | var sizeInBytes uint 118 | ret, _, _ := syscall.Syscall6( 119 | obj.vtbl.GetPrivateData, 120 | 4, 121 | uintptr(unsafe.Pointer(obj)), 122 | uintptr(unsafe.Pointer(&refguid)), 123 | 0, 124 | uintptr(unsafe.Pointer(&sizeInBytes)), 125 | 0, 126 | 0, 127 | ) 128 | if err := toErr(ret); err != nil { 129 | return nil, err 130 | } 131 | data = make([]byte, sizeInBytes) 132 | ret, _, _ = syscall.Syscall6( 133 | obj.vtbl.GetPrivateData, 134 | 4, 135 | uintptr(unsafe.Pointer(obj)), 136 | uintptr(unsafe.Pointer(&refguid)), 137 | uintptr(unsafe.Pointer(&data[0])), 138 | uintptr(unsafe.Pointer(&sizeInBytes)), 139 | 0, 140 | 0, 141 | ) 142 | return data, toErr(ret) 143 | } 144 | 145 | // FreePrivateData frees the specified private data associated with this 146 | // resource. 147 | func (obj *Surface) FreePrivateData(refguid GUID) Error { 148 | ret, _, _ := syscall.Syscall( 149 | obj.vtbl.FreePrivateData, 150 | 2, 151 | uintptr(unsafe.Pointer(obj)), 152 | uintptr(unsafe.Pointer(&refguid)), 153 | 0, 154 | ) 155 | return toErr(ret) 156 | } 157 | 158 | // SetPriority assigns the priority of a resource for scheduling purposes. 159 | func (obj *Surface) SetPriority(priorityNew uint32) uint32 { 160 | ret, _, _ := syscall.Syscall( 161 | obj.vtbl.SetPriority, 162 | 2, 163 | uintptr(unsafe.Pointer(obj)), 164 | uintptr(priorityNew), 165 | 0, 166 | ) 167 | return uint32(ret) 168 | } 169 | 170 | // GetPriority retrieves the priority for this resource. 171 | func (obj *Surface) GetPriority() uint32 { 172 | ret, _, _ := syscall.Syscall( 173 | obj.vtbl.GetPriority, 174 | 1, 175 | uintptr(unsafe.Pointer(obj)), 176 | 0, 177 | 0, 178 | ) 179 | return uint32(ret) 180 | } 181 | 182 | // PreLoad preloads a managed resource. 183 | func (obj *Surface) PreLoad() { 184 | syscall.Syscall( 185 | obj.vtbl.PreLoad, 186 | 1, 187 | uintptr(unsafe.Pointer(obj)), 188 | 0, 189 | 0, 190 | ) 191 | } 192 | 193 | // GetType returns the type of the resource. 194 | func (obj *Surface) GetType() RESOURCETYPE { 195 | ret, _, _ := syscall.Syscall( 196 | obj.vtbl.GetType, 197 | 1, 198 | uintptr(unsafe.Pointer(obj)), 199 | 0, 200 | 0, 201 | ) 202 | return RESOURCETYPE(ret) 203 | } 204 | 205 | func (obj *Surface) getContainer(riid GUID, container uintptr) Error { 206 | ret, _, _ := syscall.Syscall( 207 | obj.vtbl.GetContainer, 208 | 3, 209 | uintptr(unsafe.Pointer(obj)), 210 | uintptr(unsafe.Pointer(&riid)), 211 | container, 212 | ) 213 | return toErr(ret) 214 | } 215 | 216 | // GetContainerCubeTexture provides access to the parent cube texture. 217 | func (obj *Surface) GetContainerCubeTexture(riid GUID) (tex *CubeTexture, err Error) { 218 | err = obj.getContainer(riid, uintptr(unsafe.Pointer(&tex))) 219 | return 220 | } 221 | 222 | // GetContainerTexture provides access to the parent texture. 223 | func (obj *Surface) GetContainerTexture(riid GUID) (tex *Texture, err Error) { 224 | err = obj.getContainer(riid, uintptr(unsafe.Pointer(&tex))) 225 | return 226 | } 227 | 228 | // GetContainerSwapChain provides access to the parent swap chain if this 229 | // surface is a back buffer. 230 | func (obj Surface) GetContainerSwapChain(riid GUID) (chain *SwapChain, err Error) { 231 | err = obj.getContainer(riid, uintptr(unsafe.Pointer(&chain))) 232 | return 233 | } 234 | 235 | // GetDesc retrieves a description of the surface. 236 | func (obj *Surface) GetDesc() (desc SURFACE_DESC, err Error) { 237 | ret, _, _ := syscall.Syscall( 238 | obj.vtbl.GetDesc, 239 | 2, 240 | uintptr(unsafe.Pointer(obj)), 241 | uintptr(unsafe.Pointer(&desc)), 242 | 0, 243 | ) 244 | err = toErr(ret) 245 | return 246 | } 247 | 248 | // LockRect locks a rectangle on a surface. 249 | func (obj *Surface) LockRect( 250 | rect *RECT, 251 | flags uint32, 252 | ) (lockedRect LOCKED_RECT, err Error) { 253 | ret, _, _ := syscall.Syscall6( 254 | obj.vtbl.LockRect, 255 | 4, 256 | uintptr(unsafe.Pointer(obj)), 257 | uintptr(unsafe.Pointer(&lockedRect)), 258 | uintptr(unsafe.Pointer(rect)), 259 | uintptr(flags), 260 | 0, 261 | 0, 262 | ) 263 | err = toErr(ret) 264 | return 265 | } 266 | 267 | // UnlockRect unlocks a rectangle on a surface. 268 | func (obj *Surface) UnlockRect() Error { 269 | ret, _, _ := syscall.Syscall( 270 | obj.vtbl.UnlockRect, 271 | 1, 272 | uintptr(unsafe.Pointer(obj)), 273 | 0, 274 | 0, 275 | ) 276 | return toErr(ret) 277 | } 278 | 279 | // GetDC retrieves a device context. 280 | func (obj *Surface) GetDC() (hdc HDC, err Error) { 281 | ret, _, _ := syscall.Syscall( 282 | obj.vtbl.GetDC, 283 | 2, 284 | uintptr(unsafe.Pointer(obj)), 285 | uintptr(unsafe.Pointer(&hdc)), 286 | 0, 287 | ) 288 | err = toErr(ret) 289 | return 290 | } 291 | 292 | // ReleaseDC releases a device context handle. 293 | func (obj *Surface) ReleaseDC(hdc HDC) Error { 294 | ret, _, _ := syscall.Syscall( 295 | obj.vtbl.ReleaseDC, 296 | 2, 297 | uintptr(unsafe.Pointer(obj)), 298 | uintptr(unsafe.Pointer(hdc)), 299 | 0, 300 | ) 301 | return toErr(ret) 302 | } 303 | -------------------------------------------------------------------------------- /swap_chain_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // SwapChain and its methods are used to manipulate a swap chain. 9 | type SwapChain struct { 10 | vtbl *swapChainVtbl 11 | } 12 | 13 | type swapChainVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | Present uintptr 19 | GetFrontBufferData uintptr 20 | GetBackBuffer uintptr 21 | GetRasterStatus uintptr 22 | GetDisplayMode uintptr 23 | GetDevice uintptr 24 | GetPresentParameters uintptr 25 | } 26 | 27 | // AddRef increments the reference count for an interface on an object. This 28 | // method should be called for every new copy of a pointer to an interface on an 29 | // object. 30 | func (obj *SwapChain) AddRef() uint32 { 31 | ret, _, _ := syscall.Syscall( 32 | obj.vtbl.AddRef, 33 | 1, 34 | uintptr(unsafe.Pointer(obj)), 35 | 0, 36 | 0, 37 | ) 38 | return uint32(ret) 39 | } 40 | 41 | // Release has to be called when finished using the object to free its 42 | // associated resources. 43 | func (obj *SwapChain) Release() uint32 { 44 | ret, _, _ := syscall.Syscall( 45 | obj.vtbl.Release, 46 | 1, 47 | uintptr(unsafe.Pointer(obj)), 48 | 0, 49 | 0, 50 | ) 51 | return uint32(ret) 52 | } 53 | 54 | // Present presents the contents of the next buffer in the sequence of back 55 | // buffers owned by the swap chain. 56 | func (obj *SwapChain) Present( 57 | sourceRect *RECT, 58 | destRect *RECT, 59 | destWindowOverride HWND, 60 | dirtyRegion *RGNDATA, 61 | flags uint32, 62 | ) Error { 63 | ret, _, _ := syscall.Syscall6( 64 | obj.vtbl.Present, 65 | 6, 66 | uintptr(unsafe.Pointer(obj)), 67 | uintptr(unsafe.Pointer(sourceRect)), 68 | uintptr(unsafe.Pointer(destRect)), 69 | uintptr(destWindowOverride), 70 | uintptr(unsafe.Pointer(dirtyRegion)), 71 | uintptr(flags), 72 | ) 73 | return toErr(ret) 74 | } 75 | 76 | // GetFrontBufferData generates a copy of the swapchain's front buffer and 77 | // places that copy in a system memory buffer provided by the application. 78 | // Call Release on the returned surface when finished using it. 79 | func (obj *SwapChain) GetFrontBufferData(destSurface *Surface) Error { 80 | ret, _, _ := syscall.Syscall( 81 | obj.vtbl.GetFrontBufferData, 82 | 2, 83 | uintptr(unsafe.Pointer(obj)), 84 | uintptr(unsafe.Pointer(destSurface)), 85 | 0, 86 | ) 87 | return toErr(ret) 88 | } 89 | 90 | // GetBackBuffer retrieves a back buffer from the swap chain of the device. 91 | // Call Release on the returned surface when finished using it. 92 | func (obj *SwapChain) GetBackBuffer( 93 | backBuffer uint, 94 | typ BACKBUFFER_TYPE, 95 | ) (buffer *Surface, err Error) { 96 | ret, _, _ := syscall.Syscall6( 97 | obj.vtbl.GetBackBuffer, 98 | 4, 99 | uintptr(unsafe.Pointer(obj)), 100 | uintptr(backBuffer), 101 | uintptr(typ), 102 | uintptr(unsafe.Pointer(&buffer)), 103 | 0, 104 | 0, 105 | ) 106 | err = toErr(ret) 107 | return 108 | } 109 | 110 | // GetRasterStatus returns information describing the raster of the monitor on 111 | // which the swap chain is presented. 112 | func (obj *SwapChain) GetRasterStatus() (status RASTER_STATUS, err Error) { 113 | ret, _, _ := syscall.Syscall( 114 | obj.vtbl.GetRasterStatus, 115 | 2, 116 | uintptr(unsafe.Pointer(obj)), 117 | uintptr(unsafe.Pointer(&status)), 118 | 0, 119 | ) 120 | err = toErr(ret) 121 | return 122 | } 123 | 124 | // GetDisplayMode retrieves the display mode's spatial resolution, color 125 | // resolution, and refresh frequency. 126 | func (obj *SwapChain) GetDisplayMode() (mode DISPLAYMODE, err Error) { 127 | ret, _, _ := syscall.Syscall( 128 | obj.vtbl.GetDisplayMode, 129 | 2, 130 | uintptr(unsafe.Pointer(obj)), 131 | uintptr(unsafe.Pointer(&mode)), 132 | 0, 133 | ) 134 | err = toErr(ret) 135 | return 136 | } 137 | 138 | // GetDevice retrieves the device associated with the swap chain. 139 | // Call Release on the returned device when finished using it. 140 | func (obj *SwapChain) GetDevice() (device *Device, err Error) { 141 | ret, _, _ := syscall.Syscall( 142 | obj.vtbl.GetDevice, 143 | 2, 144 | uintptr(unsafe.Pointer(obj)), 145 | uintptr(unsafe.Pointer(&device)), 146 | 0, 147 | ) 148 | err = toErr(ret) 149 | return 150 | } 151 | 152 | // GetPresentParameters retrieves the presentation parameters associated with a 153 | // swap chain. 154 | func (obj *SwapChain) GetPresentParameters() (params PRESENT_PARAMETERS, err Error) { 155 | ret, _, _ := syscall.Syscall( 156 | obj.vtbl.GetPresentParameters, 157 | 2, 158 | uintptr(unsafe.Pointer(obj)), 159 | uintptr(unsafe.Pointer(¶ms)), 160 | 0, 161 | ) 162 | err = toErr(ret) 163 | return 164 | } 165 | -------------------------------------------------------------------------------- /texture_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // Texture and its methods are used to manipulate a texture resource. 9 | type Texture struct { 10 | vtbl *textureVtbl 11 | } 12 | 13 | type textureVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | SetPrivateData uintptr 20 | GetPrivateData uintptr 21 | FreePrivateData uintptr 22 | SetPriority uintptr 23 | GetPriority uintptr 24 | PreLoad uintptr 25 | GetType uintptr 26 | SetLOD uintptr 27 | GetLOD uintptr 28 | GetLevelCount uintptr 29 | SetAutoGenFilterType uintptr 30 | GetAutoGenFilterType uintptr 31 | GenerateMipSubLevels uintptr 32 | GetLevelDesc uintptr 33 | GetSurfaceLevel uintptr 34 | LockRect uintptr 35 | UnlockRect uintptr 36 | AddDirtyRect uintptr 37 | } 38 | 39 | func (obj *Texture) baseTexturePointer() uintptr { 40 | return uintptr(unsafe.Pointer(obj)) 41 | } 42 | 43 | // AddRef increments the reference count for an interface on an object. This 44 | // method should be called for every new copy of a pointer to an interface on an 45 | // object. 46 | func (obj *Texture) AddRef() uint32 { 47 | ret, _, _ := syscall.Syscall( 48 | obj.vtbl.AddRef, 49 | 1, 50 | uintptr(unsafe.Pointer(obj)), 51 | 0, 52 | 0, 53 | ) 54 | return uint32(ret) 55 | } 56 | 57 | // Release has to be called when finished using the object to free its 58 | // associated resources. 59 | func (obj *Texture) Release() uint32 { 60 | ret, _, _ := syscall.Syscall( 61 | obj.vtbl.Release, 62 | 1, 63 | uintptr(unsafe.Pointer(obj)), 64 | 0, 65 | 0, 66 | ) 67 | return uint32(ret) 68 | } 69 | 70 | // GetDevice retrieves the device associated with a resource. 71 | // Call Release on the returned device when finished using it. 72 | func (obj *Texture) GetDevice() (device *Device, err Error) { 73 | ret, _, _ := syscall.Syscall( 74 | obj.vtbl.GetDevice, 75 | 2, 76 | uintptr(unsafe.Pointer(obj)), 77 | uintptr(unsafe.Pointer(&device)), 78 | 0, 79 | ) 80 | err = toErr(ret) 81 | return 82 | } 83 | 84 | // SetPrivateData associates data with the resource that is intended for use by 85 | // the application, not by Direct3D. Data is passed by value, and multiple sets 86 | // of data can be associated with a single resource. 87 | func (obj *Texture) SetPrivateData( 88 | refguid GUID, 89 | data uintptr, 90 | sizeOfData uint32, 91 | flags uint32, 92 | ) Error { 93 | ret, _, _ := syscall.Syscall6( 94 | obj.vtbl.SetPrivateData, 95 | 5, 96 | uintptr(unsafe.Pointer(obj)), 97 | uintptr(unsafe.Pointer(&refguid)), 98 | data, 99 | uintptr(sizeOfData), 100 | uintptr(flags), 101 | 0, 102 | ) 103 | return toErr(ret) 104 | } 105 | 106 | // SetPrivateDataBytes associates data with the resource that is intended for 107 | // use by the application, not by Direct3D. Data is passed by value, and 108 | // multiple sets of data can be associated with a single resource. 109 | func (obj *Texture) SetPrivateDataBytes( 110 | refguid GUID, 111 | data []byte, 112 | flags uint32, 113 | ) Error { 114 | return obj.SetPrivateData( 115 | refguid, 116 | uintptr(unsafe.Pointer(&data[0])), 117 | uint32(len(data)), 118 | flags, 119 | ) 120 | } 121 | 122 | // GetPrivateData copies the private data associated with the resource to a 123 | // provided buffer. 124 | func (obj *Texture) GetPrivateData(refguid GUID) (data []byte, err Error) { 125 | // first get the data size by passing nil as the data pointer 126 | var sizeInBytes uint 127 | ret, _, _ := syscall.Syscall6( 128 | obj.vtbl.GetPrivateData, 129 | 4, 130 | uintptr(unsafe.Pointer(obj)), 131 | uintptr(unsafe.Pointer(&refguid)), 132 | 0, 133 | uintptr(unsafe.Pointer(&sizeInBytes)), 134 | 0, 135 | 0, 136 | ) 137 | if err := toErr(ret); err != nil { 138 | return nil, err 139 | } 140 | data = make([]byte, sizeInBytes) 141 | ret, _, _ = syscall.Syscall6( 142 | obj.vtbl.GetPrivateData, 143 | 4, 144 | uintptr(unsafe.Pointer(obj)), 145 | uintptr(unsafe.Pointer(&refguid)), 146 | uintptr(unsafe.Pointer(&data[0])), 147 | uintptr(unsafe.Pointer(&sizeInBytes)), 148 | 0, 149 | 0, 150 | ) 151 | return data, toErr(ret) 152 | } 153 | 154 | // FreePrivateData frees the specified private data associated with this 155 | // resource. 156 | func (obj *Texture) FreePrivateData(refguid GUID) Error { 157 | ret, _, _ := syscall.Syscall( 158 | obj.vtbl.FreePrivateData, 159 | 2, 160 | uintptr(unsafe.Pointer(obj)), 161 | uintptr(unsafe.Pointer(&refguid)), 162 | 0, 163 | ) 164 | return toErr(ret) 165 | } 166 | 167 | // SetPriority assigns the priority of a resource for scheduling purposes. 168 | func (obj *Texture) SetPriority(priorityNew uint32) uint32 { 169 | ret, _, _ := syscall.Syscall( 170 | obj.vtbl.SetPriority, 171 | 2, 172 | uintptr(unsafe.Pointer(obj)), 173 | uintptr(priorityNew), 174 | 0, 175 | ) 176 | return uint32(ret) 177 | } 178 | 179 | // GetPriority retrieves the priority for this resource. 180 | func (obj *Texture) GetPriority() uint32 { 181 | ret, _, _ := syscall.Syscall( 182 | obj.vtbl.GetPriority, 183 | 1, 184 | uintptr(unsafe.Pointer(obj)), 185 | 0, 186 | 0, 187 | ) 188 | return uint32(ret) 189 | } 190 | 191 | // PreLoad preloads a managed resource. 192 | func (obj *Texture) PreLoad() { 193 | syscall.Syscall( 194 | obj.vtbl.PreLoad, 195 | 1, 196 | uintptr(unsafe.Pointer(obj)), 197 | 0, 198 | 0, 199 | ) 200 | } 201 | 202 | // GetType returns the type of the resource. 203 | func (obj *Texture) GetType() RESOURCETYPE { 204 | ret, _, _ := syscall.Syscall( 205 | obj.vtbl.GetType, 206 | 1, 207 | uintptr(unsafe.Pointer(obj)), 208 | 0, 209 | 0, 210 | ) 211 | return RESOURCETYPE(ret) 212 | } 213 | 214 | // SetLOD sets the most detailed level-of-detail for a managed texture. 215 | func (obj *Texture) SetLOD(lodNew uint32) uint32 { 216 | ret, _, _ := syscall.Syscall( 217 | obj.vtbl.SetLOD, 218 | 2, 219 | uintptr(unsafe.Pointer(obj)), 220 | uintptr(lodNew), 221 | 0, 222 | ) 223 | return uint32(ret) 224 | } 225 | 226 | // GetLOD returns a value clamped to the maximum level-of-detail set for a 227 | // managed texture (this method is not supported for an unmanaged texture). 228 | func (obj *Texture) GetLOD() uint32 { 229 | ret, _, _ := syscall.Syscall( 230 | obj.vtbl.GetLOD, 231 | 1, 232 | uintptr(unsafe.Pointer(obj)), 233 | 0, 234 | 0, 235 | ) 236 | return uint32(ret) 237 | } 238 | 239 | // GetLevelCount returns the number of texture levels in a multilevel texture. 240 | func (obj *Texture) GetLevelCount() uint32 { 241 | ret, _, _ := syscall.Syscall( 242 | obj.vtbl.GetLevelCount, 243 | 1, 244 | uintptr(unsafe.Pointer(obj)), 245 | 0, 246 | 0, 247 | ) 248 | return uint32(ret) 249 | } 250 | 251 | // SetAutoGenFilterType sets the filter type that is used for automatically 252 | // generated mipmap sublevels. 253 | func (obj *Texture) SetAutoGenFilterType(typ TEXTUREFILTERTYPE) Error { 254 | ret, _, _ := syscall.Syscall( 255 | obj.vtbl.SetAutoGenFilterType, 256 | 2, 257 | uintptr(unsafe.Pointer(obj)), 258 | uintptr(typ), 259 | 0, 260 | ) 261 | return toErr(ret) 262 | } 263 | 264 | // GetAutoGenFilterType returns the filter type that is used for automatically 265 | // generated mipmap sublevels. 266 | func (obj *Texture) GetAutoGenFilterType() TEXTUREFILTERTYPE { 267 | ret, _, _ := syscall.Syscall( 268 | obj.vtbl.GetAutoGenFilterType, 269 | 1, 270 | uintptr(unsafe.Pointer(obj)), 271 | 0, 272 | 0, 273 | ) 274 | return TEXTUREFILTERTYPE(ret) 275 | } 276 | 277 | // GenerateMipSubLevels generates mip sub levels. 278 | func (obj *Texture) GenerateMipSubLevels() { 279 | syscall.Syscall( 280 | obj.vtbl.GenerateMipSubLevels, 281 | 1, 282 | uintptr(unsafe.Pointer(obj)), 283 | 0, 284 | 0, 285 | ) 286 | } 287 | 288 | // GetLevelDesc retrieves a level description of a texture resource. 289 | func (obj *Texture) GetLevelDesc(level uint) (desc SURFACE_DESC, err Error) { 290 | ret, _, _ := syscall.Syscall( 291 | obj.vtbl.GetLevelDesc, 292 | 3, 293 | uintptr(unsafe.Pointer(obj)), 294 | uintptr(level), 295 | uintptr(unsafe.Pointer(&desc)), 296 | ) 297 | err = toErr(ret) 298 | return 299 | } 300 | 301 | // GetSurfaceLevel retrieves the specified texture surface level. 302 | func (obj *Texture) GetSurfaceLevel(level uint) (surface *Surface, err Error) { 303 | ret, _, _ := syscall.Syscall( 304 | obj.vtbl.GetSurfaceLevel, 305 | 3, 306 | uintptr(unsafe.Pointer(obj)), 307 | uintptr(level), 308 | uintptr(unsafe.Pointer(&surface)), 309 | ) 310 | err = toErr(ret) 311 | return 312 | } 313 | 314 | // LockRect locks a rectangle on a texture resource. 315 | func (obj *Texture) LockRect( 316 | level uint, 317 | rect *RECT, 318 | flags uint32, 319 | ) (lockedRect LOCKED_RECT, err Error) { 320 | ret, _, _ := syscall.Syscall6( 321 | obj.vtbl.LockRect, 322 | 5, 323 | uintptr(unsafe.Pointer(obj)), 324 | uintptr(level), 325 | uintptr(unsafe.Pointer(&lockedRect)), 326 | uintptr(unsafe.Pointer(rect)), 327 | uintptr(flags), 328 | 0, 329 | ) 330 | err = toErr(ret) 331 | return 332 | } 333 | 334 | // UnlockRect unlocks a rectangle on a texture resource. 335 | func (obj *Texture) UnlockRect(level uint) Error { 336 | ret, _, _ := syscall.Syscall( 337 | obj.vtbl.UnlockRect, 338 | 2, 339 | uintptr(unsafe.Pointer(obj)), 340 | uintptr(level), 341 | 0, 342 | ) 343 | return toErr(ret) 344 | } 345 | 346 | // AddDirtyRect adds a dirty region to a texture resource. 347 | func (obj *Texture) AddDirtyRect(dirtyRect *RECT) Error { 348 | ret, _, _ := syscall.Syscall( 349 | obj.vtbl.AddDirtyRect, 350 | 2, 351 | uintptr(unsafe.Pointer(obj)), 352 | uintptr(unsafe.Pointer(dirtyRect)), 353 | 0, 354 | ) 355 | return toErr(ret) 356 | } 357 | -------------------------------------------------------------------------------- /types_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import "unsafe" 4 | 5 | const MAX_DEVICE_IDENTIFIER_STRING = 512 6 | 7 | // ADAPTER_IDENTIFIER contains information identifying the adapter. 8 | type ADAPTER_IDENTIFIER struct { 9 | Driver [MAX_DEVICE_IDENTIFIER_STRING]byte 10 | Description [MAX_DEVICE_IDENTIFIER_STRING]byte 11 | DeviceName [32]byte 12 | DriverVersion int64 13 | VendorId uint32 14 | DeviceId uint32 15 | SubSysId uint32 16 | Revision uint32 17 | DeviceIdentifier GUID 18 | WHQLLevel uint32 19 | } 20 | 21 | func zeroTerminatedString(b []byte) string { 22 | for i := range b { 23 | if b[i] == 0 { 24 | return string(b[:i]) 25 | } 26 | } 27 | return string(b) 28 | } 29 | 30 | // GetDriver returns the Driver member as a Go string with trailing 0s removed. 31 | func (id *ADAPTER_IDENTIFIER) GetDriver() string { 32 | if id == nil { 33 | return "" 34 | } 35 | return zeroTerminatedString(id.Driver[:]) 36 | } 37 | 38 | // GetDescription returns the Description member as a Go string with trailing 0s 39 | // removed. 40 | func (id *ADAPTER_IDENTIFIER) GetDescription() string { 41 | if id == nil { 42 | return "" 43 | } 44 | return zeroTerminatedString(id.Description[:]) 45 | } 46 | 47 | // GetDeviceName returns the DeviceName member as a Go string with trailing 0s 48 | // removed. 49 | func (id *ADAPTER_IDENTIFIER) GetDeviceName() string { 50 | if id == nil { 51 | return "" 52 | } 53 | return zeroTerminatedString(id.DeviceName[:]) 54 | } 55 | 56 | // GetVersion splits the DriverVersion into its four semantic parts: product, 57 | // version, sub-version and build. 58 | func (id *ADAPTER_IDENTIFIER) GetVersion() (product, ver, subVer, build int) { 59 | if id != nil { 60 | v := uint64(id.DriverVersion) 61 | product = int((v & 0xFFFF000000000000) >> 48) 62 | ver = int((v & 0x0000FFFF00000000) >> 32) 63 | subVer = int((v & 0x00000000FFFF0000) >> 16) 64 | build = int(v & 0x000000000000FFFF) 65 | } 66 | return 67 | } 68 | 69 | // GUID is a globally unique identifier. 70 | type GUID struct { 71 | Data1 uint32 72 | Data2 uint16 73 | Data3 uint16 74 | Data4 [8]uint8 75 | } 76 | 77 | type DISPLAYMODE struct { 78 | Width uint32 79 | Height uint32 80 | RefreshRate uint32 81 | Format FORMAT 82 | } 83 | 84 | // CAPS represents the capabilities of the hardware exposed through the Direct3D 85 | // object. 86 | type CAPS struct { 87 | DeviceType DEVTYPE 88 | AdapterOrdinal uint32 89 | Caps uint32 90 | Caps2 uint32 91 | Caps3 uint32 92 | PresentationIntervals uint32 93 | CursorCaps uint32 94 | DevCaps uint32 95 | PrimitiveMiscCaps uint32 96 | RasterCaps uint32 97 | ZCmpCaps uint32 98 | SrcBlendCaps uint32 99 | DestBlendCaps uint32 100 | AlphaCmpCaps uint32 101 | ShadeCaps uint32 102 | TextureCaps uint32 103 | TextureFilterCaps uint32 104 | CubeTextureFilterCaps uint32 105 | VolumeTextureFilterCaps uint32 106 | TextureAddressCaps uint32 107 | VolumeTextureAddressCaps uint32 108 | LineCaps uint32 109 | MaxTextureWidth uint32 110 | MaxTextureHeight uint32 111 | MaxVolumeExtent uint32 112 | MaxTextureRepeat uint32 113 | MaxTextureAspectRatio uint32 114 | MaxAnisotropy uint32 115 | MaxVertexW float32 116 | GuardBandLeft float32 117 | GuardBandTop float32 118 | GuardBandRight float32 119 | GuardBandBottom float32 120 | ExtentsAdjust float32 121 | StencilCaps uint32 122 | FVFCaps uint32 123 | TextureOpCaps uint32 124 | MaxTextureBlendStages uint32 125 | MaxSimultaneousTextures uint32 126 | VertexProcessingCaps uint32 127 | MaxActiveLights uint32 128 | MaxUserClipPlanes uint32 129 | MaxVertexBlendMatrices uint32 130 | MaxVertexBlendMatrixIndex uint32 131 | MaxPointSize float32 132 | MaxPrimitiveCount uint32 133 | MaxVertexIndex uint32 134 | MaxStreams uint32 135 | MaxStreamStride uint32 136 | VertexShaderVersion uint32 137 | MaxVertexShaderConst uint32 138 | PixelShaderVersion uint32 139 | PixelShader1xMaxValue float32 140 | DevCaps2 uint32 141 | MasterAdapterOrdinal uint32 142 | AdapterOrdinalInGroup uint32 143 | NumberOfAdaptersInGroup uint32 144 | DeclTypes uint32 145 | NumSimultaneousRTs uint32 146 | StretchRectFilterCaps uint32 147 | VS20Caps VSHADERCAPS2_0 148 | PS20Caps PSHADERCAPS2_0 149 | VertexTextureFilterCaps uint32 150 | MaxVShaderInstructionsExecuted uint32 151 | MaxPShaderInstructionsExecuted uint32 152 | MaxVertexShader30InstructionSlots uint32 153 | MaxPixelShader30InstructionSlots uint32 154 | } 155 | 156 | // VSHADERCAPS2_0 contains vertex shader capabilities. 157 | type VSHADERCAPS2_0 struct { 158 | Caps uint32 159 | DynamicFlowControlDepth int32 160 | NumTemps int32 161 | StaticFlowControlDepth int32 162 | } 163 | 164 | // PSHADERCAPS2_0 describes pixel shader driver caps. 165 | type PSHADERCAPS2_0 struct { 166 | Caps uint32 167 | DynamicFlowControlDepth int32 168 | NumTemps int32 169 | StaticFlowControlDepth int32 170 | NumInstructionSlots int32 171 | } 172 | 173 | // PRESENT_PARAMETERS describes the presentation parameters. 174 | type PRESENT_PARAMETERS struct { 175 | BackBufferWidth uint32 176 | BackBufferHeight uint32 177 | BackBufferFormat FORMAT 178 | BackBufferCount uint32 179 | MultiSampleType MULTISAMPLE_TYPE 180 | MultiSampleQuality uint32 181 | SwapEffect SWAPEFFECT 182 | HDeviceWindow HWND 183 | Windowed int32 184 | EnableAutoDepthStencil int32 185 | AutoDepthStencilFormat FORMAT 186 | Flags uint32 187 | FullScreen_RefreshRateInHz uint32 188 | PresentationInterval uint32 189 | } 190 | 191 | type ( 192 | HANDLE uintptr 193 | HWND HANDLE 194 | HMONITOR HANDLE 195 | HDC HANDLE 196 | ) 197 | 198 | // RECT describes a rectangle. 199 | type RECT struct { 200 | Left int32 201 | Top int32 202 | Right int32 203 | Bottom int32 204 | } 205 | 206 | // RGNDATA contains region data. 207 | type RGNDATA struct { 208 | Rdh RGNDATAHEADER 209 | Buffer [1]byte 210 | } 211 | 212 | // RGNDATAHEADER describes region data. 213 | type RGNDATAHEADER struct { 214 | DwSize uint32 215 | IType uint32 216 | NCount uint32 217 | NRgnSize uint32 218 | RcBound RECT 219 | } 220 | 221 | // DEVICE_CREATION_PARAMETERS describes the creation parameters for a device. 222 | type DEVICE_CREATION_PARAMETERS struct { 223 | AdapterOrdinal uint32 224 | DeviceType DEVTYPE 225 | HFocusWindow HWND 226 | BehaviorFlags uint32 227 | } 228 | 229 | // RASTER_STATUS describes the raster status. 230 | type RASTER_STATUS struct { 231 | InVBlank int32 232 | ScanLine uint32 233 | } 234 | 235 | // GAMMARAMP contains red, green, and blue ramp data. 236 | type GAMMARAMP struct { 237 | Red [256]uint16 238 | Green [256]uint16 239 | Blue [256]uint16 240 | } 241 | 242 | // POINT describes a 2D point. 243 | type POINT struct { 244 | X int32 245 | Y int32 246 | } 247 | 248 | // MATRIX describes a matrix. 249 | type MATRIX [16]float32 250 | 251 | // VIEWPORT defines the window dimensions of a render-target surface onto which 252 | // a 3D volume projects. 253 | type VIEWPORT struct { 254 | X uint32 255 | Y uint32 256 | Width uint32 257 | Height uint32 258 | MinZ float32 259 | MaxZ float32 260 | } 261 | 262 | // MATERIAL specifies material properties. 263 | type MATERIAL struct { 264 | Diffuse COLORVALUE 265 | Ambient COLORVALUE 266 | Specular COLORVALUE 267 | Emissive COLORVALUE 268 | Power float32 269 | } 270 | 271 | // COLORVALUE describes color values. 272 | type COLORVALUE struct { 273 | R float32 274 | G float32 275 | B float32 276 | A float32 277 | } 278 | 279 | // LIGHT defines a set of lighting properties. 280 | type LIGHT struct { 281 | Type LIGHTTYPE 282 | Diffuse COLORVALUE 283 | Specular COLORVALUE 284 | Ambient COLORVALUE 285 | Position VECTOR 286 | Direction VECTOR 287 | Range float32 288 | Falloff float32 289 | Attenuation0 float32 290 | Attenuation1 float32 291 | Attenuation2 float32 292 | Theta float32 293 | Phi float32 294 | } 295 | 296 | // VECTOR defines a vector. 297 | type VECTOR struct { 298 | X float32 299 | Y float32 300 | Z float32 301 | } 302 | 303 | // CLIPSTATUS describes the current clip status. 304 | type CLIPSTATUS struct { 305 | ClipUnion uint32 306 | ClipIntersection uint32 307 | } 308 | 309 | // PALETTEENTRY specifies the color and usage of an entry in a logical palette. 310 | type PALETTEENTRY struct { 311 | PeRed byte 312 | PeGreen byte 313 | PeBlue byte 314 | PeFlags byte 315 | } 316 | 317 | // VERTEXELEMENT defines the vertex data layout. Each vertex can contain one or 318 | // more data types, and each data type is described by a vertex element. 319 | type VERTEXELEMENT struct { 320 | Stream uint16 321 | Offset uint16 322 | Type DECLTYPE 323 | Method DECLMETHOD 324 | Usage DECLUSAGE 325 | UsageIndex byte 326 | } 327 | 328 | // RECTPATCH_INFO describes a rectangular high-order patch. 329 | type RECTPATCH_INFO struct { 330 | StartVertexOffsetWidth uint32 331 | StartVertexOffsetHeight uint32 332 | Width uint32 333 | Height uint32 334 | Stride uint32 335 | Basis BASISTYPE 336 | Degree DEGREETYPE 337 | } 338 | 339 | // TRIPATCH_INFO describes a triangular high-order patch. 340 | type TRIPATCH_INFO struct { 341 | StartVertexOffset uint32 342 | NumVertices uint32 343 | Basis BASISTYPE 344 | Degree DEGREETYPE 345 | } 346 | 347 | // BOX defines a volume. 348 | type BOX struct { 349 | Left uint32 350 | Top uint32 351 | Right uint32 352 | Bottom uint32 353 | Front uint32 354 | Back uint32 355 | } 356 | 357 | // VOLUME_DESC describes a volume. 358 | type VOLUME_DESC struct { 359 | Format FORMAT 360 | Type RESOURCETYPE 361 | Usage uint32 362 | Pool POOL 363 | Width uint32 364 | Height uint32 365 | Depth uint32 366 | } 367 | 368 | // LOCKED_BOX describes a locked box (volume). 369 | type LOCKED_BOX struct { 370 | RowPitch int32 371 | SlicePitch int32 372 | PBits uintptr 373 | } 374 | 375 | // VERTEXBUFFER_DESC describes a vertex buffer. 376 | type VERTEXBUFFER_DESC struct { 377 | Format FORMAT 378 | Type RESOURCETYPE 379 | Usage uint32 380 | Pool POOL 381 | Size uint32 382 | FVF uint32 383 | } 384 | 385 | // INDEXBUFFER_DESC describes an index buffer. 386 | type INDEXBUFFER_DESC struct { 387 | Format FORMAT 388 | Type RESOURCETYPE 389 | Usage uint32 390 | Pool POOL 391 | Size uint32 392 | } 393 | 394 | // SURFACE_DESC describes a surface. 395 | type SURFACE_DESC struct { 396 | Format FORMAT 397 | Type RESOURCETYPE 398 | Usage uint32 399 | Pool POOL 400 | MultiSampleType MULTISAMPLE_TYPE 401 | MultiSampleQuality uint32 402 | Width uint32 403 | Height uint32 404 | } 405 | 406 | // LOCKED_RECT describes a locked rectangular region. 407 | type LOCKED_RECT struct { 408 | Pitch int32 409 | PBits uintptr 410 | } 411 | 412 | // SetAllBytes will fill the whole rect with the given data, taking into account 413 | // the rect's pitch. The given byte slice is expected to have the given stride 414 | // in bytes, i.e. one line in the given data is bytes in length. 415 | func (r LOCKED_RECT) SetAllBytes(data []byte, srcStride int) { 416 | if len(data) == 0 { 417 | return 418 | } 419 | 420 | dest := r.PBits 421 | destStride := int(r.Pitch) 422 | src := uintptr(unsafe.Pointer(&data[0])) 423 | height := (len(data) + srcStride - 1) / srcStride 424 | 425 | stride := srcStride 426 | if destStride < srcStride { 427 | stride = destStride 428 | } 429 | destSkip := uintptr(destStride - stride) 430 | srcSkip := uintptr(srcStride - stride) 431 | d := dest 432 | s := src 433 | if srcStride%8 == 0 && destStride%8 == 0 { 434 | // in this case we can speed up copying by using 8 byte wide uint64s 435 | // instead of copying byte for byte 436 | for y := 0; y < height; y++ { 437 | for x := 0; x < stride; x += 8 { 438 | *((*uint64)(unsafe.Pointer(d))) = *((*uint64)(unsafe.Pointer(s))) 439 | d += 8 440 | s += 8 441 | } 442 | d += destSkip 443 | s += srcSkip 444 | } 445 | } else if srcStride%4 == 0 && destStride%4 == 0 { 446 | // in this case we can speed up copying by using 4 byte wide uint32s 447 | // instead of copying byte for byte 448 | for y := 0; y < height; y++ { 449 | for x := 0; x < stride; x += 4 { 450 | *((*uint32)(unsafe.Pointer(d))) = *((*uint32)(unsafe.Pointer(s))) 451 | d += 4 452 | s += 4 453 | } 454 | d += destSkip 455 | s += srcSkip 456 | } 457 | } else { 458 | // in the unlikely case that stride is neither a multiple of 8 nor 4 459 | // bytes, just copy byte for byte 460 | for y := 0; y < height; y++ { 461 | for x := 0; x < stride; x++ { 462 | *((*byte)(unsafe.Pointer(d))) = *((*byte)(unsafe.Pointer(s))) 463 | d++ 464 | s++ 465 | } 466 | d += destSkip 467 | s += srcSkip 468 | } 469 | } 470 | } 471 | 472 | // DEVINFO_D3D9BANDWIDTHTIMINGS contains throughput metrics for help in 473 | // understanding the performance of an application. 474 | type DEVINFO_D3D9BANDWIDTHTIMINGS struct { 475 | MaxBandwidthUtilized float32 476 | FrontEndUploadMemoryUtilizedPercent float32 477 | VertexRateUtilizedPercent float32 478 | TriangleSetupRateUtilizedPercent float32 479 | FillRateUtilizedPercent float32 480 | } 481 | 482 | // DEVINFO_D3D9CACHEUTILIZATION measures the cache hit rate performance for 483 | // textures and indexed vertices. 484 | type DEVINFO_D3D9CACHEUTILIZATION struct { 485 | TextureCacheHitRate float32 486 | PostTransformVertexCacheHitRate float32 487 | } 488 | 489 | // DEVINFO_D3D9INTERFACETIMINGS contains the percent of time processing data in 490 | // the driver. These statistics may help identify cases when the driver is 491 | // waiting for other resources. 492 | type DEVINFO_D3D9INTERFACETIMINGS struct { 493 | WaitingForGPUToUseApplicationResourceTimePercent float32 494 | WaitingForGPUToAcceptMoreCommandsTimePercent float32 495 | WaitingForGPUToStayWithinLatencyTimePercent float32 496 | WaitingForGPUExclusiveResourceTimePercent float32 497 | WaitingForGPUOtherTimePercent float32 498 | } 499 | 500 | // DEVINFO_D3D9PIPELINETIMINGS contains the percent of time processing data in 501 | // the pipeline. 502 | type DEVINFO_D3D9PIPELINETIMINGS struct { 503 | VertexProcessingTimePercent float32 504 | PixelProcessingTimePercent float32 505 | OtherGPUProcessingTimePercent float32 506 | GPUIdleTimePercent float32 507 | } 508 | 509 | // DEVINFO_D3D9STAGETIMINGS contains the percent of time processing shader data. 510 | type DEVINFO_D3D9STAGETIMINGS struct { 511 | MemoryProcessingPercent float32 512 | ComputationProcessingPercent float32 513 | } 514 | 515 | // DEVINFO_D3DVERTEXSTATS reports the number of triangles that have been 516 | // processed and clipped by the runtime's software vertex processing. 517 | type DEVINFO_D3DVERTEXSTATS struct { 518 | NumRenderedTriangles uint32 519 | NumExtraClippingTriangles uint32 520 | } 521 | 522 | // DEVINFO_VCACHE contains vertex cache optimization hints. 523 | type DEVINFO_VCACHE struct { 524 | Pattern uint32 525 | OptMethod uint32 526 | CacheSize uint32 527 | MagicNumber uint32 528 | } 529 | 530 | // RESOURCESTATS contains resource statistics gathered by the 531 | // DEVINFO_ResourceManager when using the asynchronous query mechanism. 532 | type RESOURCESTATS struct { 533 | BThrashing uint32 534 | ApproxBytesDownloaded uint32 535 | NumEvicts uint32 536 | NumVidCreates uint32 537 | LastPri uint32 538 | NumUsed uint32 539 | NumUsedInVidMem uint32 540 | WorkingSet uint32 541 | WorkingSetBytes uint32 542 | TotalManaged uint32 543 | TotalBytes uint32 544 | } 545 | 546 | // LUID is a 64-bit value guaranteed to be unique only on the system on which it 547 | // was generated. The uniqueness of a locally unique identifier (LUID) is 548 | // guaranteed only until the system is restarted. 549 | type LUID struct { 550 | LowPart uint32 551 | HighPart int32 552 | } 553 | 554 | // RANGE defines a range. 555 | type RANGE struct { 556 | Offset uint32 557 | Size uint32 558 | } 559 | -------------------------------------------------------------------------------- /vertex_buffer_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // VertexBuffer and its methods are used to manipulate vertex buffer resources. 9 | type VertexBuffer struct { 10 | vtbl *vertexBufferVtbl 11 | } 12 | 13 | type vertexBufferVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | SetPrivateData uintptr 20 | GetPrivateData uintptr 21 | FreePrivateData uintptr 22 | SetPriority uintptr 23 | GetPriority uintptr 24 | PreLoad uintptr 25 | GetType uintptr 26 | Lock uintptr 27 | Unlock uintptr 28 | GetDesc uintptr 29 | } 30 | 31 | // AddRef increments the reference count for an interface on an object. This 32 | // method should be called for every new copy of a pointer to an interface on an 33 | // object. 34 | func (obj *VertexBuffer) AddRef() uint32 { 35 | ret, _, _ := syscall.Syscall( 36 | obj.vtbl.AddRef, 37 | 1, 38 | uintptr(unsafe.Pointer(obj)), 39 | 0, 40 | 0, 41 | ) 42 | return uint32(ret) 43 | } 44 | 45 | // Release has to be called when finished using the object to free its 46 | // associated resources. 47 | func (obj *VertexBuffer) Release() uint32 { 48 | ret, _, _ := syscall.Syscall( 49 | obj.vtbl.Release, 50 | 1, 51 | uintptr(unsafe.Pointer(obj)), 52 | 0, 53 | 0, 54 | ) 55 | return uint32(ret) 56 | } 57 | 58 | // GetDevice retrieves the device associated with a resource. 59 | // Call Release on the returned device when finished using it. 60 | func (obj *VertexBuffer) GetDevice() (device *Device, err Error) { 61 | ret, _, _ := syscall.Syscall( 62 | obj.vtbl.GetDevice, 63 | 2, 64 | uintptr(unsafe.Pointer(obj)), 65 | uintptr(unsafe.Pointer(&device)), 66 | 0, 67 | ) 68 | err = toErr(ret) 69 | return 70 | } 71 | 72 | // SetPrivateData associates data with the resource that is intended for use by 73 | // the application, not by Direct3D. Data is passed by value, and multiple sets 74 | // of data can be associated with a single resource. 75 | func (obj *VertexBuffer) SetPrivateData( 76 | refguid GUID, 77 | data uintptr, 78 | sizeOfData uint32, 79 | flags uint32, 80 | ) Error { 81 | ret, _, _ := syscall.Syscall6( 82 | obj.vtbl.SetPrivateData, 83 | 5, 84 | uintptr(unsafe.Pointer(obj)), 85 | uintptr(unsafe.Pointer(&refguid)), 86 | data, 87 | uintptr(sizeOfData), 88 | uintptr(flags), 89 | 0, 90 | ) 91 | return toErr(ret) 92 | } 93 | 94 | // SetPrivateDataBytes associates data with the resource that is intended for 95 | // use by the application, not by Direct3D. Data is passed by value, and 96 | // multiple sets of data can be associated with a single resource. 97 | func (obj *VertexBuffer) SetPrivateDataBytes( 98 | refguid GUID, 99 | data []byte, 100 | flags uint32, 101 | ) Error { 102 | return obj.SetPrivateData( 103 | refguid, 104 | uintptr(unsafe.Pointer(&data[0])), 105 | uint32(len(data)), 106 | flags, 107 | ) 108 | } 109 | 110 | // GetPrivateData copies the private data associated with the resource to a 111 | // provided buffer. 112 | func (obj *VertexBuffer) GetPrivateData(refguid GUID) (data []byte, err Error) { 113 | // first get the data size by passing nil as the data pointer 114 | var sizeInBytes uint 115 | ret, _, _ := syscall.Syscall6( 116 | obj.vtbl.GetPrivateData, 117 | 4, 118 | uintptr(unsafe.Pointer(obj)), 119 | uintptr(unsafe.Pointer(&refguid)), 120 | 0, 121 | uintptr(unsafe.Pointer(&sizeInBytes)), 122 | 0, 123 | 0, 124 | ) 125 | if err := toErr(ret); err != nil { 126 | return nil, err 127 | } 128 | data = make([]byte, sizeInBytes) 129 | ret, _, _ = syscall.Syscall6( 130 | obj.vtbl.GetPrivateData, 131 | 4, 132 | uintptr(unsafe.Pointer(obj)), 133 | uintptr(unsafe.Pointer(&refguid)), 134 | uintptr(unsafe.Pointer(&data[0])), 135 | uintptr(unsafe.Pointer(&sizeInBytes)), 136 | 0, 137 | 0, 138 | ) 139 | return data, toErr(ret) 140 | } 141 | 142 | // FreePrivateData frees the specified private data associated with this 143 | // resource. 144 | func (obj *VertexBuffer) FreePrivateData(refguid GUID) Error { 145 | ret, _, _ := syscall.Syscall( 146 | obj.vtbl.FreePrivateData, 147 | 2, 148 | uintptr(unsafe.Pointer(obj)), 149 | uintptr(unsafe.Pointer(&refguid)), 150 | 0, 151 | ) 152 | return toErr(ret) 153 | } 154 | 155 | // SetPriority assigns the priority of a resource for scheduling purposes. 156 | func (obj *VertexBuffer) SetPriority(priorityNew uint32) uint32 { 157 | ret, _, _ := syscall.Syscall( 158 | obj.vtbl.SetPriority, 159 | 2, 160 | uintptr(unsafe.Pointer(obj)), 161 | uintptr(priorityNew), 162 | 0, 163 | ) 164 | return uint32(ret) 165 | } 166 | 167 | // GetPriority retrieves the priority for this resource. 168 | func (obj *VertexBuffer) GetPriority() uint32 { 169 | ret, _, _ := syscall.Syscall( 170 | obj.vtbl.GetPriority, 171 | 1, 172 | uintptr(unsafe.Pointer(obj)), 173 | 0, 174 | 0, 175 | ) 176 | return uint32(ret) 177 | } 178 | 179 | // PreLoad preloads a managed resource. 180 | func (obj *VertexBuffer) PreLoad() { 181 | syscall.Syscall( 182 | obj.vtbl.PreLoad, 183 | 1, 184 | uintptr(unsafe.Pointer(obj)), 185 | 0, 186 | 0, 187 | ) 188 | } 189 | 190 | // GetType returns the type of the resource. 191 | func (obj *VertexBuffer) GetType() RESOURCETYPE { 192 | ret, _, _ := syscall.Syscall( 193 | obj.vtbl.GetType, 194 | 1, 195 | uintptr(unsafe.Pointer(obj)), 196 | 0, 197 | 0, 198 | ) 199 | return RESOURCETYPE(ret) 200 | } 201 | 202 | // Lock locks a range of vertex data and obtains a pointer to the vertex buffer 203 | // memory. 204 | func (obj *VertexBuffer) Lock( 205 | offsetToLock uint, 206 | sizeToLock uint, 207 | flags uint32, 208 | ) (data VertexBufferMemory, err Error) { 209 | var dataPtr uintptr 210 | ret, _, _ := syscall.Syscall6( 211 | obj.vtbl.Lock, 212 | 5, 213 | uintptr(unsafe.Pointer(obj)), 214 | uintptr(offsetToLock), 215 | uintptr(sizeToLock), 216 | uintptr(unsafe.Pointer(&dataPtr)), 217 | uintptr(flags), 218 | 0, 219 | ) 220 | err = toErr(ret) 221 | data = VertexBufferMemory{Memory: dataPtr} 222 | return 223 | } 224 | 225 | // Unlock unlocks vertex data. 226 | func (obj *VertexBuffer) Unlock() Error { 227 | ret, _, _ := syscall.Syscall( 228 | obj.vtbl.Unlock, 229 | 1, 230 | uintptr(unsafe.Pointer(obj)), 231 | 0, 232 | 0, 233 | ) 234 | return toErr(ret) 235 | } 236 | 237 | // GetDesc retrieves a description of the vertex buffer resource. 238 | func (obj *VertexBuffer) GetDesc() (desc VERTEXBUFFER_DESC, err Error) { 239 | ret, _, _ := syscall.Syscall( 240 | obj.vtbl.GetDesc, 241 | 2, 242 | uintptr(unsafe.Pointer(obj)), 243 | uintptr(unsafe.Pointer(&desc)), 244 | 0, 245 | ) 246 | err = toErr(ret) 247 | return 248 | } 249 | 250 | // VertexBufferMemory encapsulates a raw memory pointer and provides methods to 251 | // get and set typical slice types. 252 | type VertexBufferMemory struct { 253 | Memory uintptr 254 | } 255 | 256 | // SetFloat32s copies the given slice to the memory, starting at the given 257 | // offset in bytes. 258 | func (m VertexBufferMemory) SetFloat32s(offsetInBytes int, data []float32) { 259 | if len(data) > 0 { 260 | dest := m.Memory + uintptr(offsetInBytes) 261 | for i := range data { 262 | *((*float32)(unsafe.Pointer(dest))) = data[i] 263 | dest += 4 264 | } 265 | } 266 | } 267 | 268 | // SetFloat64s copies the given slice to the memory, starting at the given 269 | // offset in bytes. 270 | func (m VertexBufferMemory) SetFloat64s(offsetInBytes int, data []float64) { 271 | if len(data) > 0 { 272 | dest := m.Memory + uintptr(offsetInBytes) 273 | for i := range data { 274 | *((*float64)(unsafe.Pointer(dest))) = data[i] 275 | dest += 8 276 | } 277 | } 278 | } 279 | 280 | // SetInt32s copies the given slice to the memory, starting at the given 281 | // offset in bytes. 282 | func (m VertexBufferMemory) SetInt32s(offsetInBytes int, data []int32) { 283 | if len(data) > 0 { 284 | dest := m.Memory + uintptr(offsetInBytes) 285 | for i := range data { 286 | *((*int32)(unsafe.Pointer(dest))) = data[i] 287 | dest += 4 288 | } 289 | } 290 | } 291 | 292 | // SetUint32s copies the given slice to the memory, starting at the given 293 | // offset in bytes. 294 | func (m VertexBufferMemory) SetUint32s(offsetInBytes int, data []uint32) { 295 | if len(data) > 0 { 296 | dest := m.Memory + uintptr(offsetInBytes) 297 | for i := range data { 298 | *((*uint32)(unsafe.Pointer(dest))) = data[i] 299 | dest += 4 300 | } 301 | } 302 | } 303 | 304 | // SetInt16s copies the given slice to the memory, starting at the given 305 | // offset in bytes. 306 | func (m VertexBufferMemory) SetInt16s(offsetInBytes int, data []int16) { 307 | if len(data) > 0 { 308 | dest := m.Memory + uintptr(offsetInBytes) 309 | for i := range data { 310 | *((*int16)(unsafe.Pointer(dest))) = data[i] 311 | dest += 2 312 | } 313 | } 314 | } 315 | 316 | // SetUint16s copies the given slice to the memory, starting at the given 317 | // offset in bytes. 318 | func (m VertexBufferMemory) SetUint16s(offsetInBytes int, data []uint16) { 319 | if len(data) > 0 { 320 | dest := m.Memory + uintptr(offsetInBytes) 321 | for i := range data { 322 | *((*uint16)(unsafe.Pointer(dest))) = data[i] 323 | dest += 2 324 | } 325 | } 326 | } 327 | 328 | // SetInt8s copies the given slice to the memory, starting at the given 329 | // offset in bytes. 330 | func (m VertexBufferMemory) SetInt8s(offsetInBytes int, data []int8) { 331 | if len(data) > 0 { 332 | dest := m.Memory + uintptr(offsetInBytes) 333 | for i := range data { 334 | *((*int8)(unsafe.Pointer(dest))) = data[i] 335 | dest++ 336 | } 337 | } 338 | } 339 | 340 | // SetUint8s copies the given slice to the memory, starting at the given offset 341 | // in bytes. 342 | func (m VertexBufferMemory) SetUint8s(offsetInBytes int, data []uint8) { 343 | if len(data) > 0 { 344 | dest := m.Memory + uintptr(offsetInBytes) 345 | for i := range data { 346 | *((*uint8)(unsafe.Pointer(dest))) = data[i] 347 | dest++ 348 | } 349 | } 350 | } 351 | 352 | // SetBytes copies the given slice to the memory, starting at the given offset 353 | // in bytes. 354 | func (m VertexBufferMemory) SetBytes(offsetInBytes int, data []byte) { 355 | if len(data) > 0 { 356 | dest := m.Memory + uintptr(offsetInBytes) 357 | for i := range data { 358 | *((*byte)(unsafe.Pointer(dest))) = data[i] 359 | dest++ 360 | } 361 | } 362 | } 363 | 364 | // GetFloat32s copies data from memory to the given slice, starting at the given 365 | // offset in bytes. 366 | func (m VertexBufferMemory) GetFloat32s(offsetInBytes int, data []float32) { 367 | if len(data) > 0 { 368 | src := m.Memory + uintptr(offsetInBytes) 369 | for i := range data { 370 | data[i] = *((*float32)(unsafe.Pointer(src))) 371 | src += 4 372 | } 373 | } 374 | } 375 | 376 | // GetFloat64s copies data from memory to the given slice, starting at the given 377 | // offset in bytes. 378 | func (m VertexBufferMemory) GetFloat64s(offsetInBytes int, data []float64) { 379 | if len(data) > 0 { 380 | src := m.Memory + uintptr(offsetInBytes) 381 | for i := range data { 382 | data[i] = *((*float64)(unsafe.Pointer(src))) 383 | src += 8 384 | } 385 | } 386 | } 387 | 388 | // GetInt32s copies data from memory to the given slice, starting at the given 389 | // offset in bytes. 390 | func (m VertexBufferMemory) GetInt32s(offsetInBytes int, data []int32) { 391 | if len(data) > 0 { 392 | src := m.Memory + uintptr(offsetInBytes) 393 | for i := range data { 394 | data[i] = *((*int32)(unsafe.Pointer(src))) 395 | src += 4 396 | } 397 | } 398 | } 399 | 400 | // GetUint32s copies data from memory to the given slice, starting at the given 401 | // offset in bytes. 402 | func (m VertexBufferMemory) GetUint32s(offsetInBytes int, data []uint32) { 403 | if len(data) > 0 { 404 | src := m.Memory + uintptr(offsetInBytes) 405 | for i := range data { 406 | data[i] = *((*uint32)(unsafe.Pointer(src))) 407 | src += 4 408 | } 409 | } 410 | } 411 | 412 | // GetInt16s copies data from memory to the given slice, starting at the given 413 | // offset in bytes. 414 | func (m VertexBufferMemory) GetInt16s(offsetInBytes int, data []int16) { 415 | if len(data) > 0 { 416 | src := m.Memory + uintptr(offsetInBytes) 417 | for i := range data { 418 | data[i] = *((*int16)(unsafe.Pointer(src))) 419 | src += 2 420 | } 421 | } 422 | } 423 | 424 | // GetUint16s copies data from memory to the given slice, starting at the given 425 | // offset in bytes. 426 | func (m VertexBufferMemory) GetUint16s(offsetInBytes int, data []uint16) { 427 | if len(data) > 0 { 428 | src := m.Memory + uintptr(offsetInBytes) 429 | for i := range data { 430 | data[i] = *((*uint16)(unsafe.Pointer(src))) 431 | src += 2 432 | } 433 | } 434 | } 435 | 436 | // GetInt8s copies data from memory to the given slice, starting at the given 437 | // offset in bytes. 438 | func (m VertexBufferMemory) GetInt8s(offsetInBytes int, data []int8) { 439 | if len(data) > 0 { 440 | src := m.Memory + uintptr(offsetInBytes) 441 | for i := range data { 442 | data[i] = *((*int8)(unsafe.Pointer(src))) 443 | src++ 444 | } 445 | } 446 | } 447 | 448 | // GetUint8s copies data from memory to the given slice, starting at the given 449 | // offset in bytes. 450 | func (m VertexBufferMemory) GetUint8s(offsetInBytes int, data []uint8) { 451 | if len(data) > 0 { 452 | src := m.Memory + uintptr(offsetInBytes) 453 | for i := range data { 454 | data[i] = *((*uint8)(unsafe.Pointer(src))) 455 | src++ 456 | } 457 | } 458 | } 459 | 460 | // GetBytes copies data from memory to the given slice, starting at the given 461 | // offset in bytes. 462 | func (m VertexBufferMemory) GetBytes(offsetInBytes int, data []byte) { 463 | if len(data) > 0 { 464 | src := m.Memory + uintptr(offsetInBytes) 465 | for i := range data { 466 | data[i] = *((*byte)(unsafe.Pointer(src))) 467 | src++ 468 | } 469 | } 470 | } 471 | -------------------------------------------------------------------------------- /vertex_declaration_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // VertexDeclaration and its methods are used to encapsulate the vertex shader 9 | // declaration. 10 | type VertexDeclaration struct { 11 | vtbl *vertexDeclarationVtbl 12 | } 13 | 14 | type vertexDeclarationVtbl struct { 15 | QueryInterface uintptr 16 | AddRef uintptr 17 | Release uintptr 18 | 19 | GetDevice uintptr 20 | GetDeclaration uintptr 21 | } 22 | 23 | // AddRef increments the reference count for an interface on an object. This 24 | // method should be called for every new copy of a pointer to an interface on an 25 | // object. 26 | func (obj *VertexDeclaration) AddRef() uint32 { 27 | ret, _, _ := syscall.Syscall( 28 | obj.vtbl.AddRef, 29 | 1, 30 | uintptr(unsafe.Pointer(obj)), 31 | 0, 32 | 0, 33 | ) 34 | return uint32(ret) 35 | } 36 | 37 | // Release has to be called when finished using the object to free its 38 | // associated resources. 39 | func (obj *VertexDeclaration) Release() uint32 { 40 | ret, _, _ := syscall.Syscall( 41 | obj.vtbl.Release, 42 | 1, 43 | uintptr(unsafe.Pointer(obj)), 44 | 0, 45 | 0, 46 | ) 47 | return uint32(ret) 48 | } 49 | 50 | // GetDevice retrieves the associated device. 51 | // Call Release on the returned device when finished using it. 52 | func (obj *VertexDeclaration) GetDevice() (device *Device, err Error) { 53 | ret, _, _ := syscall.Syscall( 54 | obj.vtbl.GetDevice, 55 | 2, 56 | uintptr(unsafe.Pointer(obj)), 57 | uintptr(unsafe.Pointer(&device)), 58 | 0, 59 | ) 60 | err = toErr(ret) 61 | return 62 | } 63 | 64 | // GetDeclaration returns the vertex shader declaration. 65 | func (obj *VertexDeclaration) GetDeclaration() (decl []VERTEXELEMENT, err Error) { 66 | // first pass nil for the elements to get the count 67 | var elemCount uint 68 | ret, _, _ := syscall.Syscall( 69 | obj.vtbl.GetDeclaration, 70 | 3, 71 | uintptr(unsafe.Pointer(obj)), 72 | 0, 73 | uintptr(unsafe.Pointer(&elemCount)), 74 | ) 75 | if err := toErr(ret); err != nil { 76 | return nil, err 77 | } 78 | 79 | decl = make([]VERTEXELEMENT, elemCount) 80 | ret, _, _ = syscall.Syscall( 81 | obj.vtbl.GetDeclaration, 82 | 3, 83 | uintptr(unsafe.Pointer(obj)), 84 | uintptr(unsafe.Pointer(&decl[0])), 85 | uintptr(unsafe.Pointer(&elemCount)), 86 | ) 87 | err = toErr(ret) 88 | return 89 | } 90 | -------------------------------------------------------------------------------- /vertex_shader_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // VertexShader and its methods are used to encapsulate the functionality of a 9 | // vertex shader. 10 | type VertexShader struct { 11 | vtbl *vertexShaderVtbl 12 | } 13 | 14 | type vertexShaderVtbl struct { 15 | QueryInterface uintptr 16 | AddRef uintptr 17 | Release uintptr 18 | 19 | GetDevice uintptr 20 | GetFunction uintptr 21 | } 22 | 23 | // AddRef increments the reference count for an interface on an object. This 24 | // method should be called for every new copy of a pointer to an interface on an 25 | // object. 26 | func (obj *VertexShader) AddRef() uint32 { 27 | ret, _, _ := syscall.Syscall( 28 | obj.vtbl.AddRef, 29 | 1, 30 | uintptr(unsafe.Pointer(obj)), 31 | 0, 32 | 0, 33 | ) 34 | return uint32(ret) 35 | } 36 | 37 | // Release has to be called when finished using the object to free its 38 | // associated resources. 39 | func (obj *VertexShader) Release() uint32 { 40 | ret, _, _ := syscall.Syscall( 41 | obj.vtbl.Release, 42 | 1, 43 | uintptr(unsafe.Pointer(obj)), 44 | 0, 45 | 0, 46 | ) 47 | return uint32(ret) 48 | } 49 | 50 | // GetDevice retrieves the associated device. 51 | // Call Release on the returned device when finished using it. 52 | func (obj *VertexShader) GetDevice() (device *Device, err Error) { 53 | ret, _, _ := syscall.Syscall( 54 | obj.vtbl.GetDevice, 55 | 2, 56 | uintptr(unsafe.Pointer(obj)), 57 | uintptr(unsafe.Pointer(&device)), 58 | 0, 59 | ) 60 | err = toErr(ret) 61 | return 62 | } 63 | 64 | // GetFunction returns the shader data. 65 | func (obj *VertexShader) GetFunction() (data []byte, err Error) { 66 | // first get the needed buffer size, pass nil as the data pointer 67 | var sizeInBytes uint 68 | ret, _, _ := syscall.Syscall( 69 | obj.vtbl.GetFunction, 70 | 3, 71 | uintptr(unsafe.Pointer(obj)), 72 | 0, 73 | uintptr(unsafe.Pointer(&sizeInBytes)), 74 | ) 75 | if err := toErr(ret); err != nil { 76 | return nil, err 77 | } 78 | 79 | data = make([]byte, sizeInBytes) 80 | ret, _, _ = syscall.Syscall( 81 | obj.vtbl.GetFunction, 82 | 3, 83 | uintptr(unsafe.Pointer(obj)), 84 | uintptr(unsafe.Pointer(&data[0])), 85 | uintptr(unsafe.Pointer(&sizeInBytes)), 86 | ) 87 | err = toErr(ret) 88 | return 89 | } 90 | -------------------------------------------------------------------------------- /volume_texture_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // VolumeTexture and its methods are used to manipulate a volume texture 9 | // resource. 10 | type VolumeTexture struct { 11 | vtbl *volumeTextureVtbl 12 | } 13 | 14 | type volumeTextureVtbl struct { 15 | QueryInterface uintptr 16 | AddRef uintptr 17 | Release uintptr 18 | 19 | GetDevice uintptr 20 | SetPrivateData uintptr 21 | GetPrivateData uintptr 22 | FreePrivateData uintptr 23 | SetPriority uintptr 24 | GetPriority uintptr 25 | PreLoad uintptr 26 | D3DRESOURCETYPE, GetType uintptr 27 | SetLOD uintptr 28 | GetLOD uintptr 29 | GetLevelCount uintptr 30 | SetAutoGenFilterType uintptr 31 | GetAutoGenFilterType uintptr 32 | GenerateMipSubLevels uintptr 33 | GetLevelDesc uintptr 34 | GetVolumeLevel uintptr 35 | LockBox uintptr 36 | UnlockBox uintptr 37 | AddDirtyBox uintptr 38 | } 39 | 40 | func (obj *VolumeTexture) baseTexturePointer() uintptr { 41 | return uintptr(unsafe.Pointer(obj)) 42 | } 43 | 44 | // AddRef increments the reference count for an interface on an object. This 45 | // method should be called for every new copy of a pointer to an interface on an 46 | // object. 47 | func (obj *VolumeTexture) AddRef() uint32 { 48 | ret, _, _ := syscall.Syscall( 49 | obj.vtbl.AddRef, 50 | 1, 51 | uintptr(unsafe.Pointer(obj)), 52 | 0, 53 | 0, 54 | ) 55 | return uint32(ret) 56 | } 57 | 58 | // Release has to be called when finished using the object to free its 59 | // associated resources. 60 | func (obj *VolumeTexture) Release() uint32 { 61 | ret, _, _ := syscall.Syscall( 62 | obj.vtbl.Release, 63 | 1, 64 | uintptr(unsafe.Pointer(obj)), 65 | 0, 66 | 0, 67 | ) 68 | return uint32(ret) 69 | } 70 | 71 | // GetDevice retrieves the device associated with a resource. 72 | // Call Release on the returned device when finished using it. 73 | func (obj *VolumeTexture) GetDevice() (device *Device, err Error) { 74 | ret, _, _ := syscall.Syscall( 75 | obj.vtbl.GetDevice, 76 | 2, 77 | uintptr(unsafe.Pointer(obj)), 78 | uintptr(unsafe.Pointer(&device)), 79 | 0, 80 | ) 81 | err = toErr(ret) 82 | return 83 | } 84 | 85 | // SetPrivateData associates data with the resource that is intended for use by 86 | // the application, not by Direct3D. Data is passed by value, and multiple sets 87 | // of data can be associated with a single resource. 88 | func (obj *VolumeTexture) SetPrivateData( 89 | refguid GUID, 90 | data uintptr, 91 | sizeOfData uint32, 92 | flags uint32, 93 | ) Error { 94 | ret, _, _ := syscall.Syscall6( 95 | obj.vtbl.SetPrivateData, 96 | 5, 97 | uintptr(unsafe.Pointer(obj)), 98 | uintptr(unsafe.Pointer(&refguid)), 99 | data, 100 | uintptr(sizeOfData), 101 | uintptr(flags), 102 | 0, 103 | ) 104 | return toErr(ret) 105 | } 106 | 107 | // SetPrivateDataBytes associates data with the resource that is intended for 108 | // use by the application, not by Direct3D. Data is passed by value, and 109 | // multiple sets of data can be associated with a single resource. 110 | func (obj *VolumeTexture) SetPrivateDataBytes( 111 | refguid GUID, 112 | data []byte, 113 | flags uint32, 114 | ) Error { 115 | return obj.SetPrivateData( 116 | refguid, 117 | uintptr(unsafe.Pointer(&data[0])), 118 | uint32(len(data)), 119 | flags, 120 | ) 121 | } 122 | 123 | // GetPrivateData copies the private data associated with the resource to a 124 | // provided buffer. 125 | func (obj *VolumeTexture) GetPrivateData(refguid GUID) (data []byte, err Error) { 126 | // first get the data size by passing nil as the data pointer 127 | var sizeInBytes uint 128 | ret, _, _ := syscall.Syscall6( 129 | obj.vtbl.GetPrivateData, 130 | 4, 131 | uintptr(unsafe.Pointer(obj)), 132 | uintptr(unsafe.Pointer(&refguid)), 133 | 0, 134 | uintptr(unsafe.Pointer(&sizeInBytes)), 135 | 0, 136 | 0, 137 | ) 138 | if err := toErr(ret); err != nil { 139 | return nil, err 140 | } 141 | data = make([]byte, sizeInBytes) 142 | ret, _, _ = syscall.Syscall6( 143 | obj.vtbl.GetPrivateData, 144 | 4, 145 | uintptr(unsafe.Pointer(obj)), 146 | uintptr(unsafe.Pointer(&refguid)), 147 | uintptr(unsafe.Pointer(&data[0])), 148 | uintptr(unsafe.Pointer(&sizeInBytes)), 149 | 0, 150 | 0, 151 | ) 152 | return data, toErr(ret) 153 | } 154 | 155 | // FreePrivateData frees the specified private data associated with this 156 | // resource. 157 | func (obj *VolumeTexture) FreePrivateData(refguid GUID) Error { 158 | ret, _, _ := syscall.Syscall( 159 | obj.vtbl.FreePrivateData, 160 | 2, 161 | uintptr(unsafe.Pointer(obj)), 162 | uintptr(unsafe.Pointer(&refguid)), 163 | 0, 164 | ) 165 | return toErr(ret) 166 | } 167 | 168 | // SetPriority assigns the priority of a resource for scheduling purposes. 169 | func (obj *VolumeTexture) SetPriority(priorityNew uint32) uint32 { 170 | ret, _, _ := syscall.Syscall( 171 | obj.vtbl.SetPriority, 172 | 2, 173 | uintptr(unsafe.Pointer(obj)), 174 | uintptr(priorityNew), 175 | 0, 176 | ) 177 | return uint32(ret) 178 | } 179 | 180 | // GetPriority retrieves the priority for this resource. 181 | func (obj *VolumeTexture) GetPriority() uint32 { 182 | ret, _, _ := syscall.Syscall( 183 | obj.vtbl.GetPriority, 184 | 1, 185 | uintptr(unsafe.Pointer(obj)), 186 | 0, 187 | 0, 188 | ) 189 | return uint32(ret) 190 | } 191 | 192 | // PreLoad preloads a managed resource. 193 | func (obj *VolumeTexture) PreLoad() { 194 | syscall.Syscall( 195 | obj.vtbl.PreLoad, 196 | 1, 197 | uintptr(unsafe.Pointer(obj)), 198 | 0, 199 | 0, 200 | ) 201 | } 202 | 203 | // GetType returns the type of the resource. 204 | func (obj *VolumeTexture) GetType() RESOURCETYPE { 205 | ret, _, _ := syscall.Syscall( 206 | obj.vtbl.GetType, 207 | 1, 208 | uintptr(unsafe.Pointer(obj)), 209 | 0, 210 | 0, 211 | ) 212 | return RESOURCETYPE(ret) 213 | } 214 | 215 | // SetLOD sets the most detailed level-of-detail for a managed texture. 216 | func (obj *VolumeTexture) SetLOD(lodNew uint32) uint32 { 217 | ret, _, _ := syscall.Syscall( 218 | obj.vtbl.SetLOD, 219 | 2, 220 | uintptr(unsafe.Pointer(obj)), 221 | uintptr(lodNew), 222 | 0, 223 | ) 224 | return uint32(ret) 225 | } 226 | 227 | // GetLOD returns a value clamped to the maximum level-of-detail set for a 228 | // managed texture (this method is not supported for an unmanaged texture). 229 | func (obj *VolumeTexture) GetLOD() uint32 { 230 | ret, _, _ := syscall.Syscall( 231 | obj.vtbl.GetLOD, 232 | 1, 233 | uintptr(unsafe.Pointer(obj)), 234 | 0, 235 | 0, 236 | ) 237 | return uint32(ret) 238 | } 239 | 240 | // GetLevelCount returns the number of texture levels in a multilevel texture. 241 | func (obj *VolumeTexture) GetLevelCount() uint32 { 242 | ret, _, _ := syscall.Syscall( 243 | obj.vtbl.GetLevelCount, 244 | 1, 245 | uintptr(unsafe.Pointer(obj)), 246 | 0, 247 | 0, 248 | ) 249 | return uint32(ret) 250 | } 251 | 252 | // SetAutoGenFilterType sets the filter type that is used for automatically 253 | // generated mipmap sublevels. 254 | func (obj *VolumeTexture) SetAutoGenFilterType(typ TEXTUREFILTERTYPE) Error { 255 | ret, _, _ := syscall.Syscall( 256 | obj.vtbl.SetAutoGenFilterType, 257 | 2, 258 | uintptr(unsafe.Pointer(obj)), 259 | uintptr(typ), 260 | 0, 261 | ) 262 | return toErr(ret) 263 | } 264 | 265 | // GetAutoGenFilterType returns the filter type that is used for automatically 266 | // generated mipmap sublevels. 267 | func (obj *VolumeTexture) GetAutoGenFilterType() TEXTUREFILTERTYPE { 268 | ret, _, _ := syscall.Syscall( 269 | obj.vtbl.GetAutoGenFilterType, 270 | 1, 271 | uintptr(unsafe.Pointer(obj)), 272 | 0, 273 | 0, 274 | ) 275 | return TEXTUREFILTERTYPE(ret) 276 | } 277 | 278 | // GenerateMipSubLevels generates mip sub levels. 279 | func (obj *VolumeTexture) GenerateMipSubLevels() { 280 | syscall.Syscall( 281 | obj.vtbl.GenerateMipSubLevels, 282 | 1, 283 | uintptr(unsafe.Pointer(obj)), 284 | 0, 285 | 0, 286 | ) 287 | } 288 | 289 | // GetLevelDesc retrieves a level description of a volume texture resource. 290 | func (obj *VolumeTexture) GetLevelDesc(level uint) (desc VOLUME_DESC, err Error) { 291 | ret, _, _ := syscall.Syscall( 292 | obj.vtbl.GetLevelDesc, 293 | 3, 294 | uintptr(unsafe.Pointer(obj)), 295 | uintptr(level), 296 | uintptr(unsafe.Pointer(&desc)), 297 | ) 298 | err = toErr(ret) 299 | return 300 | } 301 | 302 | // GetVolumeLevel retrieves the specified volume texture level. 303 | // Call Release on the returned volume when finished using it. 304 | func (obj *VolumeTexture) GetVolumeLevel(level uint) (volume *Volume, err Error) { 305 | ret, _, _ := syscall.Syscall( 306 | obj.vtbl.GetVolumeLevel, 307 | 3, 308 | uintptr(unsafe.Pointer(obj)), 309 | uintptr(level), 310 | uintptr(unsafe.Pointer(&volume)), 311 | ) 312 | err = toErr(ret) 313 | return 314 | } 315 | 316 | // LockBox locks a box on a volume texture resource. 317 | func (obj *VolumeTexture) LockBox( 318 | level uint, 319 | box *BOX, 320 | flags uint32, 321 | ) (lockedVolume LOCKED_BOX, err Error) { 322 | ret, _, _ := syscall.Syscall6( 323 | obj.vtbl.LockBox, 324 | 5, 325 | uintptr(unsafe.Pointer(obj)), 326 | uintptr(level), 327 | uintptr(unsafe.Pointer(&lockedVolume)), 328 | uintptr(unsafe.Pointer(box)), 329 | uintptr(flags), 330 | 0, 331 | ) 332 | err = toErr(ret) 333 | return 334 | } 335 | 336 | // UnlockBox unlocks a box on a volume texture resource. 337 | func (obj *VolumeTexture) UnlockBox(level uint) Error { 338 | ret, _, _ := syscall.Syscall( 339 | obj.vtbl.UnlockBox, 340 | 2, 341 | uintptr(unsafe.Pointer(obj)), 342 | uintptr(level), 343 | 0, 344 | ) 345 | return toErr(ret) 346 | } 347 | 348 | // AddDirtyBox adds a dirty region to a volume texture resource. 349 | func (obj *VolumeTexture) AddDirtyBox(dirtyBox *BOX) Error { 350 | ret, _, _ := syscall.Syscall( 351 | obj.vtbl.AddDirtyBox, 352 | 2, 353 | uintptr(unsafe.Pointer(obj)), 354 | uintptr(unsafe.Pointer(dirtyBox)), 355 | 0, 356 | ) 357 | return toErr(ret) 358 | } 359 | -------------------------------------------------------------------------------- /volume_windows.go: -------------------------------------------------------------------------------- 1 | package d3d9 2 | 3 | import ( 4 | "syscall" 5 | "unsafe" 6 | ) 7 | 8 | // Volume and its methods are used to manipulate volume resources. 9 | type Volume struct { 10 | vtbl *volumeVtbl 11 | } 12 | 13 | type volumeVtbl struct { 14 | QueryInterface uintptr 15 | AddRef uintptr 16 | Release uintptr 17 | 18 | GetDevice uintptr 19 | SetPrivateData uintptr 20 | GetPrivateData uintptr 21 | FreePrivateData uintptr 22 | GetContainer uintptr 23 | GetDesc uintptr 24 | LockBox uintptr 25 | UnlockBox uintptr 26 | } 27 | 28 | // AddRef increments the reference count for an interface on an object. This 29 | // method should be called for every new copy of a pointer to an interface on an 30 | // object. 31 | func (obj *Volume) AddRef() uint32 { 32 | ret, _, _ := syscall.Syscall( 33 | obj.vtbl.AddRef, 34 | 1, 35 | uintptr(unsafe.Pointer(obj)), 36 | 0, 37 | 0, 38 | ) 39 | return uint32(ret) 40 | } 41 | 42 | // Release has to be called when finished using the object to free its 43 | // associated resources. 44 | func (obj *Volume) Release() uint32 { 45 | ret, _, _ := syscall.Syscall( 46 | obj.vtbl.Release, 47 | 1, 48 | uintptr(unsafe.Pointer(obj)), 49 | 0, 50 | 0, 51 | ) 52 | return uint32(ret) 53 | } 54 | 55 | // GetDevice retrieves the device associated with a volume. 56 | func (obj *Volume) GetDevice() (device *Device, err Error) { 57 | ret, _, _ := syscall.Syscall( 58 | obj.vtbl.GetDevice, 59 | 2, 60 | uintptr(unsafe.Pointer(obj)), 61 | uintptr(unsafe.Pointer(&device)), 62 | 0, 63 | ) 64 | err = toErr(ret) 65 | return 66 | } 67 | 68 | // SetPrivateData associates data with the volume that is intended for use by 69 | // the application, not by Direct3D. 70 | func (obj *Volume) SetPrivateData( 71 | refguid GUID, 72 | data uintptr, 73 | sizeOfData uint32, 74 | flags uint32, 75 | ) Error { 76 | ret, _, _ := syscall.Syscall6( 77 | obj.vtbl.SetPrivateData, 78 | 5, 79 | uintptr(unsafe.Pointer(obj)), 80 | uintptr(unsafe.Pointer(&refguid)), 81 | data, 82 | uintptr(sizeOfData), 83 | uintptr(flags), 84 | 0, 85 | ) 86 | return toErr(ret) 87 | } 88 | 89 | // SetPrivateDataInBytes associates data with the volume that is intended for 90 | // use by the application, not by Direct3D. 91 | func (obj Volume) SetPrivateDataInBytes( 92 | refguid GUID, 93 | data []byte, 94 | flags uint32, 95 | ) Error { 96 | return obj.SetPrivateData( 97 | refguid, 98 | uintptr(unsafe.Pointer(&data[0])), 99 | uint32(len(data)), 100 | flags, 101 | ) 102 | } 103 | 104 | // GetPrivateData copies the private data associated with the volume to a 105 | // buffer. 106 | func (obj *Volume) GetPrivateData(refguid GUID) (data []byte, err Error) { 107 | // first get the buffer size by passing nil as the data pointer 108 | var sizeInBytes uint 109 | ret, _, _ := syscall.Syscall6( 110 | obj.vtbl.GetPrivateData, 111 | 4, 112 | uintptr(unsafe.Pointer(obj)), 113 | uintptr(unsafe.Pointer(&refguid)), 114 | 0, 115 | uintptr(unsafe.Pointer(&sizeInBytes)), 116 | 0, 117 | 0, 118 | ) 119 | if err := toErr(ret); err != nil { 120 | return nil, err 121 | } 122 | data = make([]byte, sizeInBytes) 123 | ret, _, _ = syscall.Syscall6( 124 | obj.vtbl.GetPrivateData, 125 | 4, 126 | uintptr(unsafe.Pointer(obj)), 127 | uintptr(unsafe.Pointer(&refguid)), 128 | uintptr(unsafe.Pointer(&data[0])), 129 | uintptr(unsafe.Pointer(&sizeInBytes)), 130 | 0, 131 | 0, 132 | ) 133 | err = toErr(ret) 134 | return 135 | } 136 | 137 | // FreePrivateData frees the specified private data associated with this volume. 138 | func (obj *Volume) FreePrivateData(refguid GUID) Error { 139 | ret, _, _ := syscall.Syscall( 140 | obj.vtbl.FreePrivateData, 141 | 2, 142 | uintptr(unsafe.Pointer(obj)), 143 | uintptr(unsafe.Pointer(&refguid)), 144 | 0, 145 | ) 146 | return toErr(ret) 147 | } 148 | 149 | // GetContainer provides access to the parent volume texture object, if this 150 | // surface is a child level of a volume texture. 151 | // Call Release on the returned volume texture when finished using it. 152 | func (obj *Volume) GetContainer(riid GUID) (tex *VolumeTexture, err Error) { 153 | ret, _, _ := syscall.Syscall( 154 | obj.vtbl.GetContainer, 155 | 3, 156 | uintptr(unsafe.Pointer(obj)), 157 | uintptr(unsafe.Pointer(&riid)), 158 | uintptr(unsafe.Pointer(tex)), 159 | ) 160 | err = toErr(ret) 161 | return 162 | } 163 | 164 | // GetDesc retrieves a description of the volume. 165 | func (obj *Volume) GetDesc() (desc VOLUME_DESC, err Error) { 166 | ret, _, _ := syscall.Syscall( 167 | obj.vtbl.GetDesc, 168 | 2, 169 | uintptr(unsafe.Pointer(obj)), 170 | uintptr(unsafe.Pointer(&desc)), 171 | 0, 172 | ) 173 | err = toErr(ret) 174 | return 175 | } 176 | 177 | // LockBox locks a box on a volume resource. 178 | func (obj *Volume) LockBox( 179 | box *BOX, 180 | flags uint32, 181 | ) (locked *LOCKED_BOX, err Error) { 182 | ret, _, _ := syscall.Syscall6( 183 | obj.vtbl.LockBox, 184 | 4, 185 | uintptr(unsafe.Pointer(obj)), 186 | uintptr(unsafe.Pointer(&locked)), 187 | uintptr(unsafe.Pointer(&box)), 188 | uintptr(flags), 189 | 0, 190 | 0, 191 | ) 192 | err = toErr(ret) 193 | return 194 | } 195 | 196 | // UnlockBox unlocks a box on a volume resource. 197 | func (obj *Volume) UnlockBox() Error { 198 | ret, _, _ := syscall.Syscall( 199 | obj.vtbl.UnlockBox, 200 | 1, 201 | uintptr(unsafe.Pointer(obj)), 202 | 0, 203 | 0, 204 | ) 205 | return toErr(ret) 206 | } 207 | --------------------------------------------------------------------------------