3d graphics #183

This commit is contained in:
Vadim Lopatin 2016-02-26 15:26:27 +03:00
parent f45371673b
commit a2a4523e13
4 changed files with 165 additions and 67 deletions

View File

@ -5,6 +5,10 @@ import dlangui.graphics.scene.scene3d;
import dlangui.graphics.scene.camera;
import dlangui.graphics.scene.mesh;
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;
@ -12,34 +16,56 @@ mixin APP_ENTRY_POINT;
extern (C) int UIAppMain(string[] args) {
// create window
Window window = Platform.instance.createWindow("DlangUI example - 3D Application", null, WindowFlag.Resizable, 600, 500);
window.mainWidget = new UiWidget();
static if (false) {
VerticalLayout layout = new VerticalLayout();
Button btn = new Button(null, "Button 1"d);
btn.fontSize = 32;
Button btn2 = new Button(null, "Button 2"d);
btn2.fontSize = 32;
layout.addChild(btn);
layout.addChild(btn2);
window.mainWidget = layout;
} else {
auto canvas = window.mainWidget.childById!CanvasWidget("canvas");
canvas.onDrawListener = delegate(CanvasWidget canvas, DrawBuf buf, Rect rc) {
Log.w("canvas.onDrawListener clipRect=" ~ to!string(buf.clipRect));
buf.fill(0xFFFFFF);
int x = rc.left;
int y = rc.top;
buf.fillRect(Rect(x+20, y+20, x+150, y+200), 0x80FF80);
buf.fillRect(Rect(x+90, y+80, x+250, y+250), 0x80FF80FF);
canvas.font.drawText(buf, x + 40, y + 50, "fillRect()"d, 0xC080C0);
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));
window.mainWidget = parseML(q{
VerticalLayout {
//MeshPart part = new MeshPart();
// 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
padding: 10
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" }
HorizontalLayout {
layoutWidth: fill
TextWidget { text: "Text 20%"; backgroundColor:"#80FF0000"; layoutWidth: 20% }
layoutWidth: fill
TextWidget { text: "Text 20%"; backgroundColor:"#80FF0000"; layoutWidth: 20% }
VerticalLayout {
layoutWidth: 30%
TextWidget { text: "Text 30%"; backgroundColor:"#80FF00FF" }
layoutWidth: 30%
TextWidget { text: "Text 30%"; backgroundColor:"#80FF00FF" }
TextWidget { text: "Text 30%"; backgroundColor:"#8000FFFF" }
TextWidget { text: "Text 30%"; backgroundColor:"#8000FFFF" }
}
@ -47,8 +73,8 @@ extern (C) int UIAppMain(string[] args) {
}
// arrange controls as form - table with two columns
TableLayout {
colCount: 2
TextWidget { text: "param 1" }
colCount: 2
TextWidget { text: "param 1" }
EditLine { id: edit1; text: "some text" }
TextWidget { text: "param 2" }
EditLine { id: edit2; text: "some text for param2" }
@ -71,58 +97,124 @@ extern (C) int UIAppMain(string[] args) {
Button { id: btnCancel; text: "Cancel"; fontSize: 27px }
}
CanvasWidget {
id: canvas
minWidth: 500
minHeight: 300
id: canvas
minWidth: 500
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");
canvas.onDrawListener = delegate(CanvasWidget canvas, DrawBuf buf, Rect rc) {
Log.w("canvas.onDrawListener clipRect=" ~ to!string(buf.clipRect));
buf.fill(0xFFFFFF);
int x = rc.left;
int y = rc.top;
buf.fillRect(Rect(x+20, y+20, x+150, y+200), 0x80FF80);
buf.fillRect(Rect(x+90, y+80, x+250, y+250), 0x80FF80FF);
canvas.font.drawText(buf, x + 40, y + 50, "fillRect()"d, 0xC080C0);
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);
};
_scene = new Scene3d();
_cam = new Camera();
_cam.translation = vec3(0, 0, -5);
_scene.activeCamera = _cam;
mat4 camMatrix = _scene.viewProjectionMatrix;
VertexFormat vfmt = VertexFormat(VertexElementType.POSITION, VertexElementType.COLOR, VertexElementType.TEXCOORD0);
_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]);
}
Scene3d scene = new Scene3d();
Camera cam = new Camera();
cam.translation = vec3(0, 0, -5);
scene.activeCamera = cam;
mat4 camMatrix = scene.viewProjectionMatrix;
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]);
MyGLProgram _program;
Scene3d _scene;
Camera _cam;
Mesh _mesh;
GLTexture _tx;
//MeshPart part = new MeshPart();
// show window
window.show();
/// 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);
// run message loop
return Platform.instance.enterMessageLoop();
_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;
}
};
}
// attribute locations
protected int matrixLocation;
protected int vertexLocation;
protected int colAttrLocation;
protected int texCoordLocation;
override bool initLocations() {
matrixLocation = getUniformLocation("matrix");
vertexLocation = getAttribLocation("vertex");
colAttrLocation = getAttribLocation("colAttr");
texCoordLocation = getAttribLocation("texCoord");
return matrixLocation >= 0 && vertexLocation >= 0 && colAttrLocation >= 0 && texCoordLocation >= 0;
}
/// get location for vertex attribute
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);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

View File

@ -2,3 +2,4 @@ res/i18n/en.ini
res/i18n/ru.ini
res/mdpi/cr3_logo.png
res/mdpi/tx_fabric.jpg
res/mdpi/crate.png

View File

@ -266,6 +266,11 @@ class GLProgram : GraphicsEffect {
protected int[string] _uniformLocations;
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
int getUniformLocation(string variableName) {
if (auto p = variableName in _uniformLocations)