Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 为什么';SDL2渲染器没有在我的窗口中绘制任何内容吗?_C_Sdl 2 - Fatal编程技术网

C 为什么';SDL2渲染器没有在我的窗口中绘制任何内容吗?

C 为什么';SDL2渲染器没有在我的窗口中绘制任何内容吗?,c,sdl-2,C,Sdl 2,我目前正在使用C语言编写一个Chip-8解释器。对于渲染,我使用SDL2库。问题是我不能在屏幕上画矩形。SDL_RenderClear功能也不起作用。可能是Makefile,但我已经尝试将链接器中的console标志更改为windows。有人能帮我吗 我的代码: main.c #include "chip.h" #define NO_ROM_INSERTED 1 const int PIXEL_SIZE = 20; const int CHIP_WIDTH = 64; const int C

我目前正在使用C语言编写一个Chip-8解释器。对于渲染,我使用SDL2库。问题是我不能在屏幕上画矩形。SDL_RenderClear功能也不起作用。可能是Makefile,但我已经尝试将链接器中的console标志更改为windows。有人能帮我吗

我的代码:

main.c

#include "chip.h"

#define NO_ROM_INSERTED 1

const int PIXEL_SIZE = 20;
const int CHIP_WIDTH = 64;
const int CHIP_HEIGHT = 32;

const int SCREEN_WIDTH = CHIP_WIDTH * PIXEL_SIZE;
const int SCREEN_HEIGHT = CHIP_HEIGHT * PIXEL_SIZE;

int main(int argc, char **argv)
{
    SDL_Window *window = NULL;
    SDL_Renderer *renderer = NULL;
    SDL_Event event;
    int quit = 0;

    Chip *chip = (Chip*)malloc(sizeof(Chip));
    chipInitialize(chip);

    chip->gfx[23] = 0x01;

    /*Checks if a ROM file is inserted by an argument*/
    if(argc < 2)    
    {
        printf("Error, no Rom inserted");
        return NO_ROM_INSERTED;
    }
    else
    {
        printf("\n%s loaded into memory\n", argv[argc-1]);
    }

    loadProgramInMemory(chip, "./Roms/TETRIS");


    if(!init(window, renderer, SCREEN_WIDTH, SCREEN_HEIGHT))
    {
        printf( "Failed to initialize!\n" );
    }
    else
    {   
        while(!quit)
        {
            while(SDL_PollEvent(&event) != 0)
            {
                if(event.type == SDL_QUIT)
                {
                    quit = 1;
                }
            }

            // Clear screen
            SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0xFF, 0xFF);
            SDL_RenderClear(renderer);

            for(int i = 0; i < CHIP_HEIGHT; i++)
            {
                for(int j = 0; j < CHIP_WIDTH; j++)
                {
                    if(chip->gfx[i * CHIP_WIDTH + j] > 0x00) //Translates the one dimensional gfx to two dimensional screen
                    {
                        SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
                        SDL_Rect fillRect = {CHIP_WIDTH * i, CHIP_HEIGHT * j, PIXEL_SIZE, PIXEL_SIZE};
                        SDL_RenderFillRect(renderer, &fillRect);
                    }
                }
            }
            // Update screen
            SDL_RenderPresent(renderer);
        }
    }

    close(window, renderer);

    free(chip);

    return 0;
}
#include "chip.h"

void chipInitialize(Chip *chip)
{
    chip->pc            = 0x200;            // Set program counter to 0x200
    chip->opcode        = 0x0000;           // Reset current opcode
    chip->I             = 0x0000;           // Reset index register
    chip->sp            = 0x0000;           // Reset stack pointer

    chip->delayTimer    = 0x00;             // Reset delay timer
    chip->soundTimer    = 0x00;             // Reset sound timer

    for(int i = 0; i < 64 * 32; i++)        // Reset the graphics
        chip->gfx[i] = 0x00;

    for(int i = 0; i < 16; i++)             // Reset the stack
        chip->stack[i] = 0x0000;

    for(int i = 0; i < 4069; i++)           // Reset memory
        chip->memory[i] = 0x00;

    for(int i = 0; i < 16; i++)             // Reset registers
        chip->V[i] = 0x00;

    loadFontInMemory(chip);                 // Loads the font-set into memory
}

void loadProgramInMemory(Chip *chip, char *program)
{
    int bufferSize = 0xFFF - 0x200;         // Size of the memory which is reserved for the program
    unsigned char buffer[bufferSize];
    FILE *ptr;

    ptr = fopen(program, "rb");
    fread(buffer, bufferSize, 1, ptr);

    for(int i = 0; i < bufferSize; i++)
    chip->memory[i + 512] = buffer[i];  // Reads in the program and stores it in memory at location 0x200 or 512
}

void loadFontInMemory(Chip *chip)
{
    // Zero                         // Six                          // C
    chip->memory[0x000] = 0xF0;     chip->memory[0x01E] = 0xF0;     chip->memory[0x03C] = 0xF0;
    chip->memory[0x001] = 0x90;     chip->memory[0x01F] = 0x80;     chip->memory[0x03D] = 0x80;
    chip->memory[0x002] = 0x90;     chip->memory[0x020] = 0xF0;     chip->memory[0x03E] = 0x80;
    chip->memory[0x003] = 0x90;     chip->memory[0x021] = 0x90;     chip->memory[0x03F] = 0x80;
    chip->memory[0x004] = 0xF0;     chip->memory[0x022] = 0xF0;     chip->memory[0x040] = 0xF0;

    // One                          // Seven                        // D
    chip->memory[0x005] = 0x20;     chip->memory[0x023] = 0xF0;     chip->memory[0x041] = 0xE0;
    chip->memory[0x006] = 0x60;     chip->memory[0x024] = 0x10;     chip->memory[0x042] = 0x90;
    chip->memory[0x007] = 0x20;     chip->memory[0x025] = 0x20;     chip->memory[0x043] = 0x90;
    chip->memory[0x008] = 0x20;     chip->memory[0x026] = 0x40;     chip->memory[0x044] = 0x90;
    chip->memory[0x009] = 0x70;     chip->memory[0x027] = 0x40;     chip->memory[0x045] = 0xE0;

    // Two                          // Eight                        // E
    chip->memory[0x00A] = 0xF0;     chip->memory[0x028] = 0xF0;     chip->memory[0x046] = 0xF0;
    chip->memory[0x00B] = 0x10;     chip->memory[0x029] = 0x90;     chip->memory[0x047] = 0x80;
    chip->memory[0x00C] = 0xF0;     chip->memory[0x02A] = 0xF0;     chip->memory[0x048] = 0xF0;
    chip->memory[0x00D] = 0x80;     chip->memory[0x02B] = 0x90;     chip->memory[0x049] = 0x80;
    chip->memory[0x00E] = 0xF0;     chip->memory[0x02C] = 0xF0;     chip->memory[0x04A] = 0xF0;

    // Three                        // Nine                         // F
    chip->memory[0x00F] = 0xF0;     chip->memory[0x02D] = 0xF0;     chip->memory[0x04B] = 0xF0;
    chip->memory[0x010] = 0x10;     chip->memory[0x02E] = 0x90;     chip->memory[0x04C] = 0x80;
    chip->memory[0x011] = 0xF0;     chip->memory[0x02F] = 0xF0;     chip->memory[0x04D] = 0xF0;
    chip->memory[0x012] = 0x10;     chip->memory[0x030] = 0x10;     chip->memory[0x04E] = 0x80;
    chip->memory[0x013] = 0xF0;     chip->memory[0x031] = 0xF0;     chip->memory[0x04F] = 0x80;

    // Four                         // A
    chip->memory[0x014] = 0x90;     chip->memory[0x032] = 0xF0;
    chip->memory[0x015] = 0x90;     chip->memory[0x033] = 0x90;
    chip->memory[0x016] = 0xF0;     chip->memory[0x034] = 0xF0;
    chip->memory[0x017] = 0x10;     chip->memory[0x035] = 0x90;
    chip->memory[0x018] = 0x10;     chip->memory[0x036] = 0x90;

    // Five                         // B
    chip->memory[0x019] = 0xF0;     chip->memory[0x037] = 0xE0;
    chip->memory[0x01A] = 0x80;     chip->memory[0x038] = 0x90;
    chip->memory[0x01B] = 0xF0;     chip->memory[0x039] = 0xE0;
    chip->memory[0x01C] = 0x10;     chip->memory[0x03A] = 0x90;
    chip->memory[0x01D] = 0xF0;     chip->memory[0x03B] = 0xE0;
}
#include "window.h"

int init(SDL_Window *window, SDL_Renderer *renderer, const 
int width, const int height)
{
//Initialization flag
int success = 1;

//Initialize SDL
if( SDL_Init(SDL_INIT_VIDEO) < 0)
{
    printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
    success = 0;
}
else
{
    //Create window
    window = SDL_CreateWindow( "Chip-8 Emulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN );
    if( window == NULL )
    {
        printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError());
        success = 0;
    }
    else
    {
        renderer = SDL_CreateRenderer(window, -1, 0);
        if(renderer == NULL)
        {
            printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
            success = 0;
        }
        else
        {
            SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0xFF, 0xFF);
        }
    }
}

return success;
}

 void close(SDL_Window *window, SDL_Renderer* renderer)
{
//Destroy window
SDL_DestroyWindow( window );
window = NULL;

SDL_DestroyRenderer(renderer);
renderer = NULL;
//Quit SDL subsystems
SDL_Quit();
}
chip.c

#include "chip.h"

#define NO_ROM_INSERTED 1

const int PIXEL_SIZE = 20;
const int CHIP_WIDTH = 64;
const int CHIP_HEIGHT = 32;

const int SCREEN_WIDTH = CHIP_WIDTH * PIXEL_SIZE;
const int SCREEN_HEIGHT = CHIP_HEIGHT * PIXEL_SIZE;

int main(int argc, char **argv)
{
    SDL_Window *window = NULL;
    SDL_Renderer *renderer = NULL;
    SDL_Event event;
    int quit = 0;

    Chip *chip = (Chip*)malloc(sizeof(Chip));
    chipInitialize(chip);

    chip->gfx[23] = 0x01;

    /*Checks if a ROM file is inserted by an argument*/
    if(argc < 2)    
    {
        printf("Error, no Rom inserted");
        return NO_ROM_INSERTED;
    }
    else
    {
        printf("\n%s loaded into memory\n", argv[argc-1]);
    }

    loadProgramInMemory(chip, "./Roms/TETRIS");


    if(!init(window, renderer, SCREEN_WIDTH, SCREEN_HEIGHT))
    {
        printf( "Failed to initialize!\n" );
    }
    else
    {   
        while(!quit)
        {
            while(SDL_PollEvent(&event) != 0)
            {
                if(event.type == SDL_QUIT)
                {
                    quit = 1;
                }
            }

            // Clear screen
            SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0xFF, 0xFF);
            SDL_RenderClear(renderer);

            for(int i = 0; i < CHIP_HEIGHT; i++)
            {
                for(int j = 0; j < CHIP_WIDTH; j++)
                {
                    if(chip->gfx[i * CHIP_WIDTH + j] > 0x00) //Translates the one dimensional gfx to two dimensional screen
                    {
                        SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0x00, 0xFF);
                        SDL_Rect fillRect = {CHIP_WIDTH * i, CHIP_HEIGHT * j, PIXEL_SIZE, PIXEL_SIZE};
                        SDL_RenderFillRect(renderer, &fillRect);
                    }
                }
            }
            // Update screen
            SDL_RenderPresent(renderer);
        }
    }

    close(window, renderer);

    free(chip);

    return 0;
}
#include "chip.h"

void chipInitialize(Chip *chip)
{
    chip->pc            = 0x200;            // Set program counter to 0x200
    chip->opcode        = 0x0000;           // Reset current opcode
    chip->I             = 0x0000;           // Reset index register
    chip->sp            = 0x0000;           // Reset stack pointer

    chip->delayTimer    = 0x00;             // Reset delay timer
    chip->soundTimer    = 0x00;             // Reset sound timer

    for(int i = 0; i < 64 * 32; i++)        // Reset the graphics
        chip->gfx[i] = 0x00;

    for(int i = 0; i < 16; i++)             // Reset the stack
        chip->stack[i] = 0x0000;

    for(int i = 0; i < 4069; i++)           // Reset memory
        chip->memory[i] = 0x00;

    for(int i = 0; i < 16; i++)             // Reset registers
        chip->V[i] = 0x00;

    loadFontInMemory(chip);                 // Loads the font-set into memory
}

void loadProgramInMemory(Chip *chip, char *program)
{
    int bufferSize = 0xFFF - 0x200;         // Size of the memory which is reserved for the program
    unsigned char buffer[bufferSize];
    FILE *ptr;

    ptr = fopen(program, "rb");
    fread(buffer, bufferSize, 1, ptr);

    for(int i = 0; i < bufferSize; i++)
    chip->memory[i + 512] = buffer[i];  // Reads in the program and stores it in memory at location 0x200 or 512
}

void loadFontInMemory(Chip *chip)
{
    // Zero                         // Six                          // C
    chip->memory[0x000] = 0xF0;     chip->memory[0x01E] = 0xF0;     chip->memory[0x03C] = 0xF0;
    chip->memory[0x001] = 0x90;     chip->memory[0x01F] = 0x80;     chip->memory[0x03D] = 0x80;
    chip->memory[0x002] = 0x90;     chip->memory[0x020] = 0xF0;     chip->memory[0x03E] = 0x80;
    chip->memory[0x003] = 0x90;     chip->memory[0x021] = 0x90;     chip->memory[0x03F] = 0x80;
    chip->memory[0x004] = 0xF0;     chip->memory[0x022] = 0xF0;     chip->memory[0x040] = 0xF0;

    // One                          // Seven                        // D
    chip->memory[0x005] = 0x20;     chip->memory[0x023] = 0xF0;     chip->memory[0x041] = 0xE0;
    chip->memory[0x006] = 0x60;     chip->memory[0x024] = 0x10;     chip->memory[0x042] = 0x90;
    chip->memory[0x007] = 0x20;     chip->memory[0x025] = 0x20;     chip->memory[0x043] = 0x90;
    chip->memory[0x008] = 0x20;     chip->memory[0x026] = 0x40;     chip->memory[0x044] = 0x90;
    chip->memory[0x009] = 0x70;     chip->memory[0x027] = 0x40;     chip->memory[0x045] = 0xE0;

    // Two                          // Eight                        // E
    chip->memory[0x00A] = 0xF0;     chip->memory[0x028] = 0xF0;     chip->memory[0x046] = 0xF0;
    chip->memory[0x00B] = 0x10;     chip->memory[0x029] = 0x90;     chip->memory[0x047] = 0x80;
    chip->memory[0x00C] = 0xF0;     chip->memory[0x02A] = 0xF0;     chip->memory[0x048] = 0xF0;
    chip->memory[0x00D] = 0x80;     chip->memory[0x02B] = 0x90;     chip->memory[0x049] = 0x80;
    chip->memory[0x00E] = 0xF0;     chip->memory[0x02C] = 0xF0;     chip->memory[0x04A] = 0xF0;

    // Three                        // Nine                         // F
    chip->memory[0x00F] = 0xF0;     chip->memory[0x02D] = 0xF0;     chip->memory[0x04B] = 0xF0;
    chip->memory[0x010] = 0x10;     chip->memory[0x02E] = 0x90;     chip->memory[0x04C] = 0x80;
    chip->memory[0x011] = 0xF0;     chip->memory[0x02F] = 0xF0;     chip->memory[0x04D] = 0xF0;
    chip->memory[0x012] = 0x10;     chip->memory[0x030] = 0x10;     chip->memory[0x04E] = 0x80;
    chip->memory[0x013] = 0xF0;     chip->memory[0x031] = 0xF0;     chip->memory[0x04F] = 0x80;

    // Four                         // A
    chip->memory[0x014] = 0x90;     chip->memory[0x032] = 0xF0;
    chip->memory[0x015] = 0x90;     chip->memory[0x033] = 0x90;
    chip->memory[0x016] = 0xF0;     chip->memory[0x034] = 0xF0;
    chip->memory[0x017] = 0x10;     chip->memory[0x035] = 0x90;
    chip->memory[0x018] = 0x10;     chip->memory[0x036] = 0x90;

    // Five                         // B
    chip->memory[0x019] = 0xF0;     chip->memory[0x037] = 0xE0;
    chip->memory[0x01A] = 0x80;     chip->memory[0x038] = 0x90;
    chip->memory[0x01B] = 0xF0;     chip->memory[0x039] = 0xE0;
    chip->memory[0x01C] = 0x10;     chip->memory[0x03A] = 0x90;
    chip->memory[0x01D] = 0xF0;     chip->memory[0x03B] = 0xE0;
}
#include "window.h"

int init(SDL_Window *window, SDL_Renderer *renderer, const 
int width, const int height)
{
//Initialization flag
int success = 1;

//Initialize SDL
if( SDL_Init(SDL_INIT_VIDEO) < 0)
{
    printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
    success = 0;
}
else
{
    //Create window
    window = SDL_CreateWindow( "Chip-8 Emulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN );
    if( window == NULL )
    {
        printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError());
        success = 0;
    }
    else
    {
        renderer = SDL_CreateRenderer(window, -1, 0);
        if(renderer == NULL)
        {
            printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
            success = 0;
        }
        else
        {
            SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0xFF, 0xFF);
        }
    }
}

return success;
}

 void close(SDL_Window *window, SDL_Renderer* renderer)
{
//Destroy window
SDL_DestroyWindow( window );
window = NULL;

SDL_DestroyRenderer(renderer);
renderer = NULL;
//Quit SDL subsystems
SDL_Quit();
}

让我从一个建议开始——如果你对一个答案感兴趣,请不要让回答你的问题变得比需要的更难。想想它对其他人的看法——一些大量的代码,问题似乎在于没有画任何东西;为什么这个示例必须有6个文件?为什么它依赖于我们没有的外部文件,因此根本无法验证?当然,只要使用init和render,就可以将其压缩到30行的单个文件——实际上,SDL2的任何“hello world”都可以。当它起作用而你的代码不起作用时,你就开始检查有什么不同

现在谈谈你的问题。无法从主循环中绘制任何内容,因为此处的
窗口
渲染器
为空-它已初始化为空,并且从未设置为任何其他内容。似乎您对函数参数的工作方式有误解-在C中,函数参数是按值传递的,对该值的任何修改都是对本地函数副本进行的。当您传递一个int时,函数将获取该int的副本,并且不会将任何更改推回。如果传递
SDL_Window*
,则传递该指针的值(在本例中为
NULL
);当您执行
SDL\u CreateWindow
时,您将其分配给局部变量,一旦angain无法将其返回给调用者,调用者将保持空值。因此,所有渲染调用都将NULL作为渲染器传递,这自然不是有效的渲染器

在您的
关闭中也会出现同样的情况-您试图将传递的副本重置为NULL,但这没有意义,因为您不能修改外部值,只能修改函数本地副本

编程课程经常教授“按值传递”和“按引用传递”,我想这是造成这种混乱的原因之一。我更愿意说,在C中并没有通过引用传递,你们总是传递值,但指针也是一个值。为了能够修改数据,我们传递指向该数据的指针;要改变int,您可以传递
int*
,但要改变
SDL\u窗口*
,您需要获得指向该指针的指针-
SDL\u窗口**
。看看SDL本身是如何做到这一点的:

因此,简而言之,将您的
init
设置为
intinit(SDL\u窗口**窗口,SDL\u渲染器**渲染器,int宽度,int高度)(此处也不需要
const int
,因为它们是宽度和高度的副本),并相应地修改其代码。并在调用后检查
window
renderer
的值(调试器、debug printf、
if(window==NULL)
任何事情都会发生)
init
可以是

int init(SDL_Window **owindow, SDL_Renderer **orenderer,
        int width, int height)
{
    SDL_Window *window = NULL;
    SDL_Renderer *renderer = NULL;

    //Initialization flag
    int success = 1;

    //Initialize SDL
    if( SDL_Init(SDL_INIT_VIDEO) < 0)
    {
        printf( "SDL could not initialize! SDL_Error: %s\n", SDL_GetError() );
        success = 0;
    }
    else
    {
        //Create window
        window = SDL_CreateWindow( "Chip-8 Emulator", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, SDL_WINDOW_SHOWN );
        if( window == NULL )
        {
            printf( "Window could not be created! SDL_Error: %s\n", SDL_GetError());
            success = 0;
        }
        else
        {
            renderer = SDL_CreateRenderer(window, -1, 0);
            if(renderer == NULL)
            {
                printf( "Renderer could not be created! SDL Error: %s\n", SDL_GetError() );
                success = 0;
            }
            else
            {
                SDL_SetRenderDrawColor(renderer, 0xFF, 0x00, 0xFF, 0xFF);
            }
        }
    }

    *owindow = window;
    *orenderer = renderer;
    return success;
}
int init(SDL_窗口**owindow,SDL_渲染器**或渲染器,
整数宽度,整数高度)
{
SDL_Window*Window=NULL;
SDL_渲染器*渲染器=NULL;
//初始化标志
int成功=1;
//初始化SDL
if(SDL_Init(SDL_Init_视频)<0)
{
printf(“SDL无法初始化!SDL_错误:%s\n”,SDL_GetError());
成功=0;
}
其他的
{
//创建窗口
window=SDL_CreateWindow(“芯片8模拟器”,SDL_WINDOWPOS_未定义,SDL_WINDOWPOS_未定义,显示宽度、高度、SDL_窗口);
如果(窗口==NULL)
{
printf(“无法创建窗口!SDL_错误:%s\n”,SDL_GetError());
成功=0;
}
其他的
{
渲染器=SDL_CreateRenderer(窗口,-1,0);
if(渲染器==NULL)
{
printf(“无法创建渲染器!SDL错误:%s\n”,SDL_GetError());
成功=0;
}
其他的
{
SDL_SetRenderDrawColor(渲染器,0xFF,0x00,0xFF,0xFF);
}
}
}
*owindow=窗口;
*Orender=渲染器;
回归成功;
}
当然,对
init
的调用必须修改为
init(&window,&renderer,SCREEN\u WIDTH,SCREEN\u HEIGHT)

当我们在做的时候,还有两件事:

  • 头文件应该有,否则,如果您多次(直接或间接)包含它,将导致问题

  • 永远不要调用函数
    close
    。它将在linux/UNIX系统上崩溃(没有任何可能)。想想另一个没有被广泛使用的操作系统保留的名字


并且不要使用
-w
编译器标志。它会抑制所有警告,防止编译器提示您可能的错误,您需要更多的警告(从
-Wall
开始),而不是更少。