/program.go

https://github.com/anight/gl-old · Go · 207 lines · 135 code · 49 blank · 23 comment · 19 complexity · 925c0be28fb812bda9242eb928c86070 MD5 · raw file

  1. // Copyright 2012 The go-gl Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package gl
  5. // #include "gl.h"
  6. // GLuint workaroundGlGetUniformBlockIndex(GLuint program, const GLchar* uniformBlockName) {
  7. // return glGetUniformBlockIndex(program, uniformBlockName);
  8. // }
  9. import "C"
  10. import "unsafe"
  11. // Program
  12. type Program Object
  13. func CreateProgram() Program { return Program(C.glCreateProgram()) }
  14. func (program Program) Delete() { C.glDeleteProgram(C.GLuint(program)) }
  15. func (program Program) AttachShader(shader Shader) {
  16. C.glAttachShader(C.GLuint(program), C.GLuint(shader))
  17. }
  18. func (program Program) GetAttachedShaders() []Object {
  19. var len C.GLint
  20. C.glGetProgramiv(C.GLuint(program), C.GLenum(ACTIVE_UNIFORM_MAX_LENGTH), &len)
  21. objects := make([]Object, len)
  22. C.glGetAttachedShaders(C.GLuint(program), C.GLsizei(len), nil, *((**C.GLuint)(unsafe.Pointer(&objects))))
  23. return objects
  24. }
  25. func (program Program) DetachShader(shader Shader) {
  26. C.glDetachShader(C.GLuint(program), C.GLuint(shader))
  27. }
  28. func (program Program) TransformFeedbackVaryings(names []string, buffer_mode GLenum) {
  29. if len(names) == 0 {
  30. C.glTransformFeedbackVaryings(C.GLuint(program), 0, (**C.GLchar)(nil), C.GLenum(buffer_mode))
  31. } else {
  32. gl_names := make([]*C.GLchar, len(names))
  33. for i := range names {
  34. gl_names[i] = glString(names[i])
  35. }
  36. C.glTransformFeedbackVaryings(C.GLuint(program), C.GLsizei(len(gl_names)), &gl_names[0], C.GLenum(buffer_mode))
  37. for _, s := range gl_names {
  38. freeString(s)
  39. }
  40. }
  41. }
  42. func (program Program) Link() { C.glLinkProgram(C.GLuint(program)) }
  43. func (program Program) Validate() { C.glValidateProgram(C.GLuint(program)) }
  44. func (program Program) Use() { C.glUseProgram(C.GLuint(program)) }
  45. func (program Program) Unuse() { C.glUseProgram(C.GLuint(0)) }
  46. // Deprecated, please use program.Unuse()
  47. func ProgramUnuse() { C.glUseProgram(C.GLuint(0)) }
  48. func (program Program) GetInfoLog() string {
  49. var length C.GLint
  50. C.glGetProgramiv(C.GLuint(program), C.GLenum(INFO_LOG_LENGTH), &length)
  51. // length is buffer size including null character
  52. if length > 1 {
  53. log := C.malloc(C.size_t(length))
  54. defer C.free(log)
  55. C.glGetProgramInfoLog(C.GLuint(program), C.GLsizei(length), nil, (*C.GLchar)(log))
  56. return C.GoString((*C.char)(log))
  57. }
  58. return ""
  59. }
  60. func (program Program) Get(param GLenum) int {
  61. var rv C.GLint
  62. C.glGetProgramiv(C.GLuint(program), C.GLenum(param), &rv)
  63. return int(rv)
  64. }
  65. // glGetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
  66. func (program Program) GetActiveUniform(index int) (
  67. Size int, Type GLenum, Name string) {
  68. // Maximum length of active uniform name in program
  69. bufSize := program.Get(ACTIVE_UNIFORM_MAX_LENGTH)
  70. nameBuf := C.malloc(C.size_t(bufSize))
  71. defer C.free(nameBuf)
  72. var size C.GLint
  73. C.glGetActiveUniform(
  74. C.GLuint(program),
  75. C.GLuint(index),
  76. C.GLsizei(bufSize),
  77. nil, // length == len(Name)
  78. &size,
  79. (*C.GLenum)(&Type),
  80. (*C.GLchar)(nameBuf))
  81. Name = C.GoString((*C.char)(nameBuf))
  82. Size = int(size)
  83. return
  84. }
  85. func (program Program) GetUniformiv(location UniformLocation, values []int32) {
  86. if len(values) == 0 {
  87. panic("Invalid values length")
  88. }
  89. // FIXME(jimt): This should really yield only one return value instead of using a slice.
  90. // http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml
  91. C.glGetUniformiv(C.GLuint(program), C.GLint(location), (*C.GLint)(&(values[0])))
  92. }
  93. func (program Program) GetUniformfv(location UniformLocation, values []float32) {
  94. if len(values) == 0 {
  95. panic("Invalid values length")
  96. }
  97. // FIXME(jimt): This should really yield only one return value instead of using a slice.
  98. // http://www.opengl.org/sdk/docs/man/xhtml/glGetUniform.xml
  99. C.glGetUniformfv(C.GLuint(program), C.GLint(location), (*C.GLfloat)(&(values[0])))
  100. }
  101. func (program Program) GetUniformLocation(name string) UniformLocation {
  102. cname := glString(name)
  103. defer freeString(cname)
  104. return UniformLocation(C.glGetUniformLocation(C.GLuint(program), cname))
  105. }
  106. func (program Program) GetUniformBlockIndex(name string) UniformBlockIndex {
  107. cname := glString(name)
  108. defer freeString(cname)
  109. // Workaround bug in GLEW < 1.8 where glGetUniformBlockIndex expects
  110. // a string of char instead of a string of GLchar. We could ask everybody
  111. // to bump their version of GLEW, or we could add a bit of C code that
  112. // will silently cast GLchar into char.
  113. //return UniformBlockIndex(C.glGetUniformBlockIndex(C.GLuint(program), cname))
  114. return UniformBlockIndex(C.workaroundGlGetUniformBlockIndex(C.GLuint(program), cname))
  115. }
  116. func (program Program) UniformBlockBinding(index UniformBlockIndex, binding uint) {
  117. C.glUniformBlockBinding(C.GLuint(program), C.GLuint(index), C.GLuint(binding))
  118. }
  119. // glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
  120. func (program Program) GetActiveAttrib(index int) (
  121. Size int, Type GLenum, Name string) {
  122. // Maximum length of active uniform name in program
  123. bufSize := program.Get(ACTIVE_ATTRIBUTE_MAX_LENGTH)
  124. nameBuf := C.malloc(C.size_t(bufSize))
  125. defer C.free(nameBuf)
  126. var size C.GLint
  127. C.glGetActiveAttrib(
  128. C.GLuint(program),
  129. C.GLuint(index),
  130. C.GLsizei(bufSize),
  131. nil, // length == len(Name)
  132. &size,
  133. (*C.GLenum)(&Type),
  134. (*C.GLchar)(nameBuf))
  135. Name = C.GoString((*C.char)(nameBuf))
  136. Size = int(size)
  137. return
  138. }
  139. func (program Program) GetAttribLocation(name string) AttribLocation {
  140. cname := glString(name)
  141. defer freeString(cname)
  142. return AttribLocation(C.glGetAttribLocation(C.GLuint(program), cname))
  143. }
  144. func (program Program) BindAttribLocation(index AttribLocation, name string) {
  145. cname := glString(name)
  146. defer freeString(cname)
  147. C.glBindAttribLocation(C.GLuint(program), C.GLuint(index), cname)
  148. }
  149. func (program Program) BindFragDataLocation(colorNumber int, name string) {
  150. cname := glString(name)
  151. defer freeString(cname)
  152. C.glBindFragDataLocation(C.GLuint(program), C.GLuint(colorNumber), cname)
  153. }
  154. func (program Program) GetFragDataLocation(name string) int {
  155. cname := glString(name)
  156. defer freeString(cname)
  157. return int(C.glGetFragDataLocation(C.GLuint(program), cname))
  158. }