[英]Displaying image in openGL with SOIL
I'm trying to display an image in openGL using SDL and SOIL but it isn't working. 我正在尝试使用SDL和SOIL在openGL中显示图像,但是它不起作用。
#include <SDL.h>
#include <SDL_OpenGL.h>
#include <SOIL.h>
#include "player.h"
#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();
}
You have three problems in your code: 您的代码中存在三个问题:
GL_TEXTURE_2D
uses normalized texture coordinates ( 0.0 - 1.0 ). GL_TEXTURE_2D
使用归一化的纹理坐标(0.0 - 1.0)。 Unless H
and W
are 1.0 or less you do not want to use them for your texture coordinates. 除非H
和W
等于或小于1.0,否则您不希望将它们用于纹理坐标。 If you just want to stretch this texture across your quad one time, use 1.0 in-place of W
and H
. 如果只想一次在四边形上拉伸此纹理,请在W
和H
处使用1.0 。
Most Serious Issue: You are creating a new texture on each frame, you should load the texture one time and then pass the loaded texture handle to DisplayWithImage (...)
instead of having that function load a texture each time you call it. 最严重的问题:您正在每个帧上创建一个新纹理,应该加载一次纹理,然后将加载的纹理句柄传递给DisplayWithImage (...)
而不是让该函数每次调用时都加载纹理。
glOrtho (...)
creates an orthographic projection matrix, any GL operation that uses the projection matrix in isolation (eg not Projection * ModelView) is going to fail to work properly if you use an identity projection matrix and an orthographic projection matrix for your modelview matrix. glOrtho (...)
创建一个正交投影矩阵,使用单独的投影矩阵任何GL操作(例如未投影*模型视图)是要失败的,如果你使用的身份投影矩阵和正交投影矩阵正常工作的模型视图矩阵。 By the same token, things like vertex lighting will not work properly with a projection matrix serving as your modelview matrix... 出于同样的原因,像顶点照明这样的事情在投影矩阵作为模型视图矩阵的情况下将无法正常工作。
You can correct bullet point 3 by re-writing part of your code this way: 您可以通过以下方式重写部分代码来更正项目要点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.