簡體   English   中英

Linux上SDL OpenGL的新功能,這有什么問題?

[英]New to SDL OpenGL on Linux, whats wrong with this?

我已經寫了一些代碼在Ubuntu上進行opengl編程實驗,但是花了一些時間,但是我以前對C有一定的了解。由於我被告知c ++是游戲編程的首選語言,因此我試圖用它進行開發。

這是我對sdl進行opengl的第一次真正嘗試,到目前為止,它可以編譯並運行,但我的相機功能似乎無能為力。 我知道可能有很多更好的方法來執行此類操作,但是在繼續學習更高級的內容之前,我想先了解一些基礎知識。

main.cpp

#include <iostream>
#include <cmath>
#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"

int screen_width = 640;
int screen_height = 480;
const int screen_bpp = 32;
float rotqube = 0.9f;

float xpos = 0, ypos = 0, zpos = 0, xrot = 0, yrot = 0, angle=0.0;
float lastx, lasty;

SDL_Surface *screen = NULL; // create a default sdl_surface to render our opengl to

void camera (void) {
glRotatef(xrot,1.0,0.0,0.0);  // x-axis (left and right)
glRotatef(yrot,0.0,1.0,0.0);  // y-axis (up and down)
glTranslated(-xpos,-ypos,-zpos); // translate the screen to the position
SDL_GL_SwapBuffers();
}

int DrawCube(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

glTranslatef(0.0f, 0.0f,-7.0f);
glRotatef(rotqube,0.0f,1.0f,0.0f);
glRotatef(rotqube,1.0f,1.0f,1.0f);
glBegin(GL_QUADS);
    glColor3f(0.0f,1.0f,0.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glColor3f(1.0f,0.5f,0.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);
    glColor3f(1.0f,0.0f,0.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);
    glColor3f(1.0f,1.0f,0.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glColor3f(0.0f,0.0f,1.0f);
    glVertex3f(-1.0f, 1.0f, 1.0f);
    glVertex3f(-1.0f, 1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f,-1.0f);
    glVertex3f(-1.0f,-1.0f, 1.0f);
    glColor3f(1.0f,0.0f,1.0f);
    glVertex3f( 1.0f, 1.0f,-1.0f);
    glVertex3f( 1.0f, 1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f, 1.0f);
    glVertex3f( 1.0f,-1.0f,-1.0f);
glEnd();
SDL_GL_SwapBuffers();

rotqube +=0.9f;
return true;
}

bool init_sdl(void)
{
if( SDL_Init( SDL_INIT_EVERYTHING ) != 0 )
{
    return false;
}

SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );

// TODO: Add error check to this screen surface init
screen = SDL_SetVideoMode( screen_width, screen_height, screen_bpp, SDL_OPENGL | SDL_HWSURFACE | SDL_RESIZABLE );

return true;
}

static void init_opengl()
{
float aspect = (float)screen_width / (float)screen_height;
glViewport(0, 0, screen_width, screen_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0, aspect, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glClearColor(0.0, 0.0 ,0.0, 0);
glEnable(GL_DEPTH_TEST);
}

void heartbeat()
{
float xrotrad, yrotrad;
int diffx, diffy;

SDL_Event event;

while(1)
{
    while(SDL_PollEvent(&event))
    {
        switch(event.type)
        {
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_ESCAPE:
                        exit(0);
                        break;
                    case SDLK_w:
                        yrotrad = (yrot / 180 * 3.141592654f);
                        xrotrad = (xrot / 180 * 3.141592654f);
                        xpos += (float)sin(yrotrad);
                        zpos -= (float)cos(yrotrad);
                        ypos -= (float)sin(xrotrad);
                        std::cout << "w pressed" << std::endl;
                        break;
                    case SDLK_s:
                        yrotrad = (yrot / 180 * 3.141592654f);
                        xrotrad = (xrot / 180 * 3.141592654f);
                        xpos -= (float)sin(yrotrad);
                        zpos += (float)cos(yrotrad);
                        ypos += (float)sin(xrotrad);
                        break;
                    case SDLK_d:
                        yrotrad = (yrot / 180 * 3.141592654f);
                        xpos += (float)cos(yrotrad) * 0.2;
                        zpos += (float)sin(yrotrad) * 0.2;
                            break;
                        case SDLK_a:
                        yrotrad = (yrot / 180 * 3.141592654f);
                        xpos -= (float)cos(yrotrad) * 0.2;
                        zpos -= (float)sin(yrotrad) * 0.2;
                            break;
                    default:
                        break;
                }
                break;

            case SDL_MOUSEMOTION:
                diffx=event.motion.x-lastx; //check the difference between the current x and the last x position
                diffy=event.motion.y-lasty; //check the difference between the current y and the last y position
                lastx=event.motion.x; //set lastx to the current x position
                lasty=event.motion.y; //set lasty to the current y position
                xrot += (float)diffy; //set the xrot to xrot with the addition of the difference in the y position
                yrot += (float)diffx;    //set the xrot to yrot with the addition of the difference in the x position
                break;

            case SDL_QUIT:
                exit(0);
                break;

            case SDL_VIDEORESIZE:
                screen = SDL_SetVideoMode( event.resize.w, event.resize.h, screen_bpp, SDL_OPENGL | SDL_HWSURFACE | SDL_RESIZABLE );
                screen_width = event.resize.w;
                screen_height = event.resize.h;
                init_opengl();
                std::cout << "Resized to width: " << event.resize.w << " height: " << event.resize.h << std::endl;
                break;

            default:
                break;
        }
    }

    DrawCube();
    camera();

    SDL_Delay( 50 );
}
}

int main(int argc, char* argv[])
{
if( init_sdl() != false )
{
    std::cout << "SDL Init Successful" << std::endl;
}

init_opengl();

std::cout << "Hello World" << std::endl;

heartbeat();    // this is essentially the main loop

SDL_Quit();

return 0;
}

生成文件

all:
g++ -o test main.cpp -lSDL -lGL -lGLU

它可以編譯並運行,我想我在進行相機翻譯時只需要一些幫助。 謝謝

從DrawCube()中刪除glLoadIdentity()調用。 開頭替換為glPushMatrix(),結尾替換為glPopMatrix()。 現在按“ w”將執行某些操作。 (我不確定該怎么做。)

問題是glLoadIdentity清除了使用glTranslatef等設置的所有先前轉換。 詳細說明: http : //www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/pushmatrix.html

繪制立方體之前,請嘗試渲染相機。 現在,攝影機平移工作正常,但是您正在相對於攝影機在相同位置繪制立方體。 如果先繪制立方體,然后移動攝影機,您應該會看到期望的平移。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM