From 0d254c6dd43dac8a4ff15c83b730d66a8cf3d000 Mon Sep 17 00:00:00 2001 From: Dany LE Date: Mon, 20 Dec 2021 01:14:35 +0100 Subject: [PATCH] Basic example of OpenGL binding --- Diya/DiyaBoot.class.st | 56 ++++++++++++++++++++++++----------- Diya/DiyaFFIBase.class.st | 10 +++++++ Diya/OpenGL.class.st | 54 +++++++++++++++++++++++++++++++++ Diya/OpenGLConstants.class.st | 49 ++++++++++++++++++++++++++++++ Diya/OpenGLTypes.class.st | 53 +++++++++++++++++++++++++++++++++ 5 files changed, 205 insertions(+), 17 deletions(-) create mode 100644 Diya/OpenGL.class.st create mode 100644 Diya/OpenGLConstants.class.st create mode 100644 Diya/OpenGLTypes.class.st diff --git a/Diya/DiyaBoot.class.st b/Diya/DiyaBoot.class.st index 025d7ef..9e73010 100644 --- a/Diya/DiyaBoot.class.st +++ b/Diya/DiyaBoot.class.st @@ -5,12 +5,15 @@ Class { 'running', 'window', 'renderer', + 'context', 'display' ], #classVars : [ 'singleton' ], #pools : [ + 'OpenGLConstants', + 'OpenGLTypes', 'SDL2Constants', 'SDL2Types' ], @@ -38,6 +41,14 @@ DiyaBoot class >> uniqueInstance [ ^ singleton ] +{ #category : #events } +DiyaBoot >> createGLContext [ + context := SDL2 glCreateContext: window. + context ifNil: [ ^self error: SDL2 getErrorMessage ]. + ^context + +] + { #category : #events } DiyaBoot >> createRenderer [ renderer := window primCreateRenderer: -1 flags: SDL_RENDERER_ACCELERATED. @@ -48,16 +59,15 @@ DiyaBoot >> createRenderer [ { #category : #events } DiyaBoot >> createWindow [ - |handle| - handle := SDL2 createWindow: 'Diya' + window := SDL2 createWindow: 'Diya' x: 0 y: 0 width: display w height: display h - flags: SDL_WINDOW_SHOWN. - handle ifNil: [ ^self error: SDL2 getErrorMessage ]. + flags: SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL. + window ifNil: [ ^self error: SDL2 getErrorMessage ]. "handle fullscreen: SDL_WINDOW_FULLSCREEN." - ^handle + ^window ] { #category : #events } @@ -75,7 +85,7 @@ DiyaBoot >> initialize [ running := true. display := nil. window := nil. - renderer := nil. + context := nil. ] { #category : #events } @@ -105,12 +115,8 @@ DiyaBoot >> render [ [ (SDL2 pollEvent: event) > 0 ] whileTrue: [ self processEvent: event ]. - renderer drawColorR: self randomColorChannel - g: self randomColorChannel - b: self randomColorChannel - a: 255. - renderer clear. - renderer present. + self step. + SDL2 glSwapWindow: window. SDL2 delay: 50. ]. ] @@ -134,6 +140,8 @@ DiyaBoot >> run: screenSize app: application [ it is always the #run command that is executed automatically. " + OpenGLTypes initialize. + OpenGLConstants initialize. self init. display w: screenSize x. display h: screenSize y. @@ -172,8 +180,10 @@ DiyaBoot >> showSystemInfo [ stream nextPutAll: rinfo name readString; nextPutAll:' '. ]. stream cr. - renderer primGetRendererInfo: rinfo. - stream nextPutAll: 'SDL_RENDER_DRIVER selected: '; nextPutAll: rinfo name readString; cr. + renderer ifNotNil:[ + renderer primGetRendererInfo: rinfo. + stream nextPutAll: 'SDL_RENDER_DRIVER selected: '; nextPutAll: rinfo name readString; cr. + ]. stream nextPutAll:'Display resolution: '; nextPutAll:display w asString; nextPutAll: 'x'; @@ -185,11 +195,23 @@ DiyaBoot >> showSystemInfo [ { #category : #events } DiyaBoot >> startx [ display ifNil: [ ^self error: 'Please run #init before this method' ]. - window := self createWindow. - renderer := self createRenderer. + self createWindow. + self createGLContext. + "self createRenderer." self showSystemInfo. self render. - renderer destroy. + context delete. window destroy. SDL2 quit. ] + +{ #category : #events } +DiyaBoot >> step [ + OpenGL begin: GL_TRIANGLES. + "draw a simple triangle here" + OpenGL color3fR: 0.1 G:0.2 B: 0.3. + OpenGL vertex3fX: 0 Y: 0 Z: 0. + OpenGL vertex3fX: 1 Y: 0 Z: 0. + OpenGL vertex3fX: 0 Y: 1 Z: 0. + OpenGL end. +] diff --git a/Diya/DiyaFFIBase.class.st b/Diya/DiyaFFIBase.class.st index e5a217b..a1b5508 100644 --- a/Diya/DiyaFFIBase.class.st +++ b/Diya/DiyaFFIBase.class.st @@ -9,6 +9,11 @@ DiyaFFIBase class >> checkSymbol [ ^self subclassResponsibility ] +{ #category : #accessing } +DiyaFFIBase class >> ffiLibraryName [ + ^ self moduleName +] + { #category : #accessing } DiyaFFIBase class >> libNames [ ^self subclassResponsibility @@ -23,3 +28,8 @@ DiyaFFIBase class >> moduleName [ ]. self error: 'Unable to find FFI library (', self checkSymbol, ')'. ] + +{ #category : #'library path' } +DiyaFFIBase >> ffiLibraryName [ + ^self class ffiLibraryName +] diff --git a/Diya/OpenGL.class.st b/Diya/OpenGL.class.st new file mode 100644 index 0000000..c6bf6a9 --- /dev/null +++ b/Diya/OpenGL.class.st @@ -0,0 +1,54 @@ +Class { + #name : #OpenGL, + #superclass : #DiyaFFIBase, + #pools : [ + 'OpenGLConstants', + 'OpenGLTypes' + ], + #category : #'Diya-OpenGL' +} + +{ #category : #accessing } +OpenGL class >> begin: mode [ + ^ self ffiCall: #(void glBegin(GLenum mode)) +] + +{ #category : #accessing } +OpenGL class >> checkSymbol [ + ^#glBegin +] + +{ #category : #'as yet unclassified' } +OpenGL class >> clear: mask [ + ^ self ffiCall: #(void glClear(GLbitfield mask)) +] + +{ #category : #'as yet unclassified' } +OpenGL class >> clearColorR: red G: green B: blue A:alpha [ + ^self ffiCall: #(void glClearColor( GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)) +] + +{ #category : #accessing } +OpenGL class >> color3fR: red G: green B: blue [ + ^self ffiCall: #(void glColor3f(GLfloat red,GLfloat green,GLfloat blue)) +] + +{ #category : #accessing } +OpenGL class >> end [ + ^ self ffiCall: #(void glEnd( void )) +] + +{ #category : #accessing } +OpenGL class >> libNames [ + ^#('libGL.so.1') +] + +{ #category : #accessing } +OpenGL class >> vertex3fX:x Y:y Z:z [ + ^self ffiCall: #(void glVertex3f( GLfloat x,GLfloat y,GLfloat z)) +] + +{ #category : #'as yet unclassified' } +OpenGL class >> viewportX: x Y:y W: width H:height [ + ^ self ffiCall: #(void glViewport(GLint x,GLint y,GLsizei width,GLsizei height)) +] diff --git a/Diya/OpenGLConstants.class.st b/Diya/OpenGLConstants.class.st new file mode 100644 index 0000000..a97a5b1 --- /dev/null +++ b/Diya/OpenGLConstants.class.st @@ -0,0 +1,49 @@ +Class { + #name : #OpenGLConstants, + #superclass : #SharedPool, + #classVars : [ + 'GL_ACCUM_BUFFER_BIT', + 'GL_COLOR_BUFFER_BIT', + 'GL_DEPTH_BUFFER_BIT', + 'GL_LINES', + 'GL_LINE_LOOP', + 'GL_LINE_STRIP', + 'GL_POINTS', + 'GL_POLYGON', + 'GL_QUADS', + 'GL_QUAD_STRIP', + 'GL_STENCIL_BUFFER_BIT', + 'GL_TRIANGLES', + 'GL_TRIANGLE_FAN', + 'GL_TRIANGLE_STRIP' + ], + #category : #'Diya-OpenGL' +} + +{ #category : #'class initialization' } +OpenGLConstants class >> initCommonMask [ + GL_COLOR_BUFFER_BIT := 16r00004000. + GL_DEPTH_BUFFER_BIT := 16r00000100. + GL_ACCUM_BUFFER_BIT := 16r00000200. + GL_STENCIL_BUFFER_BIT := 16r00000400. +] + +{ #category : #'class initialization' } +OpenGLConstants class >> initCommonMode [ + GL_TRIANGLES := 16r0004. + GL_POINTS := 16r0000. + GL_LINES := 16r0001. + GL_LINE_STRIP := 16r0003. + GL_LINE_LOOP := 16r0002. + GL_TRIANGLE_STRIP := 16r0005. + GL_TRIANGLE_FAN := 16r0006. + GL_QUADS := 16r0007. + GL_QUAD_STRIP := 16r0008. + GL_POLYGON := 16r0009. +] + +{ #category : #'class initialization' } +OpenGLConstants class >> initialize [ + self initCommonMode. + self initCommonMask. +] diff --git a/Diya/OpenGLTypes.class.st b/Diya/OpenGLTypes.class.st new file mode 100644 index 0000000..f9b82c9 --- /dev/null +++ b/Diya/OpenGLTypes.class.st @@ -0,0 +1,53 @@ +Class { + #name : #OpenGLTypes, + #superclass : #SharedPool, + #classVars : [ + 'GLbitfield', + 'GLboolean', + 'GLbyte', + 'GLclampd', + 'GLclampf', + 'GLdouble', + 'GLenum', + 'GLfixed', + 'GLfloat', + 'GLhalf', + 'GLint', + 'GLint64', + 'GLintptr', + 'GLshort', + 'GLsizei', + 'GLsizeiptr', + 'GLsync', + 'GLubyte', + 'GLuint', + 'GLuint64', + 'GLushort' + ], + #category : #'Diya-OpenGL' +} + +{ #category : #'class initialization' } +OpenGLTypes class >> initialize [ + GLfloat := #float. + GLubyte := #uint8. + GLenum := #int32. + GLboolean := #uint8. + GLbitfield := #int32. + GLbyte := #int8. + GLclampd := #double. + GLclampf := #float. + GLdouble := #double. + GLfixed := #int32. + GLhalf := #uint16. + GLint := #int32. + GLint64 := #int64. + GLintptr := Smalltalk wordSize = 8 ifTrue: [ #int64 ] ifFalse: [ #int32 ]. + GLshort := #int16. + GLsizei := #int32. + GLsizeiptr := Smalltalk wordSize = 8 ifTrue: [ #int64 ] ifFalse: [ #int32 ]. + GLsync := Smalltalk wordSize = 8 ifTrue: [ #int64 ] ifFalse: [ #int32 ]. + GLuint := #uint32. + GLuint64 := #uint64. + GLushort := #uint16. +]