[英]Stuck on a basic OpenGL program
我正在嘗試創建一個示例程序,可用作OpenGL的測試工具。 到目前為止,我似乎有一個可行的方法,但是似乎忽略了通過統一變量MVPMatrix傳遞的MVP矩陣。 當我添加代碼以讀取統一版本並檢查其實際更新是否正確時,執行此操作時會收到無效的操作錯誤,我看不到原因-怎么回事?
#include "stdafx.h"
#include <iostream>
#include <memory>
#include <sdl/SDL.h>
#include <assimp/Importer.hpp>
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <sdl/SDL_image.h>
#include <glm/glm.hpp>
#include <Windows.h>
#include <GL/glew.h>
#include <GL/GL.h>
#include <gl/GLU.h>
#include <vector>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <assimp/Importer.hpp>
#include <assimp/mesh.h>
#include <assimp/postprocess.h>
#include <assimp/vector3.h>
using namespace std;
void checkGLShaderStatus(GLuint id, GLuint thingToCheck, bool shader) {
GLint ret;
if (shader) glGetShaderiv(id, thingToCheck, &ret); else glGetProgramiv(id, thingToCheck, &ret);
// If there was an error
if (ret == GL_FALSE) {
// Print it out, then halt
GLint maxLength = 0;
glGetShaderiv(id, GL_INFO_LOG_LENGTH, &maxLength);
GLchar *shaderErrorLog = (GLchar*)malloc(sizeof(GLchar)*(maxLength + 1));
glGetShaderInfoLog(id, maxLength, &maxLength, shaderErrorLog);
shaderErrorLog[maxLength] = '\0';
cout << shaderErrorLog;
free(shaderErrorLog);
int junk;
cin >> junk;
exit(EXIT_FAILURE);
}
}
GLuint buildShader(const GLchar **source, GLuint length, GLenum type) {
// Create the shader
GLuint shaderId = glCreateShader(type);
// Upload source code
glShaderSource(shaderId, length, source, NULL);
// Compile the shader
glCompileShader(shaderId);
// See how the compilation went
checkGLShaderStatus(shaderId, GL_COMPILE_STATUS, true);
return shaderId;
}
void checkGL(string stage) {
GLuint error = glGetError();
if (error != GL_NO_ERROR) {
cout << "OpenGL broke..";
switch (error) {
case GL_INVALID_ENUM:
cout << "Invalid Enum";
break;
case GL_INVALID_VALUE:
cout << "Value out of range";
break;
case GL_INVALID_OPERATION:
cout << "Invalid operation";
break;
case GL_INVALID_FRAMEBUFFER_OPERATION:
cout << "Incomplete framebuffer";
break;
case GL_OUT_OF_MEMORY:
cout << "Out of memory";
break;
default:
cout << "Oh boy, did it break..";
}
cout << " (" << stage << ")" << endl;
int junk;
cin >> junk;
exit(EXIT_FAILURE);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
if (SDL_Init(SDL_INIT_EVERYTHING) == -1) exit(EXIT_FAILURE);
if (IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG) == -1) exit(EXIT_FAILURE);
Assimp::Importer importer;
const aiScene *importedScene = importer.ReadFile("Table.3ds",aiProcess_Triangulate);
if (importedScene == nullptr) exit(EXIT_FAILURE);
aiMesh *theMesh = importedScene->mMeshes[0];
if (theMesh == nullptr) exit(EXIT_FAILURE);
cout << "I imported a mesh with " << theMesh->mNumVertices << " vertices and " << theMesh->mNumFaces << " faces! " << endl;
SDL_Window *win = nullptr;
win = SDL_CreateWindow("My even more awesome SDL/OGL program", 100, 100, 640, 480, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if (win == nullptr) exit(EXIT_FAILURE);
SDL_Renderer *ren = nullptr;
ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if (ren == nullptr) exit(EXIT_FAILURE);
SDL_GLContext context = SDL_GL_CreateContext(win);
if (context == nullptr) exit(EXIT_FAILURE);
glewInit();
int attrib_vPosition = 0;
const GLchar *vertexShaderSource = { "#version 430 core\n"
"layout (location=0) in vec4 vPosition;"
"uniform mat4 MVPMatrix;"
"void main() {"
" gl_Position = MVPMatrix * vPosition;"
"}"};
GLuint vertexShader = buildShader(&vertexShaderSource, 1, GL_VERTEX_SHADER);
checkGL("compiling vertex shader");
const GLchar *fragShaderSource = { "#version 430 core\n"
"out vec4 fColor;"
"void main() {"
" fColor = vec4(0.0, 0.0, 1.0, 1.0);"
"}"
};
GLuint fragmentShader = buildShader(&fragShaderSource, 1, GL_FRAGMENT_SHADER);
checkGL("compiling fragment shader");
GLuint shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);
checkGLShaderStatus(shaderProgram, GL_LINK_STATUS, false);
checkGL("Linking shader");
glUseProgram(shaderProgram);
//glDeleteShader(fragmentShader);
//glDeleteShader(vertexShader);
checkGL("Running shader");
GLint MVPlocation = glGetUniformLocation(shaderProgram, "MVPMatrix");
checkGL("Getting uniform location");
glm::mat4 mvpMatrix(0.1f);
glUniformMatrix4fv(MVPlocation, 1, GL_FALSE, glm::value_ptr(mvpMatrix));
checkGL("Setting uniform");
GLint testLocation = glGetUniformLocation(shaderProgram, "MVPMatrix[0][0]");
checkGL("Getting uninform test cell location");
GLfloat testfloat;
glGetUniformfv(shaderProgram, testLocation, &testfloat);
checkGL("Reading uniform");
if (testfloat != mvpMatrix[0][0]) {
cout << "Uniform setting did not sink in..";
}
GLuint VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
checkGL("Creating VAO");
GLfloat vertices[3][3] = { { -0.9f, -0.9f, 0.f }, { 0.85f, -0.9f, 0.f }, { -0.9f, 0.85f, 0.f } };
GLuint buffer;
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
int vertexDataSize = 9;
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, ((void *)(0)));
glEnableVertexAttribArray(0);
checkGL("creating VBO");
glClearColor(0.f, 0.f, 0.f, 1.f);
glClear(GL_COLOR_BUFFER_BIT);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, vertexDataSize);
glFlush();
SDL_GL_SwapWindow(win);
SDL_Event event;
bool quit = false;
while (!quit) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
quit = true;
}
}
}
glDeleteProgram(shaderProgram);
glDeleteBuffers(1, &buffer);
glDeleteVertexArrays(1, &VAO);
SDL_GL_DeleteContext(context);
SDL_DestroyRenderer(ren);
SDL_DestroyWindow(win);
IMG_Quit();
SDL_Quit();
return 0;
}
您不應該使用glGetUniformfv(... glGetUniformLocation(... "MVPMatrix[0][0]"))
。 該文件說
glGetUniformLocation
返回一個整數,該整數表示程序對象中特定統一變量的位置。 名稱必須是不包含空格的以空終止的字符串。 名稱必須是在程序 的活性均勻的變量名 不是一個結構,結構的陣列,或載體或基質的子組件 。
和
glGetUniform
以參數glGetUniform
返回指定統一變量的值。 由location指定的統一變量的類型決定了返回值的數量。 如果在着色器中將統一變量定義為布爾值,整數或浮點型,則將返回單個值。 如果將其定義為vec2,ivec2或bvec2,則將返回兩個值。 如果將其定義為vec3,ivec3或bvec3,則將返回三個值,依此類推。 要查詢存儲在聲明為數組的統一變量中的值,請為數組的每個元素調用glGetUniform
。 要查詢存儲在聲明為結構的統一變量中的值,請為結構中的每個字段調用glGetUniform
。 聲明為矩陣的統一變量的值將按列主順序返回。
您的統一變量uniform mat4 MVPMatrix;
聲明為矩陣類型 ,而不是數組 ,您將立即檢索整個4x4矩陣(就像在單個操作中設置的一樣)。 嘗試
GLfloat testfloat[16];
glGetUniformfv(shaderProgram, MVPLocation, testfloat);
另一個問題在這里:
GLfloat vertices[3][3] = { { -0.9f, -0.9f, 0.f }, { 0.85f, -0.9f, 0.f }, { -0.9f, 0.85f, 0.f } };
int vertexDataSize = 9;
glDrawArrays(GL_TRIANGLES, 0, vertexDataSize);
您沒有9個頂點,只有3個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.