C++/SDL need help getting an image on screen - c++

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/

Related

SDL_image fails to show WebP image - Failed to decode WEBP?

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;
}

SDL Image "undefined reference to `IMG_LoadTexture` [duplicate]

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:

MinGW C++ Eclipse CDT program terminates instantly

I have been trying for hours to get a test SDL program up and running, but no matter what I try, it instantly terminates upon launching.
My code:
#include <iostream>
#include <SDL.h>
#undef main
using namespace std;
int main(int argc, char *argv[]) {
const int WIDTH = 800, HEIGHT = 600, SDLWP = SDL_WINDOWPOS_UNDEFINED;
if(SDL_Init(SDL_INIT_VIDEO) < 0) {
cout << "SDL not working." << endl;
}
cout << "SDL working properly." << endl;
SDL_Window *window = SDL_CreateWindow("Test", SDLWP, SDLWP, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL) {
SDL_Quit();
}
bool quit = false;
SDL_Event event;
while(!quit) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
quit = true;
}
}
}
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
I have gotten the program to actually do something by having this code:
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
cout << "SDL working properly." << endl;
}
Also, about the #undef main part, I need that because otherwise, the program will think that I am calling SDL_main.
Here is the library search path if that helps:
C:\Users\ (my username)\Desktop\SDL2-2.0.4\i686-w64-mingw32\lib
And the libraries themselves, written in order from top to bottom:
mingw32
SDL2main
SDL2
No other library path will give me no compiler errors except:
C:\Users\ (my username)\Desktop\SDL2-2.0.4\lib\x86
So it seems that the root of problem is:
#include <SDL.h>

Multithreading with opencv and pthreads

I wanted to get video frames from openCV and render it onto a graphics screen with openGL. I got it to work; however, the video drops frames consistently. I believe its because reading the frame and rendering is all on the same thread. Therefore, I implemented multithreading with pthreads but imshow is just a white screen. Also, it seems like the main thread does not run. I implemented a version with conditions and signals, and one with it. Any pointers to what I am doing wrong will be very helpful. Below is my code:
void *updateloop(void *arg)
{
while(1)
{
pthread_mutex_lock(&frameLocker);
while(my_queue.empty())
{
pthread_cond_wait(&condc, &frameLocker);
}
std::cout << "entering update loop" << std::endl;
current_image = my_queue.front();
my_queue.pop();
/*
if(!current_image.empty())
{
std::cout << "rendering to output window" << std::endl;
cv::imshow("Output Window", current_image);
cv::waitKey(30);
}
*/
pthread_mutex_unlock(&frameLocker);
}
}
void *captureloop(void *arg)
{
cv::Mat tempFrame;
while(1)
{
std::cout << "entering capture loop" << std::endl;
cap.read(tempFrame);
pthread_mutex_lock(&frameLocker);
my_queue.push(tempFrame);
pthread_cond_signal(&condc);
pthread_mutex_unlock(&frameLocker);
}
}
int main(int argc, const char * argv[])
{
cap.open(0);
pthread_mutex_init(&frameLocker, NULL);
pthread_t update, webcam;
pthread_cond_init(&condc, NULL);
pthread_cond_init(&condp, NULL);
pthread_create(&update, NULL, updateloop, NULL);
pthread_create(&webcam, NULL, captureloop, NULL);
pthread_join(update, NULL);
pthread_join(webcam, NULL);
cv::Mat tempFrame;
while (1)
{
pthread_mutex_lock(&frameLocker);
std::cout << "in the main thread" << std::endl;
if(current_image.empty()){
printf("recieved empty frame\n");
continue;
}
if(!current_image.empty())
{
std::cout << "rendering to output window" << std::endl;
cv::imshow("Output Window", current_image);
}
cv::waitKey(1);
pthread_mutex_unlock(&frameLocker);
}
return 0;
}

SDL - window doesn't show anything

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.