mirror of https://github.com/buggins/dlangui.git
3d graphics #183
This commit is contained in:
parent
f45371673b
commit
a2a4523e13
|
@ -5,6 +5,10 @@ import dlangui.graphics.scene.scene3d;
|
||||||
import dlangui.graphics.scene.camera;
|
import dlangui.graphics.scene.camera;
|
||||||
import dlangui.graphics.scene.mesh;
|
import dlangui.graphics.scene.mesh;
|
||||||
import dlangui.graphics.scene.material;
|
import dlangui.graphics.scene.material;
|
||||||
|
import dlangui.graphics.glsupport;
|
||||||
|
import dlangui.graphics.gldrawbuf;
|
||||||
|
import derelict.opengl3.gl3;
|
||||||
|
import derelict.opengl3.gl;
|
||||||
|
|
||||||
mixin APP_ENTRY_POINT;
|
mixin APP_ENTRY_POINT;
|
||||||
|
|
||||||
|
@ -12,27 +16,49 @@ mixin APP_ENTRY_POINT;
|
||||||
extern (C) int UIAppMain(string[] args) {
|
extern (C) int UIAppMain(string[] args) {
|
||||||
// create window
|
// create window
|
||||||
Window window = Platform.instance.createWindow("DlangUI example - 3D Application", null, WindowFlag.Resizable, 600, 500);
|
Window window = Platform.instance.createWindow("DlangUI example - 3D Application", null, WindowFlag.Resizable, 600, 500);
|
||||||
|
window.mainWidget = new UiWidget();
|
||||||
|
|
||||||
static if (false) {
|
auto canvas = window.mainWidget.childById!CanvasWidget("canvas");
|
||||||
VerticalLayout layout = new VerticalLayout();
|
canvas.onDrawListener = delegate(CanvasWidget canvas, DrawBuf buf, Rect rc) {
|
||||||
Button btn = new Button(null, "Button 1"d);
|
Log.w("canvas.onDrawListener clipRect=" ~ to!string(buf.clipRect));
|
||||||
btn.fontSize = 32;
|
buf.fill(0xFFFFFF);
|
||||||
Button btn2 = new Button(null, "Button 2"d);
|
int x = rc.left;
|
||||||
btn2.fontSize = 32;
|
int y = rc.top;
|
||||||
layout.addChild(btn);
|
buf.fillRect(Rect(x+20, y+20, x+150, y+200), 0x80FF80);
|
||||||
layout.addChild(btn2);
|
buf.fillRect(Rect(x+90, y+80, x+250, y+250), 0x80FF80FF);
|
||||||
window.mainWidget = layout;
|
canvas.font.drawText(buf, x + 40, y + 50, "fillRect()"d, 0xC080C0);
|
||||||
} else {
|
buf.drawFrame(Rect(x + 400, y + 30, x + 550, y + 150), 0x204060, Rect(2,3,4,5), 0x80704020);
|
||||||
|
canvas.font.drawText(buf, x + 400, y + 5, "drawFrame()"d, 0x208020);
|
||||||
|
canvas.font.drawText(buf, x + 300, y + 100, "drawPixel()"d, 0x000080);
|
||||||
|
for (int i = 0; i < 80; i++)
|
||||||
|
buf.drawPixel(x+300 + i * 4, y+140 + i * 3 % 100, 0xFF0000 + i * 2);
|
||||||
|
canvas.font.drawText(buf, x + 200, y + 150, "drawLine()"d, 0x800020);
|
||||||
|
for (int i = 0; i < 40; i+=3)
|
||||||
|
buf.drawLine(Point(x+200 + i * 4, y+190), Point(x+150 + i * 7, y+320 + i * 2), 0x008000 + i * 5);
|
||||||
|
};
|
||||||
|
|
||||||
// create some widget to show in window
|
|
||||||
//window.mainWidget = (new Button()).text("Hello, world!"d).margins(Rect(20,20,20,20));
|
//MeshPart part = new MeshPart();
|
||||||
window.mainWidget = parseML(q{
|
|
||||||
VerticalLayout {
|
// show window
|
||||||
|
window.show();
|
||||||
|
|
||||||
|
// run message loop
|
||||||
|
return Platform.instance.enterMessageLoop();
|
||||||
|
}
|
||||||
|
|
||||||
|
class UiWidget : VerticalLayout {
|
||||||
|
this() {
|
||||||
|
super("OpenGLView");
|
||||||
|
layoutWidth = FILL_PARENT;
|
||||||
|
layoutHeight = FILL_PARENT;
|
||||||
|
alignment = Align.Center;
|
||||||
|
parseML(q{
|
||||||
|
{
|
||||||
|
id: glView
|
||||||
margins: 10
|
margins: 10
|
||||||
padding: 10
|
padding: 10
|
||||||
backgroundColor: "#C0E0E070" // semitransparent yellow background
|
backgroundColor: "#C0E0E070" // semitransparent yellow background
|
||||||
// red bold text with size = 150% of base style size and font face Arial
|
|
||||||
MainMenu {}
|
|
||||||
TextWidget { text: "Hello World example for DlangUI"; textColor: "red"; fontSize: 150%; fontWeight: 800; fontFace: "Arial" }
|
TextWidget { text: "Hello World example for DlangUI"; textColor: "red"; fontSize: 150%; fontWeight: 800; fontFace: "Arial" }
|
||||||
HorizontalLayout {
|
HorizontalLayout {
|
||||||
layoutWidth: fill
|
layoutWidth: fill
|
||||||
|
@ -76,53 +102,119 @@ extern (C) int UIAppMain(string[] args) {
|
||||||
minHeight: 300
|
minHeight: 300
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}, "", this);
|
||||||
|
// assign OpenGL drawable to child widget background
|
||||||
|
childById("glView").backgroundDrawable = DrawableRef(new OpenGLDrawable(&doDraw));
|
||||||
|
|
||||||
MenuItem mainMenuItems = new MenuItem();
|
|
||||||
MenuItem fileItem = new MenuItem(new Action(1, "MENU_FILE"));
|
|
||||||
fileItem.add(new Action(2, "MENU_FILE_OPEN"c, "document-open", KeyCode.KEY_O, KeyFlag.Control));
|
|
||||||
fileItem.add(new Action(3, "MENU_FILE_SAVE"c, "document-save", KeyCode.KEY_S, KeyFlag.Control));
|
|
||||||
mainMenuItems.add(fileItem);
|
|
||||||
window.mainWidget.childById!MainMenu("MAIN_MENU").menuItems = mainMenuItems;
|
|
||||||
|
|
||||||
auto canvas = window.mainWidget.childById!CanvasWidget("canvas");
|
_scene = new Scene3d();
|
||||||
canvas.onDrawListener = delegate(CanvasWidget canvas, DrawBuf buf, Rect rc) {
|
_cam = new Camera();
|
||||||
Log.w("canvas.onDrawListener clipRect=" ~ to!string(buf.clipRect));
|
_cam.translation = vec3(0, 0, -5);
|
||||||
buf.fill(0xFFFFFF);
|
_scene.activeCamera = _cam;
|
||||||
int x = rc.left;
|
mat4 camMatrix = _scene.viewProjectionMatrix;
|
||||||
int y = rc.top;
|
VertexFormat vfmt = VertexFormat(VertexElementType.POSITION, VertexElementType.COLOR, VertexElementType.TEXCOORD0);
|
||||||
buf.fillRect(Rect(x+20, y+20, x+150, y+200), 0x80FF80);
|
_mesh = new Mesh(vfmt);
|
||||||
buf.fillRect(Rect(x+90, y+80, x+250, y+250), 0x80FF80FF);
|
_mesh.addVertex([1,2,3, 1,1,1,1, 0,0]);
|
||||||
canvas.font.drawText(buf, x + 40, y + 50, "fillRect()"d, 0xC080C0);
|
_mesh.addVertex([-1,2,3, 1,1,1,1, 1,0]);
|
||||||
buf.drawFrame(Rect(x + 400, y + 30, x + 550, y + 150), 0x204060, Rect(2,3,4,5), 0x80704020);
|
_mesh.addVertex([-1,-2,3, 1,1,1,1, 1,1]);
|
||||||
canvas.font.drawText(buf, x + 400, y + 5, "drawFrame()"d, 0x208020);
|
_mesh.addVertex([1,-2,3, 1,1,1,1, 0,1]);
|
||||||
canvas.font.drawText(buf, x + 300, y + 100, "drawPixel()"d, 0x000080);
|
_mesh.addPart(PrimitiveType.triangles, [0, 1, 2, 2, 3, 0]);
|
||||||
for (int i = 0; i < 80; i++)
|
|
||||||
buf.drawPixel(x+300 + i * 4, y+140 + i * 3 % 100, 0xFF0000 + i * 2);
|
}
|
||||||
canvas.font.drawText(buf, x + 200, y + 150, "drawLine()"d, 0x800020);
|
|
||||||
for (int i = 0; i < 40; i+=3)
|
MyGLProgram _program;
|
||||||
buf.drawLine(Point(x+200 + i * 4, y+190), Point(x+150 + i * 7, y+320 + i * 2), 0x008000 + i * 5);
|
Scene3d _scene;
|
||||||
|
Camera _cam;
|
||||||
|
Mesh _mesh;
|
||||||
|
GLTexture _tx;
|
||||||
|
|
||||||
|
|
||||||
|
/// this is OpenGLDrawableDelegate implementation
|
||||||
|
private void doDraw(Rect windowRect, Rect rc) {
|
||||||
|
if (!_program) {
|
||||||
|
_program = new MyGLProgram();
|
||||||
|
}
|
||||||
|
if (!_program.check())
|
||||||
|
return;
|
||||||
|
if (!_tx)
|
||||||
|
_tx = new GLTexture("crate");
|
||||||
|
if (!_tx.isValid) {
|
||||||
|
Log.e("Invalid texture");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mat4 camMatrix = _scene.viewProjectionMatrix;
|
||||||
|
_program.bind();
|
||||||
|
_program.setUniform("matrix", camMatrix);
|
||||||
|
_tx.texture.setup();
|
||||||
|
_tx.texture.setSamplerParams(true);
|
||||||
|
|
||||||
|
_program.draw(_mesh);
|
||||||
|
|
||||||
|
_tx.texture.unbind();
|
||||||
|
_program.unbind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Simple texture + color shader
|
||||||
|
class MyGLProgram : GLProgram {
|
||||||
|
@property override string vertexSource() {
|
||||||
|
return q{
|
||||||
|
in vec4 vertex;
|
||||||
|
in vec4 colAttr;
|
||||||
|
in vec4 texCoord;
|
||||||
|
out vec4 col;
|
||||||
|
out vec4 texc;
|
||||||
|
uniform mat4 matrix;
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
gl_Position = matrix * vertex;
|
||||||
|
col = colAttr;
|
||||||
|
texc = texCoord;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
@property override string fragmentSource() {
|
||||||
|
return q{
|
||||||
|
uniform sampler2D tex;
|
||||||
|
in vec4 col;
|
||||||
|
in vec4 texc;
|
||||||
|
out vec4 outColor;
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
outColor = texture(tex, texc.st) * col;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Scene3d scene = new Scene3d();
|
// attribute locations
|
||||||
Camera cam = new Camera();
|
protected int matrixLocation;
|
||||||
cam.translation = vec3(0, 0, -5);
|
protected int vertexLocation;
|
||||||
scene.activeCamera = cam;
|
protected int colAttrLocation;
|
||||||
mat4 camMatrix = scene.viewProjectionMatrix;
|
protected int texCoordLocation;
|
||||||
VertexFormat vfmt = VertexFormat(VertexElementType.POSITION, VertexElementType.COLOR, VertexElementType.TEXCOORD0);
|
|
||||||
Mesh mesh = new Mesh(vfmt);
|
|
||||||
mesh.addVertex([1,2,3, 1,1,1,1, 0,0]);
|
|
||||||
mesh.addVertex([-1,2,3, 1,1,1,1, 1,0]);
|
|
||||||
mesh.addVertex([-1,-2,3, 1,1,1,1, 1,1]);
|
|
||||||
mesh.addVertex([1,-2,3, 1,1,1,1, 0,1]);
|
|
||||||
mesh.addPart(PrimitiveType.triangles, [0, 1, 2, 2, 3, 0]);
|
|
||||||
|
|
||||||
//MeshPart part = new MeshPart();
|
override bool initLocations() {
|
||||||
|
matrixLocation = getUniformLocation("matrix");
|
||||||
|
vertexLocation = getAttribLocation("vertex");
|
||||||
|
colAttrLocation = getAttribLocation("colAttr");
|
||||||
|
texCoordLocation = getAttribLocation("texCoord");
|
||||||
|
return matrixLocation >= 0 && vertexLocation >= 0 && colAttrLocation >= 0 && texCoordLocation >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
// show window
|
/// get location for vertex attribute
|
||||||
window.show();
|
override int getVertexElementLocation(VertexElementType type) {
|
||||||
|
switch(type) with(VertexElementType) {
|
||||||
|
case POSITION:
|
||||||
|
return vertexLocation;
|
||||||
|
case COLOR:
|
||||||
|
return colAttrLocation;
|
||||||
|
case TEXCOORD0:
|
||||||
|
return texCoordLocation;
|
||||||
|
default:
|
||||||
|
return super.getVertexElementLocation(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// run message loop
|
|
||||||
return Platform.instance.enterMessageLoop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 470 KiB |
|
@ -2,3 +2,4 @@ res/i18n/en.ini
|
||||||
res/i18n/ru.ini
|
res/i18n/ru.ini
|
||||||
res/mdpi/cr3_logo.png
|
res/mdpi/cr3_logo.png
|
||||||
res/mdpi/tx_fabric.jpg
|
res/mdpi/tx_fabric.jpg
|
||||||
|
res/mdpi/crate.png
|
||||||
|
|
|
@ -266,6 +266,11 @@ class GLProgram : GraphicsEffect {
|
||||||
protected int[string] _uniformLocations;
|
protected int[string] _uniformLocations;
|
||||||
protected int[string] _attribLocations;
|
protected int[string] _attribLocations;
|
||||||
|
|
||||||
|
/// get location for vertex attribute
|
||||||
|
override int getVertexElementLocation(VertexElementType type) {
|
||||||
|
return VERTEX_ELEMENT_NOT_FOUND;
|
||||||
|
}
|
||||||
|
|
||||||
/// get uniform location from program, returns -1 if location is not found
|
/// get uniform location from program, returns -1 if location is not found
|
||||||
int getUniformLocation(string variableName) {
|
int getUniformLocation(string variableName) {
|
||||||
if (auto p = variableName in _uniformLocations)
|
if (auto p = variableName in _uniformLocations)
|
||||||
|
|
Loading…
Reference in New Issue