diff --git a/Diya/DiyaBoot.class.st b/Diya/DiyaBoot.class.st index a5af552..4c98427 100644 --- a/Diya/DiyaBoot.class.st +++ b/Diya/DiyaBoot.class.st @@ -20,6 +20,11 @@ Class { #category : #'Diya-Runtime' } +{ #category : #'instance creation' } +DiyaBoot class >> new [ + self error: 'Use #uniqueInstance' +] + { #category : #'instance creation' } DiyaBoot class >> reset [ singleton := nil @@ -37,7 +42,7 @@ DiyaBoot class >> startx [ { #category : #'instance creation' } DiyaBoot class >> uniqueInstance [ - singleton ifNil: [ singleton := self new ]. + singleton ifNil: [ singleton := super new ]. ^ singleton ] diff --git a/Diya/OpenGLConstants.class.st b/Diya/OpenGLConstants.class.st index a97a5b1..51761be 100644 --- a/Diya/OpenGLConstants.class.st +++ b/Diya/OpenGLConstants.class.st @@ -3,19 +3,37 @@ Class { #superclass : #SharedPool, #classVars : [ 'GL_ACCUM_BUFFER_BIT', + 'GL_ACTIVE_ATTRIBUTES', + 'GL_ACTIVE_ATTRIBUTE_MAX_LENGTH', + 'GL_ACTIVE_UNIFORMS', + 'GL_ACTIVE_UNIFORM_MAX_LENGTH', + 'GL_ATTACHED_SHADERS', 'GL_COLOR_BUFFER_BIT', + 'GL_COMPILE_STATUS', + 'GL_COMPUTE_SHADER', + 'GL_DELETE_STATUS', 'GL_DEPTH_BUFFER_BIT', + 'GL_FRAGMENT_SHADER', + 'GL_GEOMETRY_SHADER', + 'GL_INFO_LOG_LENGTH', 'GL_LINES', 'GL_LINE_LOOP', 'GL_LINE_STRIP', + 'GL_LINK_STATUS', 'GL_POINTS', 'GL_POLYGON', 'GL_QUADS', 'GL_QUAD_STRIP', + 'GL_SHADER_SOURCE_LENGTH', + 'GL_SHADER_TYPE', 'GL_STENCIL_BUFFER_BIT', + 'GL_TESS_CONTROL_SHADER', + 'GL_TESS_EVALUATION_SHADER', 'GL_TRIANGLES', 'GL_TRIANGLE_FAN', - 'GL_TRIANGLE_STRIP' + 'GL_TRIANGLE_STRIP', + 'GL_VALIDATE_STATUS', + 'GL_VERTEX_SHADER' ], #category : #'Diya-OpenGL' } @@ -42,8 +60,31 @@ OpenGLConstants class >> initCommonMode [ GL_POLYGON := 16r0009. ] +{ #category : #'class initialization' } +OpenGLConstants class >> initCommonShader [ + GL_COMPUTE_SHADER := 16r91B9. + GL_VERTEX_SHADER := 16r8B31. + GL_TESS_CONTROL_SHADER := 16r8E88. + GL_TESS_EVALUATION_SHADER := 16r8E87. + GL_GEOMETRY_SHADER := 16r8DD9. + GL_FRAGMENT_SHADER := 16r8B30. + GL_SHADER_TYPE := 16r8B4F. + GL_DELETE_STATUS := 16r8B80. + GL_COMPILE_STATUS := 16r8B81. + GL_INFO_LOG_LENGTH := 16r8B84. + GL_SHADER_SOURCE_LENGTH := 16r8B88. + GL_LINK_STATUS := 16r8B82. + GL_VALIDATE_STATUS := 16r8B83. + GL_ATTACHED_SHADERS := 16r8B85. + GL_ACTIVE_ATTRIBUTES := 16r8B89. + GL_ACTIVE_ATTRIBUTE_MAX_LENGTH := 16r8B8A. + GL_ACTIVE_UNIFORMS := 16r8B86. + GL_ACTIVE_UNIFORM_MAX_LENGTH := 16r8B87. +] + { #category : #'class initialization' } OpenGLConstants class >> initialize [ self initCommonMode. self initCommonMask. + self initCommonShader. ] diff --git a/Diya/OpenGLSL.class.st b/Diya/OpenGLSL.class.st new file mode 100644 index 0000000..87d104d --- /dev/null +++ b/Diya/OpenGLSL.class.st @@ -0,0 +1,194 @@ +Class { + #name : #OpenGLSL, + #superclass : #DiyaBaseObject, + #instVars : [ + 'programID' + ], + #classVars : [ + 'singleton' + ], + #pools : [ + 'OpenGLConstants', + 'OpenGLTypes' + ], + #category : #'Diya-OpenGL' +} + +{ #category : #'as yet unclassified' } +OpenGLSL class >> attachShader: shader to: program [ + ^self ffiCall: #(void glAttachShader(GLuint program,GLuint shader)) +] + +{ #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' } +OpenGLSL class >> linkProgram: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' } +OpenGLSL class >> setShaderSourceFor: shader count: n string: s length: l [ + ^ self ffiCall: #(void glShaderSource( GLuint shader,GLsizei n,const char ** s,const GLint *l)) +] + +{ #category : #'instance creation' } +OpenGLSL class >> uniqueInstance [ + singleton ifNil: [ singleton := super new. singleton compile ]. + ^ singleton +] + +{ #category : #accessing } +OpenGLSL class >> vertextShader [ + ^ self subclassResponsibility +] + +{ #category : #compiling } +OpenGLSL >> checkStatus:status of: id [ + |infoLength buffer| + infoLength := FFIExternalArray externalNewType: #GLint size: 1. + infoLength autoRelease. + OpenGLSL getShaderiv: id parameterName: status params: nil. + OpenGLSL getShaderiv: id parameterName: GL_INFO_LOG_LENGTH params: infoLength. + (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 + ]. + ^self error: buffer asString + ]. + ^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. + +] + +{ #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 [ + self getSourcePtr:self class vertextShader for: vertexShaderID. + OpenGLSL compileShader: vertexShaderID. + self checkStatus:GL_COMPILE_STATUS of: vertexShaderID + +] + +{ #category : #'submorphs-add/remove' } +OpenGLSL >> delete [ + OpenGLSL deleteProgram: programID +] + +{ #category : #'library path' } +OpenGLSL >> ffiLibraryName [ + ^self class ffiLibraryName +] + +{ #category : #compiling } +OpenGLSL >> getSourcePtr: string for: shaderId [ + |cstr i ptr | + cstr := FFIExternalArray externalNewType: #uint8 size: string size + 1. + cstr autoRelease. + i := 1. + (string asByteArray copyWith: 0) do: [ :e| + cstr at: i put: e. + i := i+1. + ]. + ptr := FFIExternalArray externalNewType: #GLintptr size: 1. + ptr autoRelease. + ptr at: 1 put: cstr pointer value. + OpenGLSL setShaderSourceFor: shaderId count: 1 string: ptr length: nil. +] + +{ #category : #'submorphs-add/remove' } +OpenGLSL >> use [ + ^self ffiCall: #(void glUseProgram( GLuint program)) +] diff --git a/Diya/OpenGLTypes.class.st b/Diya/OpenGLTypes.class.st index f9b82c9..14e6e98 100644 --- a/Diya/OpenGLTypes.class.st +++ b/Diya/OpenGLTypes.class.st @@ -5,6 +5,7 @@ Class { 'GLbitfield', 'GLboolean', 'GLbyte', + 'GLchar', 'GLclampd', 'GLclampf', 'GLdouble', @@ -50,4 +51,5 @@ OpenGLTypes class >> initialize [ GLuint := #uint32. GLuint64 := #uint64. GLushort := #uint16. + GLchar := #char. ]