texture sur un cercle en mouvement [SDL2] [OpenGL]

Comment afficher une texture sur un cercle en mouvement ?

a marqué ce sujet comme résolu.
Auteur du sujet

Voici mon code :

#define GLEW_STATIC
#include <stdlib.h>
#include <SDL2/SDL.h>
#include <math.h>
#include <stdio.h>
#include <iostream>
#include<conio.h>
#include<dos.h>
#include <GL/glew.h>
#include "SceneOpenGL.h"
#include <SDL2/SDL_image.h>
 
using namespace std;
 
#ifdef WIN32
#include <GL/glew.h>
 
#else
#define GL3_PROTOTYPES 1
#include <GL3/gl3.h>
 
#endif
 
#include <SDL2/SDL.h>
#include <iostream>
void DrawCircle(float cx, float cy, float r, int num_segments);
void DrawEllipse(float cx, float cy, float a, float b, int num_segments);
void Rotation(float a,float b,float r, float g_theta );
void ECRITURE();
 
int main(int argc, char **argv)
{
    SDL_Window* fenetre(0);
    SDL_GLContext contexteOpenGL(0);
 
    SDL_Event evenements;
    bool terminer(false);
 
    if(SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        std::cout << "Erreur lors de l'initialisation de la SDL : " << SDL_GetError() << std::endl;
        SDL_Quit();
 
        return -1;
    }
 
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
 
 
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
 
 
    fenetre = SDL_CreateWindow("Test SDL 2.0", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 600, 600, SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);
 
    if(fenetre == 0)
    {
        std::cout << "Erreur lors de la creation de la fenetre : " << SDL_GetError() << std::endl;
        SDL_Quit();
 
        return -1;
    }
     
    contexteOpenGL = SDL_GL_CreateContext(fenetre);
 
    if(contexteOpenGL == 0)
    {
        std::cout << SDL_GetError() << std::endl;
        SDL_DestroyWindow(fenetre);
        SDL_Quit();
 
        return -1;
    }
 
 
    #ifdef WIN32
 
        GLenum initialisationGLEW( glewInit() );
 
        if(initialisationGLEW != GLEW_OK)
        {
  
            std::cout << "Erreur d'initialisation de GLEW : " << glewGetErrorString(initialisationGLEW) << std::endl;
 
            SDL_GL_DeleteContext(contexteOpenGL);
            SDL_DestroyWindow(fenetre);
            SDL_Quit();
 
            return -1;
        }
 
    #endif
 
    // Vertices et coordonnées
 while(!terminer)
    {
        SDL_WaitEvent(&evenements);
 
        if(evenements.window.event == SDL_WINDOWEVENT_CLOSE)
            terminer = true;
 
    glClear(GL_COLOR_BUFFER_BIT);
 
float g_theta = 0.0f;
 
while (g_theta<360)
    {
glClear(GL_COLOR_BUFFER_BIT);
g_theta += 1.0f;
DrawCircle(0, 0, 0.3, 50);
Rotation(0.8,0.65,0.1,g_theta);
Rotation(0.5,0.5,0.2,g_theta);
Rotation(0.1,0.1,0.01,g_theta);
 
        glDisableVertexAttribArray(0);
        SDL_GL_SwapWindow(fenetre);
    }
    }
    SDL_GL_DeleteContext(contexteOpenGL);
    SDL_DestroyWindow(fenetre);
    SDL_Quit();
 
    return 0;
 
}
 
void DrawCircle(float cx, float cy, float r, int num_segments)
{
    glBegin(GL_LINE_LOOP);
    for(int ii = 0; ii < num_segments; ii++)
    {
        float theta = 2.0 * M_PI * float(ii) / float(num_segments);//get the current angle
 
        float x_c = r * cosf(theta);//calculate the x component
        float y_c = r * sinf(theta);//calculate the y component
        glColor3f(1.0f,0.0f,0.0f);
        glVertex2f(x_c + cx, y_c + cy);//output vertex
    }
    glEnd();
}
void DrawEllipse(float cx, float cy, float a, float b, int num_segments)
{
    glBegin(GL_LINE_LOOP);
    for(int ii = 0; ii < num_segments; ii++)
    {
        float theta = 2.0 * M_PI * float(ii) / float(num_segments);//get the current angle
 
        float x_e = a * cosf(theta);//calculate the x component
        float y_e = b * sinf(theta);//calculate the y component
        glColor3f(0.0f,0.0f,1.0f);
        glVertex2f(x_e + cx, y_e + cy);//output vertex
    }
    glEnd();
}
void Rotation(float a,float b,float r, float g_theta )
{
 
float x = a * cosf(g_theta * M_PI / 180.0f);
float y = b * sinf(g_theta * M_PI / 180.0f);
float d = sqrtf( x*x + y*y );
 
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
 
 
 
glPushMatrix();
glRotatef( g_theta, 0, 0, 1 );  // rotation around the z axis
glTranslatef( d, 0, 0 );        // translation by the distance
 
DrawCircle(0, 0, r, 50);
glPopMatrix();
 
DrawEllipse(0, 0, a, b, 50);
 
    }

Le résultat actuelle ressemble à cela : résultat de la compilation

Les cercles rouges tournent sur les ellipses bleues.

Je voudrais que chaque cercle aille sa propre texture. J’ai déjà téléchargé SDL2_image et essayé cela :

IMG_Init(IMG_INIT_JPG);
SDL_Surface * image = IMG_Load("PICT3159.JPG");
IMG_Quit();

Mais cela ne fonctionne pas. Comment puis-je afficher des textures sur ces cercles en mouvement?

(PS: Mon but final est de créer une représentation 2D de notre système solaire)

Merci de votre futur aide

Édité par Astronight

+0 -0

Le lien de l’image est https://cdn.pbrd.co/images/HJvHT48.jpg, tu dois utiliser celui-ci pour afficher l’image via la balise markdown.


Pour ton problème, tu peux utiliser SDL_SetColorKey pour définir une couleur alpha d’une image.

Pour un fond vert ton dernier argument sera :

SDL_MapRGB(image->format, 0, 255, 0);

Édité par A-312

+0 -0
Auteur du sujet

J’arrive à afficher une image grâce à cela :

SDL_Renderer *pRenderer = SDL_CreateRenderer(fenetre,-1,SDL_RENDERER_ACCELERATED); // Création d'un SDL_Renderer utilisant l'accélération matérielle

if ( pRenderer )
{
    SDL_Surface* pSprite = SDL_LoadBMP("earth.bmp");
    if ( pSprite )
    {
        SDL_Texture* pTexture = SDL_CreateTextureFromSurface(pRenderer,pSprite); // Préparation du sprite
        if ( pTexture )
        {
            SDL_Rect dest = { 640/2 - pSprite->w/2,480/2 - pSprite->h/2, pSprite->w, pSprite->h};
            SDL_RenderCopy(pRenderer,pTexture,NULL,&dest); // Copie du sprite grâce au SDL_Renderer

            SDL_RenderPresent(pRenderer); // Affichage
           SDL_Delay(3000); /* Attendre trois secondes, que l'utilisateur voit la fenêtre */

          //  SDL_DestroyTexture(pTexture); // Libération de la mémoire associée à la texture
        }
        else
        {
            fprintf(stdout,"Échec de création de la texture (%s)\n",SDL_GetError());
        }

        SDL_FreeSurface(pSprite); // Libération de la ressource occupée par le sprite
    }
    else
    {
        fprintf(stdout,"Échec de chargement du sprite (%s)\n",SDL_GetError());
    }

    SDL_DestroyRenderer(pRenderer); // Libération de la mémoire du SDL_Renderer
}
else
{
    fprintf(stdout,"Échec de création du renderer (%s)\n",SDL_GetError());
}

Peut-être il serait plus simple de redimensionner l’image, de la couper en forme de rond et de la faire tourner, elle, sur l’ellipse ?
(Mais je sais pas comment faire non plus :'( )

Édité par Astronight

+0 -0

Dessine ta planète sur ton éditeur d’image puis met une couleur de fond sur ton BMP que tu enlèveras par la suite.

Ainsi :

SDL_SetColorKey(pSprite, SDL_TRUE, SDL_MapRGB(pSprite->format, 0, 255, 0));

https://wiki.libsdl.org/SDL_SetColorKey


Parcontre c’est la planète qui bouge ou la texture ?

+1 -0

Je rajoute que c’est pas la peine de redimensionner l’image, tu peux le faire à l’affichage avec la SDL (voir le dernier paramètre de SDL_RenderCopy).

Assez des salamis, je passe au jambon — Je fais un carnage si ce car nage car je nage, moi, Karnaj ! — Le comble pour un professeur de mathématique ? Mourir dans l’exercice de ses fonctions.

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte