2021-12-20 18:32:08 +01:00
|
|
|
Class {
|
|
|
|
#name : #OpenGLSL,
|
2022-02-15 18:04:54 +01:00
|
|
|
#superclass : #DiyaSingleton,
|
2021-12-20 18:32:08 +01:00
|
|
|
#instVars : [
|
2022-02-15 18:04:54 +01:00
|
|
|
'programID',
|
|
|
|
'uniforms'
|
2021-12-20 18:32:08 +01:00
|
|
|
],
|
|
|
|
#pools : [
|
|
|
|
'OpenGLConstants',
|
|
|
|
'OpenGLTypes'
|
|
|
|
],
|
|
|
|
#category : #'Diya-OpenGL'
|
|
|
|
}
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> attachShader: shader to: program [
|
|
|
|
^self ffiCall: #(void glAttachShader(GLuint program,GLuint shader))
|
|
|
|
]
|
|
|
|
|
2022-02-15 18:04:54 +01:00
|
|
|
{ #category : #'instance creation' }
|
|
|
|
OpenGLSL class >> cleanUpInstance: singleton [
|
2022-03-15 19:11:19 +01:00
|
|
|
singleton ifNil:[^self].
|
2022-02-15 18:04:54 +01:00
|
|
|
singleton delete
|
|
|
|
]
|
|
|
|
|
2021-12-20 18:32:08 +01:00
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> compileShader: shader [
|
|
|
|
^ self ffiCall: #(void glCompileShader( GLuint shader))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> createProgram [
|
|
|
|
^self ffiCall: #(GLuint glCreateProgram(void))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> createShader: shaderType [
|
|
|
|
^ self ffiCall: #(GLuint glCreateShader( GLenum shaderType))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> deleteProgram: program [
|
|
|
|
^self ffiCall: #(void glDeleteProgram(GLuint program))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> deleteShader: shader [
|
|
|
|
^ self ffiCall: #(void glDeleteShader( GLuint shader))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> detachShaderFrom: program shader:shader [
|
|
|
|
^ self ffiCall: #(void glDetachShader(GLuint program,GLuint shader))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'library path' }
|
|
|
|
OpenGLSL class >> ffiLibraryName [
|
|
|
|
^ OpenGL ffiLibraryName
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #accessing }
|
|
|
|
OpenGLSL class >> fragmentShader [
|
|
|
|
^ self subclassResponsibility
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> getProgramInfoLogOf: prog maxLength: maxLength lengthPtr: length buffer: infoLog [
|
|
|
|
^self ffiCall:#(void glGetProgramInfoLog(GLuint prog,GLsizei maxLength,GLsizei *length,GLchar *infoLog))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> getShaderInfoLogOf: shader maxLength: maxLength lengthPtr: length buffer: infoLog [
|
|
|
|
^self ffiCall:#(void glGetShaderInfoLog(GLuint shader,GLsizei maxLength,GLsizei *length,GLchar *infoLog))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> getShaderiv:shader parameterName: pname params: ptr [
|
|
|
|
^ self ffiCall: #(void glGetShaderiv(GLuint shader,GLenum pname,GLint *ptr))
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
2022-02-15 18:04:54 +01:00
|
|
|
OpenGLSL class >> getUniformLocation: uname ofProgram: program [
|
|
|
|
^self ffiCall:#(GLint glGetUniformLocation( GLuint program,const GLchar *uname))
|
2021-12-20 18:32:08 +01:00
|
|
|
]
|
|
|
|
|
2022-02-15 18:04:54 +01:00
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> linkProgram:program [
|
|
|
|
^self ffiCall: #(void glLinkProgram(GLuint program))
|
2021-12-20 18:32:08 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> setShaderSourceFor: shader count: n string: s length: l [
|
2022-02-13 17:15:23 +01:00
|
|
|
^ self ffiCall: #(void glShaderSource( GLuint shader,GLsizei n,const void* s,const GLint *l))
|
2021-12-20 18:32:08 +01:00
|
|
|
]
|
|
|
|
|
2022-02-15 18:04:54 +01:00
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> systemUniforms [
|
|
|
|
^#(u_time u_resolution u_mouse)
|
2021-12-20 18:32:08 +01:00
|
|
|
]
|
|
|
|
|
2022-02-13 17:15:23 +01:00
|
|
|
{ #category : #'as yet unclassified' }
|
|
|
|
OpenGLSL class >> useProgram:program [
|
|
|
|
^self ffiCall:#(void glUseProgram(GLuint program))
|
|
|
|
]
|
|
|
|
|
2021-12-20 18:32:08 +01:00
|
|
|
{ #category : #accessing }
|
2022-03-03 19:19:40 +01:00
|
|
|
OpenGLSL class >> vertexShader [
|
2022-03-06 18:33:10 +01:00
|
|
|
^self subclassResponsibility
|
2021-12-20 18:32:08 +01:00
|
|
|
]
|
|
|
|
|
2022-02-15 18:04:54 +01:00
|
|
|
{ #category : #initialization }
|
|
|
|
OpenGLSL >> addUniform: uname of: utype [
|
|
|
|
uniforms at:uname put: (utype fromName: uname).
|
|
|
|
]
|
|
|
|
|
2021-12-20 18:32:08 +01:00
|
|
|
{ #category : #compiling }
|
|
|
|
OpenGLSL >> checkStatus:status of: id [
|
2022-02-14 00:02:14 +01:00
|
|
|
|infoLength buffer result|
|
|
|
|
result := FFIExternalArray externalNewType: GLint size: 1.
|
2022-02-13 17:15:23 +01:00
|
|
|
infoLength := FFIExternalArray externalNewType: GLint size: 1.
|
2022-02-15 20:32:33 +01:00
|
|
|
infoLength at: 1 put: 0.
|
2021-12-20 18:32:08 +01:00
|
|
|
infoLength autoRelease.
|
2022-02-14 00:02:14 +01:00
|
|
|
result autoRelease.
|
|
|
|
OpenGLSL getShaderiv: id parameterName: status params: result getHandle.
|
2022-02-13 17:15:23 +01:00
|
|
|
OpenGLSL getShaderiv: id parameterName: GL_INFO_LOG_LENGTH params: infoLength getHandle.
|
2021-12-20 18:32:08 +01:00
|
|
|
(infoLength at:1) > 0 ifTrue: [
|
|
|
|
"report the error"
|
|
|
|
buffer := ByteArray new:(infoLength at: 1).
|
|
|
|
id = programID ifTrue: [
|
|
|
|
OpenGLSL getProgramInfoLogOf: id maxLength: (infoLength at: 1) lengthPtr: nil buffer: buffer
|
|
|
|
] ifFalse: [
|
|
|
|
OpenGLSL getShaderInfoLogOf: id maxLength: (infoLength at: 1) lengthPtr: nil buffer: buffer
|
|
|
|
].
|
2022-03-19 02:18:29 +01:00
|
|
|
^DiyaCoreAPIError signal: buffer asString
|
2021-12-20 18:32:08 +01:00
|
|
|
].
|
|
|
|
^self
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #compiling }
|
|
|
|
OpenGLSL >> compile [
|
|
|
|
|vertexShaderID fragmentShaderID|
|
|
|
|
vertexShaderID := OpenGLSL createShader: GL_VERTEX_SHADER.
|
|
|
|
fragmentShaderID := OpenGLSL createShader: GL_FRAGMENT_SHADER.
|
|
|
|
self compileVertexShader: vertexShaderID.
|
|
|
|
self compileFragmentShader: fragmentShaderID.
|
|
|
|
programID := OpenGLSL createProgram.
|
|
|
|
OpenGLSL attachShader: vertexShaderID to: programID.
|
|
|
|
OpenGLSL attachShader: fragmentShaderID to: programID.
|
|
|
|
OpenGLSL linkProgram: programID.
|
|
|
|
self checkStatus: GL_LINK_STATUS of: programID.
|
|
|
|
OpenGLSL detachShaderFrom: programID shader: vertexShaderID.
|
|
|
|
OpenGLSL detachShaderFrom: programID shader: fragmentShaderID.
|
2022-02-13 17:15:23 +01:00
|
|
|
OpenGLSL deleteShader: vertexShaderID.
|
2022-02-15 18:04:54 +01:00
|
|
|
OpenGLSL deleteShader: fragmentShaderID.
|
|
|
|
self locateUniforms
|
2021-12-20 18:32:08 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #compiling }
|
|
|
|
OpenGLSL >> compileFragmentShader:fragmentShaderID [
|
|
|
|
self getSourcePtr:self class fragmentShader for: fragmentShaderID.
|
|
|
|
OpenGLSL compileShader: fragmentShaderID.
|
|
|
|
self checkStatus:GL_COMPILE_STATUS of: fragmentShaderID
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #compiling }
|
|
|
|
OpenGLSL >> compileVertexShader: vertexShaderID [
|
2022-03-03 19:19:40 +01:00
|
|
|
self getSourcePtr:self class vertexShader for: vertexShaderID.
|
2021-12-20 18:32:08 +01:00
|
|
|
OpenGLSL compileShader: vertexShaderID.
|
|
|
|
self checkStatus:GL_COMPILE_STATUS of: vertexShaderID
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #'submorphs-add/remove' }
|
|
|
|
OpenGLSL >> delete [
|
|
|
|
OpenGLSL deleteProgram: programID
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #compiling }
|
|
|
|
OpenGLSL >> getSourcePtr: string for: shaderId [
|
2022-02-13 17:15:23 +01:00
|
|
|
|xarray|
|
|
|
|
xarray := FFIExternalArray externalNewType: 'char*' size: 1.
|
|
|
|
xarray at:1 put: (ExternalAddress fromString: string).
|
|
|
|
xarray autoRelease.
|
|
|
|
OpenGLSL setShaderSourceFor: shaderId count: 1 string: xarray getHandle length: nil.
|
2021-12-20 18:32:08 +01:00
|
|
|
]
|
|
|
|
|
2022-02-15 18:04:54 +01:00
|
|
|
{ #category : #'submorphs-add/remove' }
|
|
|
|
OpenGLSL >> getUniformLocation:uname [
|
|
|
|
^ self class getUniformLocation: uname asString ofProgram: programID
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #initialization }
|
|
|
|
OpenGLSL >> initialize [
|
|
|
|
super initialize.
|
|
|
|
uniforms := Dictionary new.
|
|
|
|
self addUniform: #u_time of: Uniform1F.
|
|
|
|
self addUniform: #u_resolution of: Uniform2F.
|
|
|
|
self addUniform: #u_mouse of: Uniform2F.
|
2022-03-03 19:19:40 +01:00
|
|
|
self addUniform: #u_projection of: UniformMatrix4fv.
|
2022-03-05 11:55:20 +01:00
|
|
|
self addUniform: #u_transform of: UniformMatrix3fv.
|
2022-02-15 18:04:54 +01:00
|
|
|
self setUpUniforms.
|
|
|
|
self compile
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #compiling }
|
|
|
|
OpenGLSL >> locateUniforms [
|
|
|
|
|loc|
|
|
|
|
uniforms valuesDo: [ :uniform|
|
|
|
|
loc := self getUniformLocation: uniform uname.
|
|
|
|
loc = -1 ifFalse:[uniform location: loc]
|
|
|
|
]
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #initialization }
|
|
|
|
OpenGLSL >> setUniform: uname value: values [
|
|
|
|
|uniform|
|
|
|
|
uniform := uniforms at: uname asSymbol ifAbsent:[
|
2022-03-19 02:18:29 +01:00
|
|
|
^DiyaCoreAPIError signal: 'Uniform ', uname, ' is not defined in this program'].
|
2022-02-15 18:04:54 +01:00
|
|
|
uniform value: values
|
|
|
|
]
|
|
|
|
|
|
|
|
{ #category : #initialization }
|
|
|
|
OpenGLSL >> setUpUniforms [
|
|
|
|
"do nothing, custom uniform can be set up by subclass"
|
|
|
|
]
|
|
|
|
|
2021-12-20 18:32:08 +01:00
|
|
|
{ #category : #'submorphs-add/remove' }
|
|
|
|
OpenGLSL >> use [
|
2022-02-13 17:15:23 +01:00
|
|
|
^OpenGLSL useProgram: programID
|
2021-12-20 18:32:08 +01:00
|
|
|
]
|