LINUX.ORG.RU

Си Opengl Sdl событие при наведении на объект мыши


1

3

Разбираюсь с 3d и не могу найти нормальное решение для реакции наведения мыши на объект отличный от прямоугольника. Для прямоугольной области всё ясно и работает (4 условия с координатами прямоугольника), даже с изменением пропорций окна. Но если например нужно поймать мышью треугольник, то это решение не прокатит. Если кто сталкивался с подобной задачей можете подкинуть кусок кода, интересует только Си и Sdl без глюта. Спасибо!

★★★

Гугли opengl object picking. Эта задача чуть менее тривиальна для того чтобы можно было просто кинуть кусок кода.

slovazap ★★★★★
()
Ответ на: комментарий от slovazap

Гуглил, но всё что нашел это на c++ и впридачу ещё и глют. Я с Си только начал разбираться что к чему. Мне эти примеры не по зубам. Поэтому и спросил. Может мне скинуть сюда простой пример вывода плоскости по которой нужно жмякнуть, а ты подскажешь что дальше?

Frost ★★★
() автор топика
Ответ на: комментарий от Frost

всё разобрался! заработало :) спасибо

Если ты новенький, то принято писать о том как была проблема решена. Представь другой человек будет читать твою тему через год и увидит что у тебя всё заработало и ты разобрался, зашибись какая радость.

Надеюсь ты понял что на форумах отвечают не только от душевной доброты, что несомненно есть, но и для того чтобы пополнить копилку знаний, даже если вопросы простые и тривиальные.

I-Love-Microsoft ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

да чтож такое то...

#include "SDL.h"
#include "SDL_opengl.h"
#include <stdio.h>
#include <stdlib.h>

#define SW 400
#define SH 400
 
int selected = 0;
void gl_draw();
void gl_init(int w, int h);
void gl_select(int x, int y);
void gl_selall(GLint hits, GLuint *buff);
void sdl_events();
void sdl_mousedw(int x, int y, int but);
void draw_block(float x, float y, float z);
void list_hits(GLint hits, GLuint *names);
 
 void gl_draw()
 {
  	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 	glMatrixMode(GL_MODELVIEW);
 	glLoadIdentity();
  	glTranslatef(0.0, 0.0, -5.0);
  	glColor3f(1.0, 0.0, 0.0);
 	glLoadName(7);
 	draw_block(-0.3, 0, -2);
  	glColor3f(0.0, 1.0, 0.0);
 }
 
 void gl_init(int w, int h)
 {
 	glClearColor(0.0, 0.0, 0.0, 1.0);
 	glViewport(0, 0, w, h);
 	glMatrixMode(GL_PROJECTION);
 	glLoadIdentity();
 	gluPerspective(60.0, 1.0, 0.0001, 1000.0);
 	glMatrixMode(GL_MODELVIEW);
 }
 
 void sdl_events()
 {
 	SDL_Event event;
 	while (SDL_PollEvent(&event))
 	{
 		switch (event.type)
 		{
 			case SDL_QUIT: exit(0);
 			case SDL_MOUSEBUTTONDOWN:
 			{
 				sdl_mousedw(event.button.x, event.button.y, event.button.button);
 			}; break;
 			case SDL_KEYDOWN: exit(0);

 		}
 	}
 }
 
 void sdl_mousedw(int x, int y, int but)
 {
 	printf("Mouse button %d pressed at %d %d\n", but, x, y);
 	if (but == SDL_BUTTON_LEFT)
 		gl_select(x,SH-y);
 }
 
 void gl_select(int x, int y)
 {
 	GLuint buff[64] = {0};
 	GLint hits, view[4];
	glSelectBuffer(64, buff);
 	glGetIntegerv(GL_VIEWPORT, view);
 	glRenderMode(GL_SELECT);
 	glInitNames();
 	glPushName(0);
 	glMatrixMode(GL_PROJECTION);
 	glPushMatrix();
 	glLoadIdentity();
 	gluPickMatrix(x, y, 1.0, 1.0, view);
	gluPerspective(60, (float)view[2]/(float)view[3], 0.0001, 1000.0);
 	glMatrixMode(GL_MODELVIEW);
 	gl_draw();
 	glMatrixMode(GL_PROJECTION);
 	glPopMatrix();
  	hits = glRenderMode(GL_RENDER);
 	list_hits(hits, buff);
 	glMatrixMode(GL_MODELVIEW);
 }
 
 void draw_block(float x, float y, float z)
 {
	float card_x=0.0;
	float card_y=0.5;
	float card_width=1.0;
	float card_height=0.5;
	float card_z=-2.01;
 	glPushMatrix();
	glTranslatef(x, y, z);
	glLoadIdentity();
	glTranslatef( card_x, card_y, card_z  );
	glBegin(GL_QUADS);
		glColor3f( 0.4f, 0.7f, 0.0); glVertex3f( 0, -card_height, 0.0 ); /* left down */
		glColor3f( 0.4f, 0.7f, 0.0); glVertex3f(  0, -card_height, 0.0 ); /* right down */
		glColor3f(0.0f,0.0f,0.0f); glVertex3f(  card_width,  card_height, 0.0 ); /* right up */
		glColor3f(0.0f,0.0f,0.0f); glVertex3f( -card_width,  card_height, 0.0 ); /* left up */
	glEnd( ); 		
 	glPopMatrix();
 }
 
 void list_hits(GLint hits, GLuint *names)
 {
 	int i;
 	printf("%d hits:\n", hits);
 
 	for (i = 0; i < hits; i++)
 		printf(	"Name on stack: %d\n",
 				(GLubyte)names[i * 4 + 3]
 				);
 
 	printf("\n");
 }
 
 int main(int argc, char **argv)
 {
 	if (SDL_Init(SDL_INIT_VIDEO) < 0)
 	{
 		exit(1);
 	}
 	atexit(SDL_Quit);
 	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
 	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
 	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
 	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
 	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
 
 	if (!SDL_SetVideoMode(SW, SH, 0, SDL_OPENGL))
 	{
 		exit(1);
 	}
 	gl_init(SW, SH);
 
 	while (1)
 	{
 		sdl_events();
 		gl_draw();
 		SDL_GL_SwapBuffers();
 	}
  	return EXIT_SUCCESS;
 }
Frost ★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

ну учитывая что в гугл был послан... но я не злопамятен :)

Frost ★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

да, компиляция: gcc -std=c99 -Wall -ansi имя_исходника.c -o имя_исполняемого -lGL -lGLU -lm `sdl-config --libs --cflags`

Frost ★★★
() автор топика
Ответ на: комментарий от anonymous

(-std=c99)-запрет неявного указания переменных, (-ansi)-запрет однострочных комментариев типа //abs. Почему не с90? да пожалуйста, пусть будет c90 :)

Frost ★★★
() автор топика
Ответ на: комментарий от gavlig

а точнее карточная игра в Кинга (кажется это разновидность преферанса)... под windows она есть, а под линукс никто не написал ещё

Frost ★★★
() автор топика
Ответ на: комментарий от gavlig

спасибо огромное за ссылку! интересно... я только не совсем понял, спецификация Opengl ниже 2.0 версии эти модерновые выкрутасы не поддерживает?

Frost ★★★
() автор топика
Ответ на: комментарий от gavlig

для поддержки слабеньких видеокарт... например интегрированная intel gma 3100 - opengl 1,4... хотя может ты и прав, ситуация как с Explorer 6.0, тащили тащили его, а потом дружноо взяли и забили

Frost ★★★
() автор топика
Ответ на: комментарий от Frost

Ну смотри, если ты реально хочешь поддерживать большой парк машин и там особо красивых рисований не будет у тебя, то можно и такое старьё юзать, но ты должен понимать, что апи твоё уже deprecated

gavlig ★★★
()
Ответ на: комментарий от gavlig

Игрушку больше для семьи для себя начал делать, какой там парк:) Да и старинного железа 4 компьютера, хочется чтобы на всех она работала. Насчет апи полностью согласен, старьё. Glus посмотрел, сказка конечно. Спасибо еще раз.

Frost ★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.