我使用SDL 2.0和OpenGL 1.1编写了一个小测试程序,并遇到了这个非常奇怪的问题:使某些变量const
破坏程序!任何人都可以解释为什么会这样吗?
static float vertexes[] = { // Good
static uint8_t colors[] = {
static float vertexes[] = { // No problem
static const uint8_t colors[] = {
static const float vertexes[] = { // Bad
static const uint8_t colors[] = {
static const float vertexes[] = { // VERY bad
static uint8_t colors[] = {
此程序提供所需的行为。注释掉const
以查看损坏的版本。
// gcc -o main main.c -std=c11 -pedantic -Wall -I. -lm -lmingw32 -lSDL2main -lSDL2 -lopengl32 -lglu32 -mwindows
#include <SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(*arr))
typedef struct {
float x;
float y;
float z;
} vec3;
bool running;
int width, height;
SDL_Window *window;
SDL_GLContext ctx;
vec3 rotation;
static /* const */ float vertexes[] = {
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
-1.0f, -1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, -1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, 1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, 1.0f,
-1.0f, -1.0f, 1.0f,
1.0f, -1.0f, 1.0f,
1.0f, 1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
-1.0f, 1.0f, -1.0f,
1.0f, 1.0f, -1.0f,
1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
};
static /* const */ uint8_t colors[] = {
0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF,
0x00, 0x00, 0xFF,
0x00, 0x7F, 0x3F,
0x00, 0x7F, 0x3F,
0x00, 0x7F, 0x3F,
0x00, 0x7F, 0x3F,
0x00, 0x7F, 0x3F,
0x00, 0x7F, 0x3F,
0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00,
0xFF, 0xFF, 0x00,
0xFF, 0xB3, 0x00,
0xFF, 0xB3, 0x00,
0xFF, 0xB3, 0x00,
0xFF, 0xB3, 0x00,
0xFF, 0xB3, 0x00,
0xFF, 0xB3, 0x00,
0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00,
0xFF, 0x00, 0x00,
};
void onresize(void)
{
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (float)width/(float)height, 1, -1);
}
void init(void);
void fini(void);
void loop(void);
void handle(void);
void render(void);
void update(void);
int main(int argc, char* argv[])
{
init();
loop();
fini();
return 0;
}
void init(void)
{
SDL_DisplayMode mode;
if (SDL_Init(SDL_INIT_VIDEO)) return;
SDL_GetDesktopDisplayMode(0, &mode);
width = mode.w;
height = mode.h;
window = SDL_CreateWindow(
"Game",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
width,
height,
SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN
);
if (!window) return;
ctx = SDL_GL_CreateContext(window);
if (!ctx) return;
onresize();
glEnable(GL_DEPTH_TEST);
running = true;
}
void fini(void)
{
if (ctx) SDL_GL_DeleteContext(ctx);
if (window) SDL_DestroyWindow(window);
SDL_Quit();
}
void loop(void)
{
while (running) {
handle();
render();
update();
}
}
void handle(void)
{
SDL_Event event;
while (SDL_PollEvent(&event)) {
switch (event.type) {
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_RESIZED:
width = event.window.data1, height = event.window.data2;
onresize();
break;
}
break;
case SDL_QUIT:
running = false;
break;
default:
break;
}
}
}
void render(void)
{
glClearColor(0.9f, 0.8f, 0.7f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, -5, 0, 0, 0, 0, 1, 0);
glRotatef(rotation.x, 1, 0, 0);
glRotatef(rotation.y, 0, 1, 0);
glRotatef(rotation.z, 0, 0, 1);
glScalef(0.25f, 0.25f, 0.25f);
glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
glBegin(GL_LINES);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(9.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 9.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 0.0f);
glVertex3f(0.0f, 0.0f, 9.0f);
glEnd();
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glVertexPointer(3, GL_FLOAT, 0, vertexes);
glColorPointer(3, GL_UNSIGNED_BYTE, 0, colors);
glDrawArrays(GL_TRIANGLES, 0, ARRAYSIZE(vertexes));
glEnableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
SDL_GL_SwapWindow(window);
}
void update(void)
{
rotation.x++;
rotation.y++;
}
另作选择here。