Jump to content

  • Log In with Google      Sign In   
  • Create Account

Moving a single object around in 2D


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 johnmarinelli   Members   -  Reputation: 304

Like
0Likes
Like

Posted 30 August 2013 - 08:01 PM

Hi everyone,

I know this question has been asked a few times before, but I still can't get my program to work.

 

I'm working on an Asteroids clone in OpenGL, and I'm starting off by simply getting my spaceship to move around.  I also have 4 quads set up in each respective corner so I know if the movement is working or not.

 

However, it seems like I'm moving the quads around, and not my spaceship.  Here's the code:

void renderScene()
{
	glClear(GL_COLOR_BUFFER_BIT);
	
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glPushMatrix();

	gSpaceship.render();

	glPopMatrix();

	glPushMatrix();
	//move to bottom right corner
	glTranslatef(SPACE_WIDTH / 2.f, SPACE_HEIGHT / 2.f, 0.f);

	glBegin(GL_QUADS);
		glColor3f(0.f, 1.f, 0.f);
		glVertex2f(0.f, 0.f);
		glVertex2f(50.f, 0.f);
		glVertex2f(50.f, 50.f);
		glVertex2f(0.f, 50.f);
	glEnd();

	//move to bottom left corner
	glTranslatef(-SPACE_WIDTH, 0.f, 0.f);

	glBegin(GL_QUADS);
		glColor3f(0.f, 0.f, 1.f);
		glVertex2f(0.f, 0.f);
		glVertex2f(50.f, 0.f);
		glVertex2f(50.f, 50.f);
		glVertex2f(0.f, 50.f);
	glEnd();

	//move to top left corner
	glTranslatef(0.f, -SPACE_HEIGHT, 0.f);

	glBegin(GL_QUADS);
		glColor3f(1.f, 1.f, 1.f);
		glVertex2f(0.f, 0.f);
		glVertex2f(50.f, 0.f);
		glVertex2f(50.f, 50.f);
		glVertex2f(0.f, 50.f);
	glEnd();

	//move to top right corner
	glTranslatef(SPACE_WIDTH, 0.f, 0.f);

	glBegin(GL_QUADS);
		glColor3f(1.f, 0.f, 1.f);
		glVertex2f(0.f, 0.f);
		glVertex2f(50.f, 0.f);
		glVertex2f(50.f, 50.f);
		glVertex2f(0.f, 50.f);
	glEnd();
	glPopMatrix();

	glFlush();
	
	glutSwapBuffers();
}

and heres' gSpaceship.render(), and consequently, JTexture.render():

void Spaceship::render()
{
       //mGraphics is a JTexture
       //m_xPos and m_yPos start out in the center of the 4 quads
	mGraphics.render(m_xPos, m_yPos);
}

void JTexture::render(GLfloat x, GLfloat y)
{
	if (mTextureID != 0)
	{
		glTranslatef(x, y, 0.f);

		glBindTexture(GL_TEXTURE_2D, mTextureID);

		glBegin(GL_QUADS);
			glTexCoord2f(0.f, 0.f); glVertex2f(0.f, 0.f );
            glTexCoord2f(1.f, 0.f); glVertex2f(mTextureWidth, 0.f );
            glTexCoord2f(1.f, 1.f); glVertex2f(mTextureWidth, mTextureHeight);
            glTexCoord2f(0.f, 1.f); glVertex2f(0.f, mTextureHeight);
        glEnd();
	}
}

also, I'd like to eventually be able to rotate the texture and move in the direction its facing; I know how to rotate a texture, but I know I will be very lost when it comes to moving in a direction thats not axis-aligned.  How does one go about this?

 

Thanks a lot!


Edited by johnmarinelli, 30 August 2013 - 08:13 PM.


Sponsor:

#2 Danicco   Members   -  Reputation: 449

Like
1Likes
Like

Posted 30 August 2013 - 09:35 PM

An easy way to deal with position and rotation and everything else related to transforms is to use a matrix to represent an object's transformations.

 

So you can have a class with your object's data (in the case, a single Quad + Texture) in it's original state, and when you're about to draw it, you use glLoadMatrix(matrix) and all it's transformations will be done.

 

Also, a suggestion, do some research about VBOs, what you're doing is called "Immediate Mode" and is pretty outdated and usually bad on performance.



#3 AtomicOrbital   Members   -  Reputation: 118

Like
1Likes
Like

Posted 02 September 2013 - 07:42 PM

Here is a basic bare bones multiple triangle animation using modern OpenGL 3.x with inline vertex and fragment shaders.

compile it using :     g++ -o 005_tri_mo_mu_f8_ver3_simple 005_tri_mo_mu_f8_ver3_simple.cpp  -lGL -lGLEW -lglut -lGLU
 

//		g++ -o opengl_tri_multi_move opengl_tri_multi_move.cpp -lGL -lGLU -lGLEW -lglut
//		optirun ./opengl_tri_multi_move


#include <GL/glew.h>
#include <GL/freeglut.h>
#include <vector>
#include <iostream>

#include <string.h>		//	strlen
#include <cstdio>	// printf, sprintf  in cpp c++

// ---------


#include <iomanip>	// std::setprecision
//#include <locale>	// to insert commas into large numbers


#include <sstream>



#define WINDOW_TITLE_PREFIX "move multiple triangles"
int CurrentWidth = 1100, CurrentHeight = 1000, WindowHandle = 0;
unsigned FrameCount = 0;

#define YES 1
#define NO  0

//#define DEBUG YES
#define DEBUG NO

int did_load_program = NO;
int x1_reached_edge = NO;
int y1_reached_edge = NO;

GLfloat x_max = 0.9, y_max = 0.9;
GLfloat x_min = -0.9, y_min = -0.9;
GLfloat min_incr = -0.3, max_incr = 0.3;
// GLfloat size_triangle_side = 0.007;
GLfloat size_triangle_side = 0.2;


struct struct_program {

    static GLuint Load( const char * vert, const char * geom, const char * frag ) {

        GLuint prog = glCreateProgram();
        if( vert ) AttachShader( prog, GL_VERTEX_SHADER, vert );
        if( geom ) AttachShader( prog, GL_GEOMETRY_SHADER, geom );
        if( frag ) AttachShader( prog, GL_FRAGMENT_SHADER, frag );
        glLinkProgram( prog );
        CheckStatus( prog );
        return prog;
    }

private:

    static void CheckStatus( GLuint obj ) {

        GLint status = GL_FALSE, len = 10;
        if( glIsShader(obj) )   glGetShaderiv ( obj, GL_COMPILE_STATUS, & status );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_LINK_STATUS, & status );
        if( status == GL_TRUE ) return;
        if( glIsShader(obj) )   glGetShaderiv ( obj, GL_INFO_LOG_LENGTH, & len );
        if( glIsProgram(obj) )  glGetProgramiv( obj, GL_INFO_LOG_LENGTH, & len );
        std::vector< char > log( len, 'X' );
        if( glIsShader(obj) )   glGetShaderInfoLog ( obj, len, NULL, &log[0] );
        if( glIsProgram(obj) )  glGetProgramInfoLog( obj, len, NULL, &log[0] );
        std::cerr << & log[0] << std::endl;
        exit( -1 );
    }

    static void AttachShader( GLuint program, GLenum type, const char * src ) {

        GLuint shader = glCreateShader( type );
        glShaderSource( shader, 1, & src, NULL );
        glCompileShader( shader );
        CheckStatus( shader );
        glAttachShader( program, shader );
        glDeleteShader( shader );
    }
};

#define GLSL(version, shader) "#version " #version "\n" #shader

const char* vert = GLSL (
    400 core,
    layout( location = 0 ) in vec4 vPosition;
    void main()
    {
        gl_Position = vPosition;
    }
);

const char* frag = GLSL (
    400 core,
    out vec4 fColor;
    void main()
    {
        fColor = vec4( 0.0, 0.0, 1.0, 1.0 );
    }
);

//#define total_num_triangles  1500
//#define total_num_triangles  3
//#define total_num_triangles  10000000
// #define total_num_triangles  100000
#define total_num_triangles  10

#define index_ArrayBuffer 0
#define NumBuffers 1

//num_vertex_arrays

GLuint vPosition = 0;

//GLuint VAOs[total_num_triangles];
GLuint vertex_array_object;

GLuint Buffers[NumBuffers];

const GLuint  NumVertices = 3;

#define X 0
#define Y 1
//GLfloat tri_location[total_num_triangles][2];
GLfloat vertex_locations[ 3 * total_num_triangles][2];	//	3 vertex per triangle, X&Y per vertex
//GLfloat incr[total_num_triangles][2];

GLfloat triangle_incr[total_num_triangles][2];

// ------------------------

bool get_direction(GLfloat curr_location, GLfloat min_location, GLfloat max_location) {

	bool answer = false;
	if (curr_location < min_location || curr_location > max_location) {

		answer = true;
	}
	return answer;
}

void setup_opengl() {

    glGenVertexArrays(NumBuffers, & vertex_array_object);



    glBindVertexArray(vertex_array_object);

    glGenBuffers(NumBuffers, Buffers);
    glBindBuffer(GL_ARRAY_BUFFER, Buffers[index_ArrayBuffer]);

    // ----------


    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0) );
    glEnableVertexAttribArray(vPosition);
    glBindVertexArray(vertex_array_object);
}

void display(void) {

	++FrameCount;

    glClear(GL_COLOR_BUFFER_BIT);

//    glGenVertexArrays(total_num_triangles, & vertex_array_object);
//    glGenVertexArrays(NumBuffers, & vertex_array_object);

//	std::cout << "----- top of display ------ " << std::endl;

    // ----------------

    int curr_vertex = 0;
    int curr_triangle = 0;
    for (; curr_triangle < total_num_triangles; curr_triangle++) {

    	if (get_direction(vertex_locations[curr_vertex    ][X], x_min, x_max) ||
    		get_direction(vertex_locations[curr_vertex + 1][X], x_min, x_max) ||
    		get_direction(vertex_locations[curr_vertex + 2][X], x_min, x_max)) {

    		triangle_incr[curr_triangle][X] *= -1.0;
    	}

    	if (get_direction(vertex_locations[curr_vertex    ][Y], y_min, y_max) ||
    		get_direction(vertex_locations[curr_vertex + 1][Y], y_min, y_max) ||
    		get_direction(vertex_locations[curr_vertex + 2][Y], y_min, y_max)) {

    		triangle_incr[curr_triangle][Y] *= -1.0;
    	}

    	// triangle vertex 1
    	vertex_locations[curr_vertex][X] += triangle_incr[curr_triangle][X];
    	vertex_locations[curr_vertex][Y] += triangle_incr[curr_triangle][Y];

    	if (YES == DEBUG) {
        	std::cout << "tri " << curr_triangle;
			std::cout << " X " << vertex_locations[curr_vertex][X]
					  << " Y " << vertex_locations[curr_vertex][Y];
    	}

    	curr_vertex++;

    	// triangle vertex 2
    	vertex_locations[curr_vertex][X] += triangle_incr[curr_triangle][X];
    	vertex_locations[curr_vertex][Y] += triangle_incr[curr_triangle][Y];

    	if (YES == DEBUG) {
			std::cout << "        X " << vertex_locations[curr_vertex][X]
					  <<        " Y " << vertex_locations[curr_vertex][Y];
    	}

    	curr_vertex++;

    	// triangle vertex 3
    	vertex_locations[curr_vertex][X] += triangle_incr[curr_triangle][X];
    	vertex_locations[curr_vertex][Y] += triangle_incr[curr_triangle][Y];

    	if (YES == DEBUG) {
			std::cout << "        X " << vertex_locations[curr_vertex][X]
					  <<        " Y " << vertex_locations[curr_vertex][Y] << std::endl;
    	}

    	curr_vertex++;
    }

    // ----------

    glBindVertexArray(vertex_array_object);

//    glGenBuffers(NumBuffers, Buffers);
//    glBindBuffer(GL_ARRAY_BUFFER, Buffers[index_ArrayBuffer]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_locations), vertex_locations, GL_STATIC_DRAW);
//    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_locations), vertex_locations, GL_DYNAMIC_DRAW);
//
//    glVertexAttribPointer(vPosition, 2, GL_FLOAT, GL_FALSE, 0, (void*)(0) );
//    glEnableVertexAttribArray(vPosition);
//    glBindVertexArray(vertex_array_object);

    glDrawArrays(GL_TRIANGLES, 0, 3 * total_num_triangles);
//    glDrawArrays(GL_TRIANGLES, 0, total_num_triangles);

    // ----------

    glutSwapBuffers();
}

// ---------------

void process_SHIFT_ALT_CTRL(unsigned char key, int x, int y) {

    switch(key) {

    	case 27: {

//    		printf ("just hit ESC key\n");
    		exit(8);
    	}
    }
}

// --------------

const char * insert_commas_into_int(int given_integer) {

	std::ostringstream stm ;
	stm << given_integer;
	std::string str_num(stm.str());

	int size_str = str_num.size() ;

//	std::cout << " num digits in " << given_integer << " is " << size_str << std::endl;
	for( int i = size_str ; i > 0 ; i -= 3 ) {

		if (i != size_str)
			str_num.insert( i, 1, ',' ) ;
	}
//	std::cout << str_num << '\n' ;

	return str_num.c_str();
}

// --------------

void TimerFunction(int Value) {

	if (0 != Value) {
		char* TempString = (char*)
			malloc(512 + strlen(WINDOW_TITLE_PREFIX));

		sprintf(
			TempString,
			"%s: %s triangles doing %d Frames Per Second @ %d x %d",
			WINDOW_TITLE_PREFIX,
			insert_commas_into_int(total_num_triangles),
			FrameCount * 4,
			CurrentWidth,
			CurrentHeight
		);

		glutSetWindowTitle(TempString);
		free(TempString);
	}

	FrameCount = 0;
	glutTimerFunc(250, TimerFunction, 1);
}

GLfloat get_random_in_range(GLfloat minimum, GLfloat maximum) {

	return(minimum + (float)rand()/((float)RAND_MAX/(maximum - minimum)));
}
void IdleFunction(void)
{
	glutPostRedisplay();
}


static void define_callbacks() {

    glutDisplayFunc(display);
    glutKeyboardFunc( process_SHIFT_ALT_CTRL );
	glutIdleFunc(IdleFunction);
	glutTimerFunc(0, TimerFunction, 0);
}

int main(int argc, char** argv) {

	// initialize random seed
	srand ( time(NULL) );

	glutInit(&argc, argv);
	glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE );
 	glutInitWindowSize(CurrentWidth, CurrentHeight);

     glutInitContextVersion(4, 0);
     glutInitContextProfile(GLUT_CORE_PROFILE);
     glutCreateWindow(argv[0]);

     glewExperimental = GL_TRUE;
     if( GLEW_OK != glewInit() )
         exit(EXIT_FAILURE);

     int curr_vertex = 0;
     int curr_triangle = 0;
     for (; curr_triangle < total_num_triangles; curr_triangle++) {

    	 triangle_incr[curr_triangle][X] = get_random_in_range(min_incr, max_incr) / 50.0;
    	 triangle_incr[curr_triangle][Y] = get_random_in_range(min_incr, max_incr) / 50.0;


     	if (YES == DEBUG) {
			 std::cout << " triangle_incr X " << triangle_incr[curr_triangle][X]
					   << " triangle_incr Y " << triangle_incr[curr_triangle][Y] << std::endl;
     	}

    	 GLfloat x_curr = get_random_in_range(min_incr, max_incr);
    	 GLfloat y_curr = get_random_in_range(min_incr, max_incr);

    	 // triangle vertex 1
    	 vertex_locations[curr_vertex][X] = x_curr;
    	 vertex_locations[curr_vertex][Y] = y_curr;

     	if (YES == DEBUG) {
			 std::cout << "tri " << curr_triangle << std::endl;
			 std::cout << " vertex 1 X " << vertex_locations[curr_vertex][X]
					   << " Y " << vertex_locations[curr_vertex][Y] << std::endl;
     	}

    	 // triangle vertex 2
    	 vertex_locations[curr_vertex + 1][X] = x_curr;
    	 vertex_locations[curr_vertex + 1][Y] = y_curr - size_triangle_side;

     	if (YES == DEBUG) {
			 std::cout << " vertex 2 X " << vertex_locations[curr_vertex + 1][X]
					 << " Y " << vertex_locations[curr_vertex + 1][Y] << std::endl;
     	}

    	 // triangle vertex 3
    	 vertex_locations[curr_vertex + 2][X] = x_curr - size_triangle_side;
    	 vertex_locations[curr_vertex + 2][Y] = y_curr - size_triangle_side;

     	if (YES == DEBUG) {
			 std::cout << " vertex 3 X " << vertex_locations[curr_vertex + 2][X]
					 << " Y " << vertex_locations[curr_vertex + 2][Y] << std::endl;
     	}

    	 curr_vertex += 3;	// 3 vertex per triangle
     }

     // -----------

     GLuint program = struct_program::Load( vert, NULL, frag );
     glUseProgram(program);

     // -----------

     setup_opengl();

     define_callbacks();

     glutMainLoop();
}




#4 Irlan   Members   -  Reputation: 1521

Like
0Likes
Like

Posted 23 September 2013 - 08:21 AM

A tip:

 

Use Shaders instead of the fixed pipeline. If you are thinking that's from another world, just read 5 minutes about it.

A awesome site : http://research.ncl.ac.uk/game/mastersdegree/graphicsforgames/ (where i start)


Edited by irlanrobson, 23 September 2013 - 08:22 AM.





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS