1
0
mirror of https://github.com/lxsang/Diya-API.git synced 2024-12-27 03:48:21 +01:00

add uniform support to shader

This commit is contained in:
Dany LE 2022-02-15 18:04:54 +01:00
parent 13804205f8
commit e047a89801
18 changed files with 426 additions and 47 deletions

View File

@ -1,15 +1,13 @@
Class { Class {
#name : #DiyaBoot, #name : #DiyaBoot,
#superclass : #DiyaBaseObject, #superclass : #DiyaSingleton,
#instVars : [ #instVars : [
'running', 'running',
'window', 'window',
'renderer', 'renderer',
'context', 'context',
'display' 'display',
], 'clock'
#classVars : [
'singleton'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -20,16 +18,6 @@ Class {
#category : #'Diya-Runtime' #category : #'Diya-Runtime'
} }
{ #category : #'instance creation' }
DiyaBoot class >> new [
self error: 'Use #uniqueInstance'
]
{ #category : #'instance creation' }
DiyaBoot class >> reset [
singleton := nil
]
{ #category : #'instance creation' } { #category : #'instance creation' }
DiyaBoot class >> startUp: status [ DiyaBoot class >> startUp: status [
self startx. self startx.
@ -40,12 +28,6 @@ DiyaBoot class >> startx [
self uniqueInstance run self uniqueInstance run
] ]
{ #category : #'instance creation' }
DiyaBoot class >> uniqueInstance [
singleton ifNil: [ singleton := super new ].
^ singleton
]
{ #category : #events } { #category : #events }
DiyaBoot >> createGLContext [ DiyaBoot >> createGLContext [
context := SDL2 glCreateContext: window. context := SDL2 glCreateContext: window.
@ -91,6 +73,7 @@ DiyaBoot >> initialize [
display := nil. display := nil.
window := nil. window := nil.
context := nil. context := nil.
clock := DiyaClock uniqueInstance.
] ]
{ #category : #events } { #category : #events }
@ -101,6 +84,7 @@ DiyaBoot >> processEvent: event [
mappedEvt type = SDL_QUIT ifTrue:[ ^running:= false ]. mappedEvt type = SDL_QUIT ifTrue:[ ^running:= false ].
mappedEvt type = SDL_FINGERDOWN ifTrue:[^self setCursorPosition: mappedEvt ]. mappedEvt type = SDL_FINGERDOWN ifTrue:[^self setCursorPosition: mappedEvt ].
mappedEvt type = SDL_FINGERMOTION ifTrue:[^self setCursorPosition: mappedEvt ]. mappedEvt type = SDL_FINGERMOTION ifTrue:[^self setCursorPosition: mappedEvt ].
mappedEvt type = SDL_MOUSEMOTION ifTrue:[DiyaRendererContext uniqueInstance mouse: mappedEvt].
] ]
{ #category : #events } { #category : #events }
@ -167,6 +151,8 @@ DiyaBoot >> run: screenSize app: application [
display h: screenSize y. display h: screenSize y.
self startx. self startx.
self class reset. self class reset.
DiyaClock reset.
DiyaRendererContext reset.
Smalltalk garbageCollect. Smalltalk garbageCollect.
] ]
@ -220,6 +206,7 @@ DiyaBoot >> startx [
self createGLContext. self createGLContext.
self createRenderer. self createRenderer.
self showSystemInfo. self showSystemInfo.
DiyaRendererContext uniqueInstance display: display.
sr := SimpleDiyaRenderer new. sr := SimpleDiyaRenderer new.
sr setup. sr setup.
self render:sr. self render:sr.

18
Diya/DiyaClock.class.st Normal file
View File

@ -0,0 +1,18 @@
Class {
#name : #DiyaClock,
#superclass : #DiyaSingleton,
#instVars : [
'monotonic'
],
#category : #'Diya-Runtime'
}
{ #category : #initialization }
DiyaClock >> elapsedTime [
^(DateAndTime now) - monotonic
]
{ #category : #initialization }
DiyaClock >> initialize [
monotonic := DateAndTime now.
]

View File

@ -1,6 +1,9 @@
Class { Class {
#name : #DiyaRenderer, #name : #DiyaRenderer,
#superclass : #DiyaBaseObject, #superclass : #DiyaBaseObject,
#instVars : [
'context'
],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
'OpenGLTypes' 'OpenGLTypes'
@ -8,11 +11,22 @@ Class {
#category : #'Diya-Graphics' #category : #'Diya-Graphics'
} }
{ #category : #'instance creation' }
DiyaRenderer class >> fromContext: ctx [
^self new context: ctx; yourself
]
{ #category : #deleting } { #category : #deleting }
DiyaRenderer >> destroy [ DiyaRenderer >> destroy [
^ self subclassResponsibility ^ self subclassResponsibility
] ]
{ #category : #initialization }
DiyaRenderer >> initialize [
super initialize.
context := DiyaRendererContext uniqueInstance
]
{ #category : #deleting } { #category : #deleting }
DiyaRenderer >> render [ DiyaRenderer >> render [
^ self subclassResponsibility ^ self subclassResponsibility

View File

@ -0,0 +1,38 @@
Class {
#name : #DiyaRendererContext,
#superclass : #DiyaSingleton,
#instVars : [
'mouse',
'display'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-Graphics'
}
{ #category : #accessing }
DiyaRendererContext >> display [
^ display
]
{ #category : #accessing }
DiyaRendererContext >> display: anObject [
display := anObject
]
{ #category : #accessing }
DiyaRendererContext >> mouse [
^ mouse
]
{ #category : #accessing }
DiyaRendererContext >> mouse: anObject [
mouse := anObject
]
{ #category : #'as yet unclassified' }
DiyaRendererContext >> resolution [
^ (display w) @ (display h)
]

View File

@ -0,0 +1,37 @@
Class {
#name : #DiyaSingleton,
#superclass : #DiyaBaseObject,
#classVars : [
'singletons'
],
#category : #'Diya-Core'
}
{ #category : #'instance creation' }
DiyaSingleton class >> cleanUpInstance: singleton [
"do nothing for now"
]
{ #category : #'class initialization' }
DiyaSingleton class >> initialize [
singletons := Dictionary new.
]
{ #category : #'instance creation' }
DiyaSingleton class >> new [
self error: 'Use #uniqueInstance'
]
{ #category : #'instance creation' }
DiyaSingleton class >> reset [
|singleton|
singleton := singletons at: self class ifAbsent: [ ^ self ].
self cleanUpInstance: singleton.
singletons removeKey: self class
]
{ #category : #'instance creation' }
DiyaSingleton class >> uniqueInstance [
singletons at: self class ifAbsentPut: super new.
^ singletons at: self class
]

View File

@ -0,0 +1,6 @@
Extension { #name : #Duration }
{ #category : #'*Diya' }
Duration >> asFloat [
^ seconds asFloat + (nanos / 1e9) asFloat
]

View File

@ -7,9 +7,16 @@ Class {
{ #category : #accessing } { #category : #accessing }
GLSimpleShader class >> fragmentShader [ GLSimpleShader class >> fragmentShader [
^ ' ^ '
#ifdef GL_ES
precision mediump float;
#endif
uniform vec2 u_resolution;
uniform vec2 u_mouse;
uniform float u_time;
void main() void main()
{ {
gl_FragColor = vec4(0.4,0.4,0.8,1.0); vec2 mouse = vec2(u_mouse)/vec2(u_resolution);
gl_FragColor = vec4(mouse.x, mouse.y, abs(sin(u_time)), 1.0);
} }
' '
] ]

View File

@ -1,11 +1,9 @@
Class { Class {
#name : #OpenGLSL, #name : #OpenGLSL,
#superclass : #DiyaBaseObject, #superclass : #DiyaSingleton,
#instVars : [ #instVars : [
'programID' 'programID',
], 'uniforms'
#classVars : [
'singleton'
], ],
#pools : [ #pools : [
'OpenGLConstants', 'OpenGLConstants',
@ -19,6 +17,11 @@ OpenGLSL class >> attachShader: shader to: program [
^self ffiCall: #(void glAttachShader(GLuint program,GLuint shader)) ^self ffiCall: #(void glAttachShader(GLuint program,GLuint shader))
] ]
{ #category : #'instance creation' }
OpenGLSL class >> cleanUpInstance: singleton [
singleton delete
]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
OpenGLSL class >> compileShader: shader [ OpenGLSL class >> compileShader: shader [
^ self ffiCall: #(void glCompileShader( GLuint shader)) ^ self ffiCall: #(void glCompileShader( GLuint shader))
@ -74,33 +77,24 @@ OpenGLSL class >> getShaderiv:shader parameterName: pname params: ptr [
^ self ffiCall: #(void glGetShaderiv(GLuint shader,GLenum pname,GLint *ptr)) ^ self ffiCall: #(void glGetShaderiv(GLuint shader,GLenum pname,GLint *ptr))
] ]
{ #category : #'as yet unclassified' }
OpenGLSL class >> getUniformLocation: uname ofProgram: program [
^self ffiCall:#(GLint glGetUniformLocation( GLuint program,const GLchar *uname))
]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
OpenGLSL class >> linkProgram:program [ OpenGLSL class >> linkProgram:program [
^self ffiCall: #(void glLinkProgram(GLuint program)) ^self ffiCall: #(void glLinkProgram(GLuint program))
] ]
{ #category : #'instance creation' }
OpenGLSL class >> new [
self error: 'Use #uniqueInstance'
]
{ #category : #'instance creation' }
OpenGLSL class >> reset [
singleton ifNotNil: [
singleton delete.
].
singleton := nil
]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
OpenGLSL class >> setShaderSourceFor: shader count: n string: s length: l [ OpenGLSL class >> setShaderSourceFor: shader count: n string: s length: l [
^ self ffiCall: #(void glShaderSource( GLuint shader,GLsizei n,const void* s,const GLint *l)) ^ self ffiCall: #(void glShaderSource( GLuint shader,GLsizei n,const void* s,const GLint *l))
] ]
{ #category : #'instance creation' } { #category : #'as yet unclassified' }
OpenGLSL class >> uniqueInstance [ OpenGLSL class >> systemUniforms [
singleton ifNil: [ singleton := super new. singleton compile ]. ^#(u_time u_resolution u_mouse)
^ singleton
] ]
{ #category : #'as yet unclassified' } { #category : #'as yet unclassified' }
@ -113,6 +107,11 @@ OpenGLSL class >> vertextShader [
^ self subclassResponsibility ^ self subclassResponsibility
] ]
{ #category : #initialization }
OpenGLSL >> addUniform: uname of: utype [
uniforms at:uname put: (utype fromName: uname).
]
{ #category : #compiling } { #category : #compiling }
OpenGLSL >> checkStatus:status of: id [ OpenGLSL >> checkStatus:status of: id [
|infoLength buffer result| |infoLength buffer result|
@ -151,7 +150,8 @@ OpenGLSL >> compile [
OpenGLSL detachShaderFrom: programID shader: vertexShaderID. OpenGLSL detachShaderFrom: programID shader: vertexShaderID.
OpenGLSL detachShaderFrom: programID shader: fragmentShaderID. OpenGLSL detachShaderFrom: programID shader: fragmentShaderID.
OpenGLSL deleteShader: vertexShaderID. OpenGLSL deleteShader: vertexShaderID.
OpenGLSL deleteShader: fragmentShaderID OpenGLSL deleteShader: fragmentShaderID.
self locateUniforms
] ]
{ #category : #compiling } { #category : #compiling }
@ -184,6 +184,44 @@ OpenGLSL >> getSourcePtr: string for: shaderId [
OpenGLSL setShaderSourceFor: shaderId count: 1 string: xarray getHandle length: nil. OpenGLSL setShaderSourceFor: shaderId count: 1 string: xarray getHandle length: nil.
] ]
{ #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.
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:[
^self error: 'Uniform', uname, 'is not defined in this program'].
uniform value: values
]
{ #category : #initialization }
OpenGLSL >> setUpUniforms [
"do nothing, custom uniform can be set up by subclass"
]
{ #category : #'submorphs-add/remove' } { #category : #'submorphs-add/remove' }
OpenGLSL >> use [ OpenGLSL >> use [
^OpenGLSL useProgram: programID ^OpenGLSL useProgram: programID

View File

@ -0,0 +1,108 @@
Class {
#name : #OpenGLSLUniform,
#superclass : #DiyaBaseObject,
#instVars : [
'uname',
'location',
'value'
],
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> ffiLibraryName [
^ OpenGL ffiLibraryName
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> fromName: uname [
^self new uname: uname; yourself
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> fromName: uname at: location [
^self new uname: uname; location: location; yourself
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform1f: location value: v0 [
^self ffiCall: #(void glUniform1f(GLint location,GLfloat v0))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform1i: location value: v0 [
^self ffiCall: #(void glUniform1i(GLint location,GLint v0))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform2f: location value: v0 value: v1 [
^self ffiCall: #(void glUniform2f(GLint location,GLfloat v0,GLfloat v1))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform2i: location value: v0 value: v1 [
^self ffiCall: #(void glUniform2i(GLint location,GLint v0,GLint v1))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform3f: location value: v0 value: v1 value: v2 [
^self ffiCall: #(void glUniform3f(GLint location,GLfloat v0,GLfloat v1,GLfloat v2))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform3i: location value: v0 value: v1 value: v2 [
^self ffiCall: #(void glUniform3i(GLint location,GLint v0,GLint v1,GLint v2))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform4f: location value: v0 value: v1 value: v2 value: v3 [
^self ffiCall: #(void glUniform4f(GLint location,GLfloat v0,GLfloat v1,GLfloat v2, GLfloat v3))
]
{ #category : #'as yet unclassified' }
OpenGLSLUniform class >> uniform4i: location value: v0 value: v1 value: v2 value: v3 [
^self ffiCall: #(void glUniform4i(GLint location,GLint v0,GLint v1,GLint v2, GLint v3))
]
{ #category : #accessing }
OpenGLSLUniform >> location [
^ location
]
{ #category : #accessing }
OpenGLSLUniform >> location: anObject [
location := anObject
]
{ #category : #accessing }
OpenGLSLUniform >> setUniformValue [
^ self subclassResponsibility
]
{ #category : #accessing }
OpenGLSLUniform >> uname [
^ uname
]
{ #category : #accessing }
OpenGLSLUniform >> uname: anObject [
uname := anObject
]
{ #category : #accessing }
OpenGLSLUniform >> value [
^ value
]
{ #category : #accessing }
OpenGLSLUniform >> value: values [
location = -1 ifTrue: [ ^self ].
value := values.
self setUniformValue.
]

View File

@ -14,12 +14,12 @@ Class {
SimpleDiyaRenderer >> destroy [ SimpleDiyaRenderer >> destroy [
vertexBuffer delete. vertexBuffer delete.
arrayBuffer delete. arrayBuffer delete.
shader delete.
GLSimpleShader reset. GLSimpleShader reset.
] ]
{ #category : #initialization } { #category : #initialization }
SimpleDiyaRenderer >> initialize [ SimpleDiyaRenderer >> initialize [
super initialize.
vertexBuffer := OpenGLVertexBuffer new. vertexBuffer := OpenGLVertexBuffer new.
arrayBuffer := OpenGLVertexArray new. arrayBuffer := OpenGLVertexArray new.
bufferData := FFIExternalArray externalNewType: GLfloat size: 9. bufferData := FFIExternalArray externalNewType: GLfloat size: 9.
@ -33,6 +33,12 @@ SimpleDiyaRenderer >> render [
OpenGL clearColorR: 1.0 G: 0 B: 1.0 A:0. OpenGL clearColorR: 1.0 G: 0 B: 1.0 A:0.
OpenGL clear: GL_COLOR_BUFFER_BIT. OpenGL clear: GL_COLOR_BUFFER_BIT.
shader use. shader use.
shader setUniform: #u_time value: DiyaClock uniqueInstance elapsedTime asFloat.
shader setUniform: #u_resolution value: { context resolution x. context resolution y }.
context mouse ifNotNil: [
shader setUniform: #u_mouse value: { context mouse x. context mouse y }.
].
arrayBuffer enableAttribute: 0. arrayBuffer enableAttribute: 0.
vertexBuffer bind: GL_ARRAY_BUFFER. vertexBuffer bind: GL_ARRAY_BUFFER.
OpenGLVertexArray vertexAttributePointerIndex: 0 size:3 type: GL_FLOAT normalized: GL_FALSE stride: 0 pointer: nil . OpenGLVertexArray vertexAttributePointerIndex: 0 size:3 type: GL_FLOAT normalized: GL_FALSE stride: 0 pointer: nil .

14
Diya/Uniform1F.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform1F,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform1F >> setUniformValue [
OpenGLSLUniform uniform1f: location value: value
]

14
Diya/Uniform1i.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform1i,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform1i >> setUniformValue [
OpenGLSLUniform uniform1i: location value: value
]

14
Diya/Uniform2F.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform2F,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform2F >> setUniformValue [
OpenGLSLUniform uniform2f: location value: value first value: value last
]

14
Diya/Uniform2i.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform2i,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform2i >> setUniformValue [
OpenGLSLUniform uniform2i: location value: value first value: value last
]

14
Diya/Uniform3F.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform3F,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform3F >> setUniformValue [
OpenGLSLUniform uniform3f: location value: value first value: (value at:2) value: value last
]

14
Diya/Uniform3i.class.st Normal file
View File

@ -0,0 +1,14 @@
Class {
#name : #Uniform3i,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform3i >> setUniformValue [
OpenGLSLUniform uniform3i: location value: value first value: (value at:2) value: value last
]

18
Diya/Uniform4F.class.st Normal file
View File

@ -0,0 +1,18 @@
Class {
#name : #Uniform4F,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform4F >> setUniformValue [
OpenGLSLUniform uniform4f: location
value: value first
value: (value at:2)
value: (value at:3)
value: value last
]

18
Diya/Uniform4i.class.st Normal file
View File

@ -0,0 +1,18 @@
Class {
#name : #Uniform4i,
#superclass : #OpenGLSLUniform,
#pools : [
'OpenGLConstants',
'OpenGLTypes'
],
#category : #'Diya-OpenGL'
}
{ #category : #accessing }
Uniform4i >> setUniformValue [
OpenGLSLUniform uniform4i: location
value: value first
value: (value at:2)
value: (value at:3)
value: value last
]