1. Help with Pointers
- Posted by Icy_Viking 5 days ago
- 154 views
- Last edited 4 days ago
Hi all, I am bit confused on how to wrap this pointer. I tried using chatGPT to help, but every time it tried to help, nothing worked. So I'm trying here.
C example being ported to Eu [https://github.com/ColleagueRiley/RGFW/blob/main/examples/gears/gears.c]
//From gl.h WINGDIAPI void APIENTRY glLightiv(GLenum light,GLenum pname,const GLint *params);
--From opengl32 DLL public constant xglLightfv = define_c_proc(gl,"+glLightfv",{C_INT,C_INT,C_POINTER}) public procedure glLightfv(atom light,atom pname,object param) c_proc(xglLightfv,{light,pname,param}) --There's gotta be a better way to wrap this? end procedure --Update, chatGPT recommend this public constant xglLightfv = define_c_proc(gl, "+glLightfv", {C_INT, C_INT, C_POINTER}) public procedure glLightfv(atom light,atom pname,object param) atom p = allocate_data(sizeof(param)) c_proc(xglLightfv,{light,pname,p}) free(p) end procedure
include std/ffi.e include std/machine.e include std/math.e include rgfw.e include opengl.e public constant M_PI = 3.14159265 public constant NOP = 0 public constant EXIT = 1 public constant DRAW = 2 atom win = NULL atom view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0 atom gear1=NULL,gear2=NULL,gear3=NULL atom gangle = 0.0 atom fullscreen = GL_FALSE atom stereo = GL_FALSE atom samples = 0 atom animate = GL_TRUE atom eyesep = 5.0 atom fix_point = 40.0 atom left=NULL,right=NULL,asp=NULL procedure gear(atom inner_radius, atom outer_radius, atom width, atom teeth, atom tooth_depth) atom i, r0, r1, r2, angle, da, u, v, len r0 = inner_radius r1 = outer_radius - tooth_depth / 2.0 r2 = outer_radius + tooth_depth / 2.0 da = 2.0 * M_PI / teeth / 4.0 glShadeModel(GL_FLAT) glNormal3f(0.0, 0.0, 1.0) -- Draw front face glBegin(GL_QUAD_STRIP) for j = 0 to teeth - 1 do angle = j * 2.0 * M_PI / teeth glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5) glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5) glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5) glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5) end for glEnd() -- Draw front sides of teeth glBegin(GL_QUADS) for j = 0 to teeth - 1 do angle = j * 2.0 * M_PI / teeth glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5) glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5) glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), width * 0.5) glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5) end for glEnd() glNormal3f(0.0, 0.0, -1.0) -- Draw back face glBegin(GL_QUAD_STRIP) for j = 0 to teeth - 1 do angle = j * 2.0 * M_PI / teeth glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5) glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5) glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5) glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5) end for glEnd() -- Draw back sides of teeth glBegin(GL_QUADS) for j = 0 to teeth - 1 do angle = j * 2.0 * M_PI / teeth glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), -width * 0.5) glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da), -width * 0.5) glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5) glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5) end for glEnd() -- Draw outward faces of teeth glBegin(GL_QUAD_STRIP) for j = 0 to teeth - 1 do angle = j * 2.0 * M_PI / teeth glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5) glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5) u = r2 * cos(angle + da) - r1 * cos(angle) v = r2 * sin(angle + da) - r1 * sin(angle) len = sqrt(u * u + v * v) u /= len v /= len glNormal3f(v, -u, 0.0) glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5) glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5) end for glEnd() -- Draw inside radius cylinder glBegin(GL_QUAD_STRIP) for j = 0 to teeth - 1 do angle = j * 2.0 * M_PI / teeth glNormal3f(-cos(angle), -sin(angle), 0.0) glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5) glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5) end for glEnd() end procedure procedure draw() glClear(or_all({GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT})) glPushMatrix() glRotatef(view_rotx,1.0,0.0,0.0) glRotatef(view_roty,0.0,1.0,0.0) glRotatef(view_rotz,0.0,0.0,1.0) glPushMatrix() glTranslatef(-30.0,-2.0,0.0) glRotatef(gangle,0.0,0.0,1.0) glCallList(gear1) glPopMatrix() glPushMatrix() glTranslatef(3.1,-2.0,0.0) glRotatef(-2.0 * gangle - 9.0,0.0,0.0,1.0) glCallList(gear2) glPopMatrix() glPushMatrix() glTranslatef(-3.1,4.2,0.0) glRotatef(-2.0 * gangle - 25.0,0.0,0.0,1.0) glCallList(gear3) glPopMatrix() glPopMatrix() end procedure procedure draw_gears() if stereo then glDrawBuffer(GL_BACK_LEFT) glMatrixMode(GL_PROJECTION) glLoadIdentity() glFrustum(left,right,-asp,asp,5.0,60.0) glMatrixMode(GL_MODELVIEW) glPushMatrix() glTranslated(+0.5 * eyesep,0.0,0.0) draw() glPopMatrix() glDrawBuffer(GL_BACK_RIGHT) glMatrixMode(GL_PROJECTION) glLoadIdentity() glFrustum(-right,-left,-asp,asp,5.0,60.0) glMatrixMode(GL_MODELVIEW) glPushMatrix() glTranslated(-0.5 * eyesep,0.0,0.0) draw() glPopMatrix() else draw() end if end procedure procedure draw_frame() atom frames = 0 atom rot0 = -1.0, rate0 = -1.0 atom dt, t = time() if rot0 < 0.0 then rot0 = t dt = t - rot0 rot0 = t end if if animate then gangle += 70.0 * dt if gangle > 3600.0 then gangle -= 3600.0 end if end if draw_gears() RGFW_window_swapBuffers(win) frames += 1 if rate0 < 0.0 then rate0 = t if t - rate0 >= 5.0 then atom secs = t - rate0 atom fps = frames / secs printf(1,"%d frames",{frames}) rate0 = t frames = 0 end if end if end procedure procedure reshape(atom width,atom height) glViewport(0,0,width,height) if stereo then atom w asp = height / width w = fix_point * (1.0 / 5.0) left = -5.0 * ((w - 0.5 * eyesep) / fix_point) right = 5.0 * ((w + 0.5 * eyesep) / fix_point) else atom h = height / width glMatrixMode(GL_PROJECTION) glLoadIdentity() glFrustum(-1.0,1.0,-h,h,5.0,60.0) end if glMatrixMode(GL_MODELVIEW) glLoadIdentity() glTranslatef(0.0,0.0,-40.0) end procedure procedure init() sequence pos = {5.0,5.0,10.0,0.0} sequence red = {0.8,0.1,0.0,1.0} sequence green = {0.0,0.8,0.2,1.0} sequence blue = {0.2,0.2,1.0,1.0} glLightfv(GL_LIGHT0,GL_POSITION,pos[4]) --causes program to crash glEnable(GL_CULL_FACE) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glEnable(GL_DEPTH_TEST) gear1 = glGenLists(1) glNewList(gear1,GL_COMPILE) glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,{red[1],red[2],red[3],red[4]}) --same as above gear(1.0,4.0,1.0,20,0.7) glEndList() gear2 = glGenLists(1) glNewList(gear2,GL_COMPILE) glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,{green[1],green[2],green[3],green[4]}) --same as above gear(0.5,2.0,2.0,10,0.7) glEndList() gear3 = glGenLists(1) glNewList(gear3,GL_COMPILE) glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,{blue[1],blue[2],blue[3],blue[4]}) --same as above gear(1.3,2.0,0.5,10,0.7) glEndList() glEnable(GL_NORMALIZE) end procedure atom winWidth = 300, winHeight = 300 atom x = 0, y = 0 atom flag = 0 --if fullscreen then -- flag = RGFW_winodwFullscreen --end if win = RGFW_createWindow("gear",{x,y,winWidth,winHeight},RGFW_windowCenter) RGFW_window_makeCurrent(win) init() while not RGFW_window_shouldClose(win) do while RGFW_window_checkEvent(win) do if win = RGFW_quit then exit end if if RGFW_isPressed(win,RGFW_escape) then exit end if if RGFW_isPressed(win,RGFW_left) then view_roty += 5.0 end if end while draw_frame() end while glDeleteLists(gear1,1) glDeleteLists(gear2,1) glDeleteLists(gear3,1) RGFW_window_close(win)
2. Re: Help with Pointers
- Posted by petelomax 4 days ago
- 131 views
I take it you haven't looked at the glLight() routine that comes with Phix in demo\pGUI\opengl.e, so here are the relevant bits:
-- (not that I can guarantee this works in all cases...) xglLightf = define_c_proc(opengl32,"glLightf",{C_UINT,C_UINT,C_FLOAT}), xglLightfv = define_c_proc(opengl32,"glLightfv",{C_INT,C_INT,C_PTR}), procedure gl_pokef32(atom dest, sequence data) for i=1 to length(data) do poke(dest,atom_to_float32(data[i])) dest += 4 end for end procedure constant gl_vector_buffer = allocate(128) global procedure glLight(integer light, integer pname, object params) if atom(params) then c_proc(xglLightf,{light,pname,params}) else gl_pokef32(gl_vector_buffer,params) c_proc(xglLightfv,{light,pname,gl_vector_buffer}) end if end procedure
ChatGPT was allocating a buffer but leaving it with whatever garbage was in it.
You should probably also be asking ChatGPT to make things OpenGL ES 2.0 compatible,
since that at least stands a slim chance of running in a web browser or Android/iOS,
whereas 1.1 aka the fixed function pipeline quite definitely does not.
Then again, I thought about converting this very program to ES 2.0 manually several
years ago, but shelved it, and am quietly patting myself on the back now that I've
seen what ChatGPT has output, so that may well be a step too far..
3. Re: Help with Pointers
- Posted by ghaberek (admin) 4 days ago
- 104 views
C example being ported to Eu [https://github.com/ColleagueRiley/RGFW/blob/main/examples/gears/gears.c]
//From gl.h WINGDIAPI void APIENTRY glLightiv(GLenum light,GLenum pname,const GLint *params);
OpenGL functions follow a predictable nomenclature:
Function type suffixes are typically defined in the following pattern:
FunctionName{1234}{b s i i64 f d ub us ui ui64}{v}
The first set of braces is an optional number from 1 to 4. This defines the number of parameters of those types that the function takes.
The second set of braces defines the types themselves, as defined by the table to the left.
If the optional v suffix is provided, this means the function takes a "vector": a pointer to an array of some number of values.
The function glLightiv takes a vector (a pointer to an array) of GLint values. Sometimes, however, the number of values in the array varies based on some parameter.
In the case of glLight, you have to consult the options for the pname parameter to determine how many values you actually need to provide in the params array.
The ten light parameters are as follows:
- GL_AMBIENT - four integer or floating-point values
- GL_DIFFUSE - four integer or floating-point values
- GL_SPECULAR - four integer or floating-point values
- GL_POSITION - four integer or floating-point values
- GL_SPOT_DIRECTION - three integer or floating-point values
- GL_SPOT_EXPONENT - a single integer or floating-point value
- GL_SPOT_CUTOFF - a single integer or floating-point value
- GL_CONSTANT_ATTENUATION - a single integer or floating-point value
- GL_LINEAR_ATTENUATION - a single integer or floating-point value
- GL_QUADRATIC_ATTENUATION - a single integer or floating-point value
I would say that technically all you have to do is feed it any number of integers and assume they line up.
public procedure glLightiv(integer light, integer pname, sequence params) atom pparams = allocate_data(sizeof(C_INT) * length(params)) poke4(pparams, params) c_proc(_glLightiv, {light,pname,pparams}) free(pparams) end procedure
Given the max seems to be four values, you could just "round up" by padding the remaining values first.
public procedure glLightiv(integer light, integer pname, sequence params) if length(params) < 4 then params &= repeat(0, 4-length(params)) end if atom pparams = allocate_data(sizeof(C_INT) * length(params)) poke4(pparams, params) c_proc(_glLightiv, {light,pname,pparams}) free(pparams) end procedure
But to be safe, you should check the length of params corresponds to the provided pname value.
public procedure glLightiv(integer light, integer pname, sequence params) integer required = 0 switch pname do case GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION then required = 4 case GL_SPOT_DIRECTION then required = 3 case GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION then required = 1 end switch if required != length(params) then error:crash("expected %d params but received %d", {required,length(params)}) end if atom pparams = allocate_data(sizeof(C_INT) * length(params)) poke4(pparams, params) c_proc(_glLightiv, {light,pname,pparams}) free(pparams) end procedure
-Greg
4. Re: Help with Pointers
- Posted by petelomax 4 days ago
- 94 views
From the perspective of Euphoria/Phix, glLightfv/poke(atom_to_float32()) should handle all the cases needed, or I
suppose you could check whether params is all int and if so use glLightiv/poke4. Just don't mix f/poke4 or i/to_f32.
I am in no position to say whether iv might produce grubbier/grainier results than fv, or vice-versa.
Should the results always be indistinguishable, then iv would be a (likely-non-measurable) smidge faster.
Otherwise, of course, totally agree with everything Greg said, except the potential iv/fv mixup (as existed in the OP).
5. Re: Help with Pointers
- Posted by Icy_Viking 3 days ago
- 89 views
Thanks Greg. You've been a great help as always.
Here is the openGL wrapper I've been working on. Its mainly complete. Might be a little rough around the edges, but works for the most part.
I'll post my RGFW wrapper a bit later.
You'll need to use the 64-bit version of Euphoria for this to work.
6. Re: Help with Pointers
- Posted by petelomax 3 days ago
- 63 views
Thanks Greg. You've been a great help as always.
Mr Invisible here deserves a mention too...
7. Re: Help with Pointers
- Posted by ghaberek (admin) 3 days ago
- 45 views
From the perspective of Euphoria/Phix, glLightfv/poke(atom_to_float32()) should handle all the cases needed, or I
suppose you could check whether params is all int and if so use glLightiv/poke4. Just don't mix f/poke4 or i/to_f32.
I am in no position to say whether iv might produce grubbier/grainier results than fv, or vice-versa.
Should the results always be indistinguishable, then iv would be a (likely-non-measurable) smidge faster.
Otherwise, of course, totally agree with everything Greg said, except the potential iv/fv mixup (as existed in the OP).
On a side note, I find myself having to write peek/poke float routines over and over again, so I'm planning to add them directly to std/machine.e. Not sure why we didn't add them with peek_pointer(), etc.
Mr Invisible here deserves a mention too...
I appreciate your contributions, Pete!
-Greg
8. Re: Help with Pointers
- Posted by Icy_Viking 3 days ago
- 41 views
From the perspective of Euphoria/Phix, glLightfv/poke(atom_to_float32()) should handle all the cases needed, or I
suppose you could check whether params is all int and if so use glLightiv/poke4. Just don't mix f/poke4 or i/to_f32.
I am in no position to say whether iv might produce grubbier/grainier results than fv, or vice-versa.
Should the results always be indistinguishable, then iv would be a (likely-non-measurable) smidge faster.
Otherwise, of course, totally agree with everything Greg said, except the potential iv/fv mixup (as existed in the OP).
On a side note, I find myself having to write peek/poke float routines over and over again, so I'm planning to add them directly to std/machine.e. Not sure why we didn't add them with peek_pointer(), etc.
Mr Invisible here deserves a mention too...
I appreciate your contributions, Pete!
-Greg
Thanks Pete, you've been helpful too. That's great to hear Greg. Having those functions will be handy!