Simple OpenGL examples for beginners in PySDL3 #23
Replies: 9 comments
-
Change a background color by timer It based on the official SDL3 example: examples/renderer/01-clear/clear.c background-color-opengl-pysdl3.zip Click this to collapse/foldmain.pyimport ctypes
import os
import time
import OpenGL.GL as gl
os.environ["SDL_MAIN_USE_CALLBACKS"] = "1"
os.environ["SDL_RENDER_DRIVER"] = "opengl"
import sdl3
glContext = None
window = None
@sdl3.SDL_AppInit_func
def SDL_AppInit(appstate, argc, argv):
global glContext
global window
if not sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO):
sdl3.SDL_Log("Couldn't initialize SDL: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLEBUFFERS, 1) # Enable MULTISAMPLE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLESAMPLES, 2) # Can be 2, 4, 8 or 16
windowTitle = "PySDL3, OpenGL".encode()
window = sdl3.SDL_CreateWindow(windowTitle, 350, 350, sdl3.SDL_WINDOW_OPENGL)
if not window:
sdl3.SDL_Log("Couldn't create a window: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
# Create an OpenGL context
glContext = sdl3.SDL_GL_CreateContext(window)
if not glContext:
sdl3.SDL_Log("Couldn't create a glContext: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetSwapInterval(1) # Turn on vertical sync
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppEvent_func
def SDL_AppEvent(appstate, event):
if sdl3.SDL_DEREFERENCE(event).type == sdl3.SDL_EVENT_QUIT:
return sdl3.SDL_APP_SUCCESS
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppIterate_func
def SDL_AppIterate(appstate):
now = sdl3.SDL_GetTicks() / 1000 # Convert from milliseconds to seconds
# Choose the color for the frame we will draw.
# The sine wave trick makes it fade between colors smoothly
red = 0.5 + 0.5 * sdl3.SDL_sin(now)
green = 0.5 + 0.5 * sdl3.SDL_sin(now + sdl3.SDL_PI_D * 2 / 3)
blue = 0.5 + 0.5 * sdl3.SDL_sin(now + sdl3.SDL_PI_D * 4 / 3)
gl.glClearColor(red, green, blue, 1)
gl.glClear(gl.GL_COLOR_BUFFER_BIT)
sdl3.SDL_GL_SwapWindow(window)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppQuit_func
def SDL_AppQuit(appstate, result):
global glContext
sdl3.SDL_GL_DestroyContext(glContext)
# SDL will clean up the window/renderer for us
|
Beta Was this translation helpful? Give feedback.
-
Simple triangle It draws a simple triangle without matrices. simple-triangle-opengl-pysdl3.zip Click this to collapse/foldmain.pyimport ctypes
import os
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
os.environ["SDL_MAIN_USE_CALLBACKS"] = "1"
os.environ["SDL_RENDER_DRIVER"] = "opengl"
import sdl3
glContext = None
window = None
vertexShaderSource = """
attribute vec2 aPosition;
void main()
{
gl_Position = vec4(aPosition, 0.0, 1.0);
}
"""
fragmentShaderSource = """
void main()
{
gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);
}
"""
@sdl3.SDL_AppInit_func
def SDL_AppInit(appstate, argc, argv):
global glContext
global window
if not sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO):
sdl3.SDL_Log("Couldn't initialize SDL: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLEBUFFERS, 1) # Enable MULTISAMPLE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLESAMPLES, 2) # Can be 2, 4, 8 or 16
windowTitle = "PySDL3, OpenGL".encode()
window = sdl3.SDL_CreateWindow(windowTitle, 350, 350, sdl3.SDL_WINDOW_OPENGL)
if not window:
sdl3.SDL_Log("Couldn't create a window: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
# Create an OpenGL context
glContext = sdl3.SDL_GL_CreateContext(window)
if not glContext:
sdl3.SDL_Log("Couldn't create a glContext: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetSwapInterval(1) # Turn on vertical sync
glClearColor(0.2, 0.2, 0.2, 1)
vertPositions = np.array([
-0.5, -0.5,
0.5, -0.5,
0, 0.5
], dtype=np.float32)
vertPosBuffer = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vertPosBuffer)
glBufferData(GL_ARRAY_BUFFER, len(vertPositions) * 4,
vertPositions, GL_STATIC_DRAW)
program = compileProgram(
compileShader(vertexShaderSource, GL_VERTEX_SHADER),
compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER))
glUseProgram(program)
aPositionLocation = glGetAttribLocation(program, "aPosition")
glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
glEnableVertexAttribArray(aPositionLocation)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppEvent_func
def SDL_AppEvent(appstate, event):
if sdl3.SDL_DEREFERENCE(event).type == sdl3.SDL_EVENT_QUIT:
return sdl3.SDL_APP_SUCCESS
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppIterate_func
def SDL_AppIterate(appstate):
glClear(GL_COLOR_BUFFER_BIT)
glDrawArrays(GL_TRIANGLES, 0, 3)
sdl3.SDL_GL_SwapWindow(window)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppQuit_func
def SDL_AppQuit(appstate, result):
global glContext
sdl3.SDL_GL_DestroyContext(glContext)
# SDL will clean up the window/renderer for us
|
Beta Was this translation helpful? Give feedback.
-
Rotated rectangles It draws rotated rectangles with different colors using matrices from the PyGLM library. rotated-rectangles-opengl-pysdl3.zip Click this to collapse/foldmain.pyimport ctypes
import math
import os
import glm
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
os.environ["SDL_MAIN_USE_CALLBACKS"] = "1"
os.environ["SDL_RENDER_DRIVER"] = "opengl"
import sdl3
glContext = None
window = None
uColorLocation = None
uMvpMatrixLocation = None
projViewMatrix = None
vertexShaderSource = """
attribute vec2 aPosition;
uniform mat4 uMvpMatrix;
void main()
{
gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);
}
"""
fragmentShaderSource = """
uniform vec3 uColor;
void main()
{
gl_FragColor = vec4(uColor, 1.0);
}
"""
@sdl3.SDL_AppInit_func
def SDL_AppInit(appstate, argc, argv):
global glContext
global window
global projViewMatrix
global uColorLocation
global uMvpMatrixLocation
if not sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO):
sdl3.SDL_Log("Couldn't initialize SDL: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLEBUFFERS, 1) # Enable MULTISAMPLE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLESAMPLES, 2) # Can be 2, 4, 8 or 16
windowTitle = "PySDL3, PyGLM, PyOpenGL".encode()
window = sdl3.SDL_CreateWindow(windowTitle, 350, 350, sdl3.SDL_WINDOW_OPENGL)
if not window:
sdl3.SDL_Log("Couldn't create a window: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
# Create an OpenGL context
glContext = sdl3.SDL_GL_CreateContext(window)
if not glContext:
sdl3.SDL_Log("Couldn't create a glContext: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetSwapInterval(1) # Turn on vertical sync
glClearColor(0.2, 0.2, 0.2, 1)
vertPositions = np.array([
-0.5, -0.5, # First triangle
-0.5, 0.5,
0.5, -0.5,
0.5, -0.5, # Second triangle
-0.5, 0.5,
0.5, 0.5
], dtype=np.float32)
vertPosBuffer = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vertPosBuffer)
glBufferData(GL_ARRAY_BUFFER, len(vertPositions) * 4,
vertPositions, GL_STATIC_DRAW)
program = compileProgram(
compileShader(vertexShaderSource, GL_VERTEX_SHADER),
compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER))
glUseProgram(program)
aPositionLocation = glGetAttribLocation(program, "aPosition")
glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
glEnableVertexAttribArray(aPositionLocation)
# Access the uniform variables in the shaders
uColorLocation = glGetUniformLocation(program, "uColor")
uMvpMatrixLocation = glGetUniformLocation(program, "uMvpMatrix")
# Create an orthographic projection matrix and a view matrix
projMatrix = glm.ortho(0, 300, 300, 0, 1, -1)
viewMatrix = glm.lookAt(
glm.vec3(0, 0, 1), # Position
glm.vec3(0, 0, 0), # Target
glm.vec3(0, 1, 0)) # Up vector
# Combine them to one projView matrix
projViewMatrix = projMatrix * viewMatrix
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppEvent_func
def SDL_AppEvent(appstate, event):
if sdl3.SDL_DEREFERENCE(event).type == sdl3.SDL_EVENT_QUIT:
return sdl3.SDL_APP_SUCCESS
return sdl3.SDL_APP_CONTINUE
def drawRectangle(pos, size, angle, color):
# Create a model matrix, that is, a matrix combining the
# translation matrix, rotation matrix, and the scale matrix
modelMatrix = glm.translate(glm.mat4(1), glm.vec3(pos.x, pos.y, 0))
modelMatrix = glm.rotate(modelMatrix, math.radians(angle), glm.vec3(0, 0, 1))
modelMatrix = glm.scale(modelMatrix, glm.vec3(size.x, size.y, 1))
# Combine projView matrix and model matrix into one MVP matrix
mvpMatrix = projViewMatrix * modelMatrix
# Send MVP matrix to the vertex shader
glUniformMatrix4fv(uMvpMatrixLocation, 1, GL_FALSE, glm.value_ptr(mvpMatrix))
# Send a color to the fragment shader
glUniform3fv(uColorLocation, 1, glm.value_ptr(color))
# Draw a rectangle
glDrawArrays(GL_TRIANGLES, 0, 6)
@sdl3.SDL_AppIterate_func
def SDL_AppIterate(appstate):
global projViewMatrix
global uMvpMatrixLocation
glClear(GL_COLOR_BUFFER_BIT)
# First rectangle
position = glm.vec2(200, 70)
size = glm.vec2(150, 20)
angle = -20
color = glm.vec3(1, 0, 0)
drawRectangle(position, size, angle, color)
# Second rectangle
position = glm.vec2(80, 150)
size = glm.vec2(100, 30)
angle = 20
color = glm.vec3(0, 1, 0)
drawRectangle(position, size, angle, color)
# Third rectangle
position = glm.vec2(150, 250)
size = glm.vec2(200, 20)
angle = 0
color = glm.vec3(0, 0, 1)
drawRectangle(position, size, angle, color)
sdl3.SDL_GL_SwapWindow(window)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppQuit_func
def SDL_AppQuit(appstate, result):
global glContext
sdl3.SDL_GL_DestroyContext(glContext)
# SDL will clean up the window/renderer for us
|
Beta Was this translation helpful? Give feedback.
-
Draw rhombuses, pentagons, hexagons, disks using GL_TRIANGLE_FAN Change the Click this to collapse/foldmain.pyimport ctypes
import math
import os
import glm
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
os.environ["SDL_MAIN_USE_CALLBACKS"] = "1"
os.environ["SDL_RENDER_DRIVER"] = "opengl"
import sdl3
glContext = None
window = None
uColorLocation = None
uMvpMatrixLocation = None
projViewMatrix = None
numberOfVertices = 50
vertexShaderSource = """
attribute vec2 aPosition;
uniform mat4 uMvpMatrix;
void main()
{
gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);
}
"""
fragmentShaderSource = """
uniform vec3 uColor;
void main()
{
gl_FragColor = vec4(uColor, 1.0);
}
"""
@sdl3.SDL_AppInit_func
def SDL_AppInit(appstate, argc, argv):
global glContext
global window
global projViewMatrix
global uColorLocation
global uMvpMatrixLocation
if not sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO):
sdl3.SDL_Log("Couldn't initialize SDL: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLEBUFFERS, 1) # Enable MULTISAMPLE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLESAMPLES, 2) # Can be 2, 4, 8 or 16
windowTitle = "PySDL3, PyGLM, PyOpenGL".encode()
window = sdl3.SDL_CreateWindow(windowTitle, 350, 350, sdl3.SDL_WINDOW_OPENGL)
if not window:
sdl3.SDL_Log("Couldn't create a window: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
# Create an OpenGL context
glContext = sdl3.SDL_GL_CreateContext(window)
if not glContext:
sdl3.SDL_Log("Couldn't create a glContext: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetSwapInterval(1) # Turn on vertical sync
glClearColor(0.2, 0.2, 0.2, 1)
vertPositions = []
radius = 1
angle = 0
angleStep = 360 / numberOfVertices
vertPositions.extend([0, 0]) # Center
for i in range(numberOfVertices + 1):
x = radius * math.cos(math.radians(angle))
y = radius * math.sin(math.radians(angle))
vertPositions.extend([x, y])
angle += angleStep
vertPositions = np.array(vertPositions, dtype=np.float32)
vertPosBuffer = glGenBuffers(1)
glBindBuffer(GL_ARRAY_BUFFER, vertPosBuffer)
glBufferData(GL_ARRAY_BUFFER, len(vertPositions) * 4,
vertPositions, GL_STATIC_DRAW)
program = compileProgram(
compileShader(vertexShaderSource, GL_VERTEX_SHADER),
compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER))
glUseProgram(program)
aPositionLocation = glGetAttribLocation(program, "aPosition")
glVertexAttribPointer(aPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, ctypes.c_void_p(0))
glEnableVertexAttribArray(aPositionLocation)
# Access the uniform variables in the shaders
uColorLocation = glGetUniformLocation(program, "uColor")
uMvpMatrixLocation = glGetUniformLocation(program, "uMvpMatrix")
# Create an orthographic projection matrix and a view matrix
projMatrix = glm.ortho(0, 300, 300, 0, 1, -1)
viewMatrix = glm.lookAt(
glm.vec3(0, 0, 1), # Position
glm.vec3(0, 0, 0), # Target
glm.vec3(0, 1, 0)) # Up vector
# Combine them to one projView matrix
projViewMatrix = projMatrix * viewMatrix
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppEvent_func
def SDL_AppEvent(appstate, event):
if sdl3.SDL_DEREFERENCE(event).type == sdl3.SDL_EVENT_QUIT:
return sdl3.SDL_APP_SUCCESS
return sdl3.SDL_APP_CONTINUE
def drawShape(pos, size, angle, color):
# Create a model matrix, that is, a matrix combining the
# translation matrix, rotation matrix, and the scale matrix
modelMatrix = glm.translate(glm.mat4(1), glm.vec3(pos.x, pos.y, 0))
modelMatrix = glm.rotate(modelMatrix, math.radians(angle), glm.vec3(0, 0, 1))
modelMatrix = glm.scale(modelMatrix, glm.vec3(size.x, size.y, 1))
# Combine projView matrix and model matrix into one MVP matrix
mvpMatrix = projViewMatrix * modelMatrix
# Send MVP matrix to the vertex shader
glUniformMatrix4fv(uMvpMatrixLocation, 1, GL_FALSE, glm.value_ptr(mvpMatrix))
# Send a color to the fragment shader
glUniform3fv(uColorLocation, 1, glm.value_ptr(color))
# Draw
glDrawArrays(GL_TRIANGLE_FAN, 0, numberOfVertices + 2)
@sdl3.SDL_AppIterate_func
def SDL_AppIterate(appstate):
global projViewMatrix
global uMvpMatrixLocation
glClear(GL_COLOR_BUFFER_BIT)
# First shape
position = glm.vec2(200, 70)
size = glm.vec2(50, 50)
angle = 0
color = glm.vec3(1, 0, 0)
drawShape(position, size, angle, color)
# Second shape
position = glm.vec2(80, 150)
size = glm.vec2(30, 30)
angle = 0
color = glm.vec3(0, 1, 0)
drawShape(position, size, angle, color)
# Third shape
position = glm.vec2(150, 250)
size = glm.vec2(20, 20)
angle = 0
color = glm.vec3(0, 0, 1)
drawShape(position, size, angle, color)
sdl3.SDL_GL_SwapWindow(window)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppQuit_func
def SDL_AppQuit(appstate, result):
global glContext
sdl3.SDL_GL_DestroyContext(glContext)
# SDL will clean up the window/renderer for us
Rhombuses: numberOfVertices = 4 Pentagons: numberOfVertices = 5 Hexagons: numberOfVertices = 6 Disks: numberOfVertices = 50 |
Beta Was this translation helpful? Give feedback.
-
Draw line segments and a polygonal chain with thickness It draws a line segments between two points and a polygonal chain in 2D space. Source: Click this to collapse/foldline_drawer.pyimport math
import glm
import numpy as np
from OpenGL.GL import *
from math_helper import MathHelper
class LineDrawer:
def __init__(self, program, projViewMatrix):
# Save the program and projView matrix
self.program = program
self.projViewMatrix = projViewMatrix
# Activate the current shader program to access shader variables
glUseProgram(self.program)
# Access the uniform variables in the shaders
self.aPositionLocation = glGetAttribLocation(self.program, "aPosition")
self.uColorLocation = glGetUniformLocation(self.program, "uColor")
self.uMvpMatrixLocation = glGetUniformLocation(self.program, "uMvpMatrix")
# Create a buffer in the video card's RAM
self.vertPosBuffer = glGenBuffers(1)
self.initVertexBuffers()
def initVertexBuffers(self):
# Set the vertices of the square
vertPositions = np.array([
-0.5, -0.5,
-0.5, 0.5,
0.5, -0.5,
0.5, 0.5
], dtype=np.float32)
# Bind to the created buffer
glBindBuffer(GL_ARRAY_BUFFER, self.vertPosBuffer)
# Copy vertex array to buffer
glBufferData(GL_ARRAY_BUFFER, len(vertPositions) * 4,
vertPositions, GL_STATIC_DRAW)
# This method should be called if the window
# size changes or the camera position changes.
def setProjViewMatrix(self, projViewMatrix):
self.projViewMatrix = projViewMatrix
def bind(self):
# Activate Shader Program Object
glUseProgram(self.program)
# Bind to the buffer
glBindBuffer(GL_ARRAY_BUFFER, self.vertPosBuffer)
# Set up buffer
glVertexAttribPointer(self.aPositionLocation, 2, GL_FLOAT, GL_FALSE,
0, ctypes.c_void_p(0))
glEnableVertexAttribArray(self.aPositionLocation)
def draw(self, start, end, color, thickness):
# Find the center of the segment
v = end - start
centerPosition = start + v / 2
# Find the length of the segment
length = glm.length(v)
# Normalize the segment vector
norm = glm.normalize(v);
# Calculate the angle of a segment
rotation = MathHelper.rotationTo(glm.vec3(1, 0, 0), norm);
# Create a model matrix, that is, a matrix combining the
# translation matrix, rotation matrix, and the scale matrix
# Create a translation matrix
modelMatrix = glm.translate(glm.mat4(1), centerPosition)
# Create a rotation matrix
rotationMatrix = glm.mat4_cast(rotation)
modelMatrix = modelMatrix * rotationMatrix
# Create a scale matrix
modelMatrix = glm.scale(modelMatrix, glm.vec3(length, thickness, 1))
# Combine projView matrix and model matrix into one MVP matrix
mvpMatrix = self.projViewMatrix * modelMatrix
self.bind()
# Send MVP matrix to the vertex shader
glUniformMatrix4fv(self.uMvpMatrixLocation, 1, GL_FALSE,
glm.value_ptr(mvpMatrix))
# Send color value to fragment shader
glUniform3fv(self.uColorLocation, 1, glm.value_ptr(color))
# Call a draw command that will cause the vertex shader
# to be called 4 times - once for each vertex of the square
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) main.pyimport ctypes
import math
import os
import glm
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
os.environ["SDL_MAIN_USE_CALLBACKS"] = "1"
os.environ["SDL_RENDER_DRIVER"] = "opengl"
import sdl3
from line_drawer import LineDrawer
glContext = None
window = None
lineDrawer = None
vertexShaderSource = """
attribute vec2 aPosition;
uniform mat4 uMvpMatrix;
void main()
{
gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);
}
"""
fragmentShaderSource = """
uniform vec3 uColor;
void main()
{
gl_FragColor = vec4(uColor, 1.0);
}
"""
@sdl3.SDL_AppInit_func
def SDL_AppInit(appstate, argc, argv):
global glContext
global window
global lineDrawer
if not sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO):
sdl3.SDL_Log("Couldn't initialize SDL: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLEBUFFERS, 1) # Enable MULTISAMPLE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLESAMPLES, 2) # Can be 2, 4, 8 or 16
windowTitle = "PySDL3, PyGLM, PyOpenGL".encode()
window = sdl3.SDL_CreateWindow(windowTitle, 350, 350, sdl3.SDL_WINDOW_OPENGL)
if not window:
sdl3.SDL_Log("Couldn't create a window: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
# Create an OpenGL context
glContext = sdl3.SDL_GL_CreateContext(window)
if not glContext:
sdl3.SDL_Log("Couldn't create a glContext: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetSwapInterval(1) # Turn on vertical sync
glClearColor(0.2, 0.2, 0.2, 1)
program = compileProgram(
compileShader(vertexShaderSource, GL_VERTEX_SHADER),
compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER))
glUseProgram(program)
# Create an orthographic projection matrix and a view matrix
projMatrix = glm.ortho(-100, 100, -100, 100, 1, -1)
viewMatrix = glm.lookAt(
glm.vec3(0, 0, 1), # Position
glm.vec3(0, 0, 0), # Target
glm.vec3(0, 1, 0)) # Up vector
# Combine them to one projView matrix
projViewMatrix = projMatrix * viewMatrix
# Create an object for drawing segments
lineDrawer = LineDrawer(program, projViewMatrix)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppEvent_func
def SDL_AppEvent(appstate, event):
if sdl3.SDL_DEREFERENCE(event).type == sdl3.SDL_EVENT_QUIT:
return sdl3.SDL_APP_SUCCESS
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppIterate_func
def SDL_AppIterate(appstate):
global projViewMatrix
global uMvpMatrixLocation
glClear(GL_COLOR_BUFFER_BIT)
# First line
lineDrawer.draw(start = glm.vec3(-60, 50, 0), end = glm.vec3(40, 80, 0),
color = glm.vec3(1, 0.5, 0.5), thickness = 1)
# Second line
lineDrawer.draw(start = glm.vec3(-28, 37, 0), end = glm.vec3(80, 25, 0),
color = glm.vec3(0.5, 0.5, 1), thickness = 3)
# Polygonal chain
color = glm.vec3(0.5, 1, 0.5)
thickness = 5
lineDrawer.draw(start = glm.vec3(-81, -73, 0), end = glm.vec3(-43, -20, 0),
color = color, thickness = thickness)
lineDrawer.draw(start = glm.vec3(-43, -20, 0), end = glm.vec3(0, -5, 0),
color = color, thickness = thickness)
lineDrawer.draw(start = glm.vec3(0, -5, 0), end = glm.vec3(25, -10, 0),
color = color, thickness = thickness)
lineDrawer.draw(start = glm.vec3(25, -10, 0), end = glm.vec3(52, -70, 0),
color = color, thickness = thickness)
lineDrawer.draw(start = glm.vec3(52, -70, 0), end = glm.vec3(77, -5, 0),
color = color, thickness = thickness)
sdl3.SDL_GL_SwapWindow(window)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppQuit_func
def SDL_AppQuit(appstate, result):
global glContext
sdl3.SDL_GL_DestroyContext(glContext)
# SDL will clean up the window/renderer for us math_helper.pyimport math
import glm
class MathHelper:
# Sets a quat from the given angle and rotation axis, then returns it
@staticmethod
def setAxisAngle(axis, rad):
rad = rad * 0.5
s = math.sin(rad)
out = glm.quat()
out.x = s * axis[0]
out.y = s * axis[1]
out.z = s * axis[2]
out.w = math.cos(rad)
return out
# This is port of https://glmatrix.net/docs/quat.js.html#line652
# Sets a quaternion to represent the shortest rotation from one vector to another
# Both vectors are assumed to be unit length
@staticmethod
def rotationTo(initialVector, destinationVector):
xUnitVec3 = glm.vec3(1, 0, 0)
yUnitVec3 = glm.vec3(0, 1, 0)
out = glm.quat()
dot = glm.dot(destinationVector, initialVector)
if dot < -0.999999:
tmpvec3 = glm.cross(initialVector, xUnitVec3)
if glm.length(tmpvec3) < 0.000001:
tmpvec3 = glm.cross(initialVector, yUnitVec3)
tmpvec3 = glm.normalize(tmpvec3)
out = MathHelper.setAxisAngle(tmpvec3, math.pi)
return out
elif dot > 0.999999:
out.x = 0
out.y = 0
out.z = 0
out.w = 1
return out
else:
tmpvec3 = glm.cross(initialVector, destinationVector)
out.x = tmpvec3[0]
out.y = tmpvec3[1]
out.z = tmpvec3[2]
out.w = 1 + dot
return glm.normalize(out)
|
Beta Was this translation helpful? Give feedback.
-
Disk drawer The Click this to collapse/folddisk_drawer.pyimport math
import glm
import numpy as np
from OpenGL.GL import *
class DiskDrawer:
def __init__(self, program, projViewMatrix, amountOfDiskSegments):
# Save the program and projView matrix
self.program = program
self.projViewMatrix = projViewMatrix
# Activate the current shader program to access shader variables
glUseProgram(self.program)
# Access the uniform variables in the shaders
self.aPositionLocation = glGetAttribLocation(self.program, "aPosition")
self.uColorLocation = glGetUniformLocation(self.program, "uColor")
self.uMvpMatrixLocation = glGetUniformLocation(self.program, "uMvpMatrix")
self.amountOfDiskSegments = amountOfDiskSegments
self.amountOfVertices = self.amountOfDiskSegments + 2
self.angleStep = 360 / self.amountOfDiskSegments
# Create a buffer in the video card's RAM
self.vertPosBuffer = glGenBuffers(1)
self.initVertexBuffers()
def initVertexBuffers(self):
# Set the vertices of the disk
radius = 1
angle = 0
vertPositions = []
vertPositions.extend([0, 0]) # Center
for i in range(self.amountOfDiskSegments + 1):
x = radius * math.cos(math.radians(angle))
y = radius * math.sin(math.radians(angle))
vertPositions.extend([x, y])
angle += self.angleStep
vertPositions = np.array(vertPositions, dtype=np.float32)
# Bind to the created buffer
glBindBuffer(GL_ARRAY_BUFFER, self.vertPosBuffer)
# Copy vertex array to buffer
glBufferData(GL_ARRAY_BUFFER, len(vertPositions) * 4,
vertPositions, GL_STATIC_DRAW)
# This method should be called if the window
# size changes or the camera position changes.
def setProjViewMatrix(self, projViewMatrix):
self.projViewMatrix = projViewMatrix
def bind(self):
# Activate Shader Program Object
glUseProgram(self.program)
# Bind to the buffer
glBindBuffer(GL_ARRAY_BUFFER, self.vertPosBuffer)
# Set up buffer
glVertexAttribPointer(self.aPositionLocation, 2, GL_FLOAT, GL_FALSE,
0, ctypes.c_void_p(0))
glEnableVertexAttribArray(self.aPositionLocation)
def draw(self, center, radius, color):
# Create a model matrix, that is, a matrix combining the
# translation matrix, rotation matrix, and the scale matrix
# Create a translation matrix
modelMatrix = glm.translate(glm.mat4(1), center)
# Create a scale matrix
modelMatrix = glm.scale(modelMatrix, glm.vec3(radius, radius, 1))
# Combine projView matrix and model matrix into one MVP matrix
mvpMatrix = self.projViewMatrix * modelMatrix
self.bind()
# Send MVP matrix to the vertex shader
glUniformMatrix4fv(self.uMvpMatrixLocation, 1, GL_FALSE,
glm.value_ptr(mvpMatrix))
# Send color value to fragment shader
glUniform3fv(self.uColorLocation, 1, glm.value_ptr(color))
# Call a draw command that will cause the vertex shader
# to be called 4 times - once for each vertex of the square
glDrawArrays(GL_TRIANGLE_FAN, 0, self.amountOfVertices) main.pyimport ctypes
import math
import os
import glm
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
os.environ["SDL_MAIN_USE_CALLBACKS"] = "1"
os.environ["SDL_RENDER_DRIVER"] = "opengl"
import sdl3
from disk_drawer import DiskDrawer
glContext = None
window = None
diskDrawer = None
vertexShaderSource = """
attribute vec2 aPosition;
uniform mat4 uMvpMatrix;
void main()
{
gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);
}
"""
fragmentShaderSource = """
uniform vec3 uColor;
void main()
{
gl_FragColor = vec4(uColor, 1.0);
}
"""
@sdl3.SDL_AppInit_func
def SDL_AppInit(appstate, argc, argv):
global glContext
global window
global diskDrawer
if not sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO):
sdl3.SDL_Log("Couldn't initialize SDL: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLEBUFFERS, 1) # Enable MULTISAMPLE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLESAMPLES, 2) # Can be 2, 4, 8 or 16
windowTitle = "PySDL3, PyGLM, PyOpenGL".encode()
window = sdl3.SDL_CreateWindow(windowTitle, 350, 350, sdl3.SDL_WINDOW_OPENGL)
if not window:
sdl3.SDL_Log("Couldn't create a window: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
# Create an OpenGL context
glContext = sdl3.SDL_GL_CreateContext(window)
if not glContext:
sdl3.SDL_Log("Couldn't create a glContext: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetSwapInterval(1) # Turn on vertical sync
glClearColor(0.78, 0.91, 0.76, 1)
program = compileProgram(
compileShader(vertexShaderSource, GL_VERTEX_SHADER),
compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER))
glUseProgram(program)
# Create an orthographic projection matrix and a view matrix
projMatrix = glm.ortho(-100, 100, -100, 100, 1, -1)
viewMatrix = glm.lookAt(
glm.vec3(0, 0, 1), # Position
glm.vec3(0, 0, 0), # Target
glm.vec3(0, 1, 0)) # Up vector
# Combine them to one projView matrix
projViewMatrix = projMatrix * viewMatrix
# Create an object for drawing segments
diskDrawer = DiskDrawer(program, projViewMatrix, 50)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppEvent_func
def SDL_AppEvent(appstate, event):
if sdl3.SDL_DEREFERENCE(event).type == sdl3.SDL_EVENT_QUIT:
return sdl3.SDL_APP_SUCCESS
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppIterate_func
def SDL_AppIterate(appstate):
global projViewMatrix
global uMvpMatrixLocation
glClear(GL_COLOR_BUFFER_BIT)
# First disk
diskDrawer.draw(center = glm.vec3(50, 50, 0), radius = 20,
color = glm.vec3(0.8, 0.15, 0.18))
# Second disk
diskDrawer.draw(center = glm.vec3(0, 0, 0), radius = 30,
color = glm.vec3(0.2, 0.6, 0.3))
# Third disk
diskDrawer.draw(center = glm.vec3(-50, -50, 0), radius = 40,
color = glm.vec3(0.25, 0.31, 0.85))
sdl3.SDL_GL_SwapWindow(window)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppQuit_func
def SDL_AppQuit(appstate, result):
global glContext
sdl3.SDL_GL_DestroyContext(glContext)
# SDL will clean up the window/renderer for us
|
Beta Was this translation helpful? Give feedback.
-
Polygonal chain with disks polygonal-chain-with-disks-opengl-pysdl3.zip Click this to collapse/folddisk_drawer.pyimport math
import glm
import numpy as np
from OpenGL.GL import *
class DiskDrawer:
def __init__(self, program, projViewMatrix, amountOfDiskSegments):
# Save the program and projView matrix
self.program = program
self.projViewMatrix = projViewMatrix
# Activate the current shader program to access shader variables
glUseProgram(self.program)
# Access the uniform variables in the shaders
self.aPositionLocation = glGetAttribLocation(self.program, "aPosition")
self.uColorLocation = glGetUniformLocation(self.program, "uColor")
self.uMvpMatrixLocation = glGetUniformLocation(self.program, "uMvpMatrix")
self.amountOfDiskSegments = amountOfDiskSegments
self.amountOfVertices = self.amountOfDiskSegments + 2
self.angleStep = 360 / self.amountOfDiskSegments
# Create a buffer in the video card's RAM
self.vertPosBuffer = glGenBuffers(1)
self.initVertexBuffers()
def initVertexBuffers(self):
# Set the vertices of the disk
radius = 1
angle = 0
vertPositions = []
vertPositions.extend([0, 0]) # Center
for i in range(self.amountOfDiskSegments + 1):
x = radius * math.cos(math.radians(angle))
y = radius * math.sin(math.radians(angle))
vertPositions.extend([x, y])
angle += self.angleStep
vertPositions = np.array(vertPositions, dtype=np.float32)
# Bind to the created buffer
glBindBuffer(GL_ARRAY_BUFFER, self.vertPosBuffer)
# Copy vertex array to buffer
glBufferData(GL_ARRAY_BUFFER, len(vertPositions) * 4,
vertPositions, GL_STATIC_DRAW)
# This method should be called if the window
# size changes or the camera position changes.
def setProjViewMatrix(self, projViewMatrix):
self.projViewMatrix = projViewMatrix
def bind(self):
# Activate Shader Program Object
glUseProgram(self.program)
# Bind to the buffer
glBindBuffer(GL_ARRAY_BUFFER, self.vertPosBuffer)
# Set up buffer
glVertexAttribPointer(self.aPositionLocation, 2, GL_FLOAT, GL_FALSE,
0, ctypes.c_void_p(0))
glEnableVertexAttribArray(self.aPositionLocation)
def draw(self, center, radius, color):
# Create a model matrix, that is, a matrix combining the
# translation matrix, rotation matrix, and the scale matrix
# Create a translation matrix
modelMatrix = glm.translate(glm.mat4(1), center)
# Create a scale matrix
modelMatrix = glm.scale(modelMatrix, glm.vec3(radius, radius, 1))
# Combine projView matrix and model matrix into one MVP matrix
mvpMatrix = self.projViewMatrix * modelMatrix
self.bind()
# Send MVP matrix to the vertex shader
glUniformMatrix4fv(self.uMvpMatrixLocation, 1, GL_FALSE,
glm.value_ptr(mvpMatrix))
# Send color value to fragment shader
glUniform3fv(self.uColorLocation, 1, glm.value_ptr(color))
# Call a draw command that will cause the vertex shader
# to be called 4 times - once for each vertex of the square
glDrawArrays(GL_TRIANGLE_FAN, 0, self.amountOfVertices) line_drawer.pyimport math
import glm
import numpy as np
from OpenGL.GL import *
from math_helper import MathHelper
class LineDrawer:
def __init__(self, program, projViewMatrix):
# Save the program and projView matrix
self.program = program
self.projViewMatrix = projViewMatrix
# Activate the current shader program to access shader variables
glUseProgram(self.program)
# Access the uniform variables in the shaders
self.aPositionLocation = glGetAttribLocation(self.program, "aPosition")
self.uColorLocation = glGetUniformLocation(self.program, "uColor")
self.uMvpMatrixLocation = glGetUniformLocation(self.program, "uMvpMatrix")
# Create a buffer in the video card's RAM
self.vertPosBuffer = glGenBuffers(1)
self.initVertexBuffers()
def initVertexBuffers(self):
# Set the vertices of the square
vertPositions = np.array([
-0.5, -0.5,
-0.5, 0.5,
0.5, -0.5,
0.5, 0.5
], dtype=np.float32)
# Bind to the created buffer
glBindBuffer(GL_ARRAY_BUFFER, self.vertPosBuffer)
# Copy vertex array to buffer
glBufferData(GL_ARRAY_BUFFER, len(vertPositions) * 4,
vertPositions, GL_STATIC_DRAW)
# This method should be called if the window
# size changes or the camera position changes.
def setProjViewMatrix(self, projViewMatrix):
self.projViewMatrix = projViewMatrix
def bind(self):
# Activate Shader Program Object
glUseProgram(self.program)
# Bind to the buffer
glBindBuffer(GL_ARRAY_BUFFER, self.vertPosBuffer)
# Set up buffer
glVertexAttribPointer(self.aPositionLocation, 2, GL_FLOAT, GL_FALSE,
0, ctypes.c_void_p(0))
glEnableVertexAttribArray(self.aPositionLocation)
def draw(self, start, end, color, thickness):
# Find the center of the segment
v = end - start
centerPosition = start + v / 2
# Find the length of the segment
length = glm.length(v)
# Normalize the segment vector
norm = glm.normalize(v);
# Calculate the angle of a segment
rotation = MathHelper.rotationTo(glm.vec3(1, 0, 0), norm);
# Create a model matrix, that is, a matrix combining the
# translation matrix, rotation matrix, and the scale matrix
# Create a translation matrix
modelMatrix = glm.translate(glm.mat4(1), centerPosition)
# Create a rotation matrix
rotationMatrix = glm.mat4_cast(rotation)
modelMatrix = modelMatrix * rotationMatrix
# Create a scale matrix
modelMatrix = glm.scale(modelMatrix, glm.vec3(length, thickness, 1))
# Combine projView matrix and model matrix into one MVP matrix
mvpMatrix = self.projViewMatrix * modelMatrix
self.bind()
# Send MVP matrix to the vertex shader
glUniformMatrix4fv(self.uMvpMatrixLocation, 1, GL_FALSE,
glm.value_ptr(mvpMatrix))
# Send color value to fragment shader
glUniform3fv(self.uColorLocation, 1, glm.value_ptr(color))
# Call a draw command that will cause the vertex shader
# to be called 4 times - once for each vertex of the square
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4) main.pyimport ctypes
import math
import os
import glm
import numpy as np
from OpenGL.GL import *
from OpenGL.GL.shaders import *
os.environ["SDL_MAIN_USE_CALLBACKS"] = "1"
os.environ["SDL_RENDER_DRIVER"] = "opengl"
import sdl3
from disk_drawer import DiskDrawer
from line_drawer import LineDrawer
glContext = None
window = None
diskDrawer = None
lineDrawer = None
vertexShaderSource = """
attribute vec2 aPosition;
uniform mat4 uMvpMatrix;
void main()
{
gl_Position = uMvpMatrix * vec4(aPosition, 0.0, 1.0);
}
"""
fragmentShaderSource = """
uniform vec3 uColor;
void main()
{
gl_FragColor = vec4(uColor, 1.0);
}
"""
@sdl3.SDL_AppInit_func
def SDL_AppInit(appstate, argc, argv):
global glContext
global window
global diskDrawer
global lineDrawer
if not sdl3.SDL_Init(sdl3.SDL_INIT_VIDEO):
sdl3.SDL_Log("Couldn't initialize SDL: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLEBUFFERS, 1) # Enable MULTISAMPLE
sdl3.SDL_GL_SetAttribute(sdl3.SDL_GL_MULTISAMPLESAMPLES, 2) # Can be 2, 4, 8 or 16
windowTitle = "PySDL3, PyGLM, PyOpenGL".encode()
window = sdl3.SDL_CreateWindow(windowTitle, 350, 350, sdl3.SDL_WINDOW_OPENGL)
if not window:
sdl3.SDL_Log("Couldn't create a window: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
# Create an OpenGL context
glContext = sdl3.SDL_GL_CreateContext(window)
if not glContext:
sdl3.SDL_Log("Couldn't create a glContext: %s".encode() % sdl3.SDL_GetError())
return sdl3.SDL_APP_FAILURE
sdl3.SDL_GL_SetSwapInterval(1) # Turn on vertical sync
glEnable(GL_DEPTH_TEST)
glClearColor(0.78, 0.91, 0.76, 1)
program = compileProgram(
compileShader(vertexShaderSource, GL_VERTEX_SHADER),
compileShader(fragmentShaderSource, GL_FRAGMENT_SHADER))
glUseProgram(program)
# Create an orthographic projection matrix and a view matrix
projMatrix = glm.ortho(-100, 100, -100, 100, 10, -10)
viewMatrix = glm.lookAt(
glm.vec3(0, 0, 1), # Position
glm.vec3(0, 0, 0), # Target
glm.vec3(0, 1, 0)) # Up vector
# Combine them to one projView matrix
projViewMatrix = projMatrix * viewMatrix
# Create an object for drawing disks
diskDrawer = DiskDrawer(program, projViewMatrix, 50)
# Create an object for drawing segments
lineDrawer = LineDrawer(program, projViewMatrix)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppEvent_func
def SDL_AppEvent(appstate, event):
if sdl3.SDL_DEREFERENCE(event).type == sdl3.SDL_EVENT_QUIT:
return sdl3.SDL_APP_SUCCESS
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppIterate_func
def SDL_AppIterate(appstate):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
# Polygonal chains
diskColor = glm.vec3(0.8, 0.15, 0.18)
lineColor = glm.vec3(0.25, 0.31, 0.85)
thickness = 20
# First polygonal chain
yOffset = 90
lineDrawer.draw(
start = glm.vec3(-80, -30 + yOffset, 0),
end = glm.vec3(-10, -10 + yOffset, 0),
color = lineColor, thickness = thickness)
lineDrawer.draw(
start = glm.vec3(-10, -10 + yOffset, 0),
end = glm.vec3(52, -70 + yOffset, 0),
color = lineColor, thickness = thickness)
lineDrawer.draw(
start = glm.vec3(52, -70 + yOffset, 0),
end = glm.vec3(85, -5 + yOffset, 0),
color = lineColor, thickness = thickness)
# Second polygonal chain
yOffset = 40
lineDrawer.draw(
start = glm.vec3(-80, -30 + yOffset, 0),
end = glm.vec3(-10, -10 + yOffset, 0),
color = lineColor, thickness = thickness)
diskDrawer.draw(center = glm.vec3(-10, -10 + yOffset, -5), radius = 10,
color = diskColor)
lineDrawer.draw(
start = glm.vec3(-10, -10 + yOffset, 0),
end = glm.vec3(52, -70 + yOffset, 0),
color = lineColor, thickness = thickness)
diskDrawer.draw(center = glm.vec3(52, -70 + yOffset, -5), radius = 10,
color = diskColor)
lineDrawer.draw(
start = glm.vec3(52, -70 + yOffset, 0),
end = glm.vec3(85, -5 + yOffset, 0),
color = lineColor, thickness = thickness)
# Third polygonal chain
yOffset = -10
lineDrawer.draw(
start = glm.vec3(-80, -30 + yOffset, 0),
end = glm.vec3(-10, -10 + yOffset, 0),
color = lineColor, thickness = thickness)
diskDrawer.draw(center = glm.vec3(-10, -10 + yOffset, -5), radius = 10,
color = lineColor)
lineDrawer.draw(
start = glm.vec3(-10, -10 + yOffset, 0),
end = glm.vec3(52, -70 + yOffset, 0),
color = lineColor, thickness = thickness)
diskDrawer.draw(center = glm.vec3(52, -70 + yOffset, -5), radius = 10,
color = lineColor)
lineDrawer.draw(
start = glm.vec3(52, -70 + yOffset, 0),
end = glm.vec3(85, -5 + yOffset, 0),
color = lineColor, thickness = thickness)
sdl3.SDL_GL_SwapWindow(window)
return sdl3.SDL_APP_CONTINUE
@sdl3.SDL_AppQuit_func
def SDL_AppQuit(appstate, result):
global glContext
sdl3.SDL_GL_DestroyContext(glContext)
# SDL will clean up the window/renderer for us math_helper.pyimport math
import glm
class MathHelper:
# Sets a quat from the given angle and rotation axis, then returns it
@staticmethod
def setAxisAngle(axis, rad):
rad = rad * 0.5
s = math.sin(rad)
out = glm.quat()
out.x = s * axis[0]
out.y = s * axis[1]
out.z = s * axis[2]
out.w = math.cos(rad)
return out
# This is port of https://glmatrix.net/docs/quat.js.html#line652
# Sets a quaternion to represent the shortest rotation from one vector to another
# Both vectors are assumed to be unit length
@staticmethod
def rotationTo(initialVector, destinationVector):
xUnitVec3 = glm.vec3(1, 0, 0)
yUnitVec3 = glm.vec3(0, 1, 0)
out = glm.quat()
dot = glm.dot(destinationVector, initialVector)
if dot < -0.999999:
tmpvec3 = glm.cross(initialVector, xUnitVec3)
if glm.length(tmpvec3) < 0.000001:
tmpvec3 = glm.cross(initialVector, yUnitVec3)
tmpvec3 = glm.normalize(tmpvec3)
out = MathHelper.setAxisAngle(tmpvec3, math.pi)
return out
elif dot > 0.999999:
out.x = 0
out.y = 0
out.z = 0
out.w = 1
return out
else:
tmpvec3 = glm.cross(initialVector, destinationVector)
out.x = tmpvec3[0]
out.y = tmpvec3[1]
out.z = tmpvec3[2]
out.w = 1 + dot
return glm.normalize(out)
|
Beta Was this translation helpful? Give feedback.
-
Drawing a text from English and Cyrillic fonts with distance field in 2D It draws a text that is not pixelated when you zoom in and zoom out. In addition the distance field allows to add outline. I used the following ThinMatrix's video tutorial to create this example: OpenGL 3D Game Tutorial 33: Distance Field Text Rendering Source code:
Demos in the browser:
Executables:
|
Beta Was this translation helpful? Give feedback.
-
Texture drawer It draws textures. Source code:
Demos in the browser:
Executables:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello. There are some simple OpenGL examples (without ChatGPT). There are more examples in the Need examples topic.
You can try to install the latest version of all requested packages:
I have tested the examples with the following versions of the packages:
Table of contents:
Beta Was this translation helpful? Give feedback.
All reactions