我使用 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 .
最佳答案
在 glDrawArrays()
调用中使用 ARRAYSIZE(vertexes)/3
而不是 ARRAYSIZE(vertexes)
。
glDrawArrays()
的 count
参数是顶点数,而不是 float 。现在,您告诉 OpenGL 将顶点/颜色数组的末尾读入 $DIETY
-knows-what。你很幸运,它没有出现段错误。
const
/non-const
可能只是 switching其中segment数组最终会为 OpenGL 提供不同的“垃圾”顶点来尝试解释。
关于c - 使用 `const` 中断程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38402726/