gpt4 book ai didi

c++ - 停留在一个基本的 OpenGL 程序上

转载 作者:行者123 更新时间:2023-11-28 07:01:39 30 4
gpt4 key购买 nike

我正在尝试创建一个可用作 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 returns an integer that represents the location of a specific uniform variable within a program object. name must be a null terminated string that contains no white space. name must be an active uniform variable name in program that is not a structure, an array of structures, or a subcomponent of a vector or a matrix.

glGetUniform returns in params the value(s) of the specified uniform variable. The type of the uniform variable specified by location determines the number of values returned. If the uniform variable is defined in the shader as a boolean, int, or float, a single value will be returned. If it is defined as a vec2, ivec2, or bvec2, two values will be returned. If it is defined as a vec3, ivec3, or bvec3, three values will be returned, and so on. To query values stored in uniform variables declared as arrays, call glGetUniform for each element of the array. To query values stored in uniform variables declared as structures, call glGetUniform for each field in the structure. The values for uniform variables declared as a matrix will be returned in column major order.

您的统一变量 uniform mat4 MVPMatrix; 声明为 a matrix type , 不是 an array您将立即检索整个 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 个。

关于c++ - 停留在一个基本的 OpenGL 程序上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22391589/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com