我试图通过https://open.gl/drawing上的示例来学习openGL 3.0(它只是在屏幕上绘制一个彩色矩形)。
我正在使用SDL2.0.5和glew 2.0.0与VS2015社区,它在运行Win7 pro x64的i5 skylake HD4000笔记本电脑上运行良好。但是,当我在同一台笔记本电脑(双启动Win和Linux)上使用gcc和glew 2.0.0在Ubuntu Gnome 17.04 x64上编译完全相同的源时,我在GL_INVALID_OPERATION 1282
处收到glUseProgram(shaderProgram)
错误。
编译器运行时没有警告:
g++ main.cpp -Wall -I/usr/include/SDL2 -lGL -lGLEW -lSDL2 -lSDL2_image -lSDL2_mixer -o game
此功能之前没有错误(为清楚起见,我删除了错误检查代码)。
此外,屏幕从普通桌面变为空白黑屏,然后重复直到我退出应用程序。如果我注释掉SDL_GL_SwapWindow(gameWindow)
,屏幕消隐不会发生,但错误仍然存在。
我已经尝试将上下文更改为3.3并将着色器版本更改为#version 330 core - 同样的问题。
我还使用了英特尔图形更新工具来获取最新的驱动程序。
以下一些系统信息:
product: Intel(R) Core(TM) i5-3340M CPU @ 2.70GHz
vendor: Intel Corp.
physical id: 1
bus info: cpu@0
size: 3199MHz
capacity: 3400MHz
width: 64 bits
capabilities: fpu fpu_exception wp vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp x86-64 constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm epb tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt dtherm ida arat pln pts cpufreq
description: VGA compatible controller
product: 3rd Gen Core processor Graphics Controller
vendor: Intel Corporation
physical id: 2
bus info: pci@0000:00:02.0
version: 09
width: 64 bits
clock: 33MHz
capabilities: msi pm vga_controller bus_master cap_list rom
configuration: driver=i915 latency=0
resources: irq:29 memory:f6400000-f67fffff memory:e0000000-efffffff ioport:f000(size=64) memory:c0000-dffff
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Ivybridge Mobile
OpenGL core profile version string: 3.3 (Core Profile) Mesa 17.0.3
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 17.0.3
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 17.0.3
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00
OpenGL ES profile extensions:
源代码:
#define GLEW_STATIC
#include <GL/glew.h>
#include <SDL.h>
#include <SDL_opengl.h>
#include <iostream>
// SDL2 global pointers
SDL_Window* gameWindow = NULL;
SDL_GLContext context = NULL;
SDL_Surface* screenSurface = NULL;
SDL_Renderer* gameRenderer = NULL;
// Shader sources
const GLchar* vertexSource = R"glsl(
#version 150 core
in vec2 position;
in vec3 color;
out vec3 Color;
void main()
{
Color = color;
gl_Position = vec4(position, 0.0, 1.0);
}
)glsl";
const GLchar* fragmentSource = R"glsl(
#version 150 core
in vec3 Color;
out vec4 outColor;
void main()
{
outColor = vec4(Color, 1.0);
}
)glsl";
int main(int argc, char *argv[])
{
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
if(SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
printf("SDL_Init failed! Error: %s\n", SDL_GetError());
return -1;
}
else printf("SDL_Init OK.\n");
gameWindow = SDL_CreateWindow("OpenGL", 100, 100, 400, 300, SDL_WINDOW_OPENGL);
if (gameWindow == NULL)
{
printf("SDL_CreateWindow failed! Error: %s\n", SDL_GetError());
SDL_Delay(1000);
SDL_Quit();
return -1;
}
else printf("SDL_CreateWindow OK.\n");
context = SDL_GL_CreateContext(gameWindow);
if(context == NULL)
{
printf("SDL_CreateWindow failed! Error: %s\n", SDL_GetError());
SDL_Delay(1000);
SDL_DestroyWindow(gameWindow);
SDL_Quit();
return -1;
}
else printf("SDL_GL_CreateContext OK.\n");
glewExperimental=GL_TRUE;
GLenum glew_init_error = glewInit();
if (GLEW_OK != glew_init_error)
{
fprintf(stderr, "glewInit failed! Error: %s\n", glewGetErrorString(glew_init_error));
SDL_Delay(1000);
SDL_GL_DeleteContext(context);
SDL_DestroyWindow(gameWindow);
SDL_Quit();
return -1;
}
else fprintf(stdout, "glewInit OK. Version: %s\n", glewGetString(GLEW_VERSION));
// Create Vertex Array Object
GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// Create a Vertex Buffer Object and copy the vertex data to it
GLuint vbo;
glGenBuffers(1, &vbo);
GLfloat vertices[] = {
-0.5f, 0.5f, 1.0f, 0.0f, 0.0f, // Top-left
0.5f, 0.5f, 0.0f, 1.0f, 0.0f, // Top-right
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, // Bottom-right
-0.5f, -0.5f, 1.0f, 1.0f, 1.0f // Bottom-left
};
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// Create an element array
GLuint ebo;
glGenBuffers(1, &ebo);
GLuint elements[] = {
0, 1, 2,
2, 3, 0
};
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(elements), elements, GL_STATIC_DRAW);
// Create and compile the vertex shader
GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexSource, NULL);
glCompileShader(vertexShader);
// Create and compile the fragment shader
GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentSource, NULL);
glCompileShader(fragmentShader);
// Link the vertex and fragment shader into a shader program
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glBindFragDataLocation(shaderProgram, 0, "outColor");
glLinkProgram(shaderProgram);
// ************** THE NEXT FUNCTION CALL FAILS WITH GL_INVALID_OPERATION *********************************
glUseProgram(shaderProgram);
// Specify the layout of the vertex data
GLint posAttrib = glGetAttribLocation(shaderProgram, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), 0);
GLint colAttrib = glGetAttribLocation(shaderProgram, "color");
glEnableVertexAttribArray(colAttrib);
glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (void*)(2 * sizeof(GLfloat)));
SDL_Event windowEvent;
while (true)
{
if (SDL_PollEvent(&windowEvent))
{
if (windowEvent.type == SDL_QUIT) break;
if (windowEvent.type == SDL_KEYUP && windowEvent.key.keysym.sym == SDLK_ESCAPE) break;
}
// Clear the screen to black
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// Draw a rectangle from the 2 triangles using 6 indices
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
SDL_GL_SwapWindow(gameWindow);
}
glDeleteProgram(shaderProgram);
glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);
glDeleteBuffers(1, &ebo);
glDeleteBuffers(1, &vbo);
glDeleteVertexArrays(1, &vao);
SDL_GL_DeleteContext(context);
SDL_Delay(1000);
SDL_Quit();
return 0;
}
答案 0 :(得分:0)
检查着色器是否已成功编译并与glGetShaderiv / InfoLog和glGetProgramiv / InfoLog成功链接 - pleluron
感谢Pleluron我添加了着色器和链接器错误日志代码,发现在我的核心i5 HD4000 Linux上,GPU驱动程序不支持我使用的1.5(#version 150)着色器版本。当我改变顶点&amp;片段着色器版本为1.3(#version 130),主要/次要SDL上下文属性为3.0,它解决了问题。 (虽然我必须修改GL3.0 / GLSL1.3的着色器代码。)
让我感到困惑的是glxinfo报告下面的OpenGL3.3和GLSL 3.3,所以我希望能够准确地使用...
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Ivybridge Mobile
OpenGL core profile version string: 3.3 (Core Profile) Mesa 17.0.3
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
...但也报告了OpenGL 3.0&amp;下面的GLSL 1.30,虽然被要求提供更高版本,但似乎是在通过SDL创建上下文时使用的?
OpenGL version string: 3.0 Mesa 17.0.3
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
我会深入研究并更新这个答案。