/* * Copyright (c) 2024 Ross Cunniff * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ using namespace oadl; #include "libglut.oah" #include "libgl2.oah" var vtxArray = { -.5,-.5,0., .5,-.5,0., .5, .5,0., -.5,-.5,0., .5, .5,0., -.5, .5,0. }; var colArray = { 1.,0.,0., 0.,1.,0., 0.,0.,1., 1.,0.,0., 0.,0.,1., 1.,0.,1. }; var vtxProg = { "#version 120\n", "attribute vec3 pos, col;", "void main(void) {", "gl_FrontColor = vec4(col.x, col.y, col.z, 1.0);", "gl_Position = vec4(pos.x, pos.y, pos.z, 1.0);", "}" }; var fragProg = { "#version 120\n", "void main(void) {", "gl_FragColor = gl_Color;", "}" }; var vtxShader, fragShader, OGL_prog; proc dumpShaderLog(shader) { var i, len, str; len = new PackInt(1); gl2::GetShaderiv(shader, gl2::INFO_LOG_LENGTH, len); len = len[0]; str = new String(len+1); gl2::GetShaderInfoLog(shader, len, nil, str); for (i = 0; i <= len; i++) { if (str[i] == '\0') { str = str[0:i-1]; break; } } "Shader log:\n", str, "\n"; } proc dumpProgramLog(prog) { var i, len, str; len = new PackInt(1); gl2::GetProgramiv(prog, gl2::INFO_LOG_LENGTH, len); len = len[0]; str = new String(len+1); gl2::GetProgramInfoLog(prog, len, nil, str); for (i = 0; i <= len; i++) { if (str[i] == '\0') { str = str[0:i-1]; break; } } "Program log:\n", str, "\n"; } proc initVars() { var lens, i, n; vtxArray = oadl::perm(vtxArray.pack()); colArray = oadl::perm(colArray.pack()); // Generate the shaders vtxShader = gl2::CreateShader(gl2::VERTEX_SHADER); fragShader = gl2::CreateShader(gl2::FRAGMENT_SHADER); // Compile the vertex shader n = vtxProg.length(); lens = new PackInt(n); for (i = 0; i < n; i++) lens[i] = vtxProg[i].length(); gl2::ShaderSource(vtxShader, n, vtxProg, lens); gl2::CompileShader(vtxShader); dumpShaderLog(vtxShader); // Compile the fragment shader n = fragProg.length(); lens = new PackInt(n); for (i = 0; i < n; i++) lens[i] = fragProg[i].length(); gl2::ShaderSource(fragShader, n, fragProg, lens); gl2::CompileShader(fragShader); dumpShaderLog(fragShader); OGL_prog = gl2::CreateProgram(); gl2::AttachShader(OGL_prog, vtxShader); gl2::AttachShader(OGL_prog, fragShader); gl2::BindAttribLocation(OGL_prog, 0, "pos\0"); gl2::BindAttribLocation(OGL_prog, 1, "col\0"); gl2::LinkProgram(OGL_prog); dumpProgramLog(OGL_prog); } proc winshape(w, h) { var x = 0, y = 0; if (w < h) { y = (h - w) / 2; h = w; } else { x = (w - h) / 2; w = h; } gl2::Viewport(x, y, w, h); } proc display() { gl2::ClearColor(0.0,0.0,0.0,1.0); gl2::Clear(gl2::COLOR_BUFFER_BIT|gl2::DEPTH_BUFFER_BIT); gl2::UseProgram(OGL_prog); gl2::VertexAttribPointer(0, 3, gl2::FLOAT, gl2::FALSE, 0, vtxArray); gl2::VertexAttribPointer(1, 3, gl2::FLOAT, gl2::FALSE, 0, colArray); gl2::EnableVertexAttribArray(0); gl2::EnableVertexAttribArray(1); gl2::DrawArrays(gl2::TRIANGLES, 0, 6); glut::SwapBuffers(); } proc main(args) { glut::Init(args); glut::InitDisplayMode(glut::RGBA | glut::DOUBLE | glut::DEPTH); if( !glut::Get(glut::DISPLAY_MODE_POSSIBLE) ) { "Error setting display mode\n"; halt(); } glut::CreateWindow("Demo\0"); glut::DisplayFunc(display); glut::ReshapeFunc(winshape); initVars(); glut::MainLoop(); }