Help understanding some OpenGL stuff
I am working with some code to create a triangle that moves with arrow keys. I want to create a second object that moves independently. This is where I am having trouble, I have created the second actor, but cannot get it to move. There is too much code to post it all so I will just post a little and see if anyone can help at all.
ogl_test.cpp
#include "platform.h"
#include "srt/scheduler.h"
#include "model.h"
#include "controller.h"
#include "model_module.h"
#include "graphics_module.h"
class blob : public actor {
public:
blob(float x, float y) : actor(math::vector2f(x, y)) { }
void render() {
transform();
glBegin(GL_TRIANGLES);
glVertex3f(0.25f, 0.0f, -5.0f);
glVertex3f(-.5f, 0.25f, -5.0f);
glVertex3f(-.5f, -0.25f, -5.0f);
glEnd();
end_transform();
}
void update(controller& c, float dt) {
if (c.left_key) {
rho += pi / 9.0f * dt;
c.left_key = false;
}
if (c.right_key) {
rho -= pi / 9.0f * dt;
c.right_key = false;
}
if (c.up_key) {
v += .1f * dt;
c.up_key = false;
}
if (c.down_key) {
v -= .1f * dt;
if (v < 0.0) { v = 0.0; }
c.down_key = false;
}
actor::update(c, dt);
}
};
class enemyOne : public actor {
public:
enemyOne(float x, float y) : actor(math::vector2f(x, y)) { }
void render() {
transform();
glBegin(GL_TRIANGLES);
glVertex3f(0.25f, 0.0f, -5.0f);
glVertex3f(-.5f, 0.25f, -5.0f);
glVertex3f(-.5f, -0.25f, -5.0f);
glEnd();
end_transform();
}
void update(controller& c, float dt) {
if (c.left_key) {
rho += pi / 9.0f * dt;
c.left_key = false;
}
if (c.right_key) {
rho -= pi / 9.0f * dt;
c.right_key = false;
}
if (c.up_key) {
v += .1f * dt;
c.up_key = false;
}
if (c.down_key) {
v -= .1f * dt;
if (v < 0.0) { v = 0.0; }
c.down_key = false;
}
actor::update(c, dt);
}
};
int APIENTRY WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
char* lpCmdLine,
int nCmdShow
)
{
model m;
controller control(m);
srt::scheduler scheduler(33);
srt::frame* model_frame = new srt开发者_开发百科::frame(scheduler.timer(), 0, 1, 2);
srt::frame* render_frame = new srt::frame(scheduler.timer(), 1, 1, 2);
model_frame->add(new model_module(m, control));
render_frame->add(new graphics_module(m));
scheduler.add(model_frame);
scheduler.add(render_frame);
blob* prime = new blob(0.0f, 0.0f);
m.add(prime);
m.set_prime(prime);
enemyOne* primeTwo = new enemyOne(2.0f, 0.0f);
m.add(primeTwo);
m.set_prime(primeTwo);
scheduler.start();
control.start();
return 0;
}
model.h
#include <vector>
#include "vec.h"
const double pi = 3.14159265358979323;
class controller;
using math::vector2f;
class actor {
public:
vector2f P;
float theta;
float v;
float rho;
actor(const vector2f& init_location) :
P(init_location),
rho(0.0),
v(0.0),
theta(0.0)
{ }
virtual void render() = 0;
virtual void update(controller&, float dt) {
float v1 = v;
float theta1 = theta + rho * dt;
vector2f P1 = P + v1 * vector2f(cos(theta1), sin(theta1));
if (P1.x < -4.5f || P1.x > 4.5f) { P1.x = -P1.x; }
if (P1.y < -4.5f || P1.y > 4.5f) { P1.y = -P1.y; }
v = v1;
theta = theta1;
P = P1;
}
protected:
void transform() {
glPushMatrix();
glTranslatef(P.x, P.y, 0.0f);
glRotatef(theta * 180.0f / pi, 0.0f, 0.0f, 1.0f); //Rotate about the z-axis
}
void end_transform() {
glPopMatrix();
}
};
class model {
private:
typedef std::vector<actor*> actor_vector;
actor_vector actors;
public:
actor* _prime;
model() { }
void add(actor* a) {
actors.push_back(a);
}
void set_prime(actor* a) {
_prime = a;
}
void update(controller& control, float dt) {
for (actor_vector::iterator i = actors.begin(); i != actors.end(); ++i) {
(*i)->update(control, dt);
}
}
void render() {
for (actor_vector::iterator i = actors.begin(); i != actors.end(); ++i) {
(*i)->render();
}
}
};
Your blob
is erasing the keypresses before the second actor sees them:
if (c.left_key) {
rho += pi / 9.0f * dt;
c.left_key = false; // <-- HERE
}
Clearing the keyboard state after each frame should not be the concern of any single actor, the controller itself should do that.
Both blob and enemyOne both have an update function that checks the arrow keys to see whether to move. If you commented out all of the if statements inside one of the update function then it should not move anymore. Alternatively, you could change the if statements in the update function to check other keys and use those to control the other object.
EDIT: As noted in another answer, when you set c.left_key = false; (or one on the other keys) you prevent any of the other actors from seeing that the key was pressed. Either not passing the controller around as a reference, or removing these lines of code should fix this.
精彩评论