Witam. Od niedawnego czasu uczę się opengl'a. Napisałem prostego snake i chciałbym aby w kierunku jego poruszanie się padało światło (coś w stylu jak światła samochodu). Nie wiem jak obracać światłem. Wiem pytanie pewnie łatwe ale męczę się z tym od wczoraj :/ Aplikacja w załączniku Oto kod:
#include <GL/glut.h>
#include <stdlib.h>
#include <deque>
#include <ctime>
#include <cmath>
#include <StopWatch.h>
#include <OGLMaterials.h>
#include <OGLcolors.h>
#include <iostream>
using namespace std;
const unsigned int Width = 1024;
const unsigned int Height = 768;
const double ViewLeft = 10;
const double ViewRight = 10;
const double ViewBottom = 10;
const double ViewTop = 10;
const double ViewNear = 40;
const double ViewFar = 80;
const double FieldSize = 10;
enum KEYS{ UP = 1, DOWN = 2, LEFT = 3, RIGHT = 4, PAUSE = 'P' };
KEYS LastKey = UP;
struct Wspolrzedne{ int x,z; };
std::deque <Wspolrzedne> Snake;
Wspolrzedne Award;
void GameReset();
void RenderScene();
void Keyboard( unsigned char key, int x, int y );
void KeyEvent(int key, int x, int y);
void ResizeWindow(int w, int h);
void SnakeDraw();
void GenerateFloorList();
void WallDraw();
void AwardDraw();
void setAward();
void moveSnake();
void checkCollisionSnake_Snake();
void checkCollisionSnake_Award();
void checkCollisionSnake_Wall();
void checkGame();
void cubeDraw();
bool bIsAward = false;
bool bGameIsGood = false;
static CStopWatch Timer;
float SnakeSpeed = 0.3;
float Scores = 0;
GLint Lista_Podlogi;
int main(int argc, char *argv[])
{
///inicjalizacja okna programu itp.
glutInit(&argc, argv);
glutInitWindowSize(Width,Height);
glutInitWindowPosition(10,10);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
glutCreateWindow("3D Snake!");
glutDisplayFunc(RenderScene);
glutReshapeFunc(ResizeWindow);
glutSpecialFunc(KeyEvent);
glutKeyboardFunc(Keyboard);
GenerateFloorList();
glutMainLoop();
return EXIT_SUCCESS;
}
void GameReset()
{
setAward();
Snake.clear();
Wspolrzedne temporary;
temporary.x = 0;
temporary.z = 0;
Snake.push_back(temporary);
temporary.z = 1;
Snake.push_back(temporary);
temporary.z = 2;
Snake.push_back(temporary);
bGameIsGood = true;
Scores = 0;
SnakeSpeed = 0.3;
LastKey = UP;
}
void checkGame()
{
if (!bGameIsGood){
GameReset();
}
if (!bIsAward){
setAward();
}
if ( Timer.GetElapsedSeconds() >= SnakeSpeed ){
checkCollisionSnake_Wall();
checkCollisionSnake_Award();
checkCollisionSnake_Snake();
moveSnake();
Timer.Reset();
}
glutPostRedisplay();
}
void setAward()
{
srand(time(NULL));
Award.x = (rand() % 20) - 10;
Award.z = (rand() % 20) - 10;
bIsAward = true;
}
void SnakeDraw()
{
///Glowa weza
glColor3fv(CornflowerBlue);
glPushMatrix();
glTranslatef(Snake[0].x+0.5,0.5,Snake[0].z+0.5);
glScalef(0.5,0.5,0.5);
cubeDraw();
glColor3fv(LimeGreen);
glTranslatef(0.0,1.5,0.0);
glutWireSphere(0.5,30,15);
glPopMatrix();
///Cialo weza
glColor3fv(PowderBlue);
for (int i = 1; i < Snake.size(); ++i){
if (i == Snake.size() - 1)
glColor3fv(LightSkyBlue);
glPushMatrix();
glTranslatef(Snake[i].x+0.5,0.5,Snake[i].z+0.5);
glScalef(0.5,0.5,0.5);
cubeDraw();
glPopMatrix();
}
}
void GenerateFloorList()
{
Lista_Podlogi = glGenLists( 1 );
glNewList(Lista_Podlogi, GL_COMPILE);
glBegin(GL_QUADS);
glNormal3f(1.0,0.0,0.0);
for (float x = -FieldSize; x <FieldSize; x += 1.0f){
for (float z = -FieldSize; z <FieldSize; z +=1.0f){
glColor4f( Blue[ 0 ], Blue[ 1 ], Blue[ 2 ], 0.5 );
glVertex3f( x + 0.0, 0.0, z + 0.0 );
glVertex3f( x + 0.0, 0.0, z + 0.5 );
glVertex3f( x + 0.5, 0.0, z + 0.5 );
glVertex3f( x + 0.5, 0.0, z + 0.0 );
glColor4f( Silver[ 0 ], Silver[ 1 ], Silver[ 2 ], 0.7 );
glVertex3f( x + 0.5, 0.0, z + 0.0 );
glVertex3f( x + 0.5, 0.0, z + 0.5 );
glVertex3f( x + 1.0, 0.0, z + 0.5 );
glVertex3f( x + 1.0, 0.0, z + 0.0 );
glColor4f( Blue[ 0 ], Blue[ 1 ], Blue[ 2 ], 0.5 );
glVertex3f( x + 0.5, 0.0, z + 0.5 );
glVertex3f( x + 0.5, 0.0, z + 1.0 );
glVertex3f( x + 1.0, 0.0, z + 1.0 );
glVertex3f( x + 1.0, 0.0, z + 0.5 );
glColor4f( Silver[ 0 ], Silver[ 1 ], Silver[ 2 ], 0.7 );
glVertex3f( x + 0.0, 0.0, z + 0.5 );
glVertex3f( x + 0.0, 0.0, z + 1.0 );
glVertex3f( x + 0.5, 0.0, z + 1.0 );
glVertex3f( x + 0.5, 0.0, z + 0.5 );
}
}
glEnd();
glEndList();
}
void WallDraw()
{
glColor3fv(Sienna);
glPushMatrix();
///tyl
for (int x = -FieldSize; x <= FieldSize + 1; ++x ){
for (int y = 0; y < 10; ++y){
glPushMatrix();
glTranslatef(x - 0.5, y+0.5,-FieldSize -0.5 );
glScalef(0.5,0.5,0.5);
glBegin(GL_TRIANGLES);
cubeDraw();
glEnd();
glPopMatrix();
}
}
///lewa i prawa
for (int z = -FieldSize; z <= FieldSize; ++z ){
for (int y = 0; y < 10; ++y){
glPushMatrix(); ///lewa
glTranslatef(-FieldSize-0.5, y+0.5, z-0.5 );
glScalef(0.5,0.5,0.5);
glBegin(GL_TRIANGLES);
cubeDraw();
glEnd();
glPopMatrix();
glPushMatrix(); ///prawa
glTranslatef(FieldSize+0.5, y+0.5, z - 0.5);
glScalef(0.5,0.5,0.5);
glBegin(GL_TRIANGLES);
cubeDraw();
glEnd();
glPopMatrix();
}
}
}
void AwardDraw()
{
static float rot = 0;
rot += Timer.GetElapsedSeconds();
glPushMatrix();
glColor3fv(GreenYellow);
glPushMatrix();
glTranslatef(Award.x+0.5,0.5,Award.z+0.5);
glRotatef(rot*20,1,1,1);
glutWireSphere(0.5,16,8);
glPopMatrix();
glPushMatrix();
glTranslatef(Award.x+0.5,0.5,Award.z+0.5);
glTranslatef(0.0,2.0,0.0);
glRotatef(rot*20,0,1,0);
glRotatef(90,1,0,0);
glColor3fv(Red);
glutWireCone(0.5,1.0,16,8);
glPopMatrix();
glPopMatrix();
}
void RenderScene()
{
GLfloat light_direction[3] =
{
0.0,0.0,-1.0
};
glClearColor(0.0,0.1,0.1,1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glPushMatrix();
glLoadIdentity();
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glEnable(GL_NORMALIZE);
glEnable(GL_COLOR_MATERIAL);
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
glTranslatef( 0, 0, -( ViewNear + ViewFar ) / 2 );
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glLightf( GL_LIGHT0, GL_SPOT_CUTOFF, 90.0);
glLightf( GL_LIGHT0, GL_SPOT_EXPONENT, 0);
glLightf( GL_LIGHT0, GL_CONSTANT_ATTENUATION, 0.5);
glLightf( GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.4);
glLightf( GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0);
glLightfv( GL_LIGHT0, GL_SPOT_DIRECTION, light_direction );
glPushMatrix();
glScalef(1,1,1);
GLfloat light_position[ 4 ] = { Snake[0].x,0,Snake[0].z, 1 };
glLightfv( GL_LIGHT0, GL_POSITION, light_position );
glPopMatrix();
glEnable(GL_LIGHT0);
glRotated(25,1,0,0);
glCallList(Lista_Podlogi);
WallDraw();
AwardDraw();
SnakeDraw();
glPopMatrix();
glFlush();
glutSwapBuffers();
checkGame();
}
void Keyboard( unsigned char key, int x, int y )
{
switch( key )
{
}
}
void KeyEvent(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_UP:
LastKey = UP;
break;
case GLUT_KEY_DOWN:
LastKey = DOWN;
break;
case GLUT_KEY_LEFT:
LastKey = LEFT;
break;
case GLUT_KEY_RIGHT:
LastKey = RIGHT;
break;
default:
break;
}
}
void moveSnake()
{
Wspolrzedne temp;
Snake.pop_back();
switch(LastKey)
{
case UP:
temp.x = Snake[0].x;
temp.z = Snake[0].z-1;
break;
case DOWN:
temp.x = Snake[0].x;
temp.z = Snake[0].z+1;
break;
case LEFT:
temp.x = Snake[0].x-1;
temp.z = Snake[0].z;
break;
case RIGHT:
temp.x = Snake[0].x+1;
temp.z = Snake[0].z;
break;
}
Snake.push_front(temp);
}
void ResizeWindow(int width, int height)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glFrustum( -ViewLeft, ViewRight, -ViewBottom, ViewTop, ViewNear, ViewFar );
}
void checkCollisionSnake_Award()
{
if (Snake[0].x == Award.x && Snake[0].z == Award.z){
bIsAward = false;
Snake.push_back(Snake[Snake.size()-1]);
Scores += 25;
if (SnakeSpeed > 0.08f)
SnakeSpeed -= 0.01;
}
}
void checkCollisionSnake_Wall()
{
if ( Snake[0].x >= FieldSize ||
Snake[0].x < -FieldSize ||
Snake[0].z >= FieldSize ||
Snake[0].z < - FieldSize){
GameReset();
}
}
void checkCollisionSnake_Snake()
{
for (int i = 1; i < Snake.size(); ++i){
if (Snake[0].x == Snake[i].x && Snake[0].z == Snake[i].z && i > 2){
for (int j = Snake.size(); j >= i; --j){
Snake.pop_back();
}
return;
}
}
}
void cubeDraw()
{
glBegin(GL_TRIANGLES);
glVertex3f( - 1.0, - 1.0, 1.0 );
glVertex3f( 1.0, - 1.0, 1.0 );
glVertex3f( 1.0, 1.0, 1.0 );
glVertex3f( - 1.0, - 1.0, 1.0 );
glVertex3f( 1.0, 1.0, 1.0 );
glVertex3f( - 1.0, 1.0, 1.0 );
glVertex3f( - 1.0, 1.0, 1.0 );
glVertex3f( 1.0, 1.0, 1.0 );
glVertex3f( - 1.0, 1.0, - 1.0 );
glVertex3f( - 1.0, 1.0, - 1.0 );
glVertex3f( 1.0, 1.0, 1.0 );
glVertex3f( 1.0, 1.0, - 1.0 );
glVertex3f( 1.0, 1.0, - 1.0 );
glVertex3f( 1.0, 1.0, 1.0 );
glVertex3f( 1.0, - 1.0, 1.0 );
glVertex3f( 1.0, 1.0, - 1.0 );
glVertex3f( 1.0, - 1.0, 1.0 );
glVertex3f( 1.0, - 1.0, - 1.0 );
glVertex3f( 1.0, - 1.0, - 1.0 );
glVertex3f( 1.0, - 1.0, 1.0 );
glVertex3f( - 1.0, - 1.0, - 1.0 );
glVertex3f( - 1.0, - 1.0, - 1.0 );
glVertex3f( 1.0, - 1.0, 1.0 );
glVertex3f( - 1.0, - 1.0, 1.0 );
glVertex3f( - 1.0, - 1.0, - 1.0 );
glVertex3f( - 1.0, - 1.0, 1.0 );
glVertex3f( - 1.0, 1.0, - 1.0 );
glVertex3f( - 1.0, 1.0, - 1.0 );
glVertex3f( - 1.0, - 1.0, 1.0 );
glVertex3f( - 1.0, 1.0, 1.0 );
glVertex3f( - 1.0, - 1.0, - 1.0 );
glVertex3f( - 1.0, 1.0, - 1.0 );
glVertex3f( 1.0, 1.0, - 1.0 );
glVertex3f( 1.0, - 1.0, - 1.0 );
glVertex3f( - 1.0, - 1.0, - 1.0 );
glVertex3f( 1.0, 1.0, - 1.0 );
glEnd();
}
Z góry dziękuje :)
- snake.zip (174 KB) - ściągnięć: 108