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.
Related
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;
}
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'm having a problem where the following lines of code always print "Failed to initialize glad" and then exits the program:
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
I have been using https://learnopengl.com/ as a guide and have been following the steps in the getting started section. I am writing this using Visual Studio, I have moved the glad.c source file into the build to get this working and added the header files to the same location where I specified the glfw header would be, but I haven't been able to find anyone with a problem similar to mine.
Commenting out return -1; line results in an access violation exception, so it is definitely here that the program is having trouble.
Here is the entire program in case there is something else I am missing:
#include "stdafx.h"
#include <GLFW/glfw3.h>
#include <glad/glad.h>
#include <iostream>
using namespace std;
void init_glfw();
void framebuffer_size_callback(GLFWwindow*, int, int);
int main(int argc, char **argv)
{
init_glfw();
GLFWwindow* window = glfwCreateWindow(800, 600, "Lab3", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
while (!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void init_glfw()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
You never made your GL context current via glfwMakeContextCurrent(). Unlike other GL windowing frameworks GLFW doesn't leave the GL context current when glfwCreateWindow() succeeds.
Call glfwMakeContextCurrent() after glfwCreateWindow() succeeds:
GLFWwindow* window = glfwCreateWindow(800, 600, "Lab3", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent( window );
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
I'm having a problem where the following lines of code always print "Failed to initialize glad" and then exits the program:
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
I have been using https://learnopengl.com/ as a guide and have been following the steps in the getting started section. I am writing this using Visual Studio, I have moved the glad.c source file into the build to get this working and added the header files to the same location where I specified the glfw header would be, but I haven't been able to find anyone with a problem similar to mine.
Commenting out return -1; line results in an access violation exception, so it is definitely here that the program is having trouble.
Here is the entire program in case there is something else I am missing:
#include "stdafx.h"
#include <GLFW/glfw3.h>
#include <glad/glad.h>
#include <iostream>
using namespace std;
void init_glfw();
void framebuffer_size_callback(GLFWwindow*, int, int);
int main(int argc, char **argv)
{
init_glfw();
GLFWwindow* window = glfwCreateWindow(800, 600, "Lab3", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
glViewport(0, 0, 800, 600);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
while (!glfwWindowShouldClose(window))
{
glfwSwapBuffers(window);
glfwPollEvents();
}
glfwTerminate();
return 0;
}
void init_glfw()
{
glfwInit();
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
}
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
glViewport(0, 0, width, height);
}
You never made your GL context current via glfwMakeContextCurrent(). Unlike other GL windowing frameworks GLFW doesn't leave the GL context current when glfwCreateWindow() succeeds.
Call glfwMakeContextCurrent() after glfwCreateWindow() succeeds:
GLFWwindow* window = glfwCreateWindow(800, 600, "Lab3", NULL, NULL);
if (window == NULL)
{
cout << "Failed to create GLFW window" << endl;
glfwTerminate();
return -1;
}
glfwMakeContextCurrent( window );
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
std::cout << "Failed to initialize GLAD" << std::endl;
return -1;
}
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/