100 lines
2.4 KiB
Python
100 lines
2.4 KiB
Python
# OpenGL/Metal rendering test: render a red triangle to a texture
|
|
# and save it to a PNG file
|
|
|
|
import sys
|
|
sys.path.append('python')
|
|
import nanogui
|
|
from nanogui import Shader, Texture, RenderPass, Screen
|
|
import numpy as np
|
|
from PIL import Image
|
|
|
|
nanogui.init()
|
|
|
|
if nanogui.api == 'opengl':
|
|
s = Screen([16, 16], "Unnamed")
|
|
|
|
vertex_program = '''
|
|
#version 330
|
|
in vec3 position;
|
|
|
|
void main() {
|
|
gl_Position = vec4(position, 1.0);
|
|
}
|
|
'''
|
|
|
|
fragment_program = '''
|
|
#version 330
|
|
uniform vec4 color;
|
|
out vec4 fragColor;
|
|
|
|
void main() {
|
|
fragColor = color;
|
|
}
|
|
'''
|
|
elif nanogui.api == 'metal':
|
|
vertex_program = '''
|
|
using namespace metal;
|
|
|
|
struct VertexOut {
|
|
float4 position [[position]];
|
|
};
|
|
|
|
vertex VertexOut vertex_main(const device packed_float3 *position,
|
|
uint id [[vertex_id]]) {
|
|
VertexOut vert;
|
|
vert.position = float4(position[id], 1.f);
|
|
return vert;
|
|
}
|
|
'''
|
|
|
|
fragment_program = '''
|
|
using namespace metal;
|
|
|
|
struct VertexOut {
|
|
float4 position [[position]];
|
|
};
|
|
|
|
fragment float4 fragment_main(VertexOut vert [[stage_in]],
|
|
const constant float4 &color) {
|
|
return color;
|
|
}
|
|
'''
|
|
|
|
texture = Texture(
|
|
pixel_format=Texture.PixelFormat.RGBA,
|
|
component_format=Texture.ComponentFormat.UInt8,
|
|
size=[512, 512],
|
|
flags=Texture.TextureFlags.ShaderRead | Texture.TextureFlags.RenderTarget
|
|
)
|
|
|
|
render_pass = RenderPass([texture])
|
|
render_pass.set_viewport(
|
|
[10, 10], [512 - 10, 512 - 20]
|
|
)
|
|
|
|
shader = Shader(
|
|
render_pass,
|
|
"test_shader",
|
|
vertex_program,
|
|
fragment_program
|
|
)
|
|
|
|
p = np.array([[ 0.0, 0.5, 0],
|
|
[-0.5, -0.5, 0],
|
|
[ 0.5, -0.5, 0]], dtype=np.float32)
|
|
|
|
shader.set_buffer("position", p)
|
|
shader.set_buffer("color", np.array([1, 0, 0, 1], dtype=np.float32))
|
|
shader.set_buffer("indices", np.array([0, 1, 2], dtype=np.uint32))
|
|
|
|
with render_pass:
|
|
with shader:
|
|
if False:
|
|
shader.draw_array(Shader.PrimitiveType.Triangle, 0, 3)
|
|
else:
|
|
shader.draw_array(Shader.PrimitiveType.Triangle, 0, 3, indexed=True)
|
|
|
|
result = texture.download()
|
|
|
|
Image.fromarray(result).save('test_0_%s.png' % nanogui.api)
|