我正在尝试学习OpenGL作为学生。我花了很多时间试图弄清楚为什么这个简单的应用程序不起作用。这是我们教授给出的一个例子。 (我们正在使用visual studio在windows中工作,但我别无选择,只能在家中使用Linux,这不是一种任性)。这是我写的程序(在Windows上运行完美),只是显示一个黑色的窗口(它应该显示一个三角形)。
//
// main.cpp
// OpenGL_Shader_Example_step1
//
// Created by CGIS on 30/11/15.
// Copyright © 2015 CGIS. All rights reserved.
//
#define GLEW_STATIC
#include <iostream>
#include "GL/glew.h"
#include "GLFW/glfw3.h"
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
int glWindowWidth = 640;
int glWindowHeight = 480;
int retina_width, retina_height;
GLFWwindow* glWindow = NULL;
GLuint shaderProgram;
GLfloat vertexCoordinates[] = {
0.0f, 0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
-0.5f, -0.5f, 0.0f
};
GLuint verticesVBO;
GLuint triangleVAO;
void windowResizeCallback(GLFWwindow* window, int width, int height)
{
fprintf(stdout, "window resized to width: %d , and height: %d\n", width, height);
//TODO
}
void initObjects()
{
//generate a unique ID corresponding to the verticesVBO
glGenBuffers(1, &verticesVBO);
//bind the verticesVBO buffer to the GL_ARRAY_BUFFER target,
//any further buffer call made to GL_ARRAY_BUFFER will configure the
//currently bound buffer, which is verticesVBO
glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
//copy data into the currently bound buffer, the first argument specify
//the type of the buffer, the second argument specify the size (in bytes) of data,
//the third argument is the actual data we want to send,
//the last argument specify how should the graphic card manage the data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexCoordinates), vertexCoordinates, GL_STATIC_DRAW);
//generate a unique ID corresponding to the triangleVAO
glGenVertexArrays(1, &triangleVAO);
glBindVertexArray(triangleVAO);
glBindBuffer(GL_ARRAY_BUFFER, verticesVBO);
//set the vertex attributes pointers
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
//unbind the triangleVAO
glBindVertexArray(0);
}
bool initOpenGLWindow()
{
if (!glfwInit()) {
fprintf(stderr, "ERROR: could not start GLFW3\n");
return false;
}
//for Mac OS X
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glWindow = glfwCreateWindow(glWindowWidth, glWindowHeight, "OpenGL Shader Example", NULL, NULL);
if (!glWindow) {
fprintf(stderr, "ERROR: could not open window with GLFW3\n");
glfwTerminate();
return false;
}
glfwSetWindowSizeCallback(glWindow, windowResizeCallback);
glfwMakeContextCurrent(glWindow);
glfwWindowHint(GLFW_SAMPLES, 4);
// start GLEW extension handler
glewExperimental = GL_TRUE;
glewInit();
// get version info
const GLubyte* renderer = glGetString(GL_RENDERER); // get renderer string
const GLubyte* version = glGetString(GL_VERSION); // version as a string
printf("Renderer: %s\n", renderer);
printf("OpenGL version supported %s\n", version);
//for RETINA display
glfwGetFramebufferSize(glWindow, &retina_width, &retina_height);
return true;
}
void renderScene()
{
//clear the color and depth buffer before rendering the current frame
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//specify the background color
glClearColor(0.8, 0.8, 0.8, 1.0);
//specify the viewport location and dimension
glViewport (0, 0, retina_width, retina_height);
//process the keyboard inputs
if (glfwGetKey(glWindow, GLFW_KEY_A)) {
//TODO
}
if (glfwGetKey(glWindow, GLFW_KEY_D)) {
//TODO
}
//bind the shader program, any further rendering call
//will use this shader program
glUseProgram(shaderProgram);
//bind the VAO
glBindVertexArray(triangleVAO);
//specify the type of primitive, the starting index and
//the number of indices to be rendered
glDrawArrays(GL_TRIANGLES, 0, 3);
}
std::string readShaderFile(std::string fileName)
{
std::ifstream shaderFile;
std::string shaderString;
//open shader file
shaderFile.open(fileName.c_str());
std::stringstream shaderStringStream;
//read shader content into stream
shaderStringStream << shaderFile.rdbuf();
//close shader file
shaderFile.close();
//convert stream into GLchar array
shaderString = shaderStringStream.str();
return shaderString;
}
void shaderCompileLog(GLuint shaderId)
{
GLint success;
GLchar infoLog[512];
//check compilation info
glGetShaderiv(shaderId, GL_COMPILE_STATUS, &success);
if (!success)
{
glGetShaderInfoLog(shaderId, 512, NULL, infoLog);
std::cout << "Shader compilation error\n" << infoLog << std::endl;
}
}
void shaderLinkLog(GLuint shaderProgramId)
{
GLint success;
GLchar infoLog[512];
//check linking info
glGetProgramiv(shaderProgramId, GL_LINK_STATUS, &success);
if (!success) {
glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
std::cout << "Shader linking error\n" << infoLog << std::endl;
}
}
GLuint initBasicShader(std::string vertexShaderFileName, std::string fragmentShaderFileName)
{
//read, parse and compile the vertex shader
std::string v = readShaderFile(vertexShaderFileName);
const GLchar* vertexShaderString = v.c_str();
GLuint vertexShader;
vertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(vertexShader, 1, &vertexShaderString, NULL);
glCompileShader(vertexShader);
//check compilation status
shaderCompileLog(vertexShader);
//read, parse and compile the vertex shader
std::string f = readShaderFile(fragmentShaderFileName);
const GLchar* fragmentShaderString = f.c_str();
GLuint fragmentShader;
fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(fragmentShader, 1, &fragmentShaderString, NULL);
glCompileShader(fragmentShader);
//check compilation status
shaderCompileLog(fragmentShader);
//attach and link the shader programs
shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
glDeleteShader(vertexShader);
glDeleteShader(fragmentShader);
//check linking info
shaderLinkLog(shaderProgram);
return shaderProgram;
}
int main(int argc, const char * argv[])
{
initOpenGLWindow();
initObjects();
shaderProgram = initBasicShader("shaders/shader.vert", "shaders/shader.frag");
while (!glfwWindowShouldClose(glWindow)) {
renderScene();
glfwPollEvents();
glfwSwapBuffers(glWindow);
}
//close GL context and any other GLFW resources
glfwTerminate();
return 0;
}
以下是着色器程序: shader.frag:
#version 300 es
precision mediump float;
in vec3 colour;
out vec4 frag_colour;
void main() {
frag_colour = vec4 (colour, 1.0);
}
和shader.vert:
#version 300 es
layout (location = 0) in vec3 vertex_position;
out vec3 colour;
void main() {
colour = vec3(1.0, 0.0, 0.0);
gl_Position = vec4(vertex_position, 1.0);
}
这是用于编译程序的命令(我正在使用visual studio代码):
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "0.1.0",
"command": "g++",
"isShellCommand": true,
"args": ["-g",
"-Wall",
"-o", "lab2.exe",
"main.cpp",
"-I/usr/include/c++/4.8.5",
"-I/usr/include/GL",
"-I/usr/include/glm",
"-I/usr/local/include/GLFW",
"-L/usr/local/lib", "-lGLEW", "-lGLU", "-lglfw3", "-lGL", "-lm", "-ldl", "-lXrender", "-ldrm",
"-lXdamage", "-lX11-xcb", "-lxcb-glx", "-lxcb-dri2", "-lxcb-dri3", "-lxcb-present", "-lxcb-sync", "-lxshmfence", "-lXxf86vm",
"-lXfixes", "-lXext", "-lX11", "-lpthread", "-lxcb", "-lXau", "-lXdmcp",
"-lXrandr", "-lXi", "-lXxf86vm", "-lXcursor"],
"showOutput": "always"
}
args param给g ++。 如果我有一个错误,我会有一个点从哪里开始,但像这样我不知道该怎么做。
以下是glxinfo | grep OpenGL
命令的结果:
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Haswell Mobile
OpenGL core profile version string: 3.3 (Core Profile) Mesa 11.2.0
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 11.2.0
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
答案 0 :(得分:0)
我建议使用opengl / glsl调试器来查看发生了什么。已经有一段时间了,但我之前使用glslDevil取得了很大的成功 - 它兼容Linux并且可以帮助你发现一个opengl错误 - 特别是你硬件/平台上不支持的功能。