Baez's polynomials and OpenGL graphics

  • #1
sbrothy
Gold Member
556
429
TL;DR Summary
I was thinking about writing a C++ insights article using the polynomials Baez currently seems fascinated about on his blog. The math isn't really a problem using the GNU Scientific Package. The graphics is doable in OpenGL although I'd prefer Windows DirectX, but I'd prefer not dragging various linux build systems into the picture.
I was thinking about writing a C++ insights article using the polynomials Baez currently seems fascinated about on his blog. The math isn't really a problem using the GNU Scientific Package. The graphics is doable in OpenGL although I'd prefer Windows DirectX, but I'd prefer not dragging various linux build systems into the picture.

Then, to KISS (riiight) I'd only use SPDLOG, GNU Scientific Library and OpenGL. Using no build systems but raw commands to g++ along the lines of:

Code:
#ifndef    __PCH_H
#define    __PCH_H

// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//    Precompiled header. Libraries and generically useful inline functions shared across programs and modules.
/*

g++ -H -v -std=c++17 -Wall -Wextra -fmax-errors=3 -O3 -fdiagnostics-color=always -x c++-header -c pch.h -o pch.h.gch

*/
//    Include on GCC command line using the "-include" option as in "-include pch.h".
//
//        sbrothy@gmail.com    2022
//
// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


#define CPPVER17    201703L

#if !defined(__GNUC__) || !defined(__cplusplus) || (__cplusplus < CPPVER17)
#error Target platform is Linux,  C++ 17 or higher.
#endif


// c++
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <stdexcept>

// boost
//#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <boost/tokenizer.hpp>
#include <boost/regex.hpp>

// GNU scientific library
#include <gsl/gsl_poly.h>

// opengl
#include <GL/glut.h>

//#include <boost/format.hpp>
//#include <boost/foreach.hpp>
//#include <boost/algorithm/string.hpp>
//#include <boost/token_functions.hpp>
//#ifndef BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
//#define BOOST_PROPERTY_TREE_XML_PARSER_HPP_INCLUDED
//#include <boost/property_tree/ptree.hpp>
//#include <boost/property_tree/xml_parser.hpp>
//#endif
//#include <boost/property_tree/json_parser.hpp>
//#include <boost/thread/mutex.hpp>

//#include <boost/asio.hpp>
//#include <boost/asio/error.hpp>
//#include <boost/asio/ssl.hpp>
//#include <boost/beast/core.hpp>
//#include <boost/beast/http.hpp>
//#include <boost/asio/strand.hpp>
//#include <boost/beast/http/status.hpp>
//#include <boost/beast/version.hpp>
//#include <boost/algorithm/string/split.hpp>




// spdlog
#define MY_SPDLOG
#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG
#define SPDLOG_FUNCTION _PRETTY_FUNCTION_
#include <spdlog/spdlog.h>
#include <spdlog/async.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/sinks/rotating_file_sink.h>


namespace pch {
                                                       
    /*/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // hack to determine exception type
    auto const ex_type = [] -> const char * {
        return abi::__cxa_demangle(abi::__cxa_current_exception_type()->name(), 0, 0, new int);
    }
    */
   

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //
    inline void slurp_file(const std::string fname, std::string &data)
    {
        std::ifstream ifs;
        ifs.exceptions (std::ifstream::badbit | std::ifstream::eofbit | std::ifstream::failbit );

        ifs.open(fname);
        std::ostringstream oss;
        oss << ifs.rdbuf();
        ifs.close();
       
        data = oss.str();
    }


    #ifdef SPDLOG_H

        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //
        inline std::shared_ptr<spdlog::async_logger> init_spdlog(
            std::string logger_name,
            std::string logfile,
            bool log_to_console = false,
            spdlog::level::level_enum log_level = spdlog::level::trace,
            spdlog::level::level_enum flush_level = spdlog::level::trace,
            std::string pattern = "[%n][%@][%P][%t][%a:%d:%m:%Y][%H:%M:%S:%e:%f][%^%l%$]: %v"
            )
        {
            spdlog::init_thread_pool(8192, 1);
           
            std::vector<spdlog::sink_ptr> sinks;   
            if(log_to_console) {
                sinks.push_back( std::make_shared<spdlog::sinks::stdout_color_sink_mt>() );
            }
            sinks.push_back( std::make_shared<spdlog::sinks::rotating_file_sink_mt>(logfile, 1024 * 1024 * 5, 3, true));

            auto log = std::make_shared<spdlog::async_logger>(logger_name, sinks.begin(), sinks.end(), spdlog::thread_pool(), spdlog::async_overflow_policy::block);
            log->flush_on(flush_level);
            log->set_level(log_level);
            log->set_pattern(pattern);   
            spdlog::register_logger(log);   
            spdlog::set_default_logger(log);   

            spdlog::info("\r\n\r\n\
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n\
    SPDLOG header only logging API initialized for asynchronous use. The EOL character\r\n\
    has been removed so each call to a log function must be manually \"newlined\" as in :\r\n\r\n\
    log->trace(\"blah\\r\\n\");\r\n\r\n\
    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n\r\n");
            spdlog::info("logger id: \"{}\". Rotating logfile name: \"{}\".\r\n", logger_name, logfile);
            spdlog::trace("Trace entry.\r\n");
            spdlog::debug("Debug entry.\r\n");
            spdlog::info("Information entry.\r\n");
            spdlog::warn("Warning entry.\r\n");
            spdlog::error("Error entry.\r\n");
            spdlog::critical("Critical entry.\r\n");
            spdlog::info("Done.\r\n");
           
            return log;
        }
    #endif    // SPDLOG_H
};    //    namespace pch {


#endif    // __PCH_H

Code:
/*

g++ -H -v -std=c++17 -fdiagnostics-show-location=every-line -fdiagnostics-color=always -Wall -Wextra -fmax-errors=3 -Ofast -c -o main.o -include pch.h main.cpp
g++ -H -v -std=c++17 -fdiagnostics-show-location=every-line -fdiagnostics-color=always -Wall -Wextra -fmax-errors=3 -Ofast -o main main.o -L/usr/lib/x86_64-linux-gnu/cmake -lboost_regex -lfmt -lgsl -lglut -lGL -lGLU


*/

std::shared_ptr<spdlog::async_logger> g_log = nullptr;


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
void glExceptOnError(const std::string &func)
{
    const GLenum code = glGetError();   
    const std::string err_msg = reinterpret_cast<const char*>(gluErrorString(code));

    switch(code) {
        case GL_NO_ERROR:
            spdlog::trace("{}: {}\n", func, err_msg);
            break;

        case GL_INVALID_ENUM:
        case GL_INVALID_VALUE:
        case GL_INVALID_OPERATION:
        case GL_INVALID_FRAMEBUFFER_OPERATION:
        case GL_OUT_OF_MEMORY:
        case GL_STACK_UNDERFLOW:
        case GL_STACK_OVERFLOW:
            spdlog::error("{}: {}\n", func, err_msg);
            throw std::runtime_error(func + ": " + err_msg);
    };
}



void display()
{
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glBegin(GL_QUADS);              // Each set of 4 vertices form a quad
        glColor3f(1.0f, 0.0f, 0.0f); // Red
        glVertex2f(-0.5f, -0.5f);    // x, y
        glVertex2f( 0.5f, -0.5f);
        glVertex2f( 0.5f,  0.5f);
        glVertex2f(-0.5f,  0.5f);
    glEnd();

    glFlush();  // Render now
}


int main(int argc, char **argv)
{
    const std::string log_name = argv[0];
    const std::string log_file = "./" + log_name + ".log";
   
    g_log = pch::init_spdlog(log_name, log_file);
   
#ifndef NDEBUG
    std::ostringstream deb;
    deb << "[argc=" << argc << ']';
    for(int n = 0; n < argc; n++)
        deb << "\n[argv[" << n << "]=" << argv[n] << ']';
   
    spdlog::trace("int main({}, {})\n >>\n", argc, deb.str());
#endif
   
    glutInit(&argc, argv);
    glExceptOnError("glutInit");
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glExceptOnError("glutInitDisplayMode");
    glutCreateWindow("Baez Polynomial fun"); // Create a window with the given title
    glExceptOnError("glutCreateWindow");
    glutFullScreen();
    glExceptOnError("glutFullScreen");
    glutDisplayFunc(display); // Register display callback handler for window re-paint
    glExceptOnError("glutDisplayFunc");
    glutMainLoop();       
    glExceptOnError("glutMainLoop");

//    glClear(GL_COLOR_BUFFER_BIT);
//    glMatrixMode(GL_PROJECTION);
//    glLoadIdentity();
//    gluOrtho2D( 0.0, 500.0, 500.0,0.0 );   

//    glutInitWindowSize(320, 320);   // Set the window's initial width & height
   

//    glutMainLoop();       
   
/*   
    int i;

    // coefficients of P(x) =  -1 + x^5
    double a[6] = { -1, 0, 0, 0, 0, 1 };
    double z[10];

    gsl_poly_complex_workspace *w = gsl_poly_complex_workspace_alloc(6);
    gsl_poly_complex_solve(a, 6, w, z);
    gsl_poly_complex_workspace_free(w);

    std::ostringstream oss;

    for(i = 0; i < 5; i++) {
        oss << std::resetiosflags(std::ios_base::fmtflags(0));
        oss << 'z' << std::setw(10) << i;
        oss << " = " << std::fixed << std::setprecision(18) << std::showpos << std::setw(20) << z[2*i] << ' ' << z[2*i+1] << std::endl;
    }

    std::string res = oss.str();
   
    spdlog::info("\n{}\n", res);
   
    std::cout << res << std::endl;
*/   

    spdlog::trace("{} main(void) <<\n", EXIT_SUCCESS);

    return EXIT_SUCCESS;
}

Some logging *is*s needed and some reading of an XML file might be too. It's like a little project that just keeps getting bigger and bigger!

Also, I'm sure you can see I'm cannibalizing an older project. It might amount to nothing....
 
Computer science news on Phys.org
  • #3
Hah. I forgot my "simple" build file:

Code:
#!/bin/bash


################################################################################
# Perform cleanup
################################################################################
echo
if read -r -s -n 1 -t 3 -p $'\e[93;5mAbout to perform cleanup. Press any key to skip in the next 3 seconds...\033[0m' key
then
    echo
    echo $'\e[33mSkipping cleanup...\e[0m'
    echo
else
    echo
    ./clean.sh
    echo    
fi


################################################################################
# Precompiled header
################################################################################
echo
if read -r -s -n 1 -t 3 -p $'\e[93;5mAbout to precompile header pch.h. Press any key to skip in the next 3 seconds...\033[0m' key
then
    echo
    echo $'\e[33mSkipping...\e[0m'
    echo
else
    g++ -H -v -std=c++17 -Wall -Wextra -fmax-errors=3 -O3 -fdiagnostics-color=always -x c++-header -c pch.h -o pch.h.gch

    echo
    if [[ $? -ne 0 ]] 
    then
        echo    
        echo $'\e[31mError creating precompiled header.\e[0m'
        echo        
        exit 1
    fi

    echo    
    echo $'\e[32mSuccess.\e[0m'
    echo        
fi

if ! [ -f ./pch.h.gch ]; then
  echo $'\e[31mPrecompiled header not build. Stop.\033[0m'
  echo  
  exit 1;
fi


################################################################################
# Compile main executable
################################################################################
echo
echo "Compiling main executable..."
if read -r -s -n 1 -t 3 -p $'\e[93;5mAbout to main compile executable. Press any key to skip in the next 3 seconds...\033[0m' key
then
    echo
    echo $'\e[33mSkipping...\e[0m'
    echo
else

    g++ -H -v -std=c++17 -fdiagnostics-show-location=every-line -fdiagnostics-color=always -Wall -Wextra -fmax-errors=3 -Ofast -c -o main.o -include pch.h main.cpp

    echo
    if [[ $? -ne 0 ]] 
    then
        echo    
        echo $'\e[31mError compiling main executable.\e[0m'
        echo        
        exit 1
    fi

    echo    
    echo $'\e[32mSuccess.\e[0m'
    echo        
fi

if ! [ -f ./main.o ]; then
  echo $'\e[31mmain.o not created. Stop.\033[0m'
  echo  
  exit 1;
fi




###################################################33
echo
echo "Linking main executable..."

if read -r -s -n 1 -t 3 -p $'\e[93;5mAbout to link main executable. Press any key to skip in the next 3 seconds...\033[0m' key
then
    echo
    echo $'\e[33mSkipping...\e[0m'
    echo
else

    g++ -H -v -std=c++17 -fdiagnostics-show-location=every-line -fdiagnostics-color=always -Wall -Wextra -fmax-errors=3 -Ofast -o main main.o -L/usr/lib/x86_64-linux-gnu/cmake -lboost_regex -lfmt -lgsl -lglut -lGL

    if [[ $? -ne 0 ]]
    then
        echo    
        echo $'\e[31mError linking main executable.\e[0m'
        echo        
        exit 1
    fi
    
    echo    
    echo $'\e[32mSuccess.\e[0m'
    echo        
fi

echo "Done."
echo
exit 0
 

Similar threads

  • Computing and Technology
Replies
2
Views
2K
  • Programming and Computer Science
Replies
5
Views
8K
Replies
1
Views
7K
  • Programming and Computer Science
Replies
2
Views
3K
  • Programming and Computer Science
Replies
2
Views
3K
Back
Top