Advertisement

Minimum of 66 verts?

Started by November 12, 2019 11:15 PM
56 comments, last by Bozemoto 5 years, 2 months ago

I don't want to spend 55£ on a hobby project.
I might splurge at some point, if I'm confident I'll get more use out of it than I did the 3.2 book I've already got.
Graphics programming isn't really my thing, just doing it to get better insight into engine architecture. My day job is as a game mechanics programmer so don't get exposed to alot of this information normally. I'm keen on learning more about game development as I go on, most people at work just do their 8 hours. It's a big studio, many are older and have kids and families etc so have other commitments.

Video Game Programmer.
5 years in industry.

Eureka. I've narrowed it down to this matrix


static const GLfloat matrix[] = {
    1.0f, 0.0f, 0.0f, 0.0f,
    0.0f, 1.0f, 0.0f, 0.0f,
    0.0f, 0.0f, 1.0f, 0.0f,
    0.0f, 0.0f, 0.0f, 1.0f,
};


GLint modelViewProjMatLocation = glGetUniformLocation(shaderProgram, "in_ModelViewProjection");
if (modelViewProjMatLocation != -1)
{
    glEnableVertexAttribArray(modelViewProjMatLocation);
    glUniformMatrix4fv(modelViewProjMatLocation, 1, GL_FALSE, &matrix[0]);
}


And in the shader


uniform mat4 in_ModelViewProjection;

I started off with an example program and introduced more and more of my code, broke when I added this.
I tried making a static const GLfloat array set to the identity. And that still didn't work. 
Any ideas?

Video Game Programmer.
5 years in industry.

Advertisement

Maybe I'm missing something, but what is this line:


glEnableVertexAttribArray(modelViewProjMatLocation);

Intended to do?

Ah! you don't need to enable uniforms? I thought you had to enable any field that the shader was intended to use.
Why does it only break for matrices? And why doesn't it generate an error?

Video Game Programmer.
5 years in industry.

37 minutes ago, Net-Ninja said:

Ah! you don't need to enable uniforms?

Nope. As mentioned above, a uniform is not a vertex array. Vertey arrays exist to stream in per vertex (or primitive) data. Uniforms otoh are uniform (don't chenge) across a whole draw call (across all vertices in the drawcall) if not modified in the shader themselves (usually not the case, only if you want to change vertices depending on the value of a uniform). The vertex shader is executed once per vertex, one vertex from the stream after another, under application of the same uniforms, until all vertices have been processed. But the uniforms stay the same during that execution.The application only sees a draw call, and the preparation via activating the stream and setting the uniforms.

Quote

I thought you had to enable any field that the shader was intended to use.

Only the vertex attributes.

Quote

Why does it only break for matrices? And why doesn't it generate an error?

Nothing breaks, a 4*4 matrix, if declared in the shader as a uniform "layout( location = n ) uniform mat4 matrixName" is a uniform. It is set via one the glUniformMatrix4xx apis. But see the concept of a uniform buffer, with which a group of uniforms can be chunked together and handed over to opengl as a whole.

We must distinguish between the stream data (vertex arrays with their sttributes held in an array buffer) that just comes into the vertex shader vertex after vertey, and the uniform data that is meant to control the handling of one such stream. In your example, you want the same matrix operation to be executed on every vertex in the stream.

I say, grab the bloody book on OpenGL 4.5 for <30 quid (at least in euro). Much has changed in the last 15 years i read. And it won't get easier when one day the switch to Vulkan or some even werider api must be made ... ?

 

I just find it strange that a uniform, which isn't a vertex array gets called with glEnablevertexAttribArray it doesn't error.
Are uniforms and vertex arrays interchangeable to the shader? If so why have the word "uniform" in the shader at all?
I'd assume there is no valid scenario where calling glEnablevertexAttribArray is valid?

Red was 30£, blue was 26£ = 56£ together. I got my last red book around 2009 I think.
I'll consider throwing some money at it.

And by saying that it breaks for matrices I don't mean to imply it's correct to use it. I'm just saying that it renders fine for large vertex counts, if you use glDrawElements, when you do it to vec3s and vec4s and doesn't generate any errors, and works flawlessly when you use a debug context (presumably it blocks the operation). I think that's an error would be most appropriate, a crash in random memory is a bit vague, and has been a nightmare to debug.

Video Game Programmer.
5 years in industry.

Advertisement
2 minutes ago, Net-Ninja said:

I just find it strange that a uniform, which isn't a vertex array gets called with glEnablevertexAttribArray it doesn't error.

If you mean you're wondering why this:


glEnableVertexAttribArray(modelViewProjMatLocation);

Doesn't generate an error, keep in mind that that version of glEnableVertexAttribArray() just takes an integer value, so if the value you submit happens to be appropriate/correct with respect to vertex attribute arrays, it won't necessarily cause any problems. In fact, if the uniform location value happens to correspond to a vertex attribute array that's already enabled, that statement could have no effect at all, despite being incorrect.

Zakwayda: Thanks, that's seems sensible. Guess C++ typesafety has made me a bit blind to type-less stuff like this.

Video Game Programmer.
5 years in industry.

Yes, @Zakwaydais right.

There is a thing that the debug context doesn't catch and that can be really annoying, that is trying to set a unfiorm that doesn't exist in the currently bound shader's interface does not provoke an error message. That is, maybe, because the interfaces are kept or cached somewhere, so that if you switch a pipeline (a compiled shaderprogram with its shader stages and some otheer settings), the interface still exists, but is just not active atm. I believe (but am not sure and would like to be corrected), that is because changing pipelines is an expensive operation, the driver may assume that the set value is needed later elsewhere and thus accepts it.

In general, the debug context does not inhibit processing, it only generates a text message with some organisational info and sends it to a buffer where it can be picked up by the callback. Also, different classes of messages must be enabled. Learnopengl.com has the dirty details ?

19 hours ago, bioglaze said:

If vertices is empty, .data() doesn't crash. 

I find your interpretation to be incorrect.

I get the same behaviour for both, using MSVC++.


#include <iostream>
#include <vector>
using namespace std;

int main(void)
{
    vector<char> charvec;
    
    cout << reinterpret_cast<size_t>(&charvec[0]) << endl;
    cout << reinterpret_cast<size_t>(charvec.data()) << endl;
    
    charvec.push_back('H');
    charvec.push_back('e');
    charvec.push_back('l');
    charvec.push_back('l');
    charvec.push_back('o');
    
    cout << reinterpret_cast<size_t>(&charvec[0]) << endl;
    cout << reinterpret_cast<size_t>(charvec.data()) << endl;
    
    return 0;
}
	

 

This topic is closed to new replies.

Advertisement