mirror of
https://github.com/danbulant/node-x11
synced 2026-06-24 01:01:51 +00:00
glx extension and glxRender-encoded commands
This commit is contained in:
parent
c92cb57bb2
commit
10fef2fe9a
3 changed files with 379 additions and 1 deletions
|
|
@ -9,3 +9,198 @@
|
||||||
http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)
|
http://www.opengl.org/wiki/Tutorial:_OpenGL_3.0_Context_Creation_(GLX)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
var x11 = require('..');
|
||||||
|
// TODO: move to templates
|
||||||
|
exports.requireExt = function(display, callback)
|
||||||
|
{
|
||||||
|
var X = display.client;
|
||||||
|
X.QueryExtension('GLX', function(err, ext) {
|
||||||
|
var constants = require('./glxconstants');
|
||||||
|
for (var i in constants)
|
||||||
|
ext[i] = constants[i];
|
||||||
|
|
||||||
|
if (!ext.present)
|
||||||
|
return callback(new Error('extension not available'));
|
||||||
|
|
||||||
|
ext.QueryVersion = function(clientMaj, clientMin, callback)
|
||||||
|
{
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSLL', [ext.majorOpcode, 7, 3, clientMaj, clientMin]);
|
||||||
|
X.replies[X.seq_num] = [
|
||||||
|
function(buf, opt) {
|
||||||
|
var res = buf.unpack('LL');
|
||||||
|
return res;
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
];
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.QueryServerString = function(screen, name, callback) {
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSLL', [ext.majorOpcode, 19, 3, screen, name]);
|
||||||
|
X.replies[X.seq_num] = [
|
||||||
|
function(buf, opt) {
|
||||||
|
var len = buf.unpack('xxxxL')[0];
|
||||||
|
return buf.toString().substring(24, 24+len*4);
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
];
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.QueryExtensionsString = function(screen, callback) {
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSL', [ext.majorOpcode, 18, 2, screen]);
|
||||||
|
X.replies[X.seq_num] = [
|
||||||
|
function(buf, opt) {
|
||||||
|
var len = buf.unpack('xxxxL')[0];
|
||||||
|
return buf.toString().substring(24, 24+len*4);
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
];
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// see __glXInitializeVisualConfigFromTags in mesa/src/glx/glxext.c
|
||||||
|
//
|
||||||
|
ext.GetVisualConfigs = function(screen, callback) {
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSL', [ext.majorOpcode, 14, 2, screen]);
|
||||||
|
X.replies[X.seq_num] = [
|
||||||
|
function(buf, opt) {
|
||||||
|
var res = buf.unpack('LL');
|
||||||
|
var numConfigs = res[0];
|
||||||
|
var numProps = res[1];
|
||||||
|
var configs = new Array(numConfigs);
|
||||||
|
var i,j;
|
||||||
|
for (i=0; i < numConfigs; ++i) {
|
||||||
|
var props = {}; //new Array(numProps);
|
||||||
|
var names = 'visualID visualType rgbMode redBits greenBits blueBits alphaBits accumRedBits accumGreen accumBlueBits accumAlphaBits doubleBufferMode stereoMode rgbBits depthBits stencilBits numAuxBuffers level'.split(' ');
|
||||||
|
for (var j=0; j < 18 && j < numProps; ++j) {
|
||||||
|
props[names[j]] = buf.unpack('L', 24+(i*numProps +j)*4)[0];
|
||||||
|
}
|
||||||
|
// read tag + property
|
||||||
|
configs[i] = props;
|
||||||
|
}
|
||||||
|
|
||||||
|
return configs;
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
];
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.GetFBConfigs = function(screen, callback) {
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSL', [ext.majorOpcode, 21, 2, screen]);
|
||||||
|
X.replies[X.seq_num] = [
|
||||||
|
function(buf, opt) {
|
||||||
|
var res = buf.unpack('LL');
|
||||||
|
var numConfigs = res[0];
|
||||||
|
var numProps = res[1];
|
||||||
|
var configs = new Array(numConfigs);
|
||||||
|
var i,j;
|
||||||
|
for (i=0; i < numConfigs; ++i) {
|
||||||
|
var props = new Array(numProps);
|
||||||
|
for (var j=0; j < numProps; ++j) {
|
||||||
|
props[j] = buf.unpack('LL', 24+(i*numProps +j)*8);
|
||||||
|
}
|
||||||
|
configs[i] = props;
|
||||||
|
}
|
||||||
|
return configs;
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
];
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.CreateContext = function(ctx, visual, screen, shareListCtx, isDirect)
|
||||||
|
{
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSLLLLCxxx', [ext.majorOpcode, 3, 6, ctx, visual, screen, shareListCtx, isDirect]);
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.SwapBuffers = function(ctx, drawable)
|
||||||
|
{
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSLL', [ext.majorOpcode, 11, 3, ctx, drawable]);
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.NewList = function(ctx, list, mode)
|
||||||
|
{
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSLLL', [ext.majorOpcode, 101, 4, ctx, list, mode]);
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.EndList = function(ctx)
|
||||||
|
{
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSL', [ext.majorOpcode, 102, 2, ctx]);
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.GenLists = function(ctx, count, callback)
|
||||||
|
{
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSLL', [ext.majorOpcode, 104, 3, ctx, count]);
|
||||||
|
X.replies[X.seq_num] = [
|
||||||
|
function(buf, opt) {
|
||||||
|
return buf.unpack('L')[0];
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
];
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.MakeCurrent = function(drawable, ctx, oldctx, callback)
|
||||||
|
{
|
||||||
|
X.seq_num++;
|
||||||
|
X.pack_stream.pack('CCSLLL', [ext.majorOpcode, 5, 4, drawable, ctx, oldctx]);
|
||||||
|
X.replies[X.seq_num] = [
|
||||||
|
function(buf, opt) {
|
||||||
|
return buf.unpack('L')[0];
|
||||||
|
},
|
||||||
|
callback
|
||||||
|
];
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
// glClearColor ( 0, 0.5, 1, 1 ); glClear ( GL_COLOR_BUFFER_BIT );
|
||||||
|
// xtrace: render commands={command=ClearColor(0x0082) unknown=0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x3f;},{command=Clear(0x007f) mask=0x00004000 };
|
||||||
|
// (context 0300 4004) (1400 8200 0000 803f 0000 003f 0000 0000 0000 803f) (0800 7f00 0040 0000)
|
||||||
|
|
||||||
|
ext.Render = function(ctx, data) {
|
||||||
|
X.seq_num++;
|
||||||
|
var length = 0;
|
||||||
|
//console.log(data);
|
||||||
|
if (Buffer.isBuffer(data))
|
||||||
|
length = 2+data.length/4;
|
||||||
|
else if (Array.isArray(data)) {
|
||||||
|
length = 2;
|
||||||
|
for (var i=0; i < data.length; ++i)
|
||||||
|
length += data[i].length/4;
|
||||||
|
}
|
||||||
|
//console.log('LENGTH: ', length);
|
||||||
|
X.pack_stream.pack('CCSL', [ext.majorOpcode, 1, length, ctx]);
|
||||||
|
if (Buffer.isBuffer(data))
|
||||||
|
X.pack_stream.write_queue.push(data);
|
||||||
|
else if (Array.isArray(data))
|
||||||
|
for (var i=0; i < data.length; ++i)
|
||||||
|
X.pack_stream.write_queue.push(data[i]);
|
||||||
|
else
|
||||||
|
throw new Error('invalid data, expected buffer or buffers array', data);
|
||||||
|
X.pack_stream.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ext.renderPipeline = function() {
|
||||||
|
return require('./glxrender')(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(ext);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
51
lib/x11/ext/glxconstants.js
Normal file
51
lib/x11/ext/glxconstants.js
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
module.exports = {
|
||||||
|
//
|
||||||
|
LIGHT0: 0x4000,
|
||||||
|
|
||||||
|
// glEnable
|
||||||
|
POSITION: 0x1203,
|
||||||
|
CULL_FACE: 0x0B44,
|
||||||
|
LIGHTING: 0x0B50,
|
||||||
|
DEPTH_TEST: 0x0B71,
|
||||||
|
NORMALIZE: 0x0BA1,
|
||||||
|
|
||||||
|
// glShadeModel
|
||||||
|
FLAT: 0x1D00,
|
||||||
|
SMOOTH: 0x1D01,
|
||||||
|
|
||||||
|
//
|
||||||
|
TRUE: 1,
|
||||||
|
FALSE: 0,
|
||||||
|
|
||||||
|
// glBegin
|
||||||
|
POINTS: 0x0000,
|
||||||
|
LINES: 0x0001,
|
||||||
|
LINE_LOOP: 0x0002,
|
||||||
|
LINE_STRIP: 0x0003,
|
||||||
|
TRIANGLES: 0x0004,
|
||||||
|
TRIANGLES_STRIP: 0x0005,
|
||||||
|
TRIANGLES_FAN: 0x0006,
|
||||||
|
QUADS: 0x0007,
|
||||||
|
QUAD_STRIP: 0x0008,
|
||||||
|
POLYGON: 0x0009,
|
||||||
|
|
||||||
|
// glClear
|
||||||
|
COLOR_BUFFER_BIT: 0x00004000,
|
||||||
|
DEPTH_BUFFER_BIT: 0x00000100,
|
||||||
|
|
||||||
|
// glMatrixMode
|
||||||
|
PROJECTION: 0x1701,
|
||||||
|
MODELVIEW: 0x1700,
|
||||||
|
|
||||||
|
// glMaterial
|
||||||
|
FRONT: 0x0404,
|
||||||
|
AMBIENT_AND_DIFFUSE: 0x1602,
|
||||||
|
|
||||||
|
COMPILE: 0x1300,
|
||||||
|
|
||||||
|
// glGetString
|
||||||
|
RENDERER: 0x1F01,
|
||||||
|
VERSION: 0x1F02,
|
||||||
|
VENDOR: 0x1F00,
|
||||||
|
EXTENSIONS: 0x1F03
|
||||||
|
}
|
||||||
132
lib/x11/ext/glxrender.js
Normal file
132
lib/x11/ext/glxrender.js
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
// see http://cgit.freedesktop.org/mesa/mesa/tree/src/mapi/glapi/gen/gl_API.xml
|
||||||
|
|
||||||
|
module.exports = function(GLX) {
|
||||||
|
buffers = [];
|
||||||
|
|
||||||
|
function commandBuffer(opcode, len) {
|
||||||
|
var res = Buffer(len);
|
||||||
|
res.writeUInt16LE(len, 0);
|
||||||
|
res.writeUInt16LE(opcode, 2);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
function serialize0(opcode) {
|
||||||
|
buffers.push(commandBuffer(opcode, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
function serialize3fv(opcode, c1, c2, c3) {
|
||||||
|
var res = commandBuffer(opcode, 16);
|
||||||
|
res.writeFloatLE(c1, 4);
|
||||||
|
res.writeFloatLE(c2, 8);
|
||||||
|
res.writeFloatLE(c3, 12);
|
||||||
|
buffers.push(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function serialize4fv(opcode, c1, c2, c3, c4) {
|
||||||
|
var res = commandBuffer(opcode, 20);
|
||||||
|
res.writeFloatLE(c1, 4);
|
||||||
|
res.writeFloatLE(c2, 8);
|
||||||
|
res.writeFloatLE(c3, 12);
|
||||||
|
res.writeFloatLE(c4, 16);
|
||||||
|
buffers.push(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function serialize4i(opcode, c1, c2, c3, c4) {
|
||||||
|
var res = commandBuffer(opcode, 20);
|
||||||
|
res.writeInt32LE(c1, 4);
|
||||||
|
res.writeInt32LE(c2, 8);
|
||||||
|
res.writeInt32LE(c3, 12);
|
||||||
|
res.writeInt32LE(c4, 16);
|
||||||
|
buffers.push(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
function serialize6d(opcode, d1, d2, d3, d4, d5, d6)
|
||||||
|
{
|
||||||
|
var res = commandBuffer(opcode, 52);
|
||||||
|
res.writeDoubleLE(d1, 4);
|
||||||
|
res.writeDoubleLE(d2, 12);
|
||||||
|
res.writeDoubleLE(d3, 20);
|
||||||
|
res.writeDoubleLE(d4, 28);
|
||||||
|
res.writeDoubleLE(d5, 36);
|
||||||
|
res.writeDoubleLE(d6, 44);
|
||||||
|
buffers.push(res);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function serialize1i(opcode, value) {
|
||||||
|
var res = commandBuffer(opcode, 8);
|
||||||
|
res.writeUInt32LE(value, 4);
|
||||||
|
buffers.push(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
render: function(ctx) {
|
||||||
|
GLX.Render(ctx, buffers);
|
||||||
|
buffers = [];
|
||||||
|
},
|
||||||
|
Begin: function(what) {
|
||||||
|
serialize1i(4, what);
|
||||||
|
},
|
||||||
|
End: function() {
|
||||||
|
serialize0(23);
|
||||||
|
},
|
||||||
|
Ortho: function(left, right, bottom, top, znear, zfar) {
|
||||||
|
serialize6d(182, left, right, bottom, top, znear, zfar);
|
||||||
|
},
|
||||||
|
Frustum: function(left, right, bottom, top, znear, zfar) {
|
||||||
|
serialize6d(182, left, right, bottom, top, znear, zfar);
|
||||||
|
},
|
||||||
|
PopMatrix: function() {
|
||||||
|
serialize0(183);
|
||||||
|
},
|
||||||
|
PushMatrix: function() {
|
||||||
|
serialize0(184);
|
||||||
|
},
|
||||||
|
LoadIdentity: function() {
|
||||||
|
serialize0(176);
|
||||||
|
},
|
||||||
|
Rotatef: function(a, x, y, z) {
|
||||||
|
serialize4fv(186, a, x, y, z);
|
||||||
|
},
|
||||||
|
CallList: function(list) {
|
||||||
|
serialize1i(1, list);
|
||||||
|
},
|
||||||
|
Viewport: function(x, y, w, h) {
|
||||||
|
serialize4i(191, x, y, w, h); // TODO: x,y - signed, w,h - unsigned (currently all 4 unsigned)
|
||||||
|
},
|
||||||
|
Vertex3f: function(x, y, z) {
|
||||||
|
serialize3fv(70, x, y, z);
|
||||||
|
},
|
||||||
|
Color3f: function(r, g, b) {
|
||||||
|
serialize3fv(8, r, g, b);
|
||||||
|
},
|
||||||
|
Color4f: function(r, g, b, a) {
|
||||||
|
serialize4fv(16, r, g, b, a);
|
||||||
|
},
|
||||||
|
Scalef: function(x, y, z) {
|
||||||
|
serialize3fv(188, x, y, z);
|
||||||
|
},
|
||||||
|
Translatef: function(x, y, z) {
|
||||||
|
serialize3fv(190, x, y, z);
|
||||||
|
},
|
||||||
|
ClearColor: function(r, g, b, a) {
|
||||||
|
serialize4fv(0x82, r, g, b, a);
|
||||||
|
},
|
||||||
|
MatrixMode: function(mode) {
|
||||||
|
serialize1i(179, mode);
|
||||||
|
},
|
||||||
|
Enable: function(value) {
|
||||||
|
serialize1i(139, value);
|
||||||
|
},
|
||||||
|
Lightfv: function(light, name, p1, p2, p3, p4) {
|
||||||
|
seralize2i4f(87, light, name, p1, p2, p3, p4);
|
||||||
|
},
|
||||||
|
Clear: function(mask) {
|
||||||
|
serialize1i(0x7f, mask);
|
||||||
|
},
|
||||||
|
ShadeModel: function(model) {
|
||||||
|
serialize1i(104, model);
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue