My current 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>
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);
int main(int argc, char **argv)
{
// the window
SDL_Window* fenetre(0);
SDL_GLContext contexteOpenGL(0);
SDL_Event evenements;
bool terminer(false);
// Initializing the SDL
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;
}
// Version OpenGL
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
// Double Buffer
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
// Creating the window
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;
}
// Creating the OpenGL context
contexteOpenGL = SDL_GL_CreateContext(fenetre);
if(contexteOpenGL == 0)
{
std::cout << SDL_GetError() << std::endl;
SDL_DestroyWindow(fenetre);
SDL_Quit();
return -1;
}
#ifdef WIN32
// We initialize GLEW
GLenum initialisationGLEW( glewInit() );
//If the initialization failed :
if(initialisationGLEW != GLEW_OK)
{
// We display the error thanks to the function : glewGetErrorString(GLenum code)
std::cout << "Erreur d'initialisation de GLEW : " << glewGetErrorString(initialisationGLEW) << std::endl;
// leave SDL
SDL_GL_DeleteContext(contexteOpenGL);
SDL_DestroyWindow(fenetre);
SDL_Quit();
return -1;
}
#endif
// Vertices and coordinates
while(!terminer)
{
// Event Management
SDL_WaitEvent(&evenements);
if(evenements.window.event == SDL_WINDOWEVENT_CLOSE)
terminer = true;
// clean the screen
glClear(GL_COLOR_BUFFER_BIT);
DrawCircle(0,0,0.3,50);
DrawCircle(0.5,0.5,0.1,50);
DrawEllipse(0,0,0.8,0.65,50);
// Disable the Vertex Attrib array
glDisableVertexAttribArray(0);
//refresh window
SDL_GL_SwapWindow(fenetre);
}
// leave SDL
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();
}
For example, I would like to rotate the little circle around the big one following the blue line:
And I would like to decide how long it takes to complete a turn.
Do I have to combine glRotatef()
and glTranslatef()
and use matrices?
Where should I put it in my code?
First of all note, that drawing by glBegin
/ glEnd
sequences is deprecated since more than 10 years.
Read about Fixed Function Pipeline and see Vertex Specification and Shader for a state of the art way of rendering.
Do I have to combine
glRotatef()
andglTranslatef()
and use matrices?
No, not necessarily.
Since you calculate the geometry of the circle on the fly in every frame, it is sufficient to calculate the center point of the circle in ever frame, and pass it to DrawCircle
:
Specify a global variable for the angle of the polar coordinate of the center point of the circle:
float g_theta = 0.0f;
Calculate the center point of the circle somehow like this:
float a = 0.8f;
float b = 0.65f;
float x = a * cosf(g_theta * M_PI / 180.0f);
float y = b * sinf(g_theta * M_PI / 180.0f);
g_theta += 1.0f;
DrawCircle(0, 0, 0.3, 50);
DrawCircle(x, y, 0.1, 50);
DrawEllipse(0, 0, a, b, 50);
If you want to do the same, by using the Fixed Function pipeline matrix stack, then you have to set the GL_MODELVIEW
matrix.
Calculate the distance ( d
) form the center of the circle to the center of the world. Apply a translation by the distance and a rotation by the angle of the polar coordinate at the z axis of the world:
float a = 0.8f;
float b = 0.65f;
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();
DrawCircle(0, 0, 0.3, 50);
glPushMatrix();
glRotatef( g_theta, 0, 0, 1 ); // rotation around the z axis
glTranslatef( d, 0, 0 ); // translation by the distance
g_theta += 1.0f;
DrawCircle(0, 0, 0.1, 50);
glPopMatrix();
DrawEllipse(0, 0, a, b, 50);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.