私はOpenGLでSDLを使用しており、これまで2Dですべてを実行してきました(glOrtho()を使用)
今は3Dで描いてみたいのですが、もちろん3次元を混ぜ合わせたので、どんどん複雑になっていきます。
私がやりたいのは、カーソルの画面座標を取得し、それらを(?)世界座標(遠近法などがあるのでOpenGLで使用できる座標)に変換し、でクワッドを描画することです。その位置(マウスカーソルはクワッドの中心にあります)
gluUnProject()に関するチュートリアルをいくつか読んだことがあり、自分が何をすべきかをある程度理解していますが、自分で学習しているため、混乱しやすく、自分が何をしているかを正しく理解できません。
そのため、私は主に私が見つけた例からコピーしました。
以下は私のコードです(少し削減するためにエラーチェックなどを削除しました)
ご覧のとおり、mouseX、mouseY、mouseZ変数があり、そのうちのmouseXとmouseYはSDLから値を取得します。
glReadPixel()を使用してmouseZを取得しようとしましたが、正しく実行されているかどうかわかりません。
問題は、クリックしたときにクワッドが正しい位置に描画されないことです(mouseZを正しく取得する方法がわからないためか、gluUnProject()で1.0に置き換えただけですか?)
glTranslatef()関数で新しい座標(wx、wy、wz)を使用していますが、mouseZを正しく取得する方法がわからないため、これが正しく機能しない理由だと思います。wzを-499に置き換えると、問題なく動作するように見えますが、正しい(またはほぼ正しい)数値を手動で見つけずに正確な結果を得る方法を知る必要があります
誰かが私が間違っていることを教えてくれたり、アドバイスをくれたら大歓迎です。
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
SDL_Surface* screen = 0;
SDL_Event event;
bool isRunning = true;
int mouseX, mouseY, mouseZ = 0;
GLint viewport[4];
GLdouble mvmatrix[16], projmatrix[16];
GLint realY; /* OpenGL y coordinate position */
GLdouble wx, wy, wz; /* returned world x, y, z coords */
int main(int argc, char **argv) {
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glViewport(0, 0, 800, 600);
glClearDepth(1.f);
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.f, 1.f, 500.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while(isRunning) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
isRunning = false;
}
if(event.type == SDL_MOUSEBUTTONDOWN) {
if(event.button.button == SDL_BUTTON_LEFT) {
SDL_GetMouseState(&mouseX, &mouseY);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
realY = viewport[3] - (GLint) mouseY - 1;
glReadPixels(mouseX, realY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &mouseZ);
gluUnProject((GLdouble)mouseX, (GLdouble)realY, 1.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);
}
}
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(wx, wy, wz);
glBegin(GL_QUADS);
glColor4f(1.f, 0.f, 0.f, 1.f);
glVertex3f(-20.f, -20.f, 0.f);
glColor4f(0.f, 1.f, 0.f, 1.f);
glVertex3f(-20.f, 20.f, 0.f);
glColor4f(0.f, 0.f, 1.f, 1.f);
glVertex3f(20.f, 20.f, 0.f);
glColor4f(1.f, 0.f, 1.f, 1.f);
glVertex3f(20.f, -20.f, 0.f);
glEnd();
glPopMatrix();
SDL_GL_SwapBuffers();
}
SDL_FreeSurface(screen);
return 0;
}