I'm trying using visual studio 2019, c++, read(show) WebP image, but nothing happens.
I can open, gif, jpg, png, but not WebP
I'm using visual studio 2019, added sld, sdl_image, WebP, include's, libs, and dlls's.
console mesage -- Failed to decode WEBP --
#include <iostream>
#include <SDL.h>
#include <SDL_image.h>
const int WIDTH = 640, HEIGHT = 360;
int main(int argc, char* argv[])
{
SDL_Surface* imageSurface = NULL;
SDL_Surface* windowSurface = NULL;
SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window* window = SDL_CreateWindow("Hello SDL World", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_ALLOW_HIGHDPI);
windowSurface = SDL_GetWindowSurface(window);
// Check that the window was successfully created
if (NULL == window)
{
// In the case that the window could not be made...
std::cout << "Could not create window: " << SDL_GetError() << std::endl;
return 1;
}
if (!(IMG_Init(IMG_INIT_WEBP) & IMG_INIT_WEBP))
{
std::cout << "Could not create window: " << IMG_GetError() << std::endl;
return 1;
}
SDL_Event windowEvent;
imageSurface = IMG_Load("logo.webp");
if (NULL == imageSurface)
{
std::cout << "SDL could not load image! SDL Error: " << SDL_GetError() << std::endl;
}
while (true)
{
if (SDL_PollEvent(&windowEvent))
{
if (SDL_QUIT == windowEvent.type)
{
break;
}
}
SDL_BlitSurface(imageSurface, NULL, windowSurface, NULL);
SDL_UpdateWindowSurface(window);
}
SDL_FreeSurface(imageSurface);
SDL_FreeSurface(windowSurface);
imageSurface = NULL;
windowSurface = NULL;
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
Related
This question already has answers here:
How do I use SDL2 in my programs correctly?
(3 answers)
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 months ago.
I've got the following piece of code attempting to use SDL_image;
#include <iostream>
#define SDL_MAIN_HANDLED
#include <SDL.h>
#include <SDL_image.h>
int WIDTH = 800;
int HEIGHT = 800;
int main(int argc, char *argv[])
{
if (SDL_Init(SDL_INIT_VIDEO) > 0) {
std::cout << "SDL INIT FAILED" << SDL_GetError() << std::endl;
}
SDL_Window* window = SDL_CreateWindow("Chaturanga", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_ALLOW_HIGHDPI);
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (NULL == window)
{
std::cout << "Could not create window: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Texture* boardTexture = IMG_LoadTexture(renderer, "res/images/board.png");
if (boardTexture == NULL) {
std::cout << "Failed to load texture. Error: " << SDL_GetError() << std::endl;
}
SDL_Event windowEvent;
while (true)
{
if (SDL_PollEvent(&windowEvent))
{
if (SDL_QUIT == windowEvent.type)
{break;}
}
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, boardTexture, NULL, NULL);
SDL_RenderPresent(renderer);
}
SDL_DestroyWindow(window);
SDL_Quit();
return EXIT_SUCCESS;
}
When I compile with:
g++ src/*.cpp -o main.exe -I lib/SDL2_lib/include -L lib/sdl2_lib/libr -L lib/sdl2_lib -lsdl2 -lsdl2_image
I get the following error;
My file structure is as follows, all functionality not relating to sdl image works fine.
Yes, the sdl_image.h file is in include;
Inside the libr folder:
I am creating a menu for a game at C++ and I have a problem when I read a text file (.cfg), and I want to show it to the screen (With SDL,not console).
The problem is that in SDL, I only get the last line. Why is that?
Here is my code:
fstream characters;
characters.open("characters.cfg", ios::in);
while (getline(characters, line))
cout << line << endl;
And I create a string to show it with SDL_ttf:
void renderUI() {
SDL_Surface* textSurface;
SDL_Texture* textTexture;
SDL_Rect textRect;
SDL_Color white = { 255,255,255 };
textRect.w = 250;
textRect.h = 20;
textRect.x = 150;
textRect.y = 200;
string names = line;
textSurface = TTF_RenderText_Blended(gameFont, names.c_str(), white);
textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
if (textSurface == NULL)
{
cout << "TTF_RenderText_Solid() Failed: " << TTF_GetError() << endl;
TTF_Quit();
SDL_Quit();
exit(1);
}
SDL_RenderCopy(renderer, textTexture, NULL, &textRect);
}
And here a photo to show that I get the full text in the console, but not in SDL:
EXAMPLE PHOTO:
I have the solution. Here is the code:
fstream characters;
string line;
string text;
characters.open("characters.cfg", ios::in);
while (getline(characters, line))
{
text = text + line + "\n";
}
characters.close();
And hereĀ“s the code of SDL_ttf and the solution to the line break problem with SDL:
SDL_Surface* textSurface;
SDL_Texture* textTexture;
SDL_Rect textRect;
SDL_Color white = { 255,255,255 };
textRect.w = 250;
textRect.h = 400;
textRect.x = 150;
textRect.y = 185;
textSurface = TTF_RenderText_Blended_Wrapped(gameFont, text.c_str(), white, 500);
textTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
// If TTF_RenderText_Solid() Fail
if (textSurface == NULL)
{
cout << "TTF_RenderText_Solid() Failed: " << TTF_GetError() << endl;
TTF_Quit();
SDL_Quit();
exit(1);
}
Used this for the line break problem with SDL_TTF:
TTF_RenderText_Blended_Wrapped for be able to use line break
I have the following sound loading function:
bool Sound::load(const char* fileName)
{
sound = Mix_LoadWAV(fileName);
if (sound == nullptr)
{
std::cout << "Failed to load sound at path: " << fileName << "SDL_mixer error: " << Mix_GetError();
return false;
}
return true;
}
In Dev-C++, this works, fine. I wanted to use another IDE, so I started using Visual Studio 2017, and configured SDL2 for it. However, when I run this code, from the moment Mix_LoadWAV is called, Visual studio gives the following:
https://imgur.com/a/STnXx
I have searched alot on the internet, but I could not find anything useful that worked for me.
EDIT: as per request, I created a minimal example that still produces the same error.
#include "SDL2\SDL_mixer.h"
#include "SDL2\SDL.h"
#include <iostream>
#undef main
class SoundTest
{
private:
Mix_Chunk* sound = nullptr;
public:
bool load(const char* fileName)
{
sound = Mix_LoadWAV(fileName);
if (sound == nullptr)
{
std::cout << "Failed to load sound at path: " << fileName << "SDL_mixer error: " << Mix_GetError();
return false;
}
return true;
}
};
SDL_Window *window = nullptr;
int main(int argc, char** argv)
{
SDL_Init(SDL_INIT_EVERYTHING);
window = SDL_CreateWindow("Sound bug? ", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 300, 300, SDL_WINDOW_SHOWN);
Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 2048);
SoundTest sound;
sound.load("audio/soundEffect.wav");
while (true)
{
//Do fun stuff with the sound
}
return 0;
}
I cant seem to load a image onto a SDL window.
Code:
#include <iostream>
#include <SDL2/SDL.h>
#include <stdio.h>
using namespace std;
SDL_Window *window;
SDL_Surface *imageSurface;
SDL_Surface *image;
void createWindow() {
SDL_INIT_EVERYTHING;
if(SDL_INIT_EVERYTHING <0) {
cout << "SDL failed to initialize!" << endl;
}
window = SDL_CreateWindow("Test Window", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 640, 480,0);
if (window==NULL) {
cout << "Window could not be made" << endl;
}
imageSurface = SDL_GetWindowSurface(window);
}
void close() {
SDL_FreeSurface(image);
SDL_DestroyWindow(window);
SDL_Quit();
}
void loadmedia() {
image = SDL_LoadBMP("Test.bmp");
if (image==NULL) {
cout << "Image could not be loaded" << endl;
}
}
int main() {
createWindow();
loadmedia();
SDL_BlitSurface(image, NULL, imageSurface, NULL);
SDL_UpdateWindowSurface(window);
SDL_Delay(10000);
close();
}
You are missing the message loop.
Basically, your application is receiving messages to process operations such as drawing the window and all.
What you are missing is something like that:
while (!done) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT)
done = true;
}
}
You can find a sample here: http://www.gamedev.net/topic/376858-a-proper-sdl-message-loop/
I'm doing my first steps in SDL (C++) an took some tutorials from the www.
But there is one problem. I have installed SDL2 on my Linux Mint System, compiled the tutorial code:
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <SDL2/SDL.h>
#include <iostream>
int main ( int argc, char** argv )
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
SDL_WINDOW_SHOWN);
if (win == NULL){
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Renderer *ren = SDL_CreateRenderer(win, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == NULL){
std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Surface *bmp = SDL_LoadBMP("cb.bmp");
if (bmp == NULL){
std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, bmp);
SDL_FreeSurface(bmp);
if (tex == NULL){
std::cout << "SDL_CreateTextureFromSurface Error: "
<< SDL_GetError() << std::endl;
return 1;
}
SDL_Delay(4000);
SDL_DestroyTexture(tex);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
with this compile command:
g++ main.cpp -lSDL2 -o prog
And I got this:
A window frame without any inside. Where I have to look for this error?
Final Code
First: thanks to starrify!
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <SDL2/SDL.h>
#include <iostream>
int main ( int argc, char** argv )
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window *window = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
SDL_WINDOW_SHOWN);
if (window == NULL){
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
return 1;
}
/*
SDL_Renderer *ren = SDL_CreateRenderer(window, -1,
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == NULL){
std::cout << "SDL_CreateRenderer Error: " << SDL_GetError() << std::endl;
return 1;
}
*/
SDL_Surface *surface_bmp = SDL_LoadBMP("cb.bmp");
if (surface_bmp == NULL){
std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
return 1;
}
/*
SDL_Texture *tex = SDL_CreateTextureFromSurface(ren, surface_bmp);
SDL_FreeSurface(surface_bmp);
if (tex == NULL){
std::cout << "SDL_CreateTextureFromSurface Error: "
<< SDL_GetError() << std::endl;
return 1;
}
*/
SDL_Surface *surface_window = SDL_GetWindowSurface(window);
/*
* Copies the bmp surface to the window surface
*/
SDL_BlitSurface(surface_bmp,
NULL,
surface_window,
NULL);
/*
* Now updating the window
*/
SDL_UpdateWindowSurface(window);
/*
* This function used to update a window with OpenGL rendering.
* This is used with double-buffered OpenGL contexts, which are the default.
*/
/* SDL_GL_SwapWindow(window); */
SDL_Delay(5000);
/* SDL_DestroyTexture(tex);*/
/* SDL_DestroyRenderer(ren);*/
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
Show me this result :)
I saw that it was truly easy. An in this way I don't need no openGL for drawing. This will be the next step.
It ould be nice, if you help me to improve this example to get it with openGL to...
SDL - window doesn't show anything
The reason is that you're not drawing anything. You created a window, a renderer, a surface, and a texture. However you're not drawing anything. And the visual result reflects exactly what you've done.
To simply display a BMP image, load the image into a surface and use SDL_BlitSurface to copy it to the screen. Or to work with textures, you shall draw primitives like triangles or quads just like working with OpenGL.
Also another problem: why your window looks filled with other content than a blank screen?
That's because these years the default video mode is set to double buffering, which means there's a front buffer to be shown and a back buffer to render on. When finishing rendering a single frame, you shall call something like SDL_Flip (seems it's been obsoleted in SDL2) or SDL_UpdateWindowSurface.
EDITED: I've edited your code and here's something that works: (removed renderer/texture, added SDL_BlitSurface and SDL_UpdateWindowSurface)
#ifdef __cplusplus
#include <cstdlib>
#else
#include <stdlib.h>
#endif
#include <stdio.h>
#include <SDL2/SDL.h>
#include <iostream>
int main ( int argc, char** argv )
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0){
std::cout << "SDL_Init Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Window *win = SDL_CreateWindow("Hello World!", 100, 100, 640, 480,
SDL_WINDOW_SHOWN);
if (win == NULL){
std::cout << "SDL_CreateWindow Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_Surface *bmp = SDL_LoadBMP("cb.bmp");
if (bmp == NULL){
std::cout << "SDL_LoadBMP Error: " << SDL_GetError() << std::endl;
return 1;
}
SDL_BlitSurface(bmp, 0, SDL_GetWindowSurface(win), 0);
SDL_UpdateWindowSurface(win);
SDL_Delay(4000);
SDL_DestroyWindow(win);
SDL_Quit();
return 0;
}
Since you're using SDL2, you should not be using an SDL_Surface to update the screen. That's the old way that SDL 1.2 had to use. The new renderer subsystem is what you want for general use because it is hardware-accelerated (uses the GPU) while SDL_BlitSurface() and SDL_UpdateWindowSurface() are not (all pixel copying is done on the CPU).
So here's what to do. Do not use SDL_GetWindowSurface(). Use your previous code for creating a renderer and texture. Replace SDL_BlitSurface() with a call to SDL_RenderCopy(). Replace SDL_UpdateWindowSurface() with a call to SDL_RenderPresent().
Alternatively, you can use SDL_gpu (note: I'm the author), which feels like the older SDL 1.2 blitting API, but has even more features and optimizations than SDL_Renderer.