OpenGL

 

I've learnt a bit from WebGL first, so OpenGL is very similar. I've tried to make the program in C++ language under Linux.

There are several editor environment that can help you to handle the project, - like e.g. QT Creator, Netbeans IDE, Eclipse IDE, ... and so on, - but you can also write your code in a simple text editor like VI or KWrite. :-)

For my example to run must be installed GLEW and SFML libraries, for creating/compiling projects like this, you may need their devel packages and glm-devel.

my Struct for vertex data

/*
 *  0     1     2      3     4       5      6       7      8      9
 * posx, posy, posz, cred, cgreen, cblue, calpha, normx, normy, normz
 */
const int mySizes_position = 3;
const int mySizes_color = 4;
const int mySizes_normal = 3;
const int mySizes_index = 3;
const int mySizes_summ = mySizes_position + mySizes_color + mySizes_normal; 

union myVertUnion {
    GLfloat data[ mySizes_summ ];
    struct myVertStruct {
        GLfloat position[mySizes_position];
        GLfloat color[mySizes_color];
        GLfloat normal[mySizes_normal];
    } vertex;
};

my Vertex Shader:

    attribute vec3 aVertexPosition;
    attribute vec4 aVertexColor;
    attribute vec3 aVertexNormal;

    uniform mat4 uProjectionMatrix;
    uniform mat4 uViewMatrix;
    uniform mat4 uModelMatrix;
    uniform vec3 uObjectMove;
    uniform mat4 uNormalMatrix;

    varying vec3 vNormal;
    varying vec4 vColor;

    void main() {
        vNormal = mat3(uNormalMatrix) * aVertexNormal + uObjectMove;
        vColor = aVertexColor; 
        vec4 modelPosition = vec4(aVertexPosition, 1.0f) * uModelMatrix + vec4( uObjectMove, 1.0f );
        gl_Position = uProjectionMatrix * uViewMatrix * modelPosition;
    }

Each object has its own modelMatrix which contains a move and a scale before rotation and the end it is moveable by objectmove. I added the additional move to normal too, because of the distance change from light. Camera gives back the ViewMatrix.

An example how can I add objects with different settings:

    this->AddObject( new myterrain() );
    this->AddObject( new mycube() );

    mycube *c2 = new mycube();
    c2->setMoveVec( glm::vec3( 3,0,0 ) );        // -|
    c2->setScaleVec( glm::vec3( 0.5,3,1 ) );     // -|==> these transforms implemented in
    c2->setRotationVec( glm::vec3( 0,1,-1 ) );   // -|            modelmatrix and normalmatrix too
    c2->setMoveObject( glm::vec3( 5,-3,1 ) );
    this->AddObject( c2 );

my Simple Camera:

/*
 * (c)2023 Tóthpál István <istvan@tothpal.eu>
 */
#ifndef MYSIMPLECAM_H
    #include "../inc/mysimplecam.h"
#endif

mysimplecam::mysimplecam( glm::vec3 pos, glm::vec3 front, glm::vec3 up ) {
    defaultCameraPos   = pos;
    defaultCameraFront = front;
    defaultCameraUp    = up;
    setSensitivity( 1.0f );
    this->InitCamSettings();
}

mysimplecam::mysimplecam( glm::mat3 camdata ) {
    defaultCameraPos   = camdata[0];
    defaultCameraFront = camdata[1];
    defaultCameraUp    = camdata[2];
    setSensitivity( 1.0f );
    this->InitCamSettings();
}

mysimplecam::~mysimplecam() {
}

void mysimplecam::InitCamSettings() {
    cameraPos   = defaultCameraPos;
    cameraFront = defaultCameraFront;
    cameraUp    = defaultCameraUp;
    stepSize = 0.05f;
    this->RecalcVectors();
}

float mysimplecam::getSensitivity() {
    return sensitivity;
}

void mysimplecam::setSensitivity( float s ) {
    sensitivity = s;    
}

void mysimplecam::RecalcVectors(){
    cameraRight = glm::normalize(glm::cross(cameraUp, cameraFront));
    cameraUp = glm::cross(cameraFront, cameraRight);
}

glm::mat4 mysimplecam::getViewMatrix(){
    return glm::lookAt(
        cameraPos,
        cameraPos + cameraFront,
        cameraUp
    );
}

void mysimplecam::StepHorizontal(float way){
    cameraPos += way * cameraRight * stepSize/(float)10 * sensitivity;
    this->RecalcVectors();
}

void mysimplecam::StepForward(float way){
    cameraPos += way * cameraFront * stepSize/(float)10 * sensitivity;
    this->RecalcVectors();
}

void mysimplecam::StepLift(float way){
    cameraPos += way * glm::cross(cameraFront,cameraRight) * stepSize/(float)10 * sensitivity;
    this->RecalcVectors();
}

void mysimplecam::Yaw(float way){
    cameraFront = glm::mat3(glm::rotate(glm::mat4(1.0f), glm::radians(way * stepSize * sensitivity), glm::cross(cameraFront,cameraRight) )) * cameraFront;
    this->RecalcVectors();
}

void mysimplecam::Pitch(float way) {
    cameraFront = glm::mat3(glm::rotate(glm::mat4(1.0f), glm::radians(way * stepSize * sensitivity), glm::cross(cameraFront, cameraUp) )) * cameraFront;
    this->RecalcVectors();
}

void mysimplecam::Roll(float way) {
    cameraUp = glm::mat3(glm::rotate(glm::mat4(1.0f), glm::radians(way * stepSize * sensitivity), cameraFront)) * cameraUp;
    this->RecalcVectors();
}

I've created a simple test prog for trying my camera object. (generated a 10x10 terrain like thing from cubes) Here you can download executable in rpm package: MyGL-TIS-0.2.3-2.mga8.x86_64.rpm

Built on Mageia Linux 8, installing to bindir (/usr/bin/). (type MyGL-TIS to run)

(controls from keyboard: W/S step FW/BW; A/D Step L/R; Y/X Lift Up/Dn; Num8/2 rotate Up/Dn; Num4/6 rotate L/R; Num1/3 roll; R - reset pos )

 

References:

Physics

Usualy there not enough that the object looks great, just like in real life, it have to behave as in real circumstances. To reach that you may need to use physics. If you wouldn't like code everything, you can use an sdk. There are several physics sdk, I've started to learn Bullet.

In Mageia Linux 8 you can install lib64bullet and its devel package. For compiling your C++ code you have to add include path "/usr/include/bullet" and you may add BulletSoftBody, BulletDynamics, BulletCollision, LinearMath libraries.

Now I have to learn it, but fast I've implemented the example below to the previous code for trying the collision with the floor using gravity:

It's just a simple example, how a ball bounce, but not all we can do with physics.

I've forced Bullet Collision to my previous OpenGL code, so the cube reflecting/bouncing from other objects. Here you can download executable in rpm package: MyGL-TIS-Bullet-0.2.3-1.mga8.x86_64.rpm

Mageia 9 (using DOUBLE_PRECISION Bullet): MyGL-TIS-Bullet-0.2.3-1.mga9.x86_64.rpm

Built on Mageia Linux 8, installing to bindir (/usr/bin/). (type MyGL-TIS-Bullet to run)

(controls from keyboard: W/S step FW/BW; A/D Step L/R; Y/X Lift Up/Dn; Num8/2 rotate Up/Dn; Num4/6 rotate L/R; Num1/3 roll; R - reset pos, O - drop cube again)

 

References:

Visitcount (since 2021-05-30): 0247