OpenGL: drawLine - use line shader instead of drawing line by points

This commit is contained in:
Vadim Lopatin 2015-11-03 15:51:49 +03:00
parent cde32bf2f3
commit 0778b77531
6 changed files with 159 additions and 6 deletions

View File

@ -72,7 +72,7 @@
<debuglevel>0</debuglevel>
<debugids>DebugFocus FontResources</debugids>
<versionlevel>0</versionlevel>
<versionids>EmbedStandardResources Unicode USE_FREETYPE</versionids>
<versionids>Unicode USE_OPENGL USE_FREETYPE EmbedStandardResources</versionids>
<dump_source>0</dump_source>
<mapverbosity>0</mapverbosity>
<createImplib>1</createImplib>

View File

@ -54,7 +54,7 @@
<ccTransOpt>1</ccTransOpt>
<program>$(DMDInstallDir)windows\bin\dmd.exe</program>
<imppath>$(SolutionDir)/src $(SolutionDir)/3rdparty $(SolutionDir)/3rdparty/libpng/source $(SolutionDir)/../DerelictGL3/source $(SolutionDir)/../DerelictUtil/source $(SolutionDir)/../DerelictFT/source $(SolutionDir)/../DerelictSDL2/source $(SolutionDir)/../de_image/source/interfaces $(SolutionDir)/../de_image/source/png $(SolutionDir)/../dlib</imppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi</fileImppath>
<fileImppath>views views/res views/res/i18n views/res/mdpi views/res/hdpi</fileImppath>
<outdir>$(ConfigurationName)</outdir>
<objdir>$(OutDir)</objdir>
<objname />
@ -72,7 +72,7 @@
<debuglevel>0</debuglevel>
<debugids />
<versionlevel>0</versionlevel>
<versionids>Unicode USE_OPENGL USE_FREETYPE USE_SDL EmbedStandardResources</versionids>
<versionids>Unicode USE_OPENGL USE_FREETYPE EmbedStandardResources</versionids>
<dump_source>0</dump_source>
<mapverbosity>0</mapverbosity>
<createImplib>0</createImplib>
@ -96,6 +96,7 @@
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
<useStdLibPath>1</useStdLibPath>
<cRuntime>2</cRuntime>
<privatePhobos>0</privatePhobos>
<additionalOptions />
<preBuildCommand />
<postBuildCommand />
@ -197,6 +198,7 @@
<exefile>$(OutDir)\$(ProjectName).exe</exefile>
<useStdLibPath>1</useStdLibPath>
<cRuntime>1</cRuntime>
<privatePhobos>0</privatePhobos>
<additionalOptions />
<preBuildCommand />
<postBuildCommand />

View File

@ -7,7 +7,7 @@ mixin APP_ENTRY_POINT;
/// entry point for dlangui based application
extern (C) int UIAppMain(string[] args) {
// create window
Window window = Platform.instance.createWindow("DlangUI example - 3D Application", null);
Window window = Platform.instance.createWindow("DlangUI example - 3D Application", null, WindowFlag.Resizable, 600, 500);
// create some widget to show in window
//window.mainWidget = (new Button()).text("Hello, world!"d).margins(Rect(20,20,20,20));
@ -43,9 +43,33 @@ extern (C) int UIAppMain(string[] args) {
Button { id: btnOk; text: "Ok" }
Button { id: btnCancel; text: "Cancel" }
}
CanvasWidget {
id: canvas
minWidth: 500
minHeight: 300
}
}
});
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);
};
// show window
window.show();

View File

@ -149,6 +149,20 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
}
}
/// draw line from point p1 to p2 with specified color
override void drawLine(Point p1, Point p2, uint colour) {
assert(_scene !is null);
if (p1.x < _clipRect.left && p2.x < _clipRect.left)
return;
if (p1.y < _clipRect.top && p2.y < _clipRect.top)
return;
if (p1.x >= _clipRect.right && p2.x >= _clipRect.right)
return;
if (p1.y >= _clipRect.bottom && p2.y >= _clipRect.bottom)
return;
_scene.add(new LineSceneItem(p1, p2, colour));
}
/// cleanup resources
override void clear() {
if (_framebuffer) {
@ -856,6 +870,20 @@ private class GLGlyphCache {
class LineSceneItem : SceneItem {
Point _p1;
Point _p2;
uint _color;
this(Point p1, Point p2, uint color) {
_p1 = p1;
_p2 = p2;
_color = color;
}
override void draw() {
glSupport.drawLine(_p1, _p2, _color, _color);
}
}
class SolidRectSceneItem : SceneItem {
Rect _rc;

View File

@ -343,6 +343,67 @@ class SolidFillProgram : GLProgram {
}
}
class LineProgram : SolidFillProgram {
override bool execute(float[] vertices, float[] colors) {
if (error)
return false;
if (!initialized)
if (!compile())
return false;
beforeExecute();
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(
GL_ARRAY_BUFFER,
vertices.length * vertices[0].sizeof + colors.length * colors[0].sizeof,
null,
GL_STREAM_DRAW);
glBufferSubData(
GL_ARRAY_BUFFER,
0,
vertices.length * vertices[0].sizeof,
vertices.ptr);
glBufferSubData(
GL_ARRAY_BUFFER,
vertices.length * vertices[0].sizeof,
colors.length * colors[0].sizeof,
colors.ptr);
glEnableVertexAttribArray(vertexLocation);
checkError("glEnableVertexAttribArray");
glVertexAttribPointer(vertexLocation, 3, GL_FLOAT, GL_FALSE, 0, cast(void*) 0);
checkError("glVertexAttribPointer");
glEnableVertexAttribArray(colAttrLocation);
checkError("glEnableVertexAttribArray");
glVertexAttribPointer(colAttrLocation, 4, GL_FLOAT, GL_FALSE, 0, cast(void*) (float.sizeof*3*2));
checkError("glVertexAttribPointer");
glDrawArrays(GL_LINES, 0, 2);
checkError("glDrawArrays");
glDisableVertexAttribArray(vertexLocation);
checkError("glDisableVertexAttribArray");
glDisableVertexAttribArray(colAttrLocation);
checkError("glDisableVertexAttribArray");
afterExecute();
glBindBuffer(GL_ARRAY_BUFFER, 0);
glDeleteBuffers(1, &vbo);
glBindVertexArray(0);
glDeleteVertexArrays(1, &vao);
return true;
}
}
class TextureProgram : SolidFillProgram {
@property override string vertexSource() {
return q{
@ -605,10 +666,11 @@ class GLSupport {
TextureProgram _textureProgram;
SolidFillProgram _solidFillProgram;
LineProgram _lineProgram;
FontProgram _fontProgram;
@property bool valid() {
return _textureProgram && _solidFillProgram && _fontProgram;
return _textureProgram && _solidFillProgram && _fontProgram && _lineProgram;
}
bool initShaders() {
@ -618,6 +680,12 @@ class GLSupport {
if (!_solidFillProgram.compile())
return false;
}
if (_lineProgram is null) {
Log.v("Compiling line program");
_lineProgram = new LineProgram();
if (!_lineProgram.compile())
return false;
}
if (_textureProgram is null) {
Log.v("Compiling texture program");
_textureProgram = new TextureProgram();
@ -640,6 +708,10 @@ class GLSupport {
destroy(_solidFillProgram);
_solidFillProgram = null;
}
if (_lineProgram !is null) {
destroy(_lineProgram);
_lineProgram = null;
}
if (_textureProgram !is null) {
destroy(_textureProgram);
_textureProgram = null;
@ -674,6 +746,33 @@ class GLSupport {
matrix2.copyDataTo(m);
*/
}
void drawLine(Point p1, Point p2, uint color1, uint color2) {
float[2 * 4] colors;
LVGLFillColor(color1, colors.ptr + 4*0, 1);
LVGLFillColor(color2, colors.ptr + 4*1, 1);
float x0 = cast(float)(p1.x);
float y0 = cast(float)(bufferDy-p1.y);
float x1 = cast(float)(p2.x);
float y1 = cast(float)(bufferDy-p2.y);
// don't flip for framebuffer
if (currentFramebufferId) {
y0 = cast(float)(p1.y);
y1 = cast(float)(p2.y);
}
float[3 * 2] vertices = [
x0,y0,Z_2D,
x1,y1,Z_2D
];
if (_lineProgram !is null) {
//Log.d("solid fill: vertices ", vertices, " colors ", colors);
_lineProgram.execute(vertices, colors);
} else
Log.e("No program");
}
static immutable float Z_2D = -2.0f;
void drawSolidFillRect(Rect rc, uint color1, uint color2, uint color3, uint color4) {
float[6 * 4] colors;

View File

@ -1057,4 +1057,4 @@ class CanvasWidget : Widget {
}
import dlangui.widgets.metadata;
mixin(registerWidgets!(Widget, TextWidget, MultilineTextWidget, Button, ImageWidget, ImageButton, ImageTextButton, RadioButton, CheckBox, ScrollBar, HSpacer, VSpacer)());
mixin(registerWidgets!(Widget, TextWidget, MultilineTextWidget, Button, ImageWidget, ImageButton, ImageTextButton, RadioButton, CheckBox, ScrollBar, HSpacer, VSpacer, CanvasWidget)());