簡體   English   中英

在帶有SOIL的openGL中顯示圖像

[英]Displaying image in openGL with SOIL

我正在嘗試使用SDL和SOIL在openGL中顯示圖像,但是它不起作用。

Globals.h

#include <SDL.h>
#include <SDL_OpenGL.h>
#include <SOIL.h>

#include "player.h"

main.cpp

#include "Globals.h"

int main(int argc, char** argv){
    //Begin SDL initialization
    SDL_Init(SDL_INIT_EVERYTHING);
    SDL_Surface* Screen = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE|SDL_OPENGL);
    SDL_Event Event;
    //End SDL initialization

    //Begin OpenGL initialization
    glClearColor(1, 1, 1, 1);//Set colour for empty screen
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);//Enable transparency
    glEnable(GL_TEXTURE_2D);

    glShadeModel(GL_SMOOTH);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glOrtho(-400, 400, -300, 300, -1, 1);//Set grid for display

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    //End OpenGL initialization

    Player Player(0, 0, 32, 64, 1, 0, 0, 0.5);
    bool gameRunning = true;

    while(gameRunning){
        while(SDL_PollEvent(&Event)){
            if(Event.type == SDL_QUIT)
                gameRunning = false;
                //If user closed the window in any way stop gameRunning
            Player.Events(Event);
        }
        Player.Update();

        glClear(GL_COLOR_BUFFER_BIT);//Clear screen

        glPushMatrix();

        Player.DisplayWithImage("Brick.png", 32, 64);

        glPopMatrix();

        SDL_GL_SwapBuffers();//Update screen with new shit
    }

    SDL_Quit();//Quit SDL
    return 0;//End program
}

播放器

#pragma once

class Player{
public:
    GLfloat X, Y, W, H, R, G, B, A;
    bool movingUp, movingRight, movingDown, movingLeft;
    GLuint image;

    Player(GLfloat x, GLfloat y, GLfloat w, GLfloat h,
        GLfloat r, GLfloat g, GLfloat b, GLfloat a);
    void Events(SDL_Event &Event);
    void Update();
    void Display();
    void DisplayWithImage(const char* filename, GLsizei w, GLsizei h);
};

播放器

#include "Globals.h"

Player::Player(GLfloat x, GLfloat y, GLfloat w, GLfloat h, GLfloat r, GLfloat g, GLfloat b, GLfloat a){
    X = x;
    Y = y;
    W = w;
    H = h;
    R = r;
    G = g;
    B = b;
    A = a;

    movingUp = false;
    movingRight = false;
    movingDown = false;
    movingLeft = false;
}

void Player::Events(SDL_Event &Event){
    if(Event.type == SDL_KEYDOWN){
        if(Event.key.keysym.sym == SDLK_w)
            movingUp = true;
        if(Event.key.keysym.sym == SDLK_d)
            movingRight = true;
        if(Event.key.keysym.sym == SDLK_s)
            movingDown = true;
        if(Event.key.keysym.sym == SDLK_a)
            movingLeft = true;
    }
    if(Event.type == SDL_KEYUP){
        if(Event.key.keysym.sym == SDLK_w)
            movingUp = false;
        if(Event.key.keysym.sym == SDLK_d)
            movingRight = false;
        if(Event.key.keysym.sym == SDLK_s)
            movingDown = false;
        if(Event.key.keysym.sym == SDLK_a)
            movingLeft = false;
    }
}

void Player::Update(){
    if(movingUp)
        Y ++;
    if(movingRight)
        X ++;
    if(movingDown)
        Y --;
    if(movingLeft)
        X --;
}

void Player::Display(){
    glBegin(GL_QUADS);

        glColor4f(R, G, B, A);

        //bottom right
        glVertex2f(X+(W/2), Y-(H/2));
        //top right
        glVertex2f(X+(W/2), Y+(H/2));
        //top left
        glVertex2f(X-(W/2), Y+(H/2));
        //bottom left
        glVertex2f(X-(W/2), Y-(H/2));

    glEnd();
}

void Player::DisplayWithImage(const char* filename, GLsizei w, GLsizei h){
    image = SOIL_load_OGL_texture // load an image file directly as a new OpenGL texture
    (
        filename,
        SOIL_LOAD_AUTO,
        SOIL_CREATE_NEW_ID,
        SOIL_FLAG_MIPMAPS | SOIL_FLAG_INVERT_Y | SOIL_FLAG_NTSC_SAFE_RGB | SOIL_FLAG_COMPRESS_TO_DXT
    );

    glBindTexture(GL_TEXTURE_2D, image);

    glBegin(GL_QUADS);

        //bottom right
        glTexCoord2f(0, 0); glVertex2f(X+(W/2), Y-(H/2));
        //top right
        glTexCoord2f(0, H); glVertex2f(X+(W/2), Y+(H/2));
        //top left
        glTexCoord2f(W, H); glVertex2f(X-(W/2), Y+(H/2));
        //bottom left
        glTexCoord2f(W, 0); glVertex2f(X-(W/2), Y-(H/2));

    glEnd();
}

您的代碼中存在三個問題:

  1. GL_TEXTURE_2D使用歸一化的紋理坐標(0.0 - 1.0)。 除非HW等於或小於1.0,否則您不希望將它們用於紋理坐標。 如果只想一次在四邊形上拉伸此紋理,請在WH處使用1.0

  2. 最嚴重的問題:您正在每個幀上創建一個新紋理,應該加載一次紋理,然后將加載的紋理句柄傳遞給DisplayWithImage (...)而不是讓該函數每次調用時都加載紋理。

  3. glOrtho (...)創建一個正交投影矩陣,使用單獨的投影矩陣任何GL操作(例如投影*模型視圖)是要失敗的,如果你使用的身份投影矩陣和正交投影矩陣正常工作的模型視圖矩陣。 出於同樣的原因,像頂點照明這樣的事情在投影矩陣作為模型視圖矩陣的情況下將無法正常工作。

您可以通過以下方式重寫部分代碼來更正項目要點3:

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

glOrtho(-400, 400, -300, 300, -1, 1);//Set grid for display
~~~~~~~ This should come AFTER you set the matrix mode to projection!

暫無
暫無

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

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