我正在尝试使用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();
}

最佳答案

您的代码中存在三个问题:


GL_TEXTURE_2D使用归一化的纹理坐标(0.0-1.0)。除非HW等于或小于1.0,否则您不希望将它们用作纹理坐标。如果只想一次在四边形上拉伸此纹理,请在WH的原位使用1.0。
最严重的问题:您正在每个帧上创建一个新纹理,应该加载一次纹理,然后将加载的纹理句柄传递给DisplayWithImage (...),而不是让该函数每次调用时都加载纹理。
glOrtho (...)创建一个正投影矩阵,如果您将恒等投影矩阵和正投影矩阵用于Modelview矩阵,则任何单独使用投影矩阵的GL操作(例如不是Projection * ModelView)将无法正常工作。出于同样的原因,像顶点照明这样的事情在投影矩阵作为模型视图矩阵的情况下将无法正常工作。


您可以通过以下方式重写部分代码来更正项目要点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!

关于c++ - 在带有SOIL的openGL中显示图像,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19719736/

10-13 09:28