ここを参考に Fortran で頂点バッファオブジェクトを使ってみます。本体はほぼ移植です。F03GLを利用。(F90GLにはインプリメントされていない命令がある?)
Libs::opengl_glext_c.lib glew64.lib glut64.lib opengl32.lib glu32.lib
LibPath::C:\Fortran\OpenGL\rb\x64\debug
cpp::static lib
f90::ProjectRightClick->OrojectDependency->cpp
MODULE m_mod USE opengl_glu USE opengl_glut USE opengl_glext INTEGER :: n(10) REAL(GLfloat) :: points(3, 4) CONTAINS !----------------------------------------------------------------- SUBROUTINE keyboard(key, x, y) BIND(C) USE OpenGL_GL INTEGER (kind=GLbyte), INTENT(in), VALUE :: key INTEGER (kind=GLint ), INTENT(in), VALUE :: x, y IF( key == 27 ) stop 'esc hit' RETURN END SUBROUTINE keyboard !----------------------------------------------------------------- SUBROUTINE reshape0(w, h) BIND(C, name = 'reshape') INTEGER, VALUE, INTENT(IN) :: w, h CALL glViewport(0, 0, w, h) CALL glMatrixMode(GL_PROJECTION) CALL glLoadIdentity() CALL gluPerspective(30.0, REAL(w, 8) / REAL(h, 8), 1.0, 100.0) CALL glMatrixMode(GL_MODELVIEW) CALL glLoadIdentity() END SUBROUTINE reshape0 !----------------------------------------------------------------- SUBROUTINE display() BIND(C, name = 'display') CALL glClear( IOR(GL_COLOR_BUFFER_BIT, GL_DEPTH_BUFFER_BIT) ) CALL glLoadIdentity() CALL gluLookAt(3.0, 4.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) CALL DRAW_XYZ() CALL glEnable(GL_DEPTH_TEST) CALL glColor3d(0, 1, 0) CALL glBindBuffer(GL_ARRAY_BUFFER, n(1)) CALL glVertexPointer(3, GL_FLOAT, 0, NULL()) CALL glEnableClientState(GL_VERTEX_ARRAY) CALL glColor3d(1, 0, 1) CALL glDrawArrays(GL_POLYGON , 0 , 4) CALL glDisableClientState(GL_VERTEX_ARRAY) CALL glColor3d(1,1,1) CALL glDisable(GL_DEPTH_TEST) CALL glutSwapBuffers() RETURN END SUBROUTINE display !----------------------------------------------------------------- SUBROUTINE DRAW_XYZ() CALL glBegin(GL_LINES) CALL glColor3d(0, 1, 0) ! x CALL glVertex2d(-100, 0) CALL glVertex2d( 100, 0) CALL glColor3d(1, 0, 0) ! y CALL glVertex2d(0, -100) CALL glVertex2d(0, 100) CALL glColor3d(0, 0, 1) ! z CALL glVertex3d(0, 0, -100) CALL glVertex3d(0, 0, 100) CALL glEnd() RETURN END SUBROUTINE DRAW_XYZ !----------------------------------------------------------------- END MODULE m_mod !================================================================== PROGRAM test USE m_mod USE IFwin USE opengl_glut USE opengl_glext USE opengl_glee IMPLICIT NONE INTERFACE INTEGER FUNCTION glewinit() BIND(C, name='glewInit') END FUNCTION glewinit INTEGER FUNCTION glewIsSupported(text) BIND(C, name='glewIsSupported') CHARACTER(*) :: text END FUNCTION glewIsSupported END INTERFACE ! INTEGER :: i, iwin, bufferSize = 0 points = RESHAPE([-1.0, 1.0, 0.0, -1.0, -1.0, 0.0, 1.0, -1.0, 0.0, 1.0, 1.0, 0.0], [3, 4]) CALL glutInit() CALL glutInitDisplayMode(ior(GLUT_DOUBLE, ior(GLUT_RGB,GLUT_DEPTH))) CALL glutInitWindowSize(400, 400) iwin = glutCreateWindow('OpenGL VBO'//char(0)) ! i = glewInit() !PRINT *, i, glewIsSupported("GL_VERSION_1_4 GL_ARB_point_sprite"C) CALL glutDisplayFunc(display) CALL glutReshapeFunc(reshape0) CALL glutKeyboardFunc(keyboard) CALL glClearColor(1.0, 1.0, 1.0, 1.0) CALL glGenBuffers(1, n) !PRINT *, n, LOC(points), TRANSFER(C_LOC(points), 1), TRANSFER(C_LOC(points), INT(1, 8)) CALL glBindBuffer(GL_ARRAY_BUFFER, n(1)) CALL glBufferData(GL_ARRAY_BUFFER, 4*3*4, C_LOC(points), GL_STATIC_DRAW) !CALL glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, bufferSize ) !PRINT *, 'buffefsize', buffersize CALL glBindBuffer(GL_ARRAY_BUFFER, NULL) CALL glutMainLoop() STOP END PROGRAM test
MODULE opengl_glext USE opengl_gl USE, INTRINSIC :: iso_c_BINDing INTEGER(glenum), PARAMETER :: GL_TEXTURE_COMPARE_FAIL_VALUE_ARB = z'80bf' INTEGER(glenum), PARAMETER :: GL_DEPTH_TEXTURE_MODE = z'884b' INTEGER(glenum), PARAMETER :: GL_TEXTURE_COMPARE_MODE = z'884c' INTEGER(glenum), PARAMETER :: GL_COMPARE_R_TO_TEXTURE = z'884e' INTEGER(glenum), PARAMETER :: GL_QUERY_COUNTER_BITS = z'8864' INTEGER(glenum), PARAMETER :: GL_CURRENT_QUERY = z'8865' INTEGER(glenum), PARAMETER :: GL_QUERY_RESULT = z'8866' INTEGER(glenum), PARAMETER :: GL_QUERY_RESULT_AVAILABLE = z'8867' INTEGER(glenum), PARAMETER :: GL_ARRAY_BUFFER = z'8892' INTEGER(glenum), PARAMETER :: GL_ELEMENT_ARRAY_BUFFER = z'8893' INTEGER(glenum), PARAMETER :: GL_READ_WRITE = z'88ba' INTEGER(glenum), PARAMETER :: GL_PIXEL_PACK_BUFFER = z'88eb' INTEGER(glenum), PARAMETER :: GL_PIXEL_UNPACK_BUFFER = z'88ec' INTEGER(glenum), PARAMETER :: GL_STREAM_DRAW = z'88e0' INTEGER(glenum), PARAMETER :: GL_STREAM_READ = z'88e1' INTEGER(glenum), PARAMETER :: GL_STREAM_COPY = z'88e2' INTEGER(glenum), PARAMETER :: GL_STATIC_DRAW = z'88e4' INTEGER(glenum), PARAMETER :: GL_STATIC_READ = z'88e5' INTEGER(glenum), PARAMETER :: GL_STATIC_COPY = z'88e6' INTEGER(glenum), PARAMETER :: GL_DYNAMIC_DRAW = z'88e8' INTEGER(glenum), PARAMETER :: GL_DYNAMIC_READ = z'88e9' INTEGER(glenum), PARAMETER :: GL_DYNAMIC_COPY = z'88ea' INTEGER(glenum), PARAMETER :: GL_SAMPLES_PASSED = z'8914' INTEGER(glenum), PARAMETER :: gl_buffer_size = Z'8764' INTERFACE ! glGenBuffers etc is available only if the GL version is 1.5 or greater. ! glGenBuffers - generate buffer object names ! void glGenBuffers( GLsizei n, GLuint* buffers) SUBROUTINE glGenBuffers(n, buffers) BIND(C, name="cglewGenBuffers") USE opengl_gl INTEGER(kind=GLsizei), VALUE :: n INTEGER(GLuint), DIMENSION(n), intent(OUT) :: buffers END SUBROUTINE glGenBuffers ! glBINDBuffer - BIND a named buffer object ! void glBINDBuffer( GLenum TARGET, GLuint buffer) SUBROUTINE glBINDBuffer(TARGET, buffer) BIND(C, name="cglewBindBuffer") USE opengl_gl INTEGER(GLenum), VALUE :: TARGET INTEGER(GLuint), VALUE :: buffer END SUBROUTINE glBINDBuffer ! glBufferData - creates and initializes a buffer object's data store ! void glBufferData( GLenum TARGET, GLsizeiptr size, const GLvoid* data, GLenum usage) SUBROUTINE glBufferData(TARGET, size, data, usage) BIND(C, name="cglewBufferData") USE opengl_gl INTEGER(kind=GLenum), VALUE :: TARGET INTEGER(kind=GLsizei), VALUE :: size ! size in bytes TYPE(C_PTR), VALUE :: data ! pointer to data that will be copied into the data store INTEGER(kind=GLenum), VALUE :: usage ! the expected usage pattern of the data store END SUBROUTINE glBufferData ! glMapBuffer - map a buffer object's data store ! void * glMapBuffer( GLenum TARGET, GLenum access) FUNCTION glMapBuffer(TARGET, access) BIND(C, name="cglewMapBuffer") USE opengl_gl TYPE(C_PTR) :: glMapBuffer INTEGER(kind=GLenum), VALUE :: TARGET INTEGER(kind=GLenum), VALUE :: access END FUNCTION glMapBuffer ! INTEGER(GLboolean) FUNCTION glUnmapBuffer(TARGET) BIND(C, name="cglewUnmapBuffer") USE opengl_gl INTEGER(kind=GLenum), VALUE :: TARGET END FUNCTION glUnmapBuffer ! SUBROUTINE glGetBufferPARAMETERiv(TARGET, VALUE, data) BIND(C, name = 'cglewGetBufferParameteriv') USE opengl_gl INTEGER(kind=GLenum), VALUE :: TARGET INTEGER(kind=GLenum), VALUE :: VALUE INTEGER :: data END SUBROUTINE glGetBufferPARAMETERiv ! END INTERFACE END MODULE opengl_glext
#include <GL/glew.h> #include <GL/glut.h> #include <stdio.h> extern "C" void cglewGenBuffers(GLsizei n, GLuint* buffer) { glGenBuffers( n, buffer ); } extern "C" void cglewBindBuffer(GLenum target, GLuint buffer) { glBindBuffer( target, buffer ); } extern "C" void cglewBufferData(GLenum target, GLsizei size, const GLvoid * data, GLenum usage) { glBufferData(target, size, data, usage); } extern "C" GLvoid* cglewMapBuffer(GLenum target, GLenum access) { return glMapBuffer(target, access); } extern "C" GLboolean cglewUnmapBuffer(GLenum target) { return glUnmapBuffer(target); } extern "C" void cglewGetBufferParameteriv(GLenum target, GLenum value, GLint * data) { glGetBufferParameteriv(target, value, data); }
glUnmapBuffer, glmapbuffer は動作未確認。